--- /dev/null
+{\r
+ "asset": {\r
+ "generator": "COLLADA2GLTF",\r
+ "version": "2.0"\r
+ },\r
+ "scene": 0,\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 81,\r
+ 0\r
+ ]\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "children": [\r
+ 80,\r
+ 79,\r
+ 78,\r
+ 77,\r
+ 76,\r
+ 75,\r
+ 74,\r
+ 73,\r
+ 13,\r
+ 10,\r
+ 7,\r
+ 4,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 3,\r
+ 2\r
+ ],\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 136.860107421875,\r
+ -64.45372009277344,\r
+ -36.179630279541019,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "matrix": [\r
+ -1.0,\r
+ 8.979318677493353e-11,\r
+ 0.0,\r
+ 0.0,\r
+ -8.979318677493353e-11,\r
+ -1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -294.67718505859377,\r
+ 73.97987365722656,\r
+ 16.17963218688965,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 1,\r
+ "matrix": [\r
+ 0.9995650053024292,\r
+ 0.029493184760212896,\r
+ 0.0,\r
+ 0.0,\r
+ -0.029493184760212896,\r
+ 0.9995650053024292,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -45.315460205078128,\r
+ -24.617263793945317,\r
+ -26.320369720458986,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 6,\r
+ 5\r
+ ],\r
+ "matrix": [\r
+ -1.0,\r
+ 8.979318677493353e-11,\r
+ 0.0,\r
+ 0.0,\r
+ -8.979318677493353e-11,\r
+ -1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -136.860107421875,\r
+ 64.45372009277344,\r
+ 3.8203670978546144,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "matrix": [\r
+ -1.0,\r
+ 8.979318677493353e-11,\r
+ 0.0,\r
+ 0.0,\r
+ -8.979318677493353e-11,\r
+ -1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -294.67718505859377,\r
+ 73.97987365722656,\r
+ 16.17963218688965,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 1,\r
+ "matrix": [\r
+ 0.9995650053024292,\r
+ 0.029493184760212896,\r
+ 0.0,\r
+ 0.0,\r
+ -0.029493184760212896,\r
+ 0.9995650053024292,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -45.315460205078128,\r
+ -24.617263793945317,\r
+ -26.32036781311035,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 9,\r
+ 8\r
+ ],\r
+ "matrix": [\r
+ -0.5,\r
+ -0.8660253882408142,\r
+ 0.0,\r
+ 0.0,\r
+ 0.8660253882408142,\r
+ -0.5,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 18.09818458557129,\r
+ -69.69783782958985,\r
+ -105.559814453125,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 2,\r
+ "matrix": [\r
+ -0.9390941858291626,\r
+ 0.3436597883701325,\r
+ 0.0,\r
+ 0.0,\r
+ -0.3436597883701325,\r
+ -0.9390941858291626,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -51.311012268066409,\r
+ -50.52240753173828,\r
+ -18.440185546875,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 3,\r
+ "matrix": [\r
+ -0.9390941858291626,\r
+ 0.3436597883701325,\r
+ 0.0,\r
+ 0.0,\r
+ -0.3436597883701325,\r
+ -0.9390941858291626,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -51.311012268066409,\r
+ -50.52240753173828,\r
+ 107.559814453125,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 12,\r
+ 11\r
+ ],\r
+ "matrix": [\r
+ 0.7071067690849304,\r
+ -0.7071067690849304,\r
+ 0.0,\r
+ 0.0,\r
+ 0.7071067690849304,\r
+ 0.7071067690849304,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 47.17867660522461,\r
+ -52.821327209472659,\r
+ -88.94477081298828,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 4,\r
+ "matrix": [\r
+ -0.4234085381031037,\r
+ -0.9059388637542724,\r
+ -7.575183536001616e-11,\r
+ 0.0,\r
+ -0.9059388637542724,\r
+ 0.4234085381031037,\r
+ -4.821281221478735e-11,\r
+ 0.0,\r
+ 7.575183536001616e-11,\r
+ 4.821281221478735e-11,\r
+ -1.0,\r
+ 0.0,\r
+ -90.59386444091796,\r
+ -24.379817962646489,\r
+ -40.05522918701172,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 5,\r
+ "matrix": [\r
+ -1.877404400829619e-7,\r
+ -1.194886607436274e-7,\r
+ 1.0,\r
+ 0.0,\r
+ -0.905938446521759,\r
+ 0.42340943217277529,\r
+ -1.194886607436274e-7,\r
+ 0.0,\r
+ -0.42340943217277529,\r
+ -0.905938446521759,\r
+ -1.877404400829619e-7,\r
+ 0.0,\r
+ -30.2958984375,\r
+ -52.56131362915039,\r
+ 25.05522727966309,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 72,\r
+ 71,\r
+ 70,\r
+ 69,\r
+ 68,\r
+ 67,\r
+ 66,\r
+ 65,\r
+ 14\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 64,\r
+ 63,\r
+ 62,\r
+ 61,\r
+ 60,\r
+ 59,\r
+ 58,\r
+ 57,\r
+ 56,\r
+ 43,\r
+ 29,\r
+ 15\r
+ ],\r
+ "matrix": [\r
+ -2.430540746445331e-7,\r
+ 0.0000014087579529586949,\r
+ -1.0,\r
+ 0.0,\r
+ -1.0,\r
+ -2.430540746445331e-7,\r
+ 2.4305373358402006e-7,\r
+ 0.0,\r
+ -2.4305373358402006e-7,\r
+ 1.0,\r
+ 0.0000014087580666455324,\r
+ 0.0,\r
+ -48.26182556152344,\r
+ -59.11042404174805,\r
+ 34.595985412597659,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 28,\r
+ 27,\r
+ 16\r
+ ],\r
+ "matrix": [\r
+ -0.4546820223331452,\r
+ 0.6541662216186523,\r
+ -0.6044260263442993,\r
+ 0.0,\r
+ 0.8696397542953491,\r
+ 0.4726206660270691,\r
+ -0.1426759660243988,\r
+ 0.0,\r
+ 0.19233042001724244,\r
+ -0.590505063533783,\r
+ -0.7837810516357422,\r
+ 0.0,\r
+ 14.898193359375,\r
+ 85.82951354980469,\r
+ -48.034645080566409,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 26,\r
+ 25,\r
+ 24,\r
+ 23,\r
+ 22,\r
+ 21,\r
+ 20,\r
+ 19,\r
+ 18,\r
+ 17\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8450329899787903,\r
+ 0.005398945417255163,\r
+ -0.5346869230270386,\r
+ 0.0,\r
+ -0.4710906744003296,\r
+ 0.4805830717086792,\r
+ -0.7396712303161621,\r
+ 0.0,\r
+ 0.25296804308891299,\r
+ 0.8769326210021973,\r
+ 0.4086519181728363,\r
+ 0.0,\r
+ -74.0894775390625,\r
+ 71.41646575927735,\r
+ -157.91323852539066,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.7145451903343201,\r
+ -0.1154177337884903,\r
+ 0.6900028586387634,\r
+ 0.0,\r
+ -0.6522517800331116,\r
+ 0.4665486216545105,\r
+ -0.5974110960960388,\r
+ 0.0,\r
+ -0.25296807289123537,\r
+ -0.8769327998161316,\r
+ -0.4086515009403229,\r
+ 0.0,\r
+ 122.53109741210938,\r
+ 86.64814758300781,\r
+ -312.3133850097656,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8450329899787903,\r
+ 0.005398945417255163,\r
+ -0.5346869230270386,\r
+ 0.0,\r
+ -0.4710906744003296,\r
+ 0.4805830717086792,\r
+ -0.7396712303161621,\r
+ 0.0,\r
+ 0.25296804308891299,\r
+ 0.8769326210021973,\r
+ 0.4086519181728363,\r
+ 0.0,\r
+ -69.3792953491211,\r
+ 71.78133392333985,\r
+ -161.61203002929688,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.7145451903343201,\r
+ -0.1154177337884903,\r
+ 0.6900028586387634,\r
+ 0.0,\r
+ -0.6522517800331116,\r
+ 0.4665486216545105,\r
+ -0.5974110960960388,\r
+ 0.0,\r
+ -0.25296807289123537,\r
+ -0.8769327998161316,\r
+ -0.4086515009403229,\r
+ 0.0,\r
+ 127.24127197265624,\r
+ 87.01302337646485,\r
+ -316.0121765136719,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8450329899787903,\r
+ 0.005398945417255163,\r
+ -0.5346869230270386,\r
+ 0.0,\r
+ -0.4710906744003296,\r
+ 0.4805830717086792,\r
+ -0.7396712303161621,\r
+ 0.0,\r
+ 0.25296804308891299,\r
+ 0.8769326210021973,\r
+ 0.4086519181728363,\r
+ 0.0,\r
+ -64.66907501220703,\r
+ 72.14624786376953,\r
+ -165.310791015625,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.7145451903343201,\r
+ -0.1154177337884903,\r
+ 0.6900028586387634,\r
+ 0.0,\r
+ -0.6522517800331116,\r
+ 0.4665486216545105,\r
+ -0.5974110960960388,\r
+ 0.0,\r
+ -0.25296807289123537,\r
+ -0.8769327998161316,\r
+ -0.4086515009403229,\r
+ 0.0,\r
+ 131.9515380859375,\r
+ 87.37792205810547,\r
+ -319.7109680175781,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8450329899787903,\r
+ 0.005398945417255163,\r
+ -0.5346869230270386,\r
+ 0.0,\r
+ -0.4710906744003296,\r
+ 0.4805830717086792,\r
+ -0.7396712303161621,\r
+ 0.0,\r
+ 0.25296804308891299,\r
+ 0.8769326210021973,\r
+ 0.4086519181728363,\r
+ 0.0,\r
+ -59.958885192871097,\r
+ 72.5111312866211,\r
+ -169.00955200195313,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.7145451903343201,\r
+ -0.1154177337884903,\r
+ 0.6900028586387634,\r
+ 0.0,\r
+ -0.6522517800331116,\r
+ 0.4665486216545105,\r
+ -0.5974110960960388,\r
+ 0.0,\r
+ -0.25296807289123537,\r
+ -0.8769327998161316,\r
+ -0.4086515009403229,\r
+ 0.0,\r
+ 136.66165161132813,\r
+ 87.74280548095703,\r
+ -323.4097595214844,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8450329899787903,\r
+ 0.005398945417255163,\r
+ -0.5346869230270386,\r
+ 0.0,\r
+ -0.4710906744003296,\r
+ 0.4805830717086792,\r
+ -0.7396712303161621,\r
+ 0.0,\r
+ 0.25296804308891299,\r
+ 0.8769326210021973,\r
+ 0.4086519181728363,\r
+ 0.0,\r
+ -55.24869537353516,\r
+ 72.87601470947266,\r
+ -172.70831298828126,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.7145451903343201,\r
+ -0.1154177337884903,\r
+ 0.6900028586387634,\r
+ 0.0,\r
+ -0.6522517800331116,\r
+ 0.4665486216545105,\r
+ -0.5974110960960388,\r
+ 0.0,\r
+ -0.25296807289123537,\r
+ -0.8769327998161316,\r
+ -0.4086515009403229,\r
+ 0.0,\r
+ 141.37188720703126,\r
+ 88.10767364501953,\r
+ -327.1084899902344,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 7,\r
+ "matrix": [\r
+ 0.7850325703620911,\r
+ 0.06081420928239823,\r
+ -0.6164620518684387,\r
+ 0.0,\r
+ -0.13561886548995973,\r
+ 0.9878994822502136,\r
+ -0.07524696737527847,\r
+ 0.0,\r
+ 0.6044265031814575,\r
+ 0.14267520606517793,\r
+ 0.7837808728218079,\r
+ 0.0,\r
+ -5.746735095977783,\r
+ -250.409912109375,\r
+ -86.68790435791016,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 8,\r
+ "matrix": [\r
+ 0.785033106803894,\r
+ 0.06081344559788704,\r
+ -0.616461455821991,\r
+ 0.0,\r
+ -0.3681585192680359,\r
+ -0.7545340061187744,\r
+ -0.5432658195495606,\r
+ 0.0,\r
+ -0.4981790184974671,\r
+ 0.6534371972084045,\r
+ -0.569945216178894,\r
+ 0.0,\r
+ 34.187137603759769,\r
+ 252.666015625,\r
+ 65.06369018554688,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 42,\r
+ 41,\r
+ 30\r
+ ],\r
+ "matrix": [\r
+ 0.4546822011470794,\r
+ 0.6541662216186523,\r
+ 0.604425847530365,\r
+ 0.0,\r
+ -0.8696396350860596,\r
+ 0.4726209044456482,\r
+ 0.14267593622207642,\r
+ 0.0,\r
+ -0.1923305094242096,\r
+ -0.5905048847198486,\r
+ 0.7837811708450317,\r
+ 0.0,\r
+ 91.87051391601564,\r
+ 80.63255310058594,\r
+ 166.26089477539066,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 40,\r
+ 39,\r
+ 38,\r
+ 37,\r
+ 36,\r
+ 35,\r
+ 34,\r
+ 33,\r
+ 32,\r
+ 31\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8620702028274536,\r
+ -0.015319700352847577,\r
+ -0.506557285785675,\r
+ 0.0,\r
+ -0.4340354502201081,\r
+ 0.4936883449554444,\r
+ -0.7535814642906189,\r
+ 0.0,\r
+ 0.26162606477737429,\r
+ 0.8695039749145508,\r
+ 0.41894471645355227,\r
+ 0.0,\r
+ -77.39921569824219,\r
+ 74.49835205078125,\r
+ -159.90199279785157,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.6893031001091003,\r
+ -0.13550062477588654,\r
+ 0.7116886973381043,\r
+ 0.0,\r
+ -0.6755834221839905,\r
+ 0.47497618198394778,\r
+ -0.5639013051986694,\r
+ 0.0,\r
+ -0.2616262137889862,\r
+ -0.8695039749145508,\r
+ -0.4189445376396179,\r
+ 0.0,\r
+ 115.9541015625,\r
+ 89.47693634033203,\r
+ -311.7364501953125,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8620702028274536,\r
+ -0.015319700352847577,\r
+ -0.506557285785675,\r
+ 0.0,\r
+ -0.4340354502201081,\r
+ 0.4936883449554444,\r
+ -0.7535814642906189,\r
+ 0.0,\r
+ 0.26162606477737429,\r
+ 0.8695039749145508,\r
+ 0.41894471645355227,\r
+ 0.0,\r
+ -71.11894989013672,\r
+ 74.98487091064453,\r
+ -164.83367919921876,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.6893031001091003,\r
+ -0.13550062477588654,\r
+ 0.7116886973381043,\r
+ 0.0,\r
+ -0.6755834221839905,\r
+ 0.47497618198394778,\r
+ -0.5639013051986694,\r
+ 0.0,\r
+ -0.2616262137889862,\r
+ -0.8695039749145508,\r
+ -0.4189445376396179,\r
+ 0.0,\r
+ 122.234375,\r
+ 89.96346282958985,\r
+ -316.668212890625,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8620702028274536,\r
+ -0.015319700352847577,\r
+ -0.506557285785675,\r
+ 0.0,\r
+ -0.4340354502201081,\r
+ 0.4936883449554444,\r
+ -0.7535814642906189,\r
+ 0.0,\r
+ 0.26162606477737429,\r
+ 0.8695039749145508,\r
+ 0.41894471645355227,\r
+ 0.0,\r
+ -64.83870697021485,\r
+ 75.47139739990235,\r
+ -169.76536560058598,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.6893031001091003,\r
+ -0.13550062477588654,\r
+ 0.7116886973381043,\r
+ 0.0,\r
+ -0.6755834221839905,\r
+ 0.47497618198394778,\r
+ -0.5639013051986694,\r
+ 0.0,\r
+ -0.2616262137889862,\r
+ -0.8695039749145508,\r
+ -0.4189445376396179,\r
+ 0.0,\r
+ 128.51461791992188,\r
+ 90.44998931884766,\r
+ -321.5999145507813,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8620702028274536,\r
+ -0.015319700352847577,\r
+ -0.506557285785675,\r
+ 0.0,\r
+ -0.4340354502201081,\r
+ 0.4936883449554444,\r
+ -0.7535814642906189,\r
+ 0.0,\r
+ 0.26162606477737429,\r
+ 0.8695039749145508,\r
+ 0.41894471645355227,\r
+ 0.0,\r
+ -58.558441162109378,\r
+ 75.9579086303711,\r
+ -174.6970672607422,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.6893031001091003,\r
+ -0.13550062477588654,\r
+ 0.7116886973381043,\r
+ 0.0,\r
+ -0.6755834221839905,\r
+ 0.47497618198394778,\r
+ -0.5639013051986694,\r
+ 0.0,\r
+ -0.2616262137889862,\r
+ -0.8695039749145508,\r
+ -0.4189445376396179,\r
+ 0.0,\r
+ 134.79489135742188,\r
+ 90.9365005493164,\r
+ -326.5315856933594,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ 0.8620702028274536,\r
+ -0.015319700352847577,\r
+ -0.506557285785675,\r
+ 0.0,\r
+ -0.4340354502201081,\r
+ 0.4936883449554444,\r
+ -0.7535814642906189,\r
+ 0.0,\r
+ 0.26162606477737429,\r
+ 0.8695039749145508,\r
+ 0.41894471645355227,\r
+ 0.0,\r
+ -52.27817535400391,\r
+ 76.44441223144531,\r
+ -179.62875366210938,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 6,\r
+ "matrix": [\r
+ -0.6893031001091003,\r
+ -0.13550062477588654,\r
+ 0.7116886973381043,\r
+ 0.0,\r
+ -0.6755834221839905,\r
+ 0.47497618198394778,\r
+ -0.5639013051986694,\r
+ 0.0,\r
+ -0.2616262137889862,\r
+ -0.8695039749145508,\r
+ -0.4189445376396179,\r
+ 0.0,\r
+ 141.07516479492188,\r
+ 91.42301940917968,\r
+ -331.4632263183594,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 7,\r
+ "matrix": [\r
+ 0.7850325703620911,\r
+ 0.06081420928239823,\r
+ -0.6164620518684387,\r
+ 0.0,\r
+ -0.13561886548995973,\r
+ 0.9878994822502136,\r
+ -0.07524696737527847,\r
+ 0.0,\r
+ 0.6044265031814575,\r
+ 0.14267520606517793,\r
+ 0.7837808728218079,\r
+ 0.0,\r
+ -1.248520016670227,\r
+ -250.06192016601566,\r
+ -90.22713470458985,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 8,\r
+ "matrix": [\r
+ 0.7850322723388672,\r
+ 0.06081392988562584,\r
+ -0.6164625287055969,\r
+ 0.0,\r
+ -0.3924780488014221,\r
+ -0.7211048007011414,\r
+ -0.5709367990493774,\r
+ 0.0,\r
+ -0.4792549908161164,\r
+ 0.6901518106460571,\r
+ -0.5422223806381226,\r
+ 0.0,\r
+ 45.59693908691406,\r
+ 243.51312255859376,\r
+ 69.38878631591797,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 55,\r
+ 54,\r
+ 49,\r
+ 44\r
+ ],\r
+ "matrix": [\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ -0.0022710729390382768,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0022710729390382768,\r
+ 0.0,\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ -0.13409000635147096,\r
+ -12.999988555908204,\r
+ 0.12365700304508208,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 48,\r
+ 47,\r
+ 46,\r
+ 45\r
+ ],\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -0.000007999999979801942,\r
+ -0.000011000000085914508,\r
+ -99.9995346069336,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 9,\r
+ "matrix": [\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ 0.002270043129101396,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -0.002270043129101396,\r
+ 0.0,\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ 49.7321662902832,\r
+ 344.3533630371094,\r
+ 79.59915161132813,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 10,\r
+ "matrix": [\r
+ 0.9999974370002748,\r
+ 1.0191530236923485e-13,\r
+ 0.0022699993569403888,\r
+ 0.0,\r
+ -1.0191530236923485e-13,\r
+ -1.0,\r
+ 8.97931243248884e-11,\r
+ 0.0,\r
+ 0.0022699993569403888,\r
+ -8.97931243248884e-11,\r
+ -0.9999974370002748,\r
+ 0.0,\r
+ 49.69811248779297,\r
+ 257.12298583984377,\r
+ 94.59911346435549,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 11,\r
+ "matrix": [\r
+ 0.9986716508865356,\r
+ -4.959933574966158e-10,\r
+ -0.051525991410017017,\r
+ 0.0,\r
+ -0.051525991410017017,\r
+ -1.9239376314317274e-8,\r
+ -0.9986716508865356,\r
+ 0.0,\r
+ -4.959933574966158e-10,\r
+ 1.0,\r
+ -1.9239376314317274e-8,\r
+ 0.0,\r
+ 67.53964233398438,\r
+ 326.7381286621094,\r
+ 297.74066162109377,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 11,\r
+ "matrix": [\r
+ 0.9986629486083984,\r
+ -1.884843170429917e-9,\r
+ -0.05169397220015526,\r
+ 0.0,\r
+ -0.05169397220015526,\r
+ -7.287438563707839e-8,\r
+ -0.9986629486083984,\r
+ 0.0,\r
+ -1.884843170429917e-9,\r
+ 1.0,\r
+ -7.287438563707839e-8,\r
+ 0.0,\r
+ 17.574960708618165,\r
+ 326.7381286621094,\r
+ 297.6291809082031,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 53,\r
+ 52,\r
+ 51,\r
+ 50\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 9,\r
+ "matrix": [\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ 0.002270043129101396,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -0.002270043129101396,\r
+ 0.0,\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ 49.50515365600586,\r
+ 344.3533630371094,\r
+ 79.59934997558594,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 10,\r
+ "matrix": [\r
+ 0.9999974370002748,\r
+ 1.0191530236923485e-13,\r
+ 0.0022699993569403888,\r
+ 0.0,\r
+ -1.0191530236923485e-13,\r
+ -1.0,\r
+ 8.97931243248884e-11,\r
+ 0.0,\r
+ 0.0022699993569403888,\r
+ -8.97931243248884e-11,\r
+ -0.9999974370002748,\r
+ 0.0,\r
+ 49.47110366821289,\r
+ 257.1229553222656,\r
+ 94.59931182861328,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 11,\r
+ "matrix": [\r
+ 0.9984543323516846,\r
+ -6.428584886641885e-10,\r
+ -0.05557801201939583,\r
+ 0.0,\r
+ -0.05557801201939583,\r
+ -2.311567648405344e-8,\r
+ -0.9984543323516846,\r
+ 0.0,\r
+ -6.428584886641885e-10,\r
+ 1.0,\r
+ -2.311567648405344e-8,\r
+ 0.0,\r
+ 68.16710662841797,\r
+ 326.7381286621094,\r
+ 297.7886657714844,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 11,\r
+ "matrix": [\r
+ 0.998445212841034,\r
+ 5.507552747197052e-10,\r
+ -0.05574197694659233,\r
+ 0.0,\r
+ -0.05574197694659233,\r
+ 1.97455189976381e-8,\r
+ -0.998445212841034,\r
+ 0.0,\r
+ 5.507552747197052e-10,\r
+ 1.0,\r
+ 1.97455189976381e-8,\r
+ 0.0,\r
+ 18.201759338378908,\r
+ 326.7381286621094,\r
+ 297.6770324707031,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 12,\r
+ "matrix": [\r
+ -0.9999873638153076,\r
+ -0.004487415309995413,\r
+ -0.0022699744440615179,\r
+ 0.0,\r
+ 0.004487401805818081,\r
+ -0.999989926815033,\r
+ 0.000011093182365584652,\r
+ 0.0,\r
+ -0.0022700014524161817,\r
+ 9.06754564766743e-7,\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ -29.98022842407227,\r
+ 768.69921875,\r
+ -20.581327438354493,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 12,\r
+ "matrix": [\r
+ -0.9999850392341614,\r
+ -0.004973169881850481,\r
+ -0.002269970485940576,\r
+ 0.0,\r
+ 0.004973156377673149,\r
+ -0.9999876618385316,\r
+ 0.00001164450713986298,\r
+ 0.0,\r
+ -0.0022700002882629639,\r
+ 3.554153522600245e-7,\r
+ 0.9999974370002748,\r
+ 0.0,\r
+ 48.794708251953128,\r
+ 768.6771850585938,\r
+ -20.40250396728516,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 13,\r
+ "matrix": [\r
+ -0.8213930726051331,\r
+ 0.3830228745937348,\r
+ 0.4226191341876984,\r
+ 0.0,\r
+ -0.3830228745937348,\r
+ 0.17860689759254456,\r
+ -0.9063073992729188,\r
+ 0.0,\r
+ -0.4226191341876984,\r
+ -0.9063073992729188,\r
+ 4.807415265872805e-8,\r
+ 0.0,\r
+ -141.64085388183598,\r
+ 388.6727600097656,\r
+ 122.00779724121094,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 13,\r
+ "matrix": [\r
+ -0.8213450312614441,\r
+ -0.38299909234046938,\r
+ 0.42273396253585818,\r
+ 0.0,\r
+ -0.38312679529190077,\r
+ -0.1786557286977768,\r
+ -0.9062538146972656,\r
+ 0.0,\r
+ 0.4226182401180268,\r
+ -0.906307816505432,\r
+ 7.823305168130901e-7,\r
+ 0.0,\r
+ -270.7940673828125,\r
+ 145.4340057373047,\r
+ 122.04411315917968,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 14,\r
+ "matrix": [\r
+ 1.0,\r
+ -0.000060999998822808269,\r
+ -0.000001000000338535756,\r
+ 0.0,\r
+ 0.000001000000338535756,\r
+ 9.44896494381453e-10,\r
+ 1.0,\r
+ 0.0,\r
+ -0.000060999998822808269,\r
+ -1.0,\r
+ 1.0058964772241553e-9,\r
+ 0.0,\r
+ 51.087928771972659,\r
+ 325.7384033203125,\r
+ 91.09835815429688,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 15,\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ -1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 24.52630043029785,\r
+ 213.73817443847657,\r
+ 283.0735778808594,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 16,\r
+ "matrix": [\r
+ 0.9026297926902772,\r
+ -0.4304177761077881,\r
+ 0.0,\r
+ 0.0,\r
+ 0.4304177761077881,\r
+ 0.9026297926902772,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 353.9793395996094,\r
+ 330.9040222167969,\r
+ -5.389931201934815,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 17,\r
+ "matrix": [\r
+ 0.9026297330856324,\r
+ 0.4304178953170777,\r
+ 0.0,\r
+ 0.0,\r
+ -0.4304178953170777,\r
+ 0.9026297330856324,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 277.7611083984375,\r
+ 580.0806274414063,\r
+ -5.3898539543151859,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 18,\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -1.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 49.58733749389649,\r
+ 175.73818969726566,\r
+ 89.59835815429688,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 19,\r
+ "matrix": [\r
+ 0.9999933242797852,\r
+ -1.649976856532565e-11,\r
+ 0.003653998486697674,\r
+ 0.0,\r
+ 0.003653998486697674,\r
+ 9.031045244967118e-9,\r
+ -0.9999933242797852,\r
+ 0.0,\r
+ -1.649976856532565e-11,\r
+ 1.0,\r
+ 9.031045244967118e-9,\r
+ 0.0,\r
+ 81.19497680664063,\r
+ 247.73817443847657,\r
+ 220.1460723876953,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 19,\r
+ "matrix": [\r
+ 0.9999898672103882,\r
+ -4.353116391658807e-12,\r
+ -0.004497999791055918,\r
+ 0.0,\r
+ -0.004497999791055918,\r
+ -1.9355692604250409e-9,\r
+ -0.9999898672103882,\r
+ 0.0,\r
+ -4.353116391658807e-12,\r
+ 1.0,\r
+ -1.9355692604250409e-9,\r
+ 0.0,\r
+ -23.12494468688965,\r
+ 247.73817443847657,\r
+ 220.35459899902345,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 20,\r
+ "matrix": [\r
+ -2.907086411596538e-7,\r
+ 0.7071071863174439,\r
+ -0.7071064114570618,\r
+ 0.0,\r
+ 7.018321639407077e-7,\r
+ -0.7071064114570618,\r
+ -0.7071071863174439,\r
+ 0.0,\r
+ -1.0,\r
+ -7.018321639407077e-7,\r
+ -2.907086411596538e-7,\r
+ 0.0,\r
+ 65.0,\r
+ 128.71702575683598,\r
+ -3.270524024963379,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 21,\r
+ "matrix": [\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ -1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 223.9999847412109,\r
+ 31.98792839050293,\r
+ 23.50873374938965,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 22,\r
+ "matrix": [\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ -1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 223.9999847412109,\r
+ 30.487924575805665,\r
+ 25.008731842041017,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 23,\r
+ "matrix": [\r
+ 1.1084333451094608e-10,\r
+ -0.0009251347510144116,\r
+ -0.9999995827674866,\r
+ 0.0,\r
+ 2.396268712345773e-7,\r
+ -0.9999995827674866,\r
+ 0.0009251347510144116,\r
+ 0.0,\r
+ -1.0,\r
+ -2.396268712345773e-7,\r
+ 1.1084333451094608e-10,\r
+ 0.0,\r
+ -295.0,\r
+ 21.498876571655278,\r
+ 0.49255698919296267,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 23,\r
+ "matrix": [\r
+ 5.062397168131838e-10,\r
+ 0.002356505487114191,\r
+ -0.9999971985816956,\r
+ 0.0,\r
+ -4.2965237412317949e-7,\r
+ -0.9999971985816956,\r
+ -0.002356505487114191,\r
+ 0.0,\r
+ -1.0,\r
+ 4.2965237412317949e-7,\r
+ 5.062397168131838e-10,\r
+ 0.0,\r
+ -295.0,\r
+ 21.60527801513672,\r
+ -105.32867431640624,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 24,\r
+ "matrix": [\r
+ -1.0,\r
+ 6.349337028366264e-11,\r
+ 6.349337028366264e-11,\r
+ 0.0,\r
+ -6.349337028366264e-11,\r
+ -2.220446049250313e-16,\r
+ -1.0,\r
+ 0.0,\r
+ -6.349337028366264e-11,\r
+ -1.0,\r
+ -2.220446049250313e-16,\r
+ 0.0,\r
+ -126.93566131591796,\r
+ 0.000003000000106112566,\r
+ 36.558841705322269,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 25,\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -1.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 126.93566131591796,\r
+ -0.00005299999975250103,\r
+ -36.5588493347168,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 26\r
+ },\r
+ {\r
+ "mesh": 27,\r
+ "matrix": [\r
+ -0.9861037135124208,\r
+ 0.16613073647022248,\r
+ 0.0,\r
+ 0.0,\r
+ -0.16613073647022248,\r
+ -0.9861037135124208,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -71.01806640625,\r
+ -22.193012237548829,\r
+ -20.0,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 27,\r
+ "matrix": [\r
+ 0.9861037135124208,\r
+ -0.16613082587718965,\r
+ 0.0,\r
+ 0.0,\r
+ 0.16613082587718965,\r
+ 0.9861037135124208,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 71.01806640625,\r
+ 22.19301414489746,\r
+ 22.0,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 28,\r
+ "matrix": [\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -1.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ -100.0,\r
+ -66.15117645263672,\r
+ -5.627896785736084,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 28,\r
+ "matrix": [\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -1.0,\r
+ 0.0,\r
+ 4.4896641959724089e-11,\r
+ 0.0,\r
+ -100.0,\r
+ -66.15116882324219,\r
+ 14.372098922729493,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 28,\r
+ "matrix": [\r
+ -2.220446049250313e-16,\r
+ 6.349337028366264e-11,\r
+ 1.0,\r
+ 0.0,\r
+ -6.349337028366264e-11,\r
+ -1.0,\r
+ 6.349337028366264e-11,\r
+ 0.0,\r
+ 1.0,\r
+ -6.349337028366264e-11,\r
+ -2.220446049250313e-16,\r
+ 0.0,\r
+ 100.0,\r
+ -133.8488311767578,\r
+ 34.37212753295899,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 28,\r
+ "matrix": [\r
+ -2.220446049250313e-16,\r
+ 6.349337028366264e-11,\r
+ 1.0,\r
+ 0.0,\r
+ -6.349337028366264e-11,\r
+ -1.0,\r
+ 6.349337028366264e-11,\r
+ 0.0,\r
+ 1.0,\r
+ -6.349337028366264e-11,\r
+ -2.220446049250313e-16,\r
+ 0.0,\r
+ 100.0,\r
+ -133.8488311767578,\r
+ 54.37212371826172,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 23,\r
+ "matrix": [\r
+ 5.062397168131838e-10,\r
+ 0.002356505487114191,\r
+ -0.9999971985816956,\r
+ 0.0,\r
+ -4.2965237412317949e-7,\r
+ -0.9999971985816956,\r
+ -0.002356505487114191,\r
+ 0.0,\r
+ -1.0,\r
+ 4.2965237412317949e-7,\r
+ 5.062397168131838e-10,\r
+ 0.0,\r
+ -295.0,\r
+ 123.80779266357422,\r
+ -100.10150146484377,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 23,\r
+ "matrix": [\r
+ 5.062397168131838e-10,\r
+ 0.002356505487114191,\r
+ -0.9999971985816956,\r
+ 0.0,\r
+ -4.2965237412317949e-7,\r
+ -0.9999971985816956,\r
+ -0.002356505487114191,\r
+ 0.0,\r
+ -1.0,\r
+ 4.2965237412317949e-7,\r
+ 5.062397168131838e-10,\r
+ 0.0,\r
+ -295.0,\r
+ 132.1395263671875,\r
+ -3.9833459854125978,\r
+ 1.0\r
+ ]\r
+ },\r
+ {\r
+ "matrix": [\r
+ 0.7071067690849304,\r
+ -2.1563657526257888e-7,\r
+ -0.7071068286895752,\r
+ 0.0,\r
+ -0.3312943577766419,\r
+ 0.883452296257019,\r
+ -0.33129459619522097,\r
+ 0.0,\r
+ 0.6246951818466187,\r
+ 0.4685211479663849,\r
+ 0.6246950030326843,\r
+ 0.0,\r
+ 1005.9874267578124,\r
+ 766.3170776367188,\r
+ 953.3455810546876,\r
+ 1.0\r
+ ],\r
+ "camera": 0\r
+ }\r
+ ],\r
+ "cameras": [\r
+ {\r
+ "perspective": {\r
+ "aspectRatio": 1.0,\r
+ "yfov": 0.3143463730812073,\r
+ "zfar": 1000000.0,\r
+ "znear": 0.04999999701976776\r
+ },\r
+ "type": "perspective"\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 1,\r
+ "POSITION": 2\r
+ },\r
+ "indices": 0,\r
+ "mode": 4,\r
+ "material": 0\r
+ },\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 4,\r
+ "POSITION": 5\r
+ },\r
+ "indices": 3,\r
+ "mode": 4,\r
+ "material": 1\r
+ }\r
+ ],\r
+ "name": "Piston_123-844_0_Parts_1"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 7,\r
+ "POSITION": 8\r
+ },\r
+ "indices": 6,\r
+ "mode": 4,\r
+ "material": 2\r
+ }\r
+ ],\r
+ "name": "body_24"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 10,\r
+ "POSITION": 11\r
+ },\r
+ "indices": 9,\r
+ "mode": 4,\r
+ "material": 3\r
+ }\r
+ ],\r
+ "name": "body_23"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 13,\r
+ "POSITION": 14\r
+ },\r
+ "indices": 12,\r
+ "mode": 4,\r
+ "material": 4\r
+ }\r
+ ],\r
+ "name": "body_22"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 16,\r
+ "POSITION": 17\r
+ },\r
+ "indices": 15,\r
+ "mode": 4,\r
+ "material": 5\r
+ }\r
+ ],\r
+ "name": "body_21"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 19,\r
+ "POSITION": 20\r
+ },\r
+ "indices": 18,\r
+ "mode": 4,\r
+ "material": 6\r
+ }\r
+ ],\r
+ "name": "body_20"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 22,\r
+ "POSITION": 23\r
+ },\r
+ "indices": 21,\r
+ "mode": 4,\r
+ "material": 7\r
+ },\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 25,\r
+ "POSITION": 26\r
+ },\r
+ "indices": 24,\r
+ "mode": 4,\r
+ "material": 8\r
+ },\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 28,\r
+ "POSITION": 29\r
+ },\r
+ "indices": 27,\r
+ "mode": 4,\r
+ "material": 9\r
+ }\r
+ ],\r
+ "name": "Spring_Link__0_Parts_1"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 31,\r
+ "POSITION": 32\r
+ },\r
+ "indices": 30,\r
+ "mode": 4,\r
+ "material": 10\r
+ }\r
+ ],\r
+ "name": "body_19"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 34,\r
+ "POSITION": 35\r
+ },\r
+ "indices": 33,\r
+ "mode": 4,\r
+ "material": 11\r
+ }\r
+ ],\r
+ "name": "body_18"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 37,\r
+ "POSITION": 38\r
+ },\r
+ "indices": 36,\r
+ "mode": 4,\r
+ "material": 12\r
+ }\r
+ ],\r
+ "name": "body_17"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 40,\r
+ "POSITION": 41\r
+ },\r
+ "indices": 39,\r
+ "mode": 4,\r
+ "material": 13\r
+ }\r
+ ],\r
+ "name": "body_16"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 43,\r
+ "POSITION": 44\r
+ },\r
+ "indices": 42,\r
+ "mode": 4,\r
+ "material": 14\r
+ }\r
+ ],\r
+ "name": "body_15"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 46,\r
+ "POSITION": 47\r
+ },\r
+ "indices": 45,\r
+ "mode": 4,\r
+ "material": 15\r
+ }\r
+ ],\r
+ "name": "body_14"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 49,\r
+ "POSITION": 50\r
+ },\r
+ "indices": 48,\r
+ "mode": 4,\r
+ "material": 16\r
+ }\r
+ ],\r
+ "name": "body_13"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 52,\r
+ "POSITION": 53\r
+ },\r
+ "indices": 51,\r
+ "mode": 4,\r
+ "material": 17\r
+ }\r
+ ],\r
+ "name": "body_12"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 55,\r
+ "POSITION": 56\r
+ },\r
+ "indices": 54,\r
+ "mode": 4,\r
+ "material": 18\r
+ }\r
+ ],\r
+ "name": "body_11"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 58,\r
+ "POSITION": 59\r
+ },\r
+ "indices": 57,\r
+ "mode": 4,\r
+ "material": 19\r
+ }\r
+ ],\r
+ "name": "body_10"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 61,\r
+ "POSITION": 62\r
+ },\r
+ "indices": 60,\r
+ "mode": 4,\r
+ "material": 20\r
+ }\r
+ ],\r
+ "name": "body_9"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 64,\r
+ "POSITION": 65\r
+ },\r
+ "indices": 63,\r
+ "mode": 4,\r
+ "material": 21\r
+ }\r
+ ],\r
+ "name": "body_8"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 67,\r
+ "POSITION": 68\r
+ },\r
+ "indices": 66,\r
+ "mode": 4,\r
+ "material": 22\r
+ }\r
+ ],\r
+ "name": "body_7"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 70,\r
+ "POSITION": 71\r
+ },\r
+ "indices": 69,\r
+ "mode": 4,\r
+ "material": 23\r
+ }\r
+ ],\r
+ "name": "body_6"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 73,\r
+ "POSITION": 74\r
+ },\r
+ "indices": 72,\r
+ "mode": 4,\r
+ "material": 24\r
+ }\r
+ ],\r
+ "name": "body_5"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 76,\r
+ "POSITION": 77\r
+ },\r
+ "indices": 75,\r
+ "mode": 4,\r
+ "material": 25\r
+ }\r
+ ],\r
+ "name": "body_4"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 79,\r
+ "POSITION": 80\r
+ },\r
+ "indices": 78,\r
+ "mode": 4,\r
+ "material": 26\r
+ }\r
+ ],\r
+ "name": "body"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 82,\r
+ "POSITION": 83\r
+ },\r
+ "indices": 81,\r
+ "mode": 4,\r
+ "material": 27\r
+ }\r
+ ],\r
+ "name": "body_3"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 85,\r
+ "POSITION": 86\r
+ },\r
+ "indices": 84,\r
+ "mode": 4,\r
+ "material": 28\r
+ }\r
+ ],\r
+ "name": "body_2"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 88,\r
+ "POSITION": 89\r
+ },\r
+ "indices": 87,\r
+ "mode": 4,\r
+ "material": 29\r
+ }\r
+ ],\r
+ "name": "body_1"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 91,\r
+ "POSITION": 92\r
+ },\r
+ "indices": 90,\r
+ "mode": 4,\r
+ "material": 30\r
+ },\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 94,\r
+ "POSITION": 95\r
+ },\r
+ "indices": 93,\r
+ "mode": 4,\r
+ "material": 31\r
+ }\r
+ ],\r
+ "name": "rod_123-699_0_Parts_1"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 97,\r
+ "POSITION": 98\r
+ },\r
+ "indices": 96,\r
+ "mode": 4,\r
+ "material": 32\r
+ },\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 100,\r
+ "POSITION": 101\r
+ },\r
+ "indices": 99,\r
+ "mode": 4,\r
+ "material": 33\r
+ }\r
+ ],\r
+ "name": "Lifter_123-923_0_Parts_1"\r
+ }\r
+ ],\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 0,\r
+ "componentType": 5123,\r
+ "count": 8250,\r
+ "max": [\r
+ 2011\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 2012,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 24144,\r
+ "componentType": 5126,\r
+ "count": 2012,\r
+ "max": [\r
+ 63.35246658325195,\r
+ 56.026153564453128,\r
+ 46.5\r
+ ],\r
+ "min": [\r
+ -43.13071060180664,\r
+ -36.97384643554688,\r
+ -46.5\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 16500,\r
+ "componentType": 5123,\r
+ "count": 5034,\r
+ "max": [\r
+ 1295\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 48288,\r
+ "componentType": 5126,\r
+ "count": 1296,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 0.9992589950561525\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -0.9992589950561525\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 63840,\r
+ "componentType": 5126,\r
+ "count": 1296,\r
+ "max": [\r
+ 53.35246658325195,\r
+ 56.026153564453128,\r
+ 46.46559143066406\r
+ ],\r
+ "min": [\r
+ 31.869285583496095,\r
+ -36.97384643554688,\r
+ -46.46559143066406\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 26568,\r
+ "componentType": 5123,\r
+ "count": 936,\r
+ "max": [\r
+ 263\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 79392,\r
+ "componentType": 5126,\r
+ "count": 264,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 82560,\r
+ "componentType": 5126,\r
+ "count": 264,\r
+ "max": [\r
+ -242.49256896972657,\r
+ 107.58116149902344,\r
+ 85.0\r
+ ],\r
+ "min": [\r
+ -264.4925537109375,\r
+ 85.59744262695313,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 28440,\r
+ "componentType": 5123,\r
+ "count": 1845,\r
+ "max": [\r
+ 669\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 85728,\r
+ "componentType": 5126,\r
+ "count": 670,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 93768,\r
+ "componentType": 5126,\r
+ "count": 670,\r
+ "max": [\r
+ 35.97993087768555,\r
+ 35.75779342651367,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ -35.97993087768555,\r
+ -35.97336959838867,\r
+ -15.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 32130,\r
+ "componentType": 5123,\r
+ "count": 6489,\r
+ "max": [\r
+ 1552\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 101808,\r
+ "componentType": 5126,\r
+ "count": 1553,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 120444,\r
+ "componentType": 5126,\r
+ "count": 1553,\r
+ "max": [\r
+ 63.0,\r
+ 35.0,\r
+ 113.5\r
+ ],\r
+ "min": [\r
+ -62.99030303955078,\r
+ -35.0,\r
+ -140.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 45108,\r
+ "componentType": 5123,\r
+ "count": 9267,\r
+ "max": [\r
+ 2469\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 139080,\r
+ "componentType": 5126,\r
+ "count": 2470,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 168720,\r
+ "componentType": 5126,\r
+ "count": 2470,\r
+ "max": [\r
+ 68.9806137084961,\r
+ -31.11992645263672,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ -68.9806137084961,\r
+ -168.8800811767578,\r
+ -15.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 63642,\r
+ "componentType": 5123,\r
+ "count": 4839,\r
+ "max": [\r
+ 1381\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 198360,\r
+ "componentType": 5126,\r
+ "count": 1382,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 214944,\r
+ "componentType": 5126,\r
+ "count": 1382,\r
+ "max": [\r
+ 177.38954162597657,\r
+ -14.305740356445313,\r
+ 18.985939025878908\r
+ ],\r
+ "min": [\r
+ -76.1104507446289,\r
+ -55.56795501708985,\r
+ -19.073078155517576\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 73320,\r
+ "componentType": 5123,\r
+ "count": 123,\r
+ "max": [\r
+ 42\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 231528,\r
+ "componentType": 5126,\r
+ "count": 43,\r
+ "max": [\r
+ 0.9818310141563416,\r
+ 0.9992589950561525,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 232044,\r
+ "componentType": 5126,\r
+ "count": 43,\r
+ "max": [\r
+ 131.15240478515626,\r
+ -35.549163818359378,\r
+ 5.0\r
+ ],\r
+ "min": [\r
+ 129.44984436035157,\r
+ -37.250465393066409,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 73566,\r
+ "componentType": 5123,\r
+ "count": 123,\r
+ "max": [\r
+ 42\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 232560,\r
+ "componentType": 5126,\r
+ "count": 43,\r
+ "max": [\r
+ 0.9992589950561525,\r
+ 1.0,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ -0.9992589950561525,\r
+ -0.9818310141563416,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 233076,\r
+ "componentType": 5126,\r
+ "count": 43,\r
+ "max": [\r
+ 131.19471740722657,\r
+ -61.50555038452149,\r
+ 5.0\r
+ ],\r
+ "min": [\r
+ 129.4075164794922,\r
+ -63.2940788269043,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 73812,\r
+ "componentType": 5123,\r
+ "count": 4842,\r
+ "max": [\r
+ 869\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 233592,\r
+ "componentType": 5126,\r
+ "count": 870,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 0.9992589950561525\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 244032,\r
+ "componentType": 5126,\r
+ "count": 870,\r
+ "max": [\r
+ 132.30111694335938,\r
+ -34.40129470825195,\r
+ 14.998519897460938\r
+ ],\r
+ "min": [\r
+ 128.30111694335938,\r
+ -64.39833068847656,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 83496,\r
+ "componentType": 5123,\r
+ "count": 987,\r
+ "max": [\r
+ 293\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 254472,\r
+ "componentType": 5126,\r
+ "count": 294,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 0.9992589950561525\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -0.9992589950561525\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 258000,\r
+ "componentType": 5126,\r
+ "count": 294,\r
+ "max": [\r
+ 181.5590057373047,\r
+ 312.1140747070313,\r
+ 17.986684799194337\r
+ ],\r
+ "min": [\r
+ 71.55899810791016,\r
+ 276.1140747070313,\r
+ -17.986684799194337\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 85470,\r
+ "componentType": 5123,\r
+ "count": 2145,\r
+ "max": [\r
+ 623\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 261528,\r
+ "componentType": 5126,\r
+ "count": 624,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 0.9992589950561525\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -0.9992589950561525\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 269016,\r
+ "componentType": 5126,\r
+ "count": 624,\r
+ "max": [\r
+ 211.16444396972657,\r
+ 300.2055358886719,\r
+ 15.988161087036133\r
+ ],\r
+ "min": [\r
+ 202.16444396972657,\r
+ 268.2055358886719,\r
+ -15.988161087036133\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 89760,\r
+ "componentType": 5123,\r
+ "count": 1566,\r
+ "max": [\r
+ 407\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 276504,\r
+ "componentType": 5126,\r
+ "count": 408,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 281400,\r
+ "componentType": 5126,\r
+ "count": 408,\r
+ "max": [\r
+ 54.54435348510742,\r
+ -38.61518478393555,\r
+ 15.0\r
+ ],\r
+ "min": [\r
+ -44.45564651489258,\r
+ -80.61518859863281,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 92892,\r
+ "componentType": 5123,\r
+ "count": 1359,\r
+ "max": [\r
+ 339\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 286296,\r
+ "componentType": 5126,\r
+ "count": 340,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 290376,\r
+ "componentType": 5126,\r
+ "count": 340,\r
+ "max": [\r
+ 54.54435348510742,\r
+ -48.61518478393555,\r
+ 15.0\r
+ ],\r
+ "min": [\r
+ -44.45564651489258,\r
+ -61.61518478393555,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 95610,\r
+ "componentType": 5123,\r
+ "count": 1032,\r
+ "max": [\r
+ 323\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 294456,\r
+ "componentType": 5126,\r
+ "count": 324,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 298344,\r
+ "componentType": 5126,\r
+ "count": 324,\r
+ "max": [\r
+ 30.5535831451416,\r
+ 217.1583709716797,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ 15.553584098815918,\r
+ 202.16946411132813,\r
+ -81.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 97674,\r
+ "componentType": 5123,\r
+ "count": 288,\r
+ "max": [\r
+ 95\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 302232,\r
+ "componentType": 5126,\r
+ "count": 96,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 303384,\r
+ "componentType": 5126,\r
+ "count": 96,\r
+ "max": [\r
+ -36.67900466918945,\r
+ 469.6546325683594,\r
+ 115.00000762939452\r
+ ],\r
+ "min": [\r
+ -49.67900466918945,\r
+ 456.6642761230469,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 98250,\r
+ "componentType": 5123,\r
+ "count": 1266,\r
+ "max": [\r
+ 347\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 304536,\r
+ "componentType": 5126,\r
+ "count": 348,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 308712,\r
+ "componentType": 5126,\r
+ "count": 348,\r
+ "max": [\r
+ -278.3986206054688,\r
+ -55.62376022338867,\r
+ 65.0\r
+ ],\r
+ "min": [\r
+ -296.3985900878906,\r
+ -73.61044311523438,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 100782,\r
+ "componentType": 5123,\r
+ "count": 5787,\r
+ "max": [\r
+ 1408\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 312888,\r
+ "componentType": 5126,\r
+ "count": 1409,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 329796,\r
+ "componentType": 5126,\r
+ "count": 1409,\r
+ "max": [\r
+ 105.0087432861328,\r
+ 60.05363082885742,\r
+ 75.0\r
+ ],\r
+ "min": [\r
+ -97.99126434326172,\r
+ -124.0295867919922,\r
+ 2.307800054550171\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 112356,\r
+ "componentType": 5123,\r
+ "count": 8964,\r
+ "max": [\r
+ 1939\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 346704,\r
+ "componentType": 5126,\r
+ "count": 1940,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 369984,\r
+ "componentType": 5126,\r
+ "count": 1940,\r
+ "max": [\r
+ 40.85147476196289,\r
+ 233.1286773681641,\r
+ 70.0\r
+ ],\r
+ "min": [\r
+ 19.2884521484375,\r
+ 214.79766845703129,\r
+ -28.7859001159668\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 130284,\r
+ "componentType": 5123,\r
+ "count": 10167,\r
+ "max": [\r
+ 1753\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 393264,\r
+ "componentType": 5126,\r
+ "count": 1754,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9999880194664002,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 414312,\r
+ "componentType": 5126,\r
+ "count": 1754,\r
+ "max": [\r
+ -252.55343627929688,\r
+ -164.07803344726566,\r
+ 85.0\r
+ ],\r
+ "min": [\r
+ -330.4447326660156,\r
+ -199.1783599853516,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 150618,\r
+ "componentType": 5123,\r
+ "count": 10125,\r
+ "max": [\r
+ 1748\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 435360,\r
+ "componentType": 5126,\r
+ "count": 1749,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9999880194664002,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 456348,\r
+ "componentType": 5126,\r
+ "count": 1749,\r
+ "max": [\r
+ -248.47320556640626,\r
+ -164.07803344726566,\r
+ 85.0\r
+ ],\r
+ "min": [\r
+ -326.3644409179688,\r
+ -199.1783599853516,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 170868,\r
+ "componentType": 5123,\r
+ "count": 21150,\r
+ "max": [\r
+ 5473\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 477336,\r
+ "componentType": 5126,\r
+ "count": 5474,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 543024,\r
+ "componentType": 5126,\r
+ "count": 5474,\r
+ "max": [\r
+ 113.00873565673828,\r
+ 59.71368026733399,\r
+ 0.0026710000820457937\r
+ ],\r
+ "min": [\r
+ -102.99126434326172,\r
+ -120.6896514892578,\r
+ -82.39035034179688\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 213168,\r
+ "componentType": 5123,\r
+ "count": 1359,\r
+ "max": [\r
+ 371\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 608712,\r
+ "componentType": 5126,\r
+ "count": 372,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 613176,\r
+ "componentType": 5126,\r
+ "count": 372,\r
+ "max": [\r
+ 37.65166091918945,\r
+ 226.15505981445316,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ 13.65165901184082,\r
+ 202.1728057861328,\r
+ -17.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 215886,\r
+ "componentType": 5123,\r
+ "count": 684,\r
+ "max": [\r
+ 239\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 617640,\r
+ "componentType": 5126,\r
+ "count": 240,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 620520,\r
+ "componentType": 5126,\r
+ "count": 240,\r
+ "max": [\r
+ -25.97146224975586,\r
+ 156.0619659423828,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ -188.97146606445316,\r
+ -6.938029766082764,\r
+ -230.0000152587891\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 217254,\r
+ "componentType": 5123,\r
+ "count": 5889,\r
+ "max": [\r
+ 1413\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 623400,\r
+ "componentType": 5126,\r
+ "count": 1414,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 640368,\r
+ "componentType": 5126,\r
+ "count": 1414,\r
+ "max": [\r
+ 105.0087432861328,\r
+ 60.05352783203125,\r
+ 147.6921844482422\r
+ ],\r
+ "min": [\r
+ -97.99126434326172,\r
+ -124.0295867919922,\r
+ 75.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 229032,\r
+ "componentType": 5123,\r
+ "count": 20607,\r
+ "max": [\r
+ 5363\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 657336,\r
+ "componentType": 5126,\r
+ "count": 5364,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 721704,\r
+ "componentType": 5126,\r
+ "count": 5364,\r
+ "max": [\r
+ 113.00873565673828,\r
+ 59.71368026733399,\r
+ 82.39035034179688\r
+ ],\r
+ "min": [\r
+ -102.99126434326172,\r
+ -120.6896514892578,\r
+ -0.002749999985098839\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 270246,\r
+ "componentType": 5123,\r
+ "count": 573,\r
+ "max": [\r
+ 191\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 786072,\r
+ "componentType": 5126,\r
+ "count": 192,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 788376,\r
+ "componentType": 5126,\r
+ "count": 192,\r
+ "max": [\r
+ -25.97146224975586,\r
+ 81.05715942382813,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ -38.97146224975586,\r
+ 68.06676483154297,\r
+ -230.0000152587891\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 271392,\r
+ "componentType": 5123,\r
+ "count": 32934,\r
+ "max": [\r
+ 8617\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 790680,\r
+ "componentType": 5126,\r
+ "count": 8618,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 894096,\r
+ "componentType": 5126,\r
+ "count": 8618,\r
+ "max": [\r
+ 99.06433868408205,\r
+ 151.558837890625,\r
+ 80.00056457519531\r
+ ],\r
+ "min": [\r
+ -61.93566513061524,\r
+ -38.4411506652832,\r
+ -80.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 337260,\r
+ "componentType": 5123,\r
+ "count": 33420,\r
+ "max": [\r
+ 8617\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 997512,\r
+ "componentType": 5126,\r
+ "count": 8618,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1100928,\r
+ "componentType": 5126,\r
+ "count": 8618,\r
+ "max": [\r
+ 99.06433868408205,\r
+ 151.558837890625,\r
+ 80.00056457519531\r
+ ],\r
+ "min": [\r
+ -61.93566513061524,\r
+ -38.4411506652832,\r
+ -80.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 404100,\r
+ "componentType": 5123,\r
+ "count": 17691,\r
+ "max": [\r
+ 3671\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1204344,\r
+ "componentType": 5126,\r
+ "count": 3672,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1248408,\r
+ "componentType": 5126,\r
+ "count": 3672,\r
+ "max": [\r
+ 95.0,\r
+ 90.0,\r
+ 112.99999237060549\r
+ ],\r
+ "min": [\r
+ -95.0,\r
+ -180.9715576171875,\r
+ -120.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 439482,\r
+ "componentType": 5123,\r
+ "count": 3903,\r
+ "max": [\r
+ 1280\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1292472,\r
+ "componentType": 5126,\r
+ "count": 1281,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1307844,\r
+ "componentType": 5126,\r
+ "count": 1281,\r
+ "max": [\r
+ 111.05359649658205,\r
+ 30.67658042907715,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ -70.94640350341797,\r
+ -43.32342147827149,\r
+ -10.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 447288,\r
+ "componentType": 5123,\r
+ "count": 960,\r
+ "max": [\r
+ 179\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1323216,\r
+ "componentType": 5126,\r
+ "count": 180,\r
+ "max": [\r
+ 1.0,\r
+ 0.9992589950561525,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1325376,\r
+ "componentType": 5126,\r
+ "count": 180,\r
+ "max": [\r
+ 76.06450653076172,\r
+ 2.5340518951416017,\r
+ 7.0\r
+ ],\r
+ "min": [\r
+ -11.810647010803225,\r
+ -15.180893898010254,\r
+ -7.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 449208,\r
+ "componentType": 5123,\r
+ "count": 423,\r
+ "max": [\r
+ 142\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1327536,\r
+ "componentType": 5126,\r
+ "count": 143,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -0.9992589950561525,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1329252,\r
+ "componentType": 5126,\r
+ "count": 143,\r
+ "max": [\r
+ -16.62210273742676,\r
+ -26.09882354736328,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ -32.12210464477539,\r
+ -41.59605407714844,\r
+ -81.32071685791016\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 450054,\r
+ "componentType": 5123,\r
+ "count": 2163,\r
+ "max": [\r
+ 385\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1330968,\r
+ "componentType": 5126,\r
+ "count": 386,\r
+ "max": [\r
+ 0.7761409878730774,\r
+ 0.7761409878730774,\r
+ -0.6286939978599548\r
+ ],\r
+ "min": [\r
+ -0.7758179903030396,\r
+ -0.7761409878730774,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1335600,\r
+ "componentType": 5126,\r
+ "count": 386,\r
+ "max": [\r
+ -16.62210273742676,\r
+ -26.09882354736328,\r
+ -81.31858825683594\r
+ ],\r
+ "min": [\r
+ -32.11616134643555,\r
+ -41.59875106811524,\r
+ -85.0\r
+ ],\r
+ "type": "VEC3"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_21"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.42500001192092898,\r
+ 0.42500001192092898,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_22"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.42500001192092898,\r
+ 0.42500001192092898,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_22"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_18"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.5609999895095825,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_23"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_16"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_16"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_16"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_16"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.5609999895095825,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_23"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_16"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.42500001192092898,\r
+ 0.42500001192092898,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_22"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.5609999895095825,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_23"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_16"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_19"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 0.8500000238418579,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_20"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.5609999895095825,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_17"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.8500000238418579,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Material_18"\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1340232,\r
+ "byteLength": 454380,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 0,\r
+ "byteLength": 1340232,\r
+ "byteStride": 12,\r
+ "target": 34962\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "byteLength": 1794612,\r
+ "uri": "2CylinderEngine0.bin"\r
+ }\r
+ ]\r
+}\r
--- /dev/null
+{\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.0100000035,\r
+ 0.0100000035,\r
+ 0.01\r
+ ],\r
+ "min": [\r
+ -0.0100000044,\r
+ -0.0100000054,\r
+ -0.01\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "name": "thin"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.0,\r
+ 0.01893253,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "thin"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "name": "thin"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "name": "angle"\r
+ },\r
+ {\r
+ "bufferView": 7,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.0,\r
+ 0.0198908355,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "angle"\r
+ },\r
+ {\r
+ "bufferView": 8,\r
+ "componentType": 5126,\r
+ "count": 24,\r
+ "type": "VEC3",\r
+ "name": "angle"\r
+ },\r
+ {\r
+ "bufferView": 9,\r
+ "componentType": 5123,\r
+ "count": 36,\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 10,\r
+ "componentType": 5126,\r
+ "count": 127,\r
+ "type": "SCALAR",\r
+ "max": [\r
+ 4.19999743\r
+ ],\r
+ "min": [\r
+ 0.0\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 11,\r
+ "componentType": 5126,\r
+ "count": 254,\r
+ "type": "SCALAR"\r
+ }\r
+ ],\r
+ "animations": [\r
+ {\r
+ "channels": [\r
+ {\r
+ "sampler": 0,\r
+ "target": {\r
+ "node": 0,\r
+ "path": "weights"\r
+ }\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "input": 10,\r
+ "interpolation": "LINEAR",\r
+ "output": 11\r
+ }\r
+ ],\r
+ "name": "Square"\r
+ }\r
+ ],\r
+ "asset": {\r
+ "generator": "glTF Tools for Unity",\r
+ "version": "2.0"\r
+ },\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 288,\r
+ "byteLength": 384\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 672,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 960,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1248,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1536,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1824,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 2112,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 2400,\r
+ "byteLength": 288\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 2688,\r
+ "byteLength": 72\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 2760,\r
+ "byteLength": 508\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 3268,\r
+ "byteLength": 1016\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "uri": "AnimatedMorphCube.bin",\r
+ "byteLength": 4284\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 0,\r
+ "TANGENT": 1,\r
+ "POSITION": 2\r
+ },\r
+ "indices": 9,\r
+ "material": 0,\r
+ "targets": [\r
+ {\r
+ "NORMAL": 3,\r
+ "POSITION": 4,\r
+ "TANGENT": 5\r
+ },\r
+ {\r
+ "NORMAL": 6,\r
+ "POSITION": 7,\r
+ "TANGENT": 8\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "weights": [\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Cube"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.6038274,\r
+ 0.6038274,\r
+ 0.6038274,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0,\r
+ "roughnessFactor": 0.5\r
+ },\r
+ "name": "Material"\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "mesh": 0,\r
+ "rotation": [\r
+ 0.0,\r
+ 0.7071067,\r
+ -0.7071068,\r
+ 0.0\r
+ ],\r
+ "scale": [\r
+ 100.0,\r
+ 100.0,\r
+ 100.0\r
+ ],\r
+ "name": "AnimatedMorphCube"\r
+ }\r
+ ],\r
+ "scene": 0,\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 0\r
+ ]\r
+ }\r
+ ]\r
+}
\ No newline at end of file
--- /dev/null
+\86ô=½u\18ñ>f\87a¿\86ô=½u\18ñ>f\87a¿\86ô=½u\18ñ>f\87a¿\86ô=½u\18ñ>f\87a¿å7±½Çì`?9sð>å7±½Çì`?9sð>å7±½Çì`?9sð>å7±½Çì`?9sð>nk\7f½±\16"?k\81E¿nk\7f½±\16"?k\81E¿nk\7f½±\16"?k\81E¿nk\7f½±\16"?k\81E¿Õw\9b½ßQE?\95ï!?Õw\9b½ßQE?\95ï!?Õw\9b½ßQE?\95ï!?Õw\9b½ßQE?\95ï!?Õw\9b½ßQE?\95ï!¿Õw\9b½ßQE?\95ï!¿Õw\9b½ßQE?\95ï!¿Õw\9b½ßQE?\95ï!¿¹k\7f½°\16"?j\81E?¹k\7f½°\16"?j\81E?¹k\7f½°\16"?j\81E?¹k\7f½°\16"?j\81E?ð7±½Çì`?6sð¾ð7±½Çì`?6sð¾ð7±½Çì`?6sð¾ð7±½Çì`?6sð¾\88ô=½\7f\18ñ>d\87a?\88ô=½\7f\18ñ>d\87a?\88ô=½\7f\18ñ>d\87a?\88ô=½\7f\18ñ>d\87a?\8b*À½_ås?4ø\93¾\8b*À½_ås?4ø\93¾\8b*À½_ås?4ø\93¾\8b*À½_ås?4ø\93¾\v\eê¼¢\90\94>màt?\v\eê¼¢\90\94>màt?\v\eê¼¢\90\94>màt?\v\eê¼¢\90\94>màt?ãÅǽe\8d}?IÈǽãÅǽe\8d}?IÈǽãÅǽe\8d}?IÈǽãÅǽe\8d}?IÈǽ\8f\1a\1e¼ËºÈ=dÁ~¿\8f\1a\1e¼ËºÈ=dÁ~¿\8f\1a\1e¼ËºÈ=dÁ~¿Î5ê¼÷\ 3Á=bÁ~¿A+>½Pâ±=bÁ~¿ù5ê<\v\ 4Á=bÁ~¿f+>=fâ±=bÁ~¿Rç\7f½ªê\9b=fÁ~¿Rç\7f½ªê\9b=fÁ~¿[ë\9b½Cê\7f=bÁ~¿íà±½u)>=hÁ~¿\8f\ 4Á½Ò3ê<bÁ~¿\8f\ 4Á½Ò3ê<bÁ~¿ZºÈ½\a)\1e<dÁ~¿Q»È½+)\1e¼bÁ~¿\r\ 3Á½\ 64ê¼fÁ~¿\r\ 3Á½\ 64ê¼fÁ~¿\16ã±½\99)>½bÁ~¿\é\9b½vê\7f½fÁ~¿·ë\7f½Êê\9b½bÁ~¿·ë\7f½Êê\9b½bÁ~¿E'>½xâ±½dÁ~¿ª-ê¼#\ 4Á½dÁ~¿!<\1e¼çºÈ½bÁ~¿!<\1e¼çºÈ½bÁ~¿#<\1e<éºÈ½bÁ~¿¾-ê<'\ 4Á½dÁ~¿T'>=\82â±½dÁ~¿T'>=\82â±½dÁ~¿×ë\7f=Õê\9b½bÁ~¿~ê\9b=\82ê\7f½dÁ~¿1â±=°)>½dÁ~¿1â±=°)>½dÁ~¿Â\ 4Á=þ3ê¼aÁ~¿_»È=+)\1e¼bÁ~¿qºÈ=M)\1e<dÁ~¿qºÈ=M)\1e<dÁ~¿C\ 5Á=\b4ê<aÁ~¿\16á±=¡)>=fÁ~¿wë\9b=rê\7f=bÁ~¿wë\9b=rê\7f=bÁ~¿\8aç\7f=Äê\9b=fÁ~¿\94#\1e¼ÂºÈ=dÁ~?\94#\1e¼ÂºÈ=dÁ~?\94#\1e¼ÂºÈ=dÁ~?Y1ê¼ñ\ 3Á=dÁ~?{+>½Râ±=bÁ~?s1ê<þ\ 3Á=dÁ~?\8a+>=Yâ±=bÁ~?«è\7f½ªê\9b=dÁ~?«è\7f½ªê\9b=dÁ~?øê\9b½;ê\7f=bÁ~?¯â±½l)>=bÁ~?¾\ 4Á½É3ê<aÁ~?¾\ 4Á½É3ê<aÁ~?qºÈ½+)\1e<dÁ~?{»È½))\1e¼aÁ~?¶\ 3Á½Ü3ê¼dÁ~?¶\ 3Á½Ü3ê¼dÁ~?¬â±½{)>½bÁ~?¾ê\9b½Kê\7f½dÁ~?µè\7f½¬ê\9b½dÁ~?µè\7f½¬ê\9b½dÁ~?\84+>½Vâ±½bÁ~?f1ê¼ü\ 3Á½dÁ~?´&\1e¼½ºÈ½dÁ~?´&\1e¼½ºÈ½dÁ~?='\1e<ÀºÈ½dÁ~?ò1ê<ú\ 3Á½dÁ~?\8a+>=Vâ±½bÁ~?\8a+>=Vâ±½bÁ~?½è\7f=®ê\9b½dÁ~?Ãê\9b=Kê\7f½bÁ~?½â±=t)>½bÁ~?½â±=t)>½bÁ~?Ç\ 3Á=á3ê¼dÁ~?\8c»È=7)\1e¼aÁ~?\82ºÈ=8)\1e<dÁ~?\82ºÈ=8)\1e<dÁ~?Ó\ 4Á=á3ê<aÁ~?>â±=\83)>=dÁ~?Äê\9b=Mê\7f=bÁ~?Äê\9b=Mê\7f=bÁ~?Áè\7f=³ê\9b=dÁ~?ÎÅǽe\8d}?FÈÇ=ÎÅǽe\8d}?FÈÇ=ÎÅǽe\8d}?FÈÇ=ÎÅǽe\8d}?FÈÇ=\ f\eê¼³\90\94>kàt¿\ f\eê¼³\90\94>kàt¿\ f\eê¼³\90\94>kàt¿\ f\eê¼³\90\94>kàt¿e*À½cås?'ø\93>e*À½cås?'ø\93>e*À½cås?'ø\93>e*À½cås?'ø\93>Æê\93¾îÎs?FÈÇ=Æê\93¾îÎs?FÈÇ=Æê\93¾îÎs?FÈÇ=Æê\93¾îÎs?FÈÇ=òV½\13Û\8e>màt¿òV½\13Û\8e>màt¿òV½\13Û\8e>màt¿òV½\13Û\8e>màt¿£H\8e¾è\85j?Dø\93>£H\8e¾è\85j?Dø\93>£H\8e¾è\85j?Dø\93>£H\8e¾è\85j?Dø\93>\¦\f¾\8eÔç>f\87a¿\¦\f¾\8eÔç>f\87a¿\¦\f¾\8eÔç>f\87a¿\¦\f¾\8eÔç>f\87a¿m7\83¾ûGX?\1csð>m7\83¾ûGX?\1csð>m7\83¾ûGX?\1csð>m7\83¾ûGX?\1csð>E\1e=¾\12Ü\e?g\81E¿E\1e=¾\12Ü\e?g\81E¿E\1e=¾\12Ü\e?g\81E¿E\1e=¾\12Ü\e?g\81E¿o9f¾\99¼=? ï!?o9f¾\99¼=? ï!?o9f¾\99¼=? ï!?o9f¾\99¼=? ï!?s9f¾\9a¼=?\9eï!¿s9f¾\9a¼=?\9eï!¿s9f¾\9a¼=?\9eï!¿s9f¾\9a¼=?\9eï!¿=\1e=¾\10Ü\e?j\81E?=\1e=¾\10Ü\e?j\81E?=\1e=¾\10Ü\e?j\81E?=\1e=¾\10Ü\e?j\81E?j7\83¾øGX?(sð¾j7\83¾øGX?(sð¾j7\83¾øGX?(sð¾j7\83¾øGX?(sð¾[¦\f¾\90Ôç>d\87a?[¦\f¾\90Ôç>d\87a?[¦\f¾\90Ôç>d\87a?[¦\f¾\90Ôç>d\87a?\9fH\8e¾è\85j?Iø\93¾\9fH\8e¾è\85j?Iø\93¾\9fH\8e¾è\85j?Iø\93¾\9fH\8e¾è\85j?Iø\93¾«W½\ 6Û\8e>kàt?«W½\ 6Û\8e>kàt?«W½\ 6Û\8e>kàt?«W½\ 6Û\8e>kàt?Àê\93¾îÎs?FÈǽÀê\93¾îÎs?FÈǽÀê\93¾îÎs?FÈǽÀê\93¾îÎs?FÈǽ.\8e\99¾\1f¤\ f?i\81E?.\8e\99¾\1f¤\ f?i\81E?.\8e\99¾\1f¤\ f?i\81E?.\8e\99¾\1f¤\ f?i\81E?t\15Õ¾nSG?\1fsð¾t\15Õ¾nSG?\1fsð¾t\15Õ¾nSG?\1fsð¾t\15Õ¾nSG?\1fsð¾xgd¾í§Õ>b\87a?xgd¾í§Õ>b\87a?xgd¾í§Õ>b\87a?xgd¾í§Õ>b\87a?Z\ eç¾<#X?\ø\93¾Z\ eç¾<#X?\ø\93¾Z\ eç¾<#X?\ø\93¾Z\ eç¾<#X?\ø\93¾r¾\f¾\ e¨\83>màt?r¾\f¾\ e¨\83>màt?r¾\f¾\ e¨\83>màt?r¾\f¾\ e¨\83>màt?@4ð¾ï±`?öÇǽ@4ð¾ï±`?öÇǽ@4ð¾ï±`?öÇǽ@4ð¾ï±`?öÇǽ@4ð¾ï±`?öÇÇ=@4ð¾ï±`?öÇÇ=@4ð¾ï±`?öÇÇ=@4ð¾ï±`?öÇÇ=l¾\f¾\17¨\83>màt¿l¾\f¾\17¨\83>màt¿l¾\f¾\17¨\83>màt¿l¾\f¾\17¨\83>màt¿\\ eç¾=#X?Pø\93>\\ eç¾=#X?Pø\93>\\ eç¾=#X?Pø\93>\\ eç¾=#X?Pø\93>Igd¾ë§Õ>d\87a¿Igd¾ë§Õ>d\87a¿Igd¾ë§Õ>d\87a¿Igd¾ë§Õ>d\87a¿~\15Õ¾qSG?\10sð>~\15Õ¾qSG?\10sð>~\15Õ¾qSG?\10sð>~\15Õ¾qSG?\10sð>1\8e\99¾\1e¤\ f?g\81E¿1\8e\99¾\1e¤\ f?g\81E¿1\8e\99¾\1e¤\ f?g\81E¿1\8e\99¾\1e¤\ f?g\81E¿\83ÇÜ.?\9fï!?\83ÇÜ.?\9fï!?\83ÇÜ.?\9fï!?\83ÇÜ.?\9fï!?\81ÆÜ.?¢ï!¿\81ÆÜ.?¢ï!¿\81ÆÜ.?¢ï!¿\81ÆÜ.?¢ï!¿{y\e¿Cr=?Eø\93>{y\e¿Cr=?Eø\93>{y\e¿Cr=?Eø\93>{y\e¿Cr=?Eø\93>z°\99¾gE»>f\87a¿z°\99¾gE»>f\87a¿z°\99¾gE»>f\87a¿z°\99¾gE»>f\87a¿\9ea\ f¿éµ.?!sð>\9ea\ f¿éµ.?!sð>\9ea\ f¿éµ.?!sð>\9ea\ f¿éµ.?!sð>¦¦Î¾\ fÎû>f\81E¿¦¦Î¾\ fÎû>f\81E¿¦¦Î¾\ fÎû>f\81E¿¦¦Î¾\ fÎû>f\81E¿b\91û¾©D\19?\9aï!?b\91û¾©D\19?\9aï!?b\91û¾©D\19?\9aï!?b\91û¾©D\19?\9aï!?b\91û¾¨D\19?\9dï!¿b\91û¾¨D\19?\9dï!¿b\91û¾¨D\19?\9dï!¿b\91û¾¨D\19?\9dï!¿§¦Î¾\aÎû>j\81E?§¦Î¾\aÎû>j\81E?§¦Î¾\aÎû>j\81E?§¦Î¾\aÎû>j\81E?\9da\ f¿éµ.?\1dsð¾\9da\ f¿éµ.?\1dsð¾\9da\ f¿éµ.?\1dsð¾\9da\ f¿éµ.?\1dsð¾g°\99¾iE»>i\87a?g°\99¾iE»>i\87a?g°\99¾iE»>i\87a?g°\99¾iE»>i\87a?zy\e¿?r=?Oø\93¾zy\e¿?r=?Oø\93¾zy\e¿?r=?Oø\93¾zy\e¿?r=?Oø\93¾\14i=¾¨Ëf>kàt?\14i=¾¨Ëf>kàt?\14i=¾¨Ëf>kàt?\14i=¾¨Ëf>kàt?O¡!¿eòD?dÈǽO¡!¿eòD?dÈǽO¡!¿eòD?dÈǽO¡!¿eòD?dÈǽN¡!¿fòD?eÈÇ=N¡!¿fòD?eÈÇ=N¡!¿fòD?eÈÇ=N¡!¿fòD?eÈÇ=\ fi=¾ÅËf>jàt¿\ fi=¾ÅËf>jàt¿\ fi=¾ÅËf>jàt¿\ fi=¾ÅËf>jàt¿]E»¾}°\99>f\87a?]E»¾}°\99>f\87a?]E»¾}°\99>f\87a?]E»¾}°\99>f\87a?Cr=¿{y\e?Bø\93¾Cr=¿{y\e?Bø\93¾Cr=¿{y\e?Bø\93¾Cr=¿{y\e?Bø\93¾vËf¾Ãh=>sàt?vËf¾Ãh=>sàt?vËf¾Ãh=>sàt?vËf¾Ãh=>sàt?hòD¿K¡!?uÈǽhòD¿K¡!?uÈǽhòD¿K¡!?uÈǽhòD¿K¡!?uÈǽhòD¿J¡!?sÈÇ=hòD¿J¡!?sÈÇ=hòD¿J¡!?sÈÇ=hòD¿J¡!?sÈÇ=\9cËf¾Ïh=>oàt¿\9cËf¾Ïh=>oàt¿\9cËf¾Ïh=>oàt¿\9cËf¾Ïh=>oàt¿Br=¿{y\e?Bø\93>Br=¿{y\e?Bø\93>Br=¿{y\e?Bø\93>Br=¿{y\e?Bø\93>kE»¾}°\99>b\87a¿kE»¾}°\99>b\87a¿kE»¾}°\99>b\87a¿kE»¾}°\99>b\87a¿êµ.¿\9da\ f?\esð>êµ.¿\9da\ f?\esð>êµ.¿\9da\ f?\esð>êµ.¿\9da\ f?\esð>\14Îû¾\9d¦Î>g\81E¿\14Îû¾\9d¦Î>g\81E¿\14Îû¾\9d¦Î>g\81E¿\14Îû¾\9d¦Î>g\81E¿¦D\19¿]\91û>\9eï!?¦D\19¿]\91û>\9eï!?¦D\19¿]\91û>\9eï!?¦D\19¿]\91û>\9eï!?¦D\19¿]\91û>\9eï!¿¦D\19¿]\91û>\9eï!¿¦D\19¿]\91û>\9eï!¿¦D\19¿]\91û>\9eï!¿\17Îû¾\98¦Î>i\81E?\17Îû¾\98¦Î>i\81E?\17Îû¾\98¦Î>i\81E?\17Îû¾\98¦Î>i\81E?êµ.¿\97a\ f?*sð¾êµ.¿\97a\ f?*sð¾êµ.¿\97a\ f?*sð¾êµ.¿\97a\ f?*sð¾ô§Õ¾0gd>d\87a¿ô§Õ¾0gd>d\87a¿ô§Õ¾0gd>d\87a¿ô§Õ¾0gd>d\87a¿qSG¿m\15Õ>\1asð>qSG¿m\15Õ>\1asð>qSG¿m\15Õ>\1asð>qSG¿m\15Õ>\1asð>\e¤\ f¿1\8e\99>k\81E¿\e¤\ f¿1\8e\99>k\81E¿\e¤\ f¿1\8e\99>k\81E¿\e¤\ f¿1\8e\99>k\81E¿ÊÜ.¿\81îº>\9bï!?ÊÜ.¿\81îº>\9bï!?ÊÜ.¿\81îº>\9bï!?ÊÜ.¿\81îº>\9bï!?ÊÜ.¿\84îº>\9dï!¿ÊÜ.¿\84îº>\9dï!¿ÊÜ.¿\84îº>\9dï!¿ÊÜ.¿\84îº>\9dï!¿\1a¤\ f¿8\8e\99>k\81E?\1a¤\ f¿8\8e\99>k\81E?\1a¤\ f¿8\8e\99>k\81E?\1a¤\ f¿8\8e\99>k\81E?nSG¿t\15Õ>\1fsð¾nSG¿t\15Õ>\1fsð¾nSG¿t\15Õ>\1fsð¾nSG¿t\15Õ>\1fsð¾÷§Õ¾+gd>b\87a?÷§Õ¾+gd>b\87a?÷§Õ¾+gd>b\87a?÷§Õ¾+gd>b\87a?F#X¿F\ eç>Cø\93¾F#X¿F\ eç>Cø\93¾F#X¿F\ eç>Cø\93¾F#X¿F\ eç>Cø\93¾\15¨\83¾a¾\f>màt?\15¨\83¾a¾\f>màt?\15¨\83¾a¾\f>màt?\15¨\83¾a¾\f>màt?ò±`¿04ð>~Èǽò±`¿04ð>~Èǽò±`¿04ð>~Èǽò±`¿04ð>~Èǽò±`¿.4ð>~ÈÇ=ò±`¿.4ð>~ÈÇ=ò±`¿.4ð>~ÈÇ=ò±`¿.4ð>~ÈÇ=\12¨\83¾i¾\f>màt¿\12¨\83¾i¾\f>màt¿\12¨\83¾i¾\f>màt¿\12¨\83¾i¾\f>màt¿G#X¿G\ eç>=ø\93>G#X¿G\ eç>=ø\93>G#X¿G\ eç>=ø\93>G#X¿G\ eç>=ø\93>é\85j¿\9fH\8e>Aø\93¾é\85j¿\9fH\8e>Aø\93¾é\85j¿\9fH\8e>Aø\93¾é\85j¿\9fH\8e>Aø\93¾ÿÚ\8e¾ÉV=qàt?ÿÚ\8e¾ÉV=qàt?ÿÚ\8e¾ÉV=qàt?ÿÚ\8e¾ÉV=qàt?îÎs¿¼ê\93>\90ÈǽîÎs¿¼ê\93>\90ÈǽîÎs¿¼ê\93>\90ÈǽîÎs¿¼ê\93>\90ÈǽîÎs¿¼ê\93>\90ÈÇ=îÎs¿¼ê\93>\90ÈÇ=îÎs¿¼ê\93>\90ÈÇ=îÎs¿¼ê\93>\90ÈÇ=\1eÛ\8e¾ÅV=kàt¿\1eÛ\8e¾ÅV=kàt¿\1eÛ\8e¾ÅV=kàt¿\1eÛ\8e¾ÅV=kàt¿é\85j¿\9fH\8e>@ø\93>é\85j¿\9fH\8e>@ø\93>é\85j¿\9fH\8e>@ø\93>é\85j¿\9fH\8e>@ø\93>\92Ôç¾N¦\f>f\87a¿\92Ôç¾N¦\f>f\87a¿\92Ôç¾N¦\f>f\87a¿\92Ôç¾N¦\f>f\87a¿ÿGX¿b7\83>\13sð>ÿGX¿b7\83>\13sð>ÿGX¿b7\83>\13sð>ÿGX¿b7\83>\13sð>\10Ü\e¿1\1e=>i\81E¿\10Ü\e¿1\1e=>i\81E¿\10Ü\e¿1\1e=>i\81E¿\10Ü\e¿1\1e=>i\81E¿\9d¼=¿H9f>\9fï!?\9d¼=¿H9f>\9fï!?\9d¼=¿H9f>\9fï!?\9d¼=¿H9f>\9fï!?\9d¼=¿H9f>\9fï!¿\9d¼=¿H9f>\9fï!¿\9d¼=¿H9f>\9fï!¿\9d¼=¿H9f>\9fï!¿\11Ü\e¿>\1e=>g\81E?\11Ü\e¿>\1e=>g\81E?\11Ü\e¿>\1e=>g\81E?\11Ü\e¿>\1e=>g\81E?ÿGX¿[7\83>\19sð¾ÿGX¿[7\83>\19sð¾ÿGX¿[7\83>\19sð¾ÿGX¿[7\83>\19sð¾\8bÔç¾Z¦\f>f\87a?\8bÔç¾Z¦\f>f\87a?\8bÔç¾Z¦\f>f\87a?\8bÔç¾Z¦\f>f\87a?Ìì`¿\9b9±=\18sð>Ìì`¿\9b9±=\18sð>Ìì`¿\9b9±=\18sð>Ìì`¿\9b9±=\18sð>²\16"¿ðm\7f=f\81E¿²\16"¿ðm\7f=f\81E¿²\16"¿ðm\7f=f\81E¿²\16"¿ðm\7f=f\81E¿ÒQE¿yy\9b=\9fï!?ÒQE¿yy\9b=\9fï!?ÒQE¿yy\9b=\9fï!?ÒQE¿yy\9b=\9fï!?ÒQE¿yy\9b=\9fï!¿ÒQE¿yy\9b=\9fï!¿ÒQE¿yy\9b=\9fï!¿ÒQE¿yy\9b=\9fï!¿²\16"¿\95m\7f=f\81E?²\16"¿\95m\7f=f\81E?²\16"¿\95m\7f=f\81E?²\16"¿\95m\7f=f\81E?Çì`¿¢9±=#sð¾Çì`¿¢9±=#sð¾Çì`¿¢9±=#sð¾Çì`¿¢9±=#sð¾\7f\18ñ¾\r÷==a\87a?\7f\18ñ¾\r÷==a\87a?\7f\18ñ¾\r÷==a\87a?\7f\18ñ¾\r÷==a\87a?Zås¿:,À==ø\93¾Zås¿:,À==ø\93¾Zås¿:,À==ø\93¾Zås¿:,À==ø\93¾\9b\90\94¾Æ\1dê<oàt?\9b\90\94¾Æ\1dê<oàt?\9b\90\94¾Æ\1dê<oàt?\9b\90\94¾Æ\1dê<oàt?]\8d}¿óÇÇ=´Èǽ]\8d}¿óÇÇ=´Èǽ]\8d}¿óÇÇ=´Èǽ]\8d}¿óÇÇ=´Èǽ]\8d}¿óÇÇ=´ÈÇ=]\8d}¿óÇÇ=´ÈÇ=]\8d}¿óÇÇ=´ÈÇ=]\8d}¿óÇÇ=´ÈÇ=®\90\94¾\19\1eê<kàt¿®\90\94¾\19\1eê<kàt¿®\90\94¾\19\1eê<kàt¿®\90\94¾\19\1eê<kàt¿Zås¿:,À=<ø\93>Zås¿:,À=<ø\93>Zås¿:,À=<ø\93>Zås¿:,À=<ø\93>q\18ñ¾\7f÷==d\87a¿q\18ñ¾\7f÷==d\87a¿q\18ñ¾\7f÷==d\87a¿q\18ñ¾\7f÷==d\87a¿\9b\90\94¾#\1eê¼oàt?\9b\90\94¾#\1eê¼oàt?\9b\90\94¾#\1eê¼oàt?\9b\90\94¾#\1eê¼oàt?[\8d}¿(ÈǽÛÈǽ[\8d}¿(ÈǽÛÈǽ[\8d}¿(ÈǽÛÈǽ[\8d}¿(ÈǽÛÈǽ[\8d}¿(ÈǽÛÈÇ=[\8d}¿(ÈǽÛÈÇ=[\8d}¿(ÈǽÛÈÇ=[\8d}¿(ÈǽÛÈÇ=®\90\94¾\1d\1eê¼kàt¿®\90\94¾\1d\1eê¼kàt¿®\90\94¾\1d\1eê¼kàt¿®\90\94¾\1d\1eê¼kàt¿Zås¿q,À½7ø\93>Zås¿q,À½7ø\93>Zås¿q,À½7ø\93>Zås¿q,À½7ø\93>n\18ñ¾¸÷=½f\87a¿n\18ñ¾¸÷=½f\87a¿n\18ñ¾¸÷=½f\87a¿n\18ñ¾¸÷=½f\87a¿Êì`¿Õ9±½\14sð>Êì`¿Õ9±½\14sð>Êì`¿Õ9±½\14sð>Êì`¿Õ9±½\14sð>\16"¿ým\7f½k\81E¿\16"¿ým\7f½k\81E¿\16"¿ým\7f½k\81E¿\16"¿ým\7f½k\81E¿ÕQE¿wy\9b½\9dï!?ÕQE¿wy\9b½\9dï!?ÕQE¿wy\9b½\9dï!?ÕQE¿wy\9b½\9dï!?ÕQE¿wy\9b½\9dï!¿ÕQE¿wy\9b½\9dï!¿ÕQE¿wy\9b½\9dï!¿ÕQE¿wy\9b½\9dï!¿¬\16"¿Bn\7f½k\81E?¬\16"¿Bn\7f½k\81E?¬\16"¿Bn\7f½k\81E?¬\16"¿Bn\7f½k\81E?Çì`¿¢9±½#sð¾Çì`¿¢9±½#sð¾Çì`¿¢9±½#sð¾Çì`¿¢9±½#sð¾s\18ñ¾H÷=½d\87a?s\18ñ¾H÷=½d\87a?s\18ñ¾H÷=½d\87a?s\18ñ¾H÷=½d\87a?Zås¿p,À½6ø\93¾Zås¿p,À½6ø\93¾Zås¿p,À½6ø\93¾Zås¿p,À½6ø\93¾\13Ü\e¿4\1e=¾i\81E¿\13Ü\e¿4\1e=¾i\81E¿\13Ü\e¿4\1e=¾i\81E¿\13Ü\e¿4\1e=¾i\81E¿\9e¼=¿h9f¾\9aï!?\9e¼=¿h9f¾\9aï!?\9e¼=¿h9f¾\9aï!?\9e¼=¿h9f¾\9aï!?\9e¼=¿h9f¾\9aï!¿\9e¼=¿h9f¾\9aï!¿\9e¼=¿h9f¾\9aï!¿\9e¼=¿h9f¾\9aï!¿\ eÜ\e¿B\1e=¾j\81E?\ eÜ\e¿B\1e=¾j\81E?\ eÜ\e¿B\1e=¾j\81E?\ eÜ\e¿B\1e=¾j\81E?øGX¿i7\83¾(sð¾øGX¿i7\83¾(sð¾øGX¿i7\83¾(sð¾øGX¿i7\83¾(sð¾\91Ôç¾g¦\f¾b\87a?\91Ôç¾g¦\f¾b\87a?\91Ôç¾g¦\f¾b\87a?\91Ôç¾g¦\f¾b\87a?ë\85j¿\9fH\8e¾3ø\93¾ë\85j¿\9fH\8e¾3ø\93¾ë\85j¿\9fH\8e¾3ø\93¾ë\85j¿\9fH\8e¾3ø\93¾\17Û\8e¾àV½kàt?\17Û\8e¾àV½kàt?\17Û\8e¾àV½kàt?\17Û\8e¾àV½kàt?ìÎs¿»ê\93¾àÈǽìÎs¿»ê\93¾àÈǽìÎs¿»ê\93¾àÈǽìÎs¿»ê\93¾àÈǽìÎs¿»ê\93¾àÈÇ=ìÎs¿»ê\93¾àÈÇ=ìÎs¿»ê\93¾àÈÇ=ìÎs¿»ê\93¾àÈÇ=\ 1Û\8e¾ùV½oàt¿\ 1Û\8e¾ùV½oàt¿\ 1Û\8e¾ùV½oàt¿\ 1Û\8e¾ùV½oàt¿é\85j¿¡H\8e¾6ø\93>é\85j¿¡H\8e¾6ø\93>é\85j¿¡H\8e¾6ø\93>é\85j¿¡H\8e¾6ø\93>\8eÔç¾\¦\f¾f\87a¿\8eÔç¾\¦\f¾f\87a¿\8eÔç¾\¦\f¾f\87a¿\8eÔç¾\¦\f¾f\87a¿þGX¿c7\83¾\1csð>þGX¿c7\83¾\1csð>þGX¿c7\83¾\1csð>þGX¿c7\83¾\1csð>ì±`¿?4ð¾ÛÈǽì±`¿?4ð¾ÛÈǽì±`¿?4ð¾ÛÈǽì±`¿?4ð¾ÛÈǽì±`¿=4ð¾ÙÈÇ=ì±`¿=4ð¾ÙÈÇ=ì±`¿=4ð¾ÙÈÇ=ì±`¿=4ð¾ÙÈÇ=,¨\83¾n¾\f¾jàt¿,¨\83¾n¾\f¾jàt¿,¨\83¾n¾\f¾jàt¿,¨\83¾n¾\f¾jàt¿B#X¿c\ eç¾4ø\93>B#X¿c\ eç¾4ø\93>B#X¿c\ eç¾4ø\93>B#X¿c\ eç¾4ø\93>ó§Õ¾5gd¾d\87a¿ó§Õ¾5gd¾d\87a¿ó§Õ¾5gd¾d\87a¿ó§Õ¾5gd¾d\87a¿mSG¿x\15Õ¾\1dsð>mSG¿x\15Õ¾\1dsð>mSG¿x\15Õ¾\1dsð>mSG¿x\15Õ¾\1dsð> ¤\ f¿?\8e\99¾e\81E¿ ¤\ f¿?\8e\99¾e\81E¿ ¤\ f¿?\8e\99¾e\81E¿ ¤\ f¿?\8e\99¾e\81E¿ÈÜ.¿\93\98ï!?ÈÜ.¿\93\98ï!?ÈÜ.¿\93\98ï!?ÈÜ.¿\93\98ï!?ÈÜ.¿\93\9aï!¿ÈÜ.¿\93\9aï!¿ÈÜ.¿\93\9aï!¿ÈÜ.¿\93\9aï!¿\1a¤\ f¿1\8e\99¾k\81E?\1a¤\ f¿1\8e\99¾k\81E?\1a¤\ f¿1\8e\99¾k\81E?\1a¤\ f¿1\8e\99¾k\81E?kSG¿t\15Õ¾+sð¾kSG¿t\15Õ¾+sð¾kSG¿t\15Õ¾+sð¾kSG¿t\15Õ¾+sð¾ð§Õ¾0gd¾d\87a?ð§Õ¾0gd¾d\87a?ð§Õ¾0gd¾d\87a?ð§Õ¾0gd¾d\87a?B#X¿c\ eç¾2ø\93¾B#X¿c\ eç¾2ø\93¾B#X¿c\ eç¾2ø\93¾B#X¿c\ eç¾2ø\93¾\ 2¨\83¾e¾\f¾qàt?\ 2¨\83¾e¾\f¾qàt?\ 2¨\83¾e¾\f¾qàt?\ 2¨\83¾e¾\f¾qàt?§D\19¿k\91û¾\9aï!?§D\19¿k\91û¾\9aï!?§D\19¿k\91û¾\9aï!?§D\19¿k\91û¾\9aï!?¤D\19¿l\91û¾\9cï!¿¤D\19¿l\91û¾\9cï!¿¤D\19¿l\91û¾\9cï!¿¤D\19¿l\91û¾\9cï!¿\ 6Îû¾¨¦Î¾k\81E?\ 6Îû¾¨¦Î¾k\81E?\ 6Îû¾¨¦Î¾k\81E?\ 6Îû¾¨¦Î¾k\81E?çµ.¿\9ba\ f¿-sð¾çµ.¿\9ba\ f¿-sð¾çµ.¿\9ba\ f¿-sð¾çµ.¿\9ba\ f¿-sð¾kE»¾\84°\99¾b\87a?kE»¾\84°\99¾b\87a?kE»¾\84°\99¾b\87a?kE»¾\84°\99¾b\87a?Hr=¿vy\e¿8ø\93¾Hr=¿vy\e¿8ø\93¾Hr=¿vy\e¿8ø\93¾Hr=¿vy\e¿8ø\93¾\0Ìf¾¾h=¾jàt?\0Ìf¾¾h=¾jàt?\0Ìf¾¾h=¾jàt?\0Ìf¾¾h=¾jàt?bòD¿P¡!¿ËÈǽbòD¿P¡!¿ËÈǽbòD¿P¡!¿ËÈǽbòD¿P¡!¿ËÈǽbòD¿P¡!¿ËÈÇ=bòD¿P¡!¿ËÈÇ=bòD¿P¡!¿ËÈÇ=bòD¿P¡!¿ËÈÇ=ËËf¾Ðh=¾kàt¿ËËf¾Ðh=¾kàt¿ËËf¾Ðh=¾kàt¿ËËf¾Ðh=¾kàt¿Hr=¿wy\e¿5ø\93>Hr=¿wy\e¿5ø\93>Hr=¿wy\e¿5ø\93>Hr=¿wy\e¿5ø\93>^E»¾{°\99¾g\87a¿^E»¾{°\99¾g\87a¿^E»¾{°\99¾g\87a¿^E»¾{°\99¾g\87a¿ëµ.¿\9ba\ f¿"sð>ëµ.¿\9ba\ f¿"sð>ëµ.¿\9ba\ f¿"sð>ëµ.¿\9ba\ f¿"sð>\13Îû¾¦¦Î¾f\81E¿\13Îû¾¦¦Î¾f\81E¿\13Îû¾¦¦Î¾f\81E¿\13Îû¾¦¦Î¾f\81E¿O¡!¿dòD¿¶ÈÇ=O¡!¿dòD¿¶ÈÇ=O¡!¿dòD¿¶ÈÇ=O¡!¿dòD¿¶ÈÇ=¿h=¾ÒËf¾màt¿¿h=¾ÒËf¾màt¿¿h=¾ÒËf¾màt¿¿h=¾ÒËf¾màt¿zy\e¿Fr=¿8ø\93>zy\e¿Fr=¿8ø\93>zy\e¿Fr=¿8ø\93>zy\e¿Fr=¿8ø\93>z°\99¾lE»¾d\87a¿z°\99¾lE»¾d\87a¿z°\99¾lE»¾d\87a¿z°\99¾lE»¾d\87a¿\9ba\ f¿çµ.¿,sð>\9ba\ f¿çµ.¿,sð>\9ba\ f¿çµ.¿,sð>\9ba\ f¿çµ.¿,sð>¯¦Î¾\fÎû¾e\81E¿¯¦Î¾\fÎû¾e\81E¿¯¦Î¾\fÎû¾e\81E¿¯¦Î¾\fÎû¾e\81E¿\\91û¾ªD\19¿\9cï!?\\91û¾ªD\19¿\9cï!?\\91û¾ªD\19¿\9cï!?\\91û¾ªD\19¿\9cï!?]\91û¾ªD\19¿\9aï!¿]\91û¾ªD\19¿\9aï!¿]\91û¾ªD\19¿\9aï!¿]\91û¾ªD\19¿\9aï!¿\9f¦Î¾\fÎû¾j\81E?\9f¦Î¾\fÎû¾j\81E?\9f¦Î¾\fÎû¾j\81E?\9f¦Î¾\fÎû¾j\81E?\98a\ f¿çµ.¿3sð¾\98a\ f¿çµ.¿3sð¾\98a\ f¿çµ.¿3sð¾\98a\ f¿çµ.¿3sð¾b°\99¾rE»¾g\87a?b°\99¾rE»¾g\87a?b°\99¾rE»¾g\87a?b°\99¾rE»¾g\87a?zy\e¿Fr=¿8ø\93¾zy\e¿Fr=¿8ø\93¾zy\e¿Fr=¿8ø\93¾zy\e¿Fr=¿8ø\93¾Äh=¾»Ëf¾màt?Äh=¾»Ëf¾màt?Äh=¾»Ëf¾màt?Äh=¾»Ëf¾màt?O¡!¿dòD¿¶ÈǽO¡!¿dòD¿¶ÈǽO¡!¿dòD¿¶ÈǽO¡!¿dòD¿¶Èǽ/\8e\99¾\1f¤\ f¿g\81E?/\8e\99¾\1f¤\ f¿g\81E?/\8e\99¾\1f¤\ f¿g\81E?/\8e\99¾\1f¤\ f¿g\81E?b\15Õ¾mSG¿3sð¾b\15Õ¾mSG¿3sð¾b\15Õ¾mSG¿3sð¾b\15Õ¾mSG¿3sð¾\19gd¾ù§Õ¾d\87a?\19gd¾ù§Õ¾d\87a?\19gd¾ù§Õ¾d\87a?\19gd¾ù§Õ¾d\87a?S\ eç¾D#X¿7ø\93¾S\ eç¾D#X¿7ø\93¾S\ eç¾D#X¿7ø\93¾S\ eç¾D#X¿7ø\93¾y¾\f¾\ f¨\83¾màt?y¾\f¾\ f¨\83¾màt?y¾\f¾\ f¨\83¾màt?y¾\f¾\ f¨\83¾màt?/4ð¾ñ±`¿ËÈǽ/4ð¾ñ±`¿ËÈǽ/4ð¾ñ±`¿ËÈǽ/4ð¾ñ±`¿ËÈǽ14ð¾ñ±`¿ËÈÇ=14ð¾ñ±`¿ËÈÇ=14ð¾ñ±`¿ËÈÇ=14ð¾ñ±`¿ËÈÇ=y¾\f¾\1e¨\83¾kàt¿y¾\f¾\1e¨\83¾kàt¿y¾\f¾\1e¨\83¾kàt¿y¾\f¾\1e¨\83¾kàt¿Q\ eç¾D#X¿>ø\93>Q\ eç¾D#X¿>ø\93>Q\ eç¾D#X¿>ø\93>Q\ eç¾D#X¿>ø\93>Ngd¾î§Õ¾b\87a¿Ngd¾î§Õ¾b\87a¿Ngd¾î§Õ¾b\87a¿Ngd¾î§Õ¾b\87a¿f\15Õ¾nSG¿+sð>f\15Õ¾nSG¿+sð>f\15Õ¾nSG¿+sð>f\15Õ¾nSG¿+sð>5\8e\99¾\1f¤\ f¿g\81E¿5\8e\99¾\1f¤\ f¿g\81E¿5\8e\99¾\1f¤\ f¿g\81E¿5\8e\99¾\1f¤\ f¿g\81E¿\82ÌÜ.¿\99ï!?\82ÌÜ.¿\99ï!?\82ÌÜ.¿\99ï!?\82ÌÜ.¿\99ï!?{ËÜ.¿\9aï!¿{ËÜ.¿\9aï!¿{ËÜ.¿\9aï!¿{ËÜ.¿\9aï!¿W½\13Û\8e¾jàt¿W½\13Û\8e¾jàt¿W½\13Û\8e¾jàt¿W½\13Û\8e¾jàt¿\98H\8e¾í\85j¿2ø\93>\98H\8e¾í\85j¿2ø\93>\98H\8e¾í\85j¿2ø\93>\98H\8e¾í\85j¿2ø\93>^¦\f¾\8bÔç¾f\87a¿^¦\f¾\8bÔç¾f\87a¿^¦\f¾\8bÔç¾f\87a¿^¦\f¾\8bÔç¾f\87a¿V7\83¾ùGX¿0sð>V7\83¾ùGX¿0sð>V7\83¾ùGX¿0sð>V7\83¾ùGX¿0sð>:\1e=¾\18Ü\e¿c\81E¿:\1e=¾\18Ü\e¿c\81E¿:\1e=¾\18Ü\e¿c\81E¿:\1e=¾\18Ü\e¿c\81E¿_9f¾ ¼=¿\97ï!?_9f¾ ¼=¿\97ï!?_9f¾ ¼=¿\97ï!?_9f¾ ¼=¿\97ï!?_9f¾ ¼=¿\97ï!¿_9f¾ ¼=¿\97ï!¿_9f¾ ¼=¿\97ï!¿_9f¾ ¼=¿\97ï!¿0\1e=¾\11Ü\e¿i\81E?0\1e=¾\11Ü\e¿i\81E?0\1e=¾\11Ü\e¿i\81E?0\1e=¾\11Ü\e¿i\81E?U7\83¾øGX¿3sð¾U7\83¾øGX¿3sð¾U7\83¾øGX¿3sð¾U7\83¾øGX¿3sð¾_¦\f¾\93Ôç¾d\87a?_¦\f¾\93Ôç¾d\87a?_¦\f¾\93Ôç¾d\87a?_¦\f¾\93Ôç¾d\87a?\99H\8e¾í\85j¿2ø\93¾\99H\8e¾í\85j¿2ø\93¾\99H\8e¾í\85j¿2ø\93¾\99H\8e¾í\85j¿2ø\93¾\ 2W½\rÛ\8e¾màt?\ 2W½\rÛ\8e¾màt?\ 2W½\rÛ\8e¾màt?\ 2W½\rÛ\8e¾màt?·ê\93¾ìÎs¿&Éǽ·ê\93¾ìÎs¿&Éǽ·ê\93¾ìÎs¿&Éǽ·ê\93¾ìÎs¿&Éǽ·ê\93¾ìÎs¿&ÉÇ=·ê\93¾ìÎs¿&ÉÇ=·ê\93¾ìÎs¿&ÉÇ=·ê\93¾ìÎs¿&ÉÇ=£9±½Äì`¿-sð¾£9±½Äì`¿-sð¾£9±½Äì`¿-sð¾£9±½Äì`¿-sð¾ó÷=½r\18ñ¾b\87a?ó÷=½r\18ñ¾b\87a?ó÷=½r\18ñ¾b\87a?ó÷=½r\18ñ¾b\87a??,À½Xås¿Bø\93¾?,À½Xås¿Bø\93¾?,À½Xås¿Bø\93¾?,À½Xås¿Bø\93¾þ\1aê¼\9f\90\94¾oàt?þ\1aê¼\9f\90\94¾oàt?þ\1aê¼\9f\90\94¾oàt?þ\1aê¼\9f\90\94¾oàt?ãÇǽ]\8d}¿ÇÈǽãÇǽ]\8d}¿ÇÈǽãÇǽ]\8d}¿ÇÈǽãÇǽ]\8d}¿ÇÈǽãÇǽ]\8d}¿ÇÈÇ=ãÇǽ]\8d}¿ÇÈÇ=ãÇǽ]\8d}¿ÇÈÇ=ãÇǽ]\8d}¿ÇÈÇ=ý\1aê¼®\90\94¾kàt¿ý\1aê¼®\90\94¾kàt¿ý\1aê¼®\90\94¾kàt¿ý\1aê¼®\90\94¾kàt¿G,À½Xås¿Bø\93>G,À½Xås¿Bø\93>G,À½Xås¿Bø\93>G,À½Xås¿Bø\93>\14÷=½k\18ñ¾g\87a¿\14÷=½k\18ñ¾g\87a¿\14÷=½k\18ñ¾g\87a¿\14÷=½k\18ñ¾g\87a¿«9±½Çì`¿#sð>«9±½Çì`¿#sð>«9±½Çì`¿#sð>«9±½Çì`¿#sð>úm\7f½±\16"¿i\81E¿úm\7f½±\16"¿i\81E¿úm\7f½±\16"¿i\81E¿úm\7f½±\16"¿i\81E¿<y\9b½ÛQE¿\95ï!?<y\9b½ÛQE¿\95ï!?<y\9b½ÛQE¿\95ï!?<y\9b½ÛQE¿\95ï!?<y\9b½ÛQE¿\95ï!¿<y\9b½ÛQE¿\95ï!¿<y\9b½ÛQE¿\95ï!¿<y\9b½ÛQE¿\95ï!¿\9am\7f½¬\16"¿l\81E?\9am\7f½¬\16"¿l\81E?\9am\7f½¬\16"¿l\81E?\9am\7f½¬\16"¿l\81E?l,À=Xås¿<ø\93>l,À=Xås¿<ø\93>l,À=Xås¿<ø\93>l,À=Xås¿<ø\93>\11÷==f\18ñ¾i\87a¿\11÷==f\18ñ¾i\87a¿\11÷==f\18ñ¾i\87a¿\11÷==f\18ñ¾i\87a¿Â9±=Âì`¿4sð>Â9±=Âì`¿4sð>Â9±=Âì`¿4sð>Â9±=Âì`¿4sð>\ 1n\7f=¶\16"¿a\81E¿\ 1n\7f=¶\16"¿a\81E¿\ 1n\7f=¶\16"¿a\81E¿\ 1n\7f=¶\16"¿a\81E¿\83y\9b=ÞQE¿\8fï!?\83y\9b=ÞQE¿\8fï!?\83y\9b=ÞQE¿\8fï!?\83y\9b=ÞQE¿\8fï!?\83y\9b=ÞQE¿\8fï!¿\83y\9b=ÞQE¿\8fï!¿\83y\9b=ÞQE¿\8fï!¿\83y\9b=ÞQE¿\8fï!¿An\7f=®\16"¿i\81E?An\7f=®\16"¿i\81E?An\7f=®\16"¿i\81E?An\7f=®\16"¿i\81E?¾9±=¿ì`¿Asð¾¾9±=¿ì`¿Asð¾¾9±=¿ì`¿Asð¾¾9±=¿ì`¿Asð¾\18÷==w\18ñ¾b\87a?\18÷==w\18ñ¾b\87a?\18÷==w\18ñ¾b\87a?\18÷==w\18ñ¾b\87a?l,À=Xås¿<ø\93¾l,À=Xås¿<ø\93¾l,À=Xås¿<ø\93¾l,À=Xås¿<ø\93¾Ó\1dê<\9d\90\94¾oàt?Ó\1dê<\9d\90\94¾oàt?Ó\1dê<\9d\90\94¾oàt?Ó\1dê<\9d\90\94¾oàt?6ÈÇ=[\8d}¿ÕÈǽ6ÈÇ=[\8d}¿ÕÈǽ6ÈÇ=[\8d}¿ÕÈǽ6ÈÇ=[\8d}¿ÕÈǽ4ÈÇ=[\8d}¿ÕÈÇ=4ÈÇ=[\8d}¿ÕÈÇ=4ÈÇ=[\8d}¿ÕÈÇ=4ÈÇ=[\8d}¿ÕÈÇ=Î\1dê<«\90\94¾kàt¿Î\1dê<«\90\94¾kàt¿Î\1dê<«\90\94¾kàt¿Î\1dê<«\90\94¾kàt¿^¦\f>\8eÔç¾d\87a?^¦\f>\8eÔç¾d\87a?^¦\f>\8eÔç¾d\87a?^¦\f>\8eÔç¾d\87a?\9fH\8e>ï\85j¿#ø\93¾\9fH\8e>ï\85j¿#ø\93¾\9fH\8e>ï\85j¿#ø\93¾\9fH\8e>ï\85j¿#ø\93¾\ 2W=\vÛ\8e¾màt?\ 2W=\vÛ\8e¾màt?\ 2W=\vÛ\8e¾màt?\ 2W=\vÛ\8e¾màt?Âê\93>ìÎs¿\fÉǽÂê\93>ìÎs¿\fÉǽÂê\93>ìÎs¿\fÉǽÂê\93>ìÎs¿\fÉǽÂê\93>ìÎs¿\fÉÇ=Âê\93>ìÎs¿\fÉÇ=Âê\93>ìÎs¿\fÉÇ=Âê\93>ìÎs¿\fÉÇ=\ 2W=\18Û\8e¾kàt¿\ 2W=\18Û\8e¾kàt¿\ 2W=\18Û\8e¾kàt¿\ 2W=\18Û\8e¾kàt¿\9fH\8e>ï\85j¿#ø\93>\9fH\8e>ï\85j¿#ø\93>\9fH\8e>ï\85j¿#ø\93>\9fH\8e>ï\85j¿#ø\93>\¦\f>\8aÔç¾g\87a¿\¦\f>\8aÔç¾g\87a¿\¦\f>\8aÔç¾g\87a¿\¦\f>\8aÔç¾g\87a¿h7\83>ôGX¿;sð>h7\83>ôGX¿;sð>h7\83>ôGX¿;sð>h7\83>ôGX¿;sð>:\1e=>\15Ü\e¿e\81E¿:\1e=>\15Ü\e¿e\81E¿:\1e=>\15Ü\e¿e\81E¿:\1e=>\15Ü\e¿e\81E¿u9f> ¼=¿\96ï!?u9f> ¼=¿\96ï!?u9f> ¼=¿\96ï!?u9f> ¼=¿\96ï!?u9f> ¼=¿\96ï!¿u9f> ¼=¿\96ï!¿u9f> ¼=¿\96ï!¿u9f> ¼=¿\96ï!¿G\1e=>\12Ü\e¿g\81E?G\1e=>\12Ü\e¿g\81E?G\1e=>\12Ü\e¿g\81E?G\1e=>\12Ü\e¿g\81E?e7\83>ïGX¿Msð¾e7\83>ïGX¿Msð¾e7\83>ïGX¿Msð¾e7\83>ïGX¿Msð¾Hgd>å§Õ¾g\87a¿Hgd>å§Õ¾g\87a¿Hgd>å§Õ¾g\87a¿Hgd>å§Õ¾g\87a¿r\15Õ>cSG¿Csð>r\15Õ>cSG¿Csð>r\15Õ>cSG¿Csð>r\15Õ>cSG¿Csð>E\8e\99>"¤\ f¿c\81E¿E\8e\99>"¤\ f¿c\81E¿E\8e\99>"¤\ f¿c\81E¿E\8e\99>"¤\ f¿c\81E¿\9eîº>ÒÜ.¿\8bï!?\9eîº>ÒÜ.¿\8bï!?\9eîº>ÒÜ.¿\8bï!?\9eîº>ÒÜ.¿\8bï!?\9eîº>ÒÜ.¿\8bï!¿\9eîº>ÒÜ.¿\8bï!¿\9eîº>ÒÜ.¿\8bï!¿\9eîº>ÒÜ.¿\8bï!¿3\8e\99>\1e¤\ f¿i\81E?3\8e\99>\1e¤\ f¿i\81E?3\8e\99>\1e¤\ f¿i\81E?3\8e\99>\1e¤\ f¿i\81E?l\15Õ>`SG¿Tsð¾l\15Õ>`SG¿Tsð¾l\15Õ>`SG¿Tsð¾l\15Õ>`SG¿Tsð¾\85gd>ï§Õ¾a\87a?\85gd>ï§Õ¾a\87a?\85gd>ï§Õ¾a\87a?\85gd>ï§Õ¾a\87a?b\ eç>D#X¿&ø\93¾b\ eç>D#X¿&ø\93¾b\ eç>D#X¿&ø\93¾b\ eç>D#X¿&ø\93¾×¾\f>\r¨\83¾kàt?×¾\f>\r¨\83¾kàt?×¾\f>\r¨\83¾kàt?×¾\f>\r¨\83¾kàt??4ð>ì±`¿\vÉǽ?4ð>ì±`¿\vÉǽ?4ð>ì±`¿\vÉǽ?4ð>ì±`¿\vÉǽ?4ð>ì±`¿\vÉÇ=?4ð>ì±`¿\vÉÇ=?4ð>ì±`¿\vÉÇ=?4ð>ì±`¿\vÉÇ=Ö¾\f>\1c¨\83¾hàt¿Ö¾\f>\1c¨\83¾hàt¿Ö¾\f>\1c¨\83¾hàt¿Ö¾\f>\1c¨\83¾hàt¿]\ eç>D#X¿$ø\93>]\ eç>D#X¿$ø\93>]\ eç>D#X¿$ø\93>]\ eç>D#X¿$ø\93>\84y\e?>r=¿.ø\93¾\84y\e?>r=¿.ø\93¾\84y\e?>r=¿.ø\93¾\84y\e?>r=¿.ø\93¾Ëh=>½Ëf¾màt?Ëh=>½Ëf¾màt?Ëh=>½Ëf¾màt?Ëh=>½Ëf¾màt?S¡!?`òD¿ãÈǽS¡!?`òD¿ãÈǽS¡!?`òD¿ãÈǽS¡!?`òD¿ãÈǽS¡!?`òD¿ãÈÇ=S¡!?`òD¿ãÈÇ=S¡!?`òD¿ãÈÇ=S¡!?`òD¿ãÈÇ=Èh=>ØËf¾kàt¿Èh=>ØËf¾kàt¿Èh=>ØËf¾kàt¿Èh=>ØËf¾kàt¿\83y\e?=r=¿3ø\93>\83y\e?=r=¿3ø\93>\83y\e?=r=¿3ø\93>\83y\e?=r=¿3ø\93>u°\99>^E»¾i\87a¿u°\99>^E»¾i\87a¿u°\99>^E»¾i\87a¿u°\99>^E»¾i\87a¿\99a\ f?âµ.¿=sð>\99a\ f?âµ.¿=sð>\99a\ f?âµ.¿=sð>\99a\ f?âµ.¿=sð>§¦Î>\1aÎû¾c\81E¿§¦Î>\1aÎû¾c\81E¿§¦Î>\1aÎû¾c\81E¿§¦Î>\1aÎû¾c\81E¿t\91û>®D\19¿\8fï!?t\91û>®D\19¿\8fï!?t\91û>®D\19¿\8fï!?t\91û>®D\19¿\8fï!?t\91û>®D\19¿\8fï!¿t\91û>®D\19¿\8fï!¿t\91û>®D\19¿\8fï!¿t\91û>®D\19¿\8fï!¿ ¦Î>\aÎû¾k\81E? ¦Î>\aÎû¾k\81E? ¦Î>\aÎû¾k\81E? ¦Î>\aÎû¾k\81E?\98a\ f?àµ.¿Fsð¾\98a\ f?àµ.¿Fsð¾\98a\ f?àµ.¿Fsð¾\98a\ f?àµ.¿Fsð¾o°\99>gE»¾g\87a?o°\99>gE»¾g\87a?o°\99>gE»¾g\87a?o°\99>gE»¾g\87a?âµ.?\98a\ f¿Asð>âµ.?\98a\ f¿Asð>âµ.?\98a\ f¿Asð>âµ.?\98a\ f¿Asð>\15Îû>\9e¦Î¾i\81E¿\15Îû>\9e¦Î¾i\81E¿\15Îû>\9e¦Î¾i\81E¿\15Îû>\9e¦Î¾i\81E¿¯D\19?n\91û¾\92ï!?¯D\19?n\91û¾\92ï!?¯D\19?n\91û¾\92ï!?¯D\19?n\91û¾\92ï!?D\19?j\91û¾\94ï!¿D\19?j\91û¾\94ï!¿D\19?j\91û¾\94ï!¿D\19?j\91û¾\94ï!¿\14Îû>\97¦Î¾j\81E?\14Îû>\97¦Î¾j\81E?\14Îû>\97¦Î¾j\81E?\14Îû>\97¦Î¾j\81E?áµ.?\91a\ f¿Ssð¾áµ.?\91a\ f¿Ssð¾áµ.?\91a\ f¿Ssð¾áµ.?\91a\ f¿Ssð¾rE»>\80°\99¾b\87a?rE»>\80°\99¾b\87a?rE»>\80°\99¾b\87a?rE»>\80°\99¾b\87a?Cr=?\81y\e¿$ø\93¾Cr=?\81y\e¿$ø\93¾Cr=?\81y\e¿$ø\93¾Cr=?\81y\e¿$ø\93¾´Ëf>Æh=¾oàt?´Ëf>Æh=¾oàt?´Ëf>Æh=¾oàt?´Ëf>Æh=¾oàt?fòD?K¡!¿úÈǽfòD?K¡!¿úÈǽfòD?K¡!¿úÈǽfòD?K¡!¿úÈǽfòD?K¡!¿úÈÇ=fòD?K¡!¿úÈÇ=fòD?K¡!¿úÈÇ=fòD?K¡!¿úÈÇ=µËf>Óh=¾màt¿µËf>Óh=¾màt¿µËf>Óh=¾màt¿µËf>Óh=¾màt¿Er=?\80y\e¿!ø\93>Er=?\80y\e¿!ø\93>Er=?\80y\e¿!ø\93>Er=?\80y\e¿!ø\93>kE»>s°\99¾f\87a¿kE»>s°\99¾f\87a¿kE»>s°\99¾f\87a¿kE»>s°\99¾f\87a¿ø§\83>a¾\f¾qàt?ø§\83>a¾\f¾qàt?ø§\83>a¾\f¾qàt?ø§\83>a¾\f¾qàt?ò±`?'4ð¾ñÈǽò±`?'4ð¾ñÈǽò±`?'4ð¾ñÈǽò±`?'4ð¾ñÈǽò±`?'4ð¾ñÈÇ=ò±`?'4ð¾ñÈÇ=ò±`?'4ð¾ñÈÇ=ò±`?'4ð¾ñÈÇ="¨\83>n¾\f¾kàt¿"¨\83>n¾\f¾kàt¿"¨\83>n¾\f¾kàt¿"¨\83>n¾\f¾kàt¿I#X?\\ eç¾\1cø\93>I#X?\\ eç¾\1cø\93>I#X?\\ eç¾\1cø\93>I#X?\\ eç¾\1cø\93>ñ§Õ>\10gd¾g\87a¿ñ§Õ>\10gd¾g\87a¿ñ§Õ>\10gd¾g\87a¿ñ§Õ>\10gd¾g\87a¿fSG?e\15Õ¾Esð>fSG?e\15Õ¾Esð>fSG?e\15Õ¾Esð>fSG?e\15Õ¾Esð>\1d¤\ f?5\8e\99¾g\81E¿\1d¤\ f?5\8e\99¾g\81E¿\1d¤\ f?5\8e\99¾g\81E¿\1d¤\ f?5\8e\99¾g\81E¿ÏÜ.?\95\90ï!?ÏÜ.?\95\90ï!?ÏÜ.?\95\90ï!?ÏÜ.?\95\90ï!?ÑÜ.?\95\8fï!¿ÑÜ.?\95\8fï!¿ÑÜ.?\95\8fï!¿ÑÜ.?\95\8fï!¿\e¤\ f?C\8e\99¾f\81E?\e¤\ f?C\8e\99¾f\81E?\e¤\ f?C\8e\99¾f\81E?\e¤\ f?C\8e\99¾f\81E?bSG?k\15Õ¾Msð¾bSG?k\15Õ¾Msð¾bSG?k\15Õ¾Msð¾bSG?k\15Õ¾Msð¾ú§Õ>\19gd¾d\87a?ú§Õ>\19gd¾d\87a?ú§Õ>\19gd¾d\87a?ú§Õ>\19gd¾d\87a?I#X?\\ eç¾\1cø\93¾I#X?\\ eç¾\1cø\93¾I#X?\\ eç¾\1cø\93¾I#X?\\ eç¾\1cø\93¾ª¼=?Z9f¾\8eï!?ª¼=?Z9f¾\8eï!?ª¼=?Z9f¾\8eï!?ª¼=?Z9f¾\8eï!?ª¼=?Z9f¾\8eï!¿ª¼=?Z9f¾\8eï!¿ª¼=?Z9f¾\8eï!¿ª¼=?Z9f¾\8eï!¿\rÜ\e?\1d\1e=¾o\81E?\rÜ\e?\1d\1e=¾o\81E?\rÜ\e?\1d\1e=¾o\81E?\rÜ\e?\1d\1e=¾o\81E?ïGX?U7\83¾Tsð¾ïGX?U7\83¾Tsð¾ïGX?U7\83¾Tsð¾ïGX?U7\83¾Tsð¾\9cÔç>k¦\f¾b\87a?\9cÔç>k¦\f¾b\87a?\9cÔç>k¦\f¾b\87a?\9cÔç>k¦\f¾b\87a?ð\85j?\95H\8e¾\18ø\93¾ð\85j?\95H\8e¾\18ø\93¾ð\85j?\95H\8e¾\18ø\93¾ð\85j?\95H\8e¾\18ø\93¾\11Û\8e>½V½màt?\11Û\8e>½V½màt?\11Û\8e>½V½màt?\11Û\8e>½V½màt?îÎs?²ê\93¾ñÈǽîÎs?²ê\93¾ñÈǽîÎs?²ê\93¾ñÈǽîÎs?²ê\93¾ñÈǽîÎs?²ê\93¾îÈÇ=îÎs?²ê\93¾îÈÇ=îÎs?²ê\93¾îÈÇ=îÎs?²ê\93¾îÈÇ=&Û\8e>çV½jàt¿&Û\8e>çV½jàt¿&Û\8e>çV½jàt¿&Û\8e>çV½jàt¿ð\85j?\98H\8e¾\1aø\93>ð\85j?\98H\8e¾\1aø\93>ð\85j?\98H\8e¾\1aø\93>ð\85j?\98H\8e¾\1aø\93>\8bÔç>[¦\f¾f\87a¿\8bÔç>[¦\f¾f\87a¿\8bÔç>[¦\f¾f\87a¿\8bÔç>[¦\f¾f\87a¿òGX?^7\83¾Fsð>òGX?^7\83¾Fsð>òGX?^7\83¾Fsð>òGX?^7\83¾Fsð>\11Ü\e?6\1e=¾i\81E¿\11Ü\e?6\1e=¾i\81E¿\11Ü\e?6\1e=¾i\81E¿\11Ü\e?6\1e=¾i\81E¿]\8d}?öÇǽÝÈÇ=]\8d}?öÇǽÝÈÇ=]\8d}?öÇǽÝÈÇ=]\8d}?öÇǽÝÈÇ=°\90\94>Ý\1dê¼kàt¿°\90\94>Ý\1dê¼kàt¿°\90\94>Ý\1dê¼kàt¿°\90\94>Ý\1dê¼kàt¿]ås?D,À½\1cø\93>]ås?D,À½\1cø\93>]ås?D,À½\1cø\93>]ås?D,À½\1cø\93>h\18ñ>\15÷=½g\87a¿h\18ñ>\15÷=½g\87a¿h\18ñ>\15÷=½g\87a¿h\18ñ>\15÷=½g\87a¿¿ì`?\949±½Asð>¿ì`?\949±½Asð>¿ì`?\949±½Asð>¿ì`?\949±½Asð>®\16"?úm\7f½i\81E¿®\16"?úm\7f½i\81E¿®\16"?úm\7f½i\81E¿®\16"?úm\7f½i\81E¿âQE?Cy\9b½\8fï!?âQE?Cy\9b½\8fï!?âQE?Cy\9b½\8fï!?âQE?Cy\9b½\8fï!?âQE?Cy\9b½\8fï!¿âQE?Cy\9b½\8fï!¿âQE?Cy\9b½\8fï!¿âQE?Cy\9b½\8fï!¿¬\16"?\9em\7f½l\81E?¬\16"?\9em\7f½l\81E?¬\16"?\9em\7f½l\81E?¬\16"?\9em\7f½l\81E?¼ì`?\9e9±½Msð¾¼ì`?\9e9±½Msð¾¼ì`?\9e9±½Msð¾¼ì`?\9e9±½Msð¾n\18ñ>\18÷=½f\87a?n\18ñ>\18÷=½f\87a?n\18ñ>\18÷=½f\87a?n\18ñ>\18÷=½f\87a?_ås?C,À½\eø\93¾_ås?C,À½\eø\93¾_ås?C,À½\eø\93¾_ås?C,À½\eø\93¾ \90\94>\93\1eê¼màt? \90\94>\93\1eê¼màt? \90\94>\93\1eê¼màt? \90\94>\93\1eê¼màt?]\8d}?ùÇǽáÈǽ]\8d}?ùÇǽáÈǽ]\8d}?ùÇǽáÈǽ]\8d}?ùÇǽáÈǽáQE?\8ay\9b=\8eï!¿áQE?\8ay\9b=\8eï!¿áQE?\8ay\9b=\8eï!¿áQE?\8ay\9b=\8eï!¿®\16"?ëm\7f=i\81E?®\16"?ëm\7f=i\81E?®\16"?ëm\7f=i\81E?®\16"?ëm\7f=i\81E?¼ì`?\9e9±=Msð¾¼ì`?\9e9±=Msð¾¼ì`?\9e9±=Msð¾¼ì`?\9e9±=Msð¾n\18ñ>Q÷==f\87a?n\18ñ>Q÷==f\87a?n\18ñ>Q÷==f\87a?n\18ñ>Q÷==f\87a?]ås?°,À=\18ø\93¾]ås?°,À=\18ø\93¾]ås?°,À=\18ø\93¾]ås?°,À=\18ø\93¾©\90\94>\92\1eê<kàt?©\90\94>\92\1eê<kàt?©\90\94>\92\1eê<kàt?©\90\94>\92\1eê<kàt?[\8d}?bÈÇ=ÛÈǽ[\8d}?bÈÇ=ÛÈǽ[\8d}?bÈÇ=ÛÈǽ[\8d}?bÈÇ=ÛÈǽ[\8d}?bÈÇ=ÛÈÇ=[\8d}?bÈÇ=ÛÈÇ=[\8d}?bÈÇ=ÛÈÇ=[\8d}?bÈÇ=ÛÈÇ=ª\90\94>á\1dê<màt¿ª\90\94>á\1dê<màt¿ª\90\94>á\1dê<màt¿ª\90\94>á\1dê<màt¿]ås?°,À=\18ø\93>]ås?°,À=\18ø\93>]ås?°,À=\18ø\93>]ås?°,À=\18ø\93>f\18ñ>P÷==g\87a¿f\18ñ>P÷==g\87a¿f\18ñ>P÷==g\87a¿f\18ñ>P÷==g\87a¿¾ì`?Ò9±=Csð>¾ì`?Ò9±=Csð>¾ì`?Ò9±=Csð>¾ì`?Ò9±=Csð>²\16"?En\7f=e\81E¿²\16"?En\7f=e\81E¿²\16"?En\7f=e\81E¿²\16"?En\7f=e\81E¿áQE?\8ay\9b=\8eï!?áQE?\8ay\9b=\8eï!?áQE?\8ay\9b=\8eï!?áQE?\8ay\9b=\8eï!?ìÎs?Áê\93>ÞÈÇ=ìÎs?Áê\93>ÞÈÇ=ìÎs?Áê\93>ÞÈÇ=ìÎs?Áê\93>ÞÈÇ=\ fÛ\8e>þV=màt¿\ fÛ\8e>þV=màt¿\ fÛ\8e>þV=màt¿\ fÛ\8e>þV=màt¿ð\85j?\99H\8e>\10ø\93>ð\85j?\99H\8e>\10ø\93>ð\85j?\99H\8e>\10ø\93>ð\85j?\99H\8e>\10ø\93>\83Ôç>b¦\f>i\87a¿\83Ôç>b¦\f>i\87a¿\83Ôç>b¦\f>i\87a¿\83Ôç>b¦\f>i\87a¿ñGX?a7\83>Hsð>ñGX?a7\83>Hsð>ñGX?a7\83>Hsð>ñGX?a7\83>Hsð>\ fÜ\e?E\1e=>i\81E¿\ fÜ\e?E\1e=>i\81E¿\ fÜ\e?E\1e=>i\81E¿\ fÜ\e?E\1e=>i\81E¿¨¼=?\809f>\8dï!?¨¼=?\809f>\8dï!?¨¼=?\809f>\8dï!?¨¼=?\809f>\8dï!?¨¼=?\809f>\8dï!¿¨¼=?\809f>\8dï!¿¨¼=?\809f>\8dï!¿¨¼=?\809f>\8dï!¿\vÜ\e?-\1e=>m\81E?\vÜ\e?-\1e=>m\81E?\vÜ\e?-\1e=>m\81E?\vÜ\e?-\1e=>m\81E?ïGX?e7\83>Osð¾ïGX?e7\83>Osð¾ïGX?e7\83>Osð¾ïGX?e7\83>Osð¾\96Ôç>n¦\f>b\87a?\96Ôç>n¦\f>b\87a?\96Ôç>n¦\f>b\87a?\96Ôç>n¦\f>b\87a?ð\85j?\9aH\8e>\10ø\93¾ð\85j?\9aH\8e>\10ø\93¾ð\85j?\9aH\8e>\10ø\93¾ð\85j?\9aH\8e>\10ø\93¾\11Û\8e>ÔV=màt?\11Û\8e>ÔV=màt?\11Û\8e>ÔV=màt?\11Û\8e>ÔV=màt?ìÎs?Áê\93>âÈǽìÎs?Áê\93>âÈǽìÎs?Áê\93>âÈǽìÎs?Áê\93>âÈǽ\18¤\ f?A\8e\99>j\81E?\18¤\ f?A\8e\99>j\81E?\18¤\ f?A\8e\99>j\81E?\18¤\ f?A\8e\99>j\81E?`SG?o\15Õ>Rsð¾`SG?o\15Õ>Rsð¾`SG?o\15Õ>Rsð¾`SG?o\15Õ>Rsð¾ô§Õ>Egd>b\87a?ô§Õ>Egd>b\87a?ô§Õ>Egd>b\87a?ô§Õ>Egd>b\87a?D#X?i\ eç>\11ø\93¾D#X?i\ eç>\11ø\93¾D#X?i\ eç>\11ø\93¾D#X?i\ eç>\11ø\93¾\10¨\83>s¾\f>màt?\10¨\83>s¾\f>màt?\10¨\83>s¾\f>màt?\10¨\83>s¾\f>màt?é±`?M4ð>ÑÈǽé±`?M4ð>ÑÈǽé±`?M4ð>ÑÈǽé±`?M4ð>ÑÈǽé±`?K4ð>ÎÈÇ=é±`?K4ð>ÎÈÇ=é±`?K4ð>ÎÈÇ=é±`?K4ð>ÎÈÇ=#¨\83>|¾\f>kàt¿#¨\83>|¾\f>kàt¿#¨\83>|¾\f>kàt¿#¨\83>|¾\f>kàt¿D#X?k\ eç>\12ø\93>D#X?k\ eç>\12ø\93>D#X?k\ eç>\12ø\93>D#X?k\ eç>\12ø\93>Ó§Õ>?gd>l\87a¿Ó§Õ>?gd>l\87a¿Ó§Õ>?gd>l\87a¿Ó§Õ>?gd>l\87a¿bSG?r\15Õ>Gsð>bSG?r\15Õ>Gsð>bSG?r\15Õ>Gsð>bSG?r\15Õ>Gsð>\1e¤\ f?3\8e\99>g\81E¿\1e¤\ f?3\8e\99>g\81E¿\1e¤\ f?3\8e\99>g\81E¿\1e¤\ f?3\8e\99>g\81E¿ÒÜ.?\9dîº>\8aï!?ÒÜ.?\9dîº>\8aï!?ÒÜ.?\9dîº>\8aï!?ÒÜ.?\9dîº>\8aï!?ÒÜ.?\9dîº>\8bï!¿ÒÜ.?\9dîº>\8bï!¿ÒÜ.?\9dîº>\8bï!¿ÒÜ.?\9dîº>\8bï!¿ºËf>âh=>màt¿ºËf>âh=>màt¿ºËf>âh=>màt¿ºËf>âh=>màt¿Fr=?\82y\e?\12ø\93>Fr=?\82y\e?\12ø\93>Fr=?\82y\e?\12ø\93>Fr=?\82y\e?\12ø\93>aE»>\81°\99>d\87a¿aE»>\81°\99>d\87a¿aE»>\81°\99>d\87a¿aE»>\81°\99>d\87a¿ßµ.?\99a\ f?Csð>ßµ.?\99a\ f?Csð>ßµ.?\99a\ f?Csð>ßµ.?\99a\ f?Csð>ñÍû>¢¦Î>q\81E¿ñÍû>¢¦Î>q\81E¿ñÍû>¢¦Î>q\81E¿ñÍû>¢¦Î>q\81E¿³D\19?{\91û>\8aï!?³D\19?{\91û>\8aï!?³D\19?{\91û>\8aï!?³D\19?{\91û>\8aï!?³D\19?{\91û>\8aï!¿³D\19?{\91û>\8aï!¿³D\19?{\91û>\8aï!¿³D\19?{\91û>\8aï!¿\ 1Îû>\9b¦Î>o\81E?\ 1Îû>\9b¦Î>o\81E?\ 1Îû>\9b¦Î>o\81E?\ 1Îû>\9b¦Î>o\81E?ݵ.?\96a\ f?Osð¾Ýµ.?\96a\ f?Osð¾Ýµ.?\96a\ f?Osð¾Ýµ.?\96a\ f?Osð¾jE»>\82°\99>b\87a?jE»>\82°\99>b\87a?jE»>\82°\99>b\87a?jE»>\82°\99>b\87a?Fr=?\82y\e?\12ø\93¾Fr=?\82y\e?\12ø\93¾Fr=?\82y\e?\12ø\93¾Fr=?\82y\e?\12ø\93¾ëËf>Âh=>kàt?ëËf>Âh=>kàt?ëËf>Âh=>kàt?ëËf>Âh=>kàt?aòD?R¡!?ÇÈǽaòD?R¡!?ÇÈǽaòD?R¡!?ÇÈǽaòD?R¡!?ÇÈǽaòD?R¡!?ÇÈÇ=aòD?R¡!?ÇÈÇ=aòD?R¡!?ÇÈÇ=aòD?R¡!?ÇÈÇ=\90a\ f?ãµ.?Osð¾\90a\ f?ãµ.?Osð¾\90a\ f?ãµ.?Osð¾\90a\ f?ãµ.?Osð¾}°\99>jE»>b\87a?}°\99>jE»>b\87a?}°\99>jE»>b\87a?}°\99>jE»>b\87a?|y\e?Nr=?\ 5ø\93¾|y\e?Nr=?\ 5ø\93¾|y\e?Nr=?\ 5ø\93¾|y\e?Nr=?\ 5ø\93¾Îh=>ÃËf>màt?Îh=>ÃËf>màt?Îh=>ÃËf>màt?Îh=>ÃËf>màt?G¡!?jòD?ÈÈǽG¡!?jòD?ÈÈǽG¡!?jòD?ÈÈǽG¡!?jòD?ÈÈǽG¡!?jòD?ÈÈÇ=G¡!?jòD?ÈÈÇ=G¡!?jòD?ÈÈÇ=G¡!?jòD?ÈÈÇ=Óh=>ÙËf>kàt¿Óh=>ÙËf>kàt¿Óh=>ÙËf>kàt¿Óh=>ÙËf>kàt¿{y\e?Mr=?\vø\93>{y\e?Mr=?\vø\93>{y\e?Mr=?\vø\93>{y\e?Mr=?\vø\93>}°\99>dE»>f\87a¿}°\99>dE»>f\87a¿}°\99>dE»>f\87a¿}°\99>dE»>f\87a¿\92a\ f?æµ.?Bsð>\92a\ f?æµ.?Bsð>\92a\ f?æµ.?Bsð>\92a\ f?æµ.?Bsð>¥¦Î>\rÎû>g\81E¿¥¦Î>\rÎû>g\81E¿¥¦Î>\rÎû>g\81E¿¥¦Î>\rÎû>g\81E¿m\91û>µD\19?\8aï!?m\91û>µD\19?\8aï!?m\91û>µD\19?\8aï!?m\91û>µD\19?\8aï!?i\91û>¶D\19?\8bï!¿i\91û>¶D\19?\8bï!¿i\91û>¶D\19?\8bï!¿i\91û>¶D\19?\8bï!¿\99¦Î>\vÎû>l\81E?\99¦Î>\vÎû>l\81E?\99¦Î>\vÎû>l\81E?\99¦Î>\vÎû>l\81E?Z\ eç>L#X?\ 6ø\93>Z\ eç>L#X?\ 6ø\93>Z\ eç>L#X?\ 6ø\93>Z\ eç>L#X?\ 6ø\93>"gd>í§Õ>g\87a¿"gd>í§Õ>g\87a¿"gd>í§Õ>g\87a¿"gd>í§Õ>g\87a¿`\15Õ>bSG?Ssð>`\15Õ>bSG?Ssð>`\15Õ>bSG?Ssð>`\15Õ>bSG?Ssð>7\8e\99>\e¤\ f?j\81E¿7\8e\99>\e¤\ f?j\81E¿7\8e\99>\e¤\ f?j\81E¿7\8e\99>\e¤\ f?j\81E¿\97îº>ØÜ.?\8aï!?\97îº>ØÜ.?\8aï!?\97îº>ØÜ.?\8aï!?\97îº>ØÜ.?\8aï!?\95îº>ÖÜ.?\8bï!¿\95îº>ÖÜ.?\8bï!¿\95îº>ÖÜ.?\8bï!¿\95îº>ÖÜ.?\8bï!¿/\8e\99>\e¤\ f?k\81E?/\8e\99>\e¤\ f?k\81E?/\8e\99>\e¤\ f?k\81E?/\8e\99>\e¤\ f?k\81E?Y\15Õ>cSG?Wsð¾Y\15Õ>cSG?Wsð¾Y\15Õ>cSG?Wsð¾Y\15Õ>cSG?Wsð¾ gd>ú§Õ>d\87a? gd>ú§Õ>d\87a? gd>ú§Õ>d\87a? gd>ú§Õ>d\87a?]\ eç>L#X?\ 5ø\93¾]\ eç>L#X?\ 5ø\93¾]\ eç>L#X?\ 5ø\93¾]\ eç>L#X?\ 5ø\93¾\82¾\f>\16¨\83>màt?\82¾\f>\16¨\83>màt?\82¾\f>\16¨\83>màt?\82¾\f>\16¨\83>màt?/4ð>ñ±`?»Èǽ/4ð>ñ±`?»Èǽ/4ð>ñ±`?»Èǽ/4ð>ñ±`?»Èǽ/4ð>ñ±`?»ÈÇ=/4ð>ñ±`?»ÈÇ=/4ð>ñ±`?»ÈÇ=/4ð>ñ±`?»ÈÇ=ܾ\f>#¨\83>hàt¿Ü¾\f>#¨\83>hàt¿Ü¾\f>#¨\83>hàt¿Ü¾\f>#¨\83>hàt¿f¦\f>\9cÔç>b\87a?f¦\f>\9cÔç>b\87a?f¦\f>\9cÔç>b\87a?f¦\f>\9cÔç>b\87a?\9cH\8e>ô\85j?\ 1ø\93¾\9cH\8e>ô\85j?\ 1ø\93¾\9cH\8e>ô\85j?\ 1ø\93¾\9cH\8e>ô\85j?\ 1ø\93¾\bW=\ fÛ\8e>màt?\bW=\ fÛ\8e>màt?\bW=\ fÛ\8e>màt?\bW=\ fÛ\8e>màt?ê\93>ðÎs?¶Èǽê\93>ðÎs?¶Èǽê\93>ðÎs?¶Èǽê\93>ðÎs?¶Èǽ®ê\93>ðÎs?µÈÇ=®ê\93>ðÎs?µÈÇ=®ê\93>ðÎs?µÈÇ=®ê\93>ðÎs?µÈÇ= W=\1fÛ\8e>jàt¿ W=\1fÛ\8e>jàt¿ W=\1fÛ\8e>jàt¿ W=\1fÛ\8e>jàt¿\9cH\8e>ô\85j?\ 1ø\93>\9cH\8e>ô\85j?\ 1ø\93>\9cH\8e>ô\85j?\ 1ø\93>\9cH\8e>ô\85j?\ 1ø\93>,¦\f>\93Ôç>f\87a¿,¦\f>\93Ôç>f\87a¿,¦\f>\93Ôç>f\87a¿,¦\f>\93Ôç>f\87a¿X7\83>ñGX?Jsð>X7\83>ñGX?Jsð>X7\83>ñGX?Jsð>X7\83>ñGX?Jsð>1\1e=>\rÜ\e?l\81E¿1\1e=>\rÜ\e?l\81E¿1\1e=>\rÜ\e?l\81E¿1\1e=>\rÜ\e?l\81E¿e9f>°¼=?\86ï!?e9f>°¼=?\86ï!?e9f>°¼=?\86ï!?e9f>°¼=?\86ï!?e9f>°¼=?\86ï!¿e9f>°¼=?\86ï!¿e9f>°¼=?\86ï!¿e9f>°¼=?\86ï!¿)\1e=>\vÜ\e?o\81E?)\1e=>\vÜ\e?o\81E?)\1e=>\vÜ\e?o\81E?)\1e=>\vÜ\e?o\81E?W7\83>íGX?]sð¾W7\83>íGX?]sð¾W7\83>íGX?]sð¾W7\83>íGX?]sð¾\899±=¿ì`?Dsð>\899±=¿ì`?Dsð>\899±=¿ì`?Dsð>\899±=¿ì`?Dsð>Nm\7f=ª\16"?m\81E¿Nm\7f=ª\16"?m\81E¿Nm\7f=ª\16"?m\81E¿Nm\7f=ª\16"?m\81E¿Hy\9b=çQE?\88ï!?Hy\9b=çQE?\88ï!?Hy\9b=çQE?\88ï!?Hy\9b=çQE?\88ï!?Hy\9b=çQE?\88ï!¿Hy\9b=çQE?\88ï!¿Hy\9b=çQE?\88ï!¿Hy\9b=çQE?\88ï!¿\9am\7f=©\16"?o\81E?\9am\7f=©\16"?o\81E?\9am\7f=©\16"?o\81E?\9am\7f=©\16"?o\81E?\819±=¼ì`?Msð¾\819±=¼ì`?Msð¾\819±=¼ì`?Msð¾\819±=¼ì`?Msð¾"÷==}\18ñ>b\87a?"÷==}\18ñ>b\87a?"÷==}\18ñ>b\87a?"÷==}\18ñ>b\87a?2,À=aås?\aø\93¾2,À=aås?\aø\93¾2,À=aås?\aø\93¾2,À=aås?\aø\93¾ß\1dê<¢\90\94>màt?ß\1dê<¢\90\94>màt?ß\1dê<¢\90\94>màt?ß\1dê<¢\90\94>màt?ëÇÇ=]\8d}?fÈǽëÇÇ=]\8d}?fÈǽëÇÇ=]\8d}?fÈǽëÇÇ=]\8d}?fÈǽêÇÇ=]\8d}?fÈÇ=êÇÇ=]\8d}?fÈÇ=êÇÇ=]\8d}?fÈÇ=êÇÇ=]\8d}?fÈÇ=
+\eê<±\90\94>kàt¿
+\eê<±\90\94>kàt¿
+\eê<±\90\94>kàt¿
+\eê<±\90\94>kàt¿=,À=aås?\aø\93>=,À=aås?\aø\93>=,À=aås?\aø\93>=,À=aås?\aø\93>ý÷==o\18ñ>f\87a¿ý÷==o\18ñ>f\87a¿ý÷==o\18ñ>f\87a¿ý÷==o\18ñ>f\87a¿\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?\0\0\80?\0\0\0\0\0\0\0\80\0\0\80?ÑÎ\94°\90\f¶;]:\b¼u\10\8eº\1d\8d²;]:\b¼\13¶Cºùùu;P^\17¼\1d²W°\8cËz;P^\17¼@\v;±T:\b<\9b\f¶;;\9dÔºC\9c\ 5<\9b\f¶;\83>캽u\14<\99Ëz;[¼.°K^\17<\99Ëz;u?Ò°a´ç;j´ç»Aдºª@ã;j´ç»u\10\8eº\1d\8d²;]:\b¼ÑÎ\94°\90\f¶;]:\b¼u?Ò°a´ç;j´ç;Aдºª@ã;j´ç;;\9dÔºC\9c\ 5<\9b\f¶;@\v;±T:\b<\9b\f¶;@\v;±T:\b<\9b\f¶»;\9dÔºC\9c\ 5<\9b\f¶»Aдºª@ã;j´ç»u?Ò°a´ç;j´ç»³I©°\8e\f¶;]:\b<t\10\8eº\1c\8d²;]:\b<Aдºª@ã;j´ç;u?Ò°a´ç;j´ç;[¼.°K^\17< Ëz»\82>캽u\14< Ëz»;\9dÔºC\9c\ 5<\9b\f¶»@\v;±T:\b<\9b\f¶»\1d²W°\8aËz;R^\17<\r¶Cºòùu;R^\17<t\10\8eº\1c\8d²;]:\b<³I©°\8e\f¶;]:\b<ÏÍ0±\13± <uµÿº¥Ëúº\9a\1d<uµÿº\82>캽u\14< Ëz»[¼.°K^\17< Ëz»\8av&¯Pµÿ:\1e± <\9b\8bǹ\8bËú:\1e± <\r¶Cºòùu;R^\17<\1d²W°\8aËz;R^\17<@\v;±\ 1×#<ì\86O°xµÿº\1d± <ì\86O°¥Ëúº\9a\1d<uµÿºÏÍ0±\13± <uµÿº\8c\1cίaµÿ:\1d± ¼ª\8bǹ Ëú:\1d± ¼uÍø0N\fͱ
+×#¼\1c¶Cº}>ì:\1d± ¼\7f\10\8eº0\9dÔ:\1d± ¼\92\8bÇ9\8fËú:\1d± ¼
+¶C:n>ì:\1d± ¼Pдº4д:\1d± ¼uÍø0N\fͱ
+×#¼K\9dÔºb\10\8e:\1d± ¼\97>ìºâµC:\1d± ¼¹Ëúº8\8bÇ9\1d± ¼uÍø0N\fͱ
+×#¼\8bµÿºfv`±\1d± ¼¸Ëúº\18\8cǹ\1d± ¼\93>ìºP¶Cº\1d± ¼uÍø0N\fͱ
+×#¼F\9dÔº\97\10\8eº\1d± ¼Jдºgдº\1d± ¼y\10\8eºa\9dÔº\1d± ¼uÍø0N\fͱ
+×#¼\14¶Cº«>ìº\1d± ¼¡\8bǹÎËúº\1d± ¼
+\98\9e. µÿº\1d± ¼uÍø0N\fͱ
+×#¼¥\8bÇ9ËËúº\1d± ¼\13¶C:§>ìº\1d± ¼w\10\8e:\\9dÔº\1d± ¼uÍø0N\fͱ
+×#¼Fд:aдº\1d± ¼@\9dÔ:\91\10\8eº\1d± ¼\8a>ì:F¶Cº\1d± ¼uÍø0N\fͱ
+×#¼¬Ëú:
+\8cǹ\1d± ¼~µÿ:õ8V±\1d± ¼«Ëú:2\8bÇ9\1d± ¼uÍø0N\fͱ
+×#¼\89>ì:صC:\1d± ¼=\9dÔ:Y\10\8e:\1d± ¼Bд:)д:\1d± ¼uÍø0N\fͱ
+×#¼s\10\8e:"\9dÔ:\1d± ¼\0\0\0\0\9eê_±
+×#<\9b\8bǹ\8bËú:\1e± <\8av&¯Pµÿ:\1e± <\v¶Cºi>ì:\1e± <r\10\8eº \9dÔ:\1e± <\8a\8bÇ9~Ëú:\1e± <þµC:]>ì:\1e± <\0\0\0\0\9eê_±
+×#<@дº&д:\1e± <9\9dÔºW\10\8e:\1e± <\82>ìºÕµC:\1e± <\0\0\0\0\9eê_±
+×#<£Ëúº.\8bÇ9\1e± <wµÿº\99©S±\1e± <£Ëúº\ 2\8cǹ\1e± <\0\0\0\0\9eê_±
+×#<\81>ìº>¶Cº\1e± <7\9dÔº\8c\10\8eº\1e± <=дºYдº\1e± <\0\0\0\0\9eê_±
+×#<p\10\8eºR\9dÔº\1e± < ¶Cº\9b>ìº\1e± <\97\8bǹ¼Ëúº\1e± <\0\0\0\0\9eê_±
+×#<
+U.®\8eµÿº\1e± <\93\8bÇ9»Ëúº\1e± <\ 4¶C:\97>ìº\1e± <\0\0\0\0\9eê_±
+×#<l\10\8e:L\9dÔº\1e± <8д:Tдº\1e± <0\9dÔ:\87\10\8eº\1e± <\0\0\0\0\9eê_±
+×#<x>ì:7¶Cº\1e± <\99Ëú:ü\8bǹ\1e± <lµÿ:RÈX±\1e± <\0\0\0\0\9eê_±
+×#<\99Ëú:"\8bÇ9\1e± <x>ì:ʵC:\1e± </\9dÔ:O\10\8e:\1e± <\0\0\0\0\9eê_±
+×#<7д:\1cд:\1e± <j\10\8e:\14\9dÔ:\1e± <ÏÍ0±\13± <iµÿ:¦Ëúº\9a\1d<iµÿ:xµÿº\1d± <ì\86O°@\v;±\ 1×#<ì\86O°\1d²W°\8cËz;P^\17¼\13¶Cºùùu;P^\17¼ª\8bǹ Ëú:\1d± ¼\8c\1cίaµÿ:\1d± ¼[¼.°K^\17<\99Ëz;\83>캽u\14<\99Ëz;¦Ëúº\9a\1d<iµÿ:ÏÍ0±\13± <iµÿ:¦Ëúº\9a\1d<iµÿ:ýùu»¼u\14<iµÿ:¥Ëz»P^\17<ì\86O°xµÿº\1d± <ì\86O°\13¶Cºùùu;P^\17¼^ó¿ºk´g;P^\17¼\1c¶Cº}>ì:\1d± ¼ª\8bǹ Ëú:\1d± ¼\83>캽u\14<\99Ëz;o´g»\9fØ\v<\99Ëz;ýùu»¼u\14<iµÿ:¦Ëúº\9a\1d<iµÿ:u\10\8eº\1d\8d²;]:\b¼¥U\v»
+1¨;]:\b¼^ó¿ºk´g;P^\17¼\13¶Cºùùu;P^\17¼;\9dÔºC\9c\ 5<\9b\f¶;b\87P»j·û;\9b\f¶;o´g»\9fØ\v<\99Ëz;\83>캽u\14<\99Ëz;Aдºª@ã;j´ç»×V1»7\11Ö;j´ç»¥U\v»
+1¨;]:\b¼u\10\8eº\1d\8d²;]:\b¼Aдºª@ã;j´ç;×V1»7\11Ö;j´ç;b\87P»j·û;\9b\f¶;;\9dÔºC\9c\ 5<\9b\f¶;;\9dÔºC\9c\ 5<\9b\f¶»b\87P»j·û;\9b\f¶»×V1»7\11Ö;j´ç»Aдºª@ã;j´ç»t\10\8eº\1c\8d²;]:\b<¤U\v» 1¨;]:\b<×V1»7\11Ö;j´ç;Aдºª@ã;j´ç;\82>캽u\14< Ëz»n´g»\9fØ\v< Ëz»b\87P»j·û;\9b\f¶»;\9dÔºC\9c\ 5<\9b\f¶»\r¶Cºòùu;R^\17<Yó¿ºd´g;R^\17<¤U\v» 1¨;]:\b<t\10\8eº\1c\8d²;]:\b<¥Ëúº\9a\1d<uµÿºýùu»¼u\14<uµÿºn´g»\9fØ\v< Ëz»\82>캽u\14< Ëz»\9b\8bǹ\8bËú:\1e± <\v¶Cºi>ì:\1e± <Yó¿ºd´g;R^\17<\r¶Cºòùu;R^\17<xµÿº\1d± <ì\86O°¥Ëz»P^\17<ì\86O°ýùu»¼u\14<uµÿº¥Ëúº\9a\1d<uµÿº¤U\v» 1¨;]:\b<JHJ»N^\97;]:\b<sº\80»Ê§À;j´ç;×V1»7\11Ö;j´ç;n´g»\9fØ\v< Ëz»\ e1¨»i·û; Ëz»T^\97»ð\89â;\9b\f¶»b\87P»j·û;\9b\f¶»Yó¿ºd´g;R^\17<¤U\v»U\87P;R^\17<JHJ»N^\97;]:\b<¤U\v» 1¨;]:\b<ýùu»¼u\14<uµÿº \8d²»A\9c\ 5<uµÿº\ e1¨»i·û; Ëz»n´g»\9fØ\v< Ëz»\v¶Cºi>ì:\1e± <r\10\8eº \9dÔ:\1e± <¤U\v»U\87P;R^\17<Yó¿ºd´g;R^\17<¥Ëz»P^\17<ì\86O° \f¶»[:\b<ì\86O° \8d²»A\9c\ 5<uµÿºýùu»¼u\14<uµÿºýùu»¼u\14<iµÿ: \8d²»A\9c\ 5<iµÿ: \f¶»[:\b<ì\86O°¥Ëz»P^\17<ì\86O°^ó¿ºk´g;P^\17¼§U\v»\\87P;P^\17¼\7f\10\8eº0\9dÔ:\1d± ¼\1c¶Cº}>ì:\1d± ¼o´g»\9fØ\v<\99Ëz;\ e1¨»j·û;\99Ëz; \8d²»A\9c\ 5<iµÿ:ýùu»¼u\14<iµÿ:¥U\v»
+1¨;]:\b¼KHJ»O^\97;]:\b¼§U\v»\\87P;P^\17¼^ó¿ºk´g;P^\17¼b\87P»j·û;\9b\f¶;T^\97»ð\89â;\9b\f¶;\ e1¨»j·û;\99Ëz;o´g»\9fØ\v<\99Ëz;×V1»7\11Ö;j´ç»sº\80»Ê§À;j´ç»KHJ»O^\97;]:\b¼¥U\v»
+1¨;]:\b¼×V1»7\11Ö;j´ç;sº\80»Ê§À;j´ç;T^\97»ð\89â;\9b\f¶;b\87P»j·û;\9b\f¶;b\87P»j·û;\9b\f¶»T^\97»ð\89â;\9b\f¶»sº\80»Ê§À;j´ç»×V1»7\11Ö;j´ç»\ e1¨»j·û;\99Ëz;<\11Ö»7\11Ö;\99Ëz;®@㻦@ã;iµÿ: \8d²»A\9c\ 5<iµÿ:KHJ»O^\97;]:\b¼tº\80»mº\80;]:\b¼ÜV1»ÎV1;P^\17¼§U\v»\\87P;P^\17¼T^\97»ð\89â;\9b\f¶;ЧÀ»É§À;\9b\f¶;<\11Ö»7\11Ö;\99Ëz;\ e1¨»j·û;\99Ëz;sº\80»Ê§À;j´ç»\ e×£»\a×£;j´ç»tº\80»mº\80;]:\b¼KHJ»O^\97;]:\b¼sº\80»Ê§À;j´ç;\ e×£»\a×£;j´ç;ЧÀ»É§À;\9b\f¶;T^\97»ð\89â;\9b\f¶;T^\97»ð\89â;\9b\f¶»Ð§À»É§À;\9b\f¶»\ e×£»\a×£;j´ç»sº\80»Ê§À;j´ç»JHJ»N^\97;]:\b<sº\80»kº\80;]:\b<\ e×£»\a×£;j´ç;sº\80»Ê§À;j´ç;\ e1¨»i·û; Ëz»<\11Ö»5\11Ö; Ëz»Ð§À»É§À;\9b\f¶»T^\97»ð\89â;\9b\f¶»¤U\v»U\87P;R^\17<×V1»ÊV1;R^\17<sº\80»kº\80;]:\b<JHJ»N^\97;]:\b< \8d²»A\9c\ 5<uµÿº®@㻦@ã;uµÿº<\11Ö»5\11Ö; Ëz»\ e1¨»i·û; Ëz»r\10\8eº \9dÔ:\1e± <@дº&д:\1e± <×V1»ÊV1;R^\17<¤U\v»U\87P;R^\17< \f¶»[:\b<ì\86O°o´ç»f´ç;ì\86O°®@㻦@ã;uµÿº \8d²»A\9c\ 5<uµÿº \8d²»A\9c\ 5<iµÿ:®@㻦@ã;iµÿ:o´ç»f´ç;ì\86O° \f¶»[:\b<ì\86O°§U\v»\\87P;P^\17¼ÜV1»ÎV1;P^\17¼Pдº4д:\1d± ¼\7f\10\8eº0\9dÔ:\1d± ¼×V1»ÊV1;R^\17<d\87P»\97U\v;R^\17<T^\97»;HJ;]:\b<sº\80»kº\80;]:\b<®@㻦@ã;uµÿºD\9c\ 5¼\17\8d²;uµÿºo·û»\a1¨; Ëz»<\11Ö»5\11Ö; Ëz»@дº&д:\1e± <9\9dÔºW\10\8e:\1e± <d\87P»\97U\v;R^\17<×V1»ÊV1;R^\17<o´ç»f´ç;ì\86O°_:\b¼\97\f¶;ì\86O°D\9c\ 5¼\17\8d²;uµÿº®@㻦@ã;uµÿº®@㻦@ã;iµÿ:D\9c\ 5¼\17\8d²;iµÿ:_:\b¼\97\f¶;ì\86O°o´ç»f´ç;ì\86O°ÜV1»ÎV1;P^\17¼i\87P»\9aU\v;P^\17¼K\9dÔºb\10\8e:\1d± ¼Pдº4д:\1d± ¼<\11Ö»7\11Ö;\99Ëz;o·û» 1¨;\99Ëz;D\9c\ 5¼\17\8d²;iµÿ:®@㻦@ã;iµÿ:tº\80»mº\80;]:\b¼V^\97»=HJ;]:\b¼i\87P»\9aU\v;P^\17¼ÜV1»ÎV1;P^\17¼Ð§À»É§À;\9b\f¶;÷\89â»M^\97;\9b\f¶;o·û» 1¨;\99Ëz;<\11Ö»7\11Ö;\99Ëz;\ e×£»\a×£;j´ç»Ð§À»kº\80;j´ç»V^\97»=HJ;]:\b¼tº\80»mº\80;]:\b¼\ e×£»\a×£;j´ç;ЧÀ»kº\80;j´ç;÷\89â»M^\97;\9b\f¶;ЧÀ»É§À;\9b\f¶;ЧÀ»É§À;\9b\f¶»÷\89â»M^\97;\9b\f¶»Ð§À»kº\80;j´ç»\ e×£»\a×£;j´ç»sº\80»kº\80;]:\b<T^\97»;HJ;]:\b<ЧÀ»kº\80;j´ç;\ e×£»\a×£;j´ç;<\11Ö»5\11Ö; Ëz»o·û»\a1¨; Ëz»÷\89â»M^\97;\9b\f¶»Ð§À»É§À;\9b\f¶»V^\97»=HJ;]:\b¼\101¨»\97U\v;]:\b¼w´g»Dó¿:P^\17¼i\87P»\9aU\v;P^\17¼÷\89â»M^\97;\9b\f¶;p·û»R\87P;\9b\f¶;¡Ø\v¼d´g;\99Ëz;o·û» 1¨;\99Ëz;ЧÀ»kº\80;j´ç»=\11Ö»ÇV1;j´ç»\101¨»\97U\v;]:\b¼V^\97»=HJ;]:\b¼Ð§À»kº\80;j´ç;=\11Ö»ÇV1;j´ç;p·û»R\87P;\9b\f¶;÷\89â»M^\97;\9b\f¶;÷\89â»M^\97;\9b\f¶»p·û»R\87P;\9b\f¶»=\11Ö»ÇV1;j´ç»Ð§À»kº\80;j´ç»T^\97»;HJ;]:\b<\ f1¨»\94U\v;]:\b<=\11Ö»ÇV1;j´ç;ЧÀ»kº\80;j´ç;o·û»\a1¨; Ëz»¡Ø\v¼a´g; Ëz»p·û»R\87P;\9b\f¶»÷\89â»M^\97;\9b\f¶»d\87P»\97U\v;R^\17<p´g»@ó¿:R^\17<\ f1¨»\94U\v;]:\b<T^\97»;HJ;]:\b<D\9c\ 5¼\17\8d²;uµÿº¾u\14¼éùu;uµÿº¡Ø\v¼a´g; Ëz»o·û»\a1¨; Ëz»9\9dÔºW\10\8e:\1e± <\82>ìºÕµC:\1e± <p´g»@ó¿:R^\17<d\87P»\97U\v;R^\17<_:\b¼\97\f¶;ì\86O°S^\17¼\94Ëz;ì\86O°¾u\14¼éùu;uµÿºD\9c\ 5¼\17\8d²;uµÿºD\9c\ 5¼\17\8d²;iµÿ:¾u\14¼éùu;iµÿ:S^\17¼\94Ëz;ì\86O°_:\b¼\97\f¶;ì\86O°i\87P»\9aU\v;P^\17¼w´g»Dó¿:P^\17¼\97>ìºâµC:\1d± ¼K\9dÔºb\10\8e:\1d± ¼o·û» 1¨;\99Ëz;¡Ø\v¼d´g;\99Ëz;¾u\14¼éùu;iµÿ:D\9c\ 5¼\17\8d²;iµÿ:¾u\14¼éùu;uµÿº®\9a\1d¼\80Ëú:uµÿº¿u\14¼i>ì: Ëz»¡Ø\v¼a´g; Ëz»\82>ìºÕµC:\1e± <£Ëúº.\8bÇ9\1e± <þùu»×µC:R^\17<p´g»@ó¿:R^\17<S^\17¼\94Ëz;ì\86O° ± ¼Wµÿ:ì\86O°®\9a\1d¼\80Ëú:uµÿº¾u\14¼éùu;uµÿº¾u\14¼éùu;iµÿ:®\9a\1d¼\80Ëú:iµÿ: ± ¼Wµÿ:ì\86O°S^\17¼\94Ëz;ì\86O°w´g»Dó¿:P^\17¼\ 5úu»ÙµC:P^\17¼¹Ëúº8\8bÇ9\1d± ¼\97>ìºâµC:\1d± ¼¡Ø\v¼d´g;\99Ëz;¿u\14¼n>ì:\99Ëz;®\9a\1d¼\80Ëú:iµÿ:¾u\14¼éùu;iµÿ:\101¨»\97U\v;]:\b¼"\8d²»X\10\8e:]:\b¼\ 5úu»ÙµC:P^\17¼w´g»Dó¿:P^\17¼p·û»R\87P;\9b\f¶;E\9c\ 5¼\e\9dÔ:\9b\f¶;¿u\14¼n>ì:\99Ëz;¡Ø\v¼d´g;\99Ëz;=\11Ö»ÇV1;j´ç»¯@ã»%д:j´ç»"\8d²»X\10\8e:]:\b¼\101¨»\97U\v;]:\b¼=\11Ö»ÇV1;j´ç;¯@ã»%д:j´ç;E\9c\ 5¼\e\9dÔ:\9b\f¶;p·û»R\87P;\9b\f¶;p·û»R\87P;\9b\f¶»E\9c\ 5¼\e\9dÔ:\9b\f¶»¯@ã»%д:j´ç»=\11Ö»ÇV1;j´ç»\ f1¨»\94U\v;]:\b<!\8d²»T\10\8e:]:\b<¯@ã»%д:j´ç;=\11Ö»ÇV1;j´ç;¡Ø\v¼a´g; Ëz»¿u\14¼i>ì: Ëz»E\9c\ 5¼\e\9dÔ:\9b\f¶»p·û»R\87P;\9b\f¶»p´g»@ó¿:R^\17<þùu»×µC:R^\17<!\8d²»T\10\8e:]:\b<\ f1¨»\94U\v;]:\b<E\9c\ 5¼\e\9dÔ:\9b\f¶;_:\b¼\1e\95e±\9b\f¶;R^\17¼
+ç\1d±\99Ëz;¿u\14¼n>ì:\99Ëz;¯@ã»%д:j´ç»n´ç»®W[±j´ç»¡\f¶»õ8V±]:\b¼"\8d²»X\10\8e:]:\b¼¯@ã»%д:j´ç;n´ç»®W[±j´ç;_:\b¼\1e\95e±\9b\f¶;E\9c\ 5¼\e\9dÔ:\9b\f¶;E\9c\ 5¼\e\9dÔ:\9b\f¶»_:\b¼\1e\95e±\9b\f¶»n´ç»®W[±j´ç»¯@ã»%д:j´ç»!\8d²»T\10\8e:]:\b<\9e\f¶»×³j±]:\b<n´ç»®W[±j´ç;¯@ã»%д:j´ç;¿u\14¼i>ì: Ëz»R^\17¼\\9f<± Ëz»_:\b¼\1e\95e±\9b\f¶»E\9c\ 5¼\e\9dÔ:\9b\f¶»þùu»×µC:R^\17<¥Ëz»=\1aQ±R^\17<\9e\f¶»×³j±]:\b<!\8d²»T\10\8e:]:\b<®\9a\1d¼\80Ëú:uµÿº\1d± ¼pE\87±uµÿºR^\17¼\\9f<± Ëz»¿u\14¼i>ì: Ëz»£Ëúº.\8bÇ9\1e± <wµÿº\99©S±\1e± <¥Ëz»=\1aQ±R^\17<þùu»×µC:R^\17< ± ¼Wµÿ:ì\86O°\r×#¼¸&\82±ì\86O°\1d± ¼pE\87±uµÿº®\9a\1d¼\80Ëú:uµÿº®\9a\1d¼\80Ëú:iµÿ:\1d± ¼pE\87±iµÿ:\r×#¼¸&\82±ì\86O° ± ¼Wµÿ:ì\86O°\ 5úu»ÙµC:P^\17¼«Ëz»®W[±P^\17¼\8bµÿºfv`±\1d± ¼¹Ëúº8\8bÇ9\1d± ¼¿u\14¼n>ì:\99Ëz;R^\17¼
+ç\1d±\99Ëz;\1d± ¼pE\87±iµÿ:®\9a\1d¼\80Ëú:iµÿ:"\8d²»X\10\8e:]:\b¼¡\f¶»õ8V±]:\b¼«Ëz»®W[±P^\17¼\ 5úu»ÙµC:P^\17¼wµÿº\99©S±\1e± <£Ëúº\ 2\8cǹ\1e± <ýùu»>¶CºR^\17<¥Ëz»=\1aQ±R^\17<\r×#¼¸&\82±ì\86O° ± ¼\97µÿºì\86O°\9a\1d¼ÁËúºuµÿº\1d± ¼pE\87±uµÿº\1d± ¼pE\87±iµÿ:\9a\1d¼ÁËúºiµÿ: ± ¼\97µÿºì\86O°\r×#¼¸&\82±ì\86O°«Ëz»®W[±P^\17¼\ 3úu»F¶CºP^\17¼¸Ëúº\18\8cǹ\1d± ¼\8bµÿºfv`±\1d± ¼R^\17¼
+ç\1d±\99Ëz;¿u\14¼\94>ìº\99Ëz;\9a\1d¼ÁËúºiµÿ:\1d± ¼pE\87±iµÿ:¡\f¶»õ8V±]:\b¼"\8d²»\8e\10\8eº]:\b¼\ 3úu»F¶CºP^\17¼«Ëz»®W[±P^\17¼_:\b¼\1e\95e±\9b\f¶;D\9c\ 5¼S\9dÔº\9b\f¶;¿u\14¼\94>ìº\99Ëz;R^\17¼
+ç\1d±\99Ëz;n´ç»®W[±j´ç»®@ã»Yдºj´ç»"\8d²»\8e\10\8eº]:\b¼¡\f¶»õ8V±]:\b¼n´ç»®W[±j´ç;®@ã»Yдºj´ç;D\9c\ 5¼S\9dÔº\9b\f¶;_:\b¼\1e\95e±\9b\f¶;_:\b¼\1e\95e±\9b\f¶»D\9c\ 5¼S\9dÔº\9b\f¶»®@ã»Yдºj´ç»n´ç»®W[±j´ç»\9e\f¶»×³j±]:\b< \8d²»\8f\10\8eº]:\b<®@ã»Yдºj´ç;n´ç»®W[±j´ç;R^\17¼\\9f<± Ëz»¿u\14¼\98>ìº Ëz»D\9c\ 5¼S\9dÔº\9b\f¶»_:\b¼\1e\95e±\9b\f¶»¥Ëz»=\1aQ±R^\17<ýùu»>¶CºR^\17< \8d²»\8f\10\8eº]:\b<\9e\f¶»×³j±]:\b<\1d± ¼pE\87±uµÿº\9a\1d¼ÁËúºuµÿº¿u\14¼\98>ìº Ëz»R^\17¼\\9f<± Ëz»®@ã»Yдºj´ç»<\11Ö»áV1»j´ç»\ f1¨»°U\v»]:\b¼"\8d²»\8e\10\8eº]:\b¼®@ã»Yдºj´ç;<\11Ö»áV1»j´ç;l·û»n\87P»\9b\f¶;D\9c\ 5¼S\9dÔº\9b\f¶;D\9c\ 5¼S\9dÔº\9b\f¶»l·û»n\87P»\9b\f¶»<\11Ö»áV1»j´ç»®@ã»Yдºj´ç» \8d²»\8f\10\8eº]:\b<\r1¨»°U\v»]:\b<<\11Ö»áV1»j´ç;®@ã»Yдºj´ç;¿u\14¼\98>ìº Ëz»¡Ø\v¼x´g» Ëz»l·û»n\87P»\9b\f¶»D\9c\ 5¼S\9dÔº\9b\f¶»ýùu»>¶CºR^\17<n´g»ró¿ºR^\17<\r1¨»°U\v»]:\b< \8d²»\8f\10\8eº]:\b<\9a\1d¼ÁËúºuµÿº¼u\14¼\aúu»uµÿº¡Ø\v¼x´g» Ëz»¿u\14¼\98>ìº Ëz»£Ëúº\ 2\8cǹ\1e± <\81>ìº>¶Cº\1e± <n´g»ró¿ºR^\17<ýùu»>¶CºR^\17< ± ¼\97µÿºì\86O°R^\17¼³Ëz»ì\86O°¼u\14¼\aúu»uµÿº\9a\1d¼ÁËúºuµÿº\9a\1d¼ÁËúºiµÿ:¼u\14¼\aúu»iµÿ:R^\17¼³Ëz»ì\86O° ± ¼\97µÿºì\86O°\ 3úu»F¶CºP^\17¼t´g»wó¿ºP^\17¼\93>ìºP¶Cº\1d± ¼¸Ëúº\18\8cǹ\1d± ¼¿u\14¼\94>ìº\99Ëz;¡Ø\v¼u´g»\99Ëz;¼u\14¼\aúu»iµÿ:\9a\1d¼ÁËúºiµÿ:"\8d²»\8e\10\8eº]:\b¼\ f1¨»°U\v»]:\b¼t´g»wó¿ºP^\17¼\ 3úu»F¶CºP^\17¼D\9c\ 5¼S\9dÔº\9b\f¶;l·û»n\87P»\9b\f¶;¡Ø\v¼u´g»\99Ëz;¿u\14¼\94>ìº\99Ëz;R^\17¼³Ëz»ì\86O°^:\b¼¥\f¶»ì\86O°B\9c\ 5¼$\8d²»uµÿº¼u\14¼\aúu»uµÿº¼u\14¼\aúu»iµÿ:B\9c\ 5¼$\8d²»iµÿ:^:\b¼¥\f¶»ì\86O°R^\17¼³Ëz»ì\86O°t´g»wó¿ºP^\17¼f\87P»²U\v»P^\17¼F\9dÔº\97\10\8eº\1d± ¼\93>ìºP¶Cº\1d± ¼¡Ø\v¼u´g»\99Ëz;n·û»\121¨»\99Ëz;B\9c\ 5¼$\8d²»iµÿ:¼u\14¼\aúu»iµÿ:\ f1¨»°U\v»]:\b¼T^\97»UHJ»]:\b¼f\87P»²U\v»P^\17¼t´g»wó¿ºP^\17¼l·û»n\87P»\9b\f¶;ó\89â»Y^\97»\9b\f¶;n·û»\121¨»\99Ëz;¡Ø\v¼u´g»\99Ëz;<\11Ö»áV1»j´ç»Ï§À»wº\80»j´ç»T^\97»UHJ»]:\b¼\ f1¨»°U\v»]:\b¼<\11Ö»áV1»j´ç;ϧÀ»wº\80»j´ç;ó\89â»Y^\97»\9b\f¶;l·û»n\87P»\9b\f¶;l·û»n\87P»\9b\f¶»ó\89â»Y^\97»\9b\f¶»Ï§À»wº\80»j´ç»<\11Ö»áV1»j´ç»\r1¨»°U\v»]:\b<R^\97»THJ»]:\b<ϧÀ»wº\80»j´ç;<\11Ö»áV1»j´ç;¡Ø\v¼x´g» Ëz»n·û»\121¨» Ëz»ó\89â»Y^\97»\9b\f¶»l·û»n\87P»\9b\f¶»n´g»ró¿ºR^\17<`\87P»¯U\v»R^\17<R^\97»THJ»]:\b<\r1¨»°U\v»]:\b<¼u\14¼\aúu»uµÿºB\9c\ 5¼$\8d²»uµÿºn·û»\121¨» Ëz»¡Ø\v¼x´g» Ëz»\81>ìº>¶Cº\1e± <7\9dÔº\8c\10\8eº\1e± <`\87P»¯U\v»R^\17<n´g»ró¿ºR^\17<ϧÀ»wº\80»j´ç;\v×£»\12×£»j´ç;˧À»Ô§À»\9b\f¶;ó\89â»Y^\97»\9b\f¶;ó\89â»Y^\97»\9b\f¶»Ë§À»Ô§À»\9b\f¶»\v×£»\12×£»j´ç»Ï§À»wº\80»j´ç»R^\97»THJ»]:\b<pº\80»wº\80»]:\b<\v×£»\12×£»j´ç;ϧÀ»wº\80»j´ç;n·û»\121¨» Ëz»<\11Ö»@\11Ö» Ëz»Ë§À»Ô§À»\9b\f¶»ó\89â»Y^\97»\9b\f¶»`\87P»¯U\v»R^\17<ÓV1»áV1»R^\17<pº\80»wº\80»]:\b<R^\97»THJ»]:\b<B\9c\ 5¼$\8d²»uµÿº©@ã»°@ã»uµÿº<\11Ö»@\11Ö» Ëz»n·û»\121¨» Ëz»7\9dÔº\8c\10\8eº\1e± <=дºYдº\1e± <ÓV1»áV1»R^\17<`\87P»¯U\v»R^\17<^:\b¼¥\f¶»ì\86O°k´ç»t´ç»ì\86O°©@ã»°@ã»uµÿºB\9c\ 5¼$\8d²»uµÿºB\9c\ 5¼$\8d²»iµÿ:©@ã»°@ã»iµÿ:k´ç»t´ç»ì\86O°^:\b¼¥\f¶»ì\86O°f\87P»²U\v»P^\17¼ÙV1»åV1»P^\17¼Jдºgдº\1d± ¼F\9dÔº\97\10\8eº\1d± ¼n·û»\121¨»\99Ëz;<\11Ö»@\11Ö»\99Ëz;©@ã»°@ã»iµÿ:B\9c\ 5¼$\8d²»iµÿ:T^\97»UHJ»]:\b¼rº\80»xº\80»]:\b¼ÙV1»åV1»P^\17¼f\87P»²U\v»P^\17¼ó\89â»Y^\97»\9b\f¶;˧À»Ô§À»\9b\f¶;<\11Ö»@\11Ö»\99Ëz;n·û»\121¨»\99Ëz;ϧÀ»wº\80»j´ç»\v×£»\12×£»j´ç»rº\80»xº\80»]:\b¼T^\97»UHJ»]:\b¼©@ã»°@ã»iµÿ:\e\8d²»F\9c\ 5¼iµÿ:\9c\f¶»b:\b¼ì\86O°k´ç»t´ç»ì\86O°ÙV1»åV1»P^\17¼¥U\v»p\87P»P^\17¼y\10\8eºa\9dÔº\1d± ¼Jдºgдº\1d± ¼<\11Ö»@\11Ö»\99Ëz;\ e1¨»s·û»\99Ëz;\e\8d²»F\9c\ 5¼iµÿ:©@ã»°@ã»iµÿ:rº\80»xº\80»]:\b¼GHJ»Y^\97»]:\b¼¥U\v»p\87P»P^\17¼ÙV1»åV1»P^\17¼Ë§À»Ô§À»\9b\f¶;P^\97»ù\89â»\9b\f¶;\ e1¨»s·û»\99Ëz;<\11Ö»@\11Ö»\99Ëz;\v×£»\12×£»j´ç»pº\80»Ô§À»j´ç»GHJ»Y^\97»]:\b¼rº\80»xº\80»]:\b¼\v×£»\12×£»j´ç;pº\80»Ô§À»j´ç;P^\97»ù\89â»\9b\f¶;˧À»Ô§À»\9b\f¶;˧À»Ô§À»\9b\f¶»P^\97»ù\89â»\9b\f¶»pº\80»Ô§À»j´ç»\v×£»\12×£»j´ç»pº\80»wº\80»]:\b<DHJ»X^\97»]:\b<pº\80»Ô§À»j´ç;\v×£»\12×£»j´ç;<\11Ö»@\11Ö» Ëz»\ e1¨»s·û» Ëz»P^\97»ù\89â»\9b\f¶»Ë§À»Ô§À»\9b\f¶»ÓV1»áV1»R^\17< U\v»k\87P»R^\17<DHJ»X^\97»]:\b<pº\80»wº\80»]:\b<©@ã»°@ã»uµÿº\e\8d²»F\9c\ 5¼uµÿº\ e1¨»s·û» Ëz»<\11Ö»@\11Ö» Ëz»=дºYдº\1e± <p\10\8eºR\9dÔº\1e± < U\v»k\87P»R^\17<ÓV1»áV1»R^\17<k´ç»t´ç»ì\86O°\9c\f¶»b:\b¼ì\86O°\e\8d²»F\9c\ 5¼uµÿº©@ã»°@ã»uµÿºDHJ»X^\97»]:\b<\9fU\v»\121¨»]:\b<ÐV1»@\11Ö»j´ç;pº\80»Ô§À»j´ç;\ e1¨»s·û» Ëz»n´g»£Ø\v¼ Ëz»Y\87P»r·û»\9b\f¶»P^\97»ù\89â»\9b\f¶» U\v»k\87P»R^\17<Tó¿ºx´g»R^\17<\9fU\v»\121¨»]:\b<DHJ»X^\97»]:\b<\e\8d²»F\9c\ 5¼uµÿºóùu»¿u\14¼uµÿºn´g»£Ø\v¼ Ëz»\ e1¨»s·û» Ëz»p\10\8eºR\9dÔº\1e± < ¶Cº\9b>ìº\1e± <Tó¿ºx´g»R^\17< U\v»k\87P»R^\17<\9c\f¶»b:\b¼ì\86O°\9eËz»V^\17¼ì\86O°óùu»¿u\14¼uµÿº\e\8d²»F\9c\ 5¼uµÿº\e\8d²»F\9c\ 5¼iµÿ:óùu»¿u\14¼iµÿ:\9eËz»V^\17¼ì\86O°\9c\f¶»b:\b¼ì\86O°¥U\v»p\87P»P^\17¼\ó¿º}´g»P^\17¼\14¶Cº«>ìº\1d± ¼y\10\8eºa\9dÔº\1d± ¼\ e1¨»s·û»\99Ëz;n´g»£Ø\v¼\99Ëz;óùu»¿u\14¼iµÿ:\e\8d²»F\9c\ 5¼iµÿ:GHJ»Y^\97»]:\b¼¢U\v»\141¨»]:\b¼\ó¿º}´g»P^\17¼¥U\v»p\87P»P^\17¼P^\97»ù\89â»\9b\f¶;Y\87P»r·û»\9b\f¶;n´g»£Ø\v¼\99Ëz;\ e1¨»s·û»\99Ëz;pº\80»Ô§À»j´ç»ÐV1»@\11Ö»j´ç»¢U\v»\141¨»]:\b¼GHJ»Y^\97»]:\b¼pº\80»Ô§À»j´ç;ÐV1»@\11Ö»j´ç;Y\87P»r·û»\9b\f¶;P^\97»ù\89â»\9b\f¶;P^\97»ù\89â»\9b\f¶»Y\87P»r·û»\9b\f¶»ÐV1»@\11Ö»j´ç»pº\80»Ô§À»j´ç»\ó¿º}´g»P^\17¼\12¶Cº\vúu»P^\17¼¡\8bǹÎËúº\1d± ¼\14¶Cº«>ìº\1d± ¼n´g»£Ø\v¼\99Ëz;\83>ìºÀu\14¼\99Ëz;\97Ëúº¯\9a\1d¼iµÿ:óùu»¿u\14¼iµÿ:¢U\v»\141¨»]:\b¼s\10\8eº&\8d²»]:\b¼\12¶Cº\vúu»P^\17¼\ó¿º}´g»P^\17¼Y\87P»r·û»\9b\f¶;+\9dÔºE\9c\ 5¼\9b\f¶;\83>ìºÀu\14¼\99Ëz;n´g»£Ø\v¼\99Ëz;ÐV1»@\11Ö»j´ç»9дº²@ã»j´ç»s\10\8eº&\8d²»]:\b¼¢U\v»\141¨»]:\b¼ÐV1»@\11Ö»j´ç;9дº²@ã»j´ç;+\9dÔºE\9c\ 5¼\9b\f¶;Y\87P»r·û»\9b\f¶;Y\87P»r·û»\9b\f¶»+\9dÔºE\9c\ 5¼\9b\f¶»9дº²@ã»j´ç»ÐV1»@\11Ö»j´ç»\9fU\v»\121¨»]:\b<m\10\8eº$\8d²»]:\b<9дº²@ã»j´ç;ÐV1»@\11Ö»j´ç;n´g»£Ø\v¼ Ëz»\83>ìºÀu\14¼ Ëz»+\9dÔºE\9c\ 5¼\9b\f¶»Y\87P»r·û»\9b\f¶»Tó¿ºx´g»R^\17<\a¶Cº\ 6úu»R^\17<m\10\8eº$\8d²»]:\b<\9fU\v»\121¨»]:\b<óùu»¿u\14¼uµÿº\97Ëúº¯\9a\1d¼uµÿº\83>ìºÀu\14¼ Ëz»n´g»£Ø\v¼ Ëz» ¶Cº\9b>ìº\1e± <\97\8bǹ¼Ëúº\1e± <\a¶Cº\ 6úu»R^\17<Tó¿ºx´g»R^\17<\9eËz»V^\17¼ì\86O°lµÿº"± ¼ì\86O°\97Ëúº¯\9a\1d¼uµÿºóùu»¿u\14¼uµÿºóùu»¿u\14¼iµÿ:\97Ëúº¯\9a\1d¼iµÿ:lµÿº"± ¼ì\86O°\9eËz»V^\17¼ì\86O°\83>ìºÀu\14¼ Ëz»[¼.°T^\17¼ Ëz»>Ýj0^:\b¼\9b\f¶»+\9dÔºE\9c\ 5¼\9b\f¶»\a¶Cº\ 6úu»R^\17<
+U.®¬Ëz»R^\17<\8f\83ð.¡\f¶»]:\b<m\10\8eº$\8d²»]:\b<\97Ëúº¯\9a\1d¼uµÿº>Ýj0\1e± ¼uµÿº[¼.°T^\17¼ Ëz»\83>ìºÀu\14¼ Ëz»\97\8bǹ¼Ëúº\1e± <
+U.®\8eµÿº\1e± <
+U.®¬Ëz»R^\17<\a¶Cº\ 6úu»R^\17<lµÿº"± ¼ì\86O°\80é\890\ e×#¼ì\86O°>Ýj0\1e± ¼uµÿº\97Ëúº¯\9a\1d¼uµÿº\97Ëúº¯\9a\1d¼iµÿ:>Ýj0\1e± ¼iµÿ:\80é\890\ e×#¼ì\86O°lµÿº"± ¼ì\86O°\12¶Cº\vúu»P^\17¼n\97⯲Ëz»P^\17¼
+\98\9e. µÿº\1d± ¼¡\8bǹÎËúº\1d± ¼\83>ìºÀu\14¼\99Ëz;[¼.°T^\17¼\99Ëz;>Ýj0\1e± ¼iµÿ:\97Ëúº¯\9a\1d¼iµÿ:s\10\8eº&\8d²»]:\b¼é«\90¯¥\f¶»]:\b¼n\97⯲Ëz»P^\17¼\12¶Cº\vúu»P^\17¼+\9dÔºE\9c\ 5¼\9b\f¶;>Ýj0^:\b¼\9b\f¶;[¼.°T^\17¼\99Ëz;\83>ìºÀu\14¼\99Ëz;9дº²@ã»j´ç»i\f\8e/p´ç»j´ç»é«\90¯¥\f¶»]:\b¼s\10\8eº&\8d²»]:\b¼9дº²@ã»j´ç;i\f\8e/p´ç»j´ç;>Ýj0^:\b¼\9b\f¶;+\9dÔºE\9c\ 5¼\9b\f¶;+\9dÔºE\9c\ 5¼\9b\f¶»>Ýj0^:\b¼\9b\f¶»i\f\8e/p´ç»j´ç»9дº²@ã»j´ç»m\10\8eº$\8d²»]:\b<\8f\83ð.¡\f¶»]:\b<i\f\8e/p´ç»j´ç;9дº²@ã»j´ç;[¼.°T^\17¼\99Ëz;y>ì:Àu\14¼\99Ëz;£Ëú:®\9a\1d¼iµÿ:>Ýj0\1e± ¼iµÿ:é«\90¯¥\f¶»]:\b¼n\10\8e:&\8d²»]:\b¼\ 2¶C: úu»P^\17¼n\97⯲Ëz»P^\17¼>Ýj0^:\b¼\9b\f¶;9\9dÔ:D\9c\ 5¼\9b\f¶;y>ì:Àu\14¼\99Ëz;[¼.°T^\17¼\99Ëz;i\f\8e/p´ç»j´ç»>д:°@ã»j´ç»n\10\8e:&\8d²»]:\b¼é«\90¯¥\f¶»]:\b¼i\f\8e/p´ç»j´ç;>д:°@ã»j´ç;9\9dÔ:D\9c\ 5¼\9b\f¶;>Ýj0^:\b¼\9b\f¶;>Ýj0^:\b¼\9b\f¶»9\9dÔ:D\9c\ 5¼\9b\f¶»>д:°@ã»j´ç»i\f\8e/p´ç»j´ç»\8f\83ð.¡\f¶»]:\b<n\10\8e:"\8d²»]:\b<>д:°@ã»j´ç;i\f\8e/p´ç»j´ç;[¼.°T^\17¼ Ëz»y>ì:Àu\14¼ Ëz»9\9dÔ:D\9c\ 5¼\9b\f¶»>Ýj0^:\b¼\9b\f¶»
+U.®¬Ëz»R^\17<\ 4¶C:\ 3úu»R^\17<n\10\8e:"\8d²»]:\b<\8f\83ð.¡\f¶»]:\b<>Ýj0\1e± ¼uµÿº£Ëú:®\9a\1d¼uµÿºy>ì:Àu\14¼ Ëz»[¼.°T^\17¼ Ëz»
+U.®\8eµÿº\1e± <\93\8bÇ9»Ëúº\1e± <\ 4¶C:\ 3úu»R^\17<
+U.®¬Ëz»R^\17<\80é\890\ e×#¼ì\86O°}µÿ:!± ¼ì\86O°£Ëú:®\9a\1d¼uµÿº>Ýj0\1e± ¼uµÿº>Ýj0\1e± ¼iµÿ:£Ëú:®\9a\1d¼iµÿ:}µÿ:!± ¼ì\86O°\80é\890\ e×#¼ì\86O°n\97⯲Ëz»P^\17¼\ 2¶C: úu»P^\17¼¥\8bÇ9ËËúº\1d± ¼
+\98\9e. µÿº\1d± ¼\ 4¶C:\ 3úu»R^\17<Ró¿:t´g»R^\17<\9fU\v;\101¨»]:\b<n\10\8e:"\8d²»]:\b<£Ëú:®\9a\1d¼uµÿºøùu;½u\14¼uµÿºg´g;£Ø\v¼ Ëz»y>ì:Àu\14¼ Ëz»\93\8bÇ9»Ëúº\1e± <\ 4¶C:\97>ìº\1e± <Ró¿:t´g»R^\17<\ 4¶C:\ 3úu»R^\17<}µÿ:!± ¼ì\86O°¦Ëz;T^\17¼ì\86O°øùu;½u\14¼uµÿº£Ëú:®\9a\1d¼uµÿº£Ëú:®\9a\1d¼iµÿ:øùu;½u\14¼iµÿ:¦Ëz;T^\17¼ì\86O°}µÿ:!± ¼ì\86O°\ 2¶C: úu»P^\17¼Só¿:y´g»P^\17¼\13¶C:§>ìº\1d± ¼¥\8bÇ9ËËúº\1d± ¼y>ì:Àu\14¼\99Ëz;g´g;£Ø\v¼\99Ëz;øùu;½u\14¼iµÿ:£Ëú:®\9a\1d¼iµÿ:n\10\8e:&\8d²»]:\b¼ U\v;\141¨»]:\b¼Só¿:y´g»P^\17¼\ 2¶C: úu»P^\17¼9\9dÔ:D\9c\ 5¼\9b\f¶;]\87P;k·û»\9b\f¶;g´g;£Ø\v¼\99Ëz;y>ì:Àu\14¼\99Ëz;>д:°@ã»j´ç»ÒV1;>\11Ö»j´ç» U\v;\141¨»]:\b¼n\10\8e:&\8d²»]:\b¼>д:°@ã»j´ç;ÒV1;>\11Ö»j´ç;]\87P;k·û»\9b\f¶;9\9dÔ:D\9c\ 5¼\9b\f¶;9\9dÔ:D\9c\ 5¼\9b\f¶»]\87P;k·û»\9b\f¶»ÒV1;>\11Ö»j´ç»>д:°@ã»j´ç»n\10\8e:"\8d²»]:\b<\9fU\v;\101¨»]:\b<ÒV1;>\11Ö»j´ç;>д:°@ã»j´ç;y>ì:Àu\14¼ Ëz»g´g;£Ø\v¼ Ëz»]\87P;k·û»\9b\f¶»9\9dÔ:D\9c\ 5¼\9b\f¶» U\v;\141¨»]:\b¼EHJ;Y^\97»]:\b¼\9fU\v;k\87P»P^\17¼Só¿:y´g»P^\17¼]\87P;k·û»\9b\f¶;O^\97;ò\89â»\9b\f¶;
+1¨;r·û»\99Ëz;g´g;£Ø\v¼\99Ëz;ÒV1;>\11Ö»j´ç»oº\80;Ò§À»j´ç»EHJ;Y^\97»]:\b¼ U\v;\141¨»]:\b¼ÒV1;>\11Ö»j´ç;oº\80;Ò§À»j´ç;O^\97;ò\89â»\9b\f¶;]\87P;k·û»\9b\f¶;]\87P;k·û»\9b\f¶»O^\97;ò\89â»\9b\f¶»oº\80;Ò§À»j´ç»ÒV1;>\11Ö»j´ç»\9fU\v;\101¨»]:\b<BHJ;V^\97»]:\b<oº\80;Ò§À»j´ç;ÒV1;>\11Ö»j´ç;g´g;£Ø\v¼ Ëz»
+1¨;r·û» Ëz»O^\97;ò\89â»\9b\f¶»]\87P;k·û»\9b\f¶»Ró¿:t´g»R^\17<\9dU\v;f\87P»R^\17<BHJ;V^\97»]:\b<\9fU\v;\101¨»]:\b<øùu;½u\14¼uµÿº\1c\8d²;C\9c\ 5¼uµÿº
+1¨;r·û» Ëz»g´g;£Ø\v¼ Ëz»\ 4¶C:\97>ìº\1e± <l\10\8e:L\9dÔº\1e± <\9dU\v;f\87P»R^\17<Ró¿:t´g»R^\17<¦Ëz;T^\17¼ì\86O°\9e\f¶;_:\b¼ì\86O°\1c\8d²;C\9c\ 5¼uµÿºøùu;½u\14¼uµÿºøùu;½u\14¼iµÿ:\1c\8d²;C\9c\ 5¼iµÿ:\9e\f¶;_:\b¼ì\86O°¦Ëz;T^\17¼ì\86O°Só¿:y´g»P^\17¼\9fU\v;k\87P»P^\17¼w\10\8e:\\9dÔº\1d± ¼\13¶C:§>ìº\1d± ¼g´g;£Ø\v¼\99Ëz;
+1¨;r·û»\99Ëz;\1c\8d²;C\9c\ 5¼iµÿ:øùu;½u\14¼iµÿ:\1c\8d²;C\9c\ 5¼uµÿº§@ã;ª@ã»uµÿº7\11Ö;>\11Ö» Ëz»
+1¨;r·û» Ëz»l\10\8e:L\9dÔº\1e± <8д:Tдº\1e± <ÏV1;ÛV1»R^\17<\9dU\v;f\87P»R^\17<\9e\f¶;_:\b¼ì\86O°l´ç;n´ç»ì\86O°§@ã;ª@ã»uµÿº\1c\8d²;C\9c\ 5¼uµÿº\1c\8d²;C\9c\ 5¼iµÿ:§@ã;ª@ã»iµÿ:l´ç;n´ç»ì\86O°\9e\f¶;_:\b¼ì\86O°\9fU\v;k\87P»P^\17¼ÒV1;ÞV1»P^\17¼Fд:aдº\1d± ¼w\10\8e:\\9dÔº\1d± ¼
+1¨;r·û»\99Ëz;7\11Ö;>\11Ö»\99Ëz;§@ã;ª@ã»iµÿ:\1c\8d²;C\9c\ 5¼iµÿ:EHJ;Y^\97»]:\b¼pº\80;wº\80»]:\b¼ÒV1;ÞV1»P^\17¼\9fU\v;k\87P»P^\17¼O^\97;ò\89â»\9b\f¶;ɧÀ;˧À»\9b\f¶;7\11Ö;>\11Ö»\99Ëz;
+1¨;r·û»\99Ëz;oº\80;Ò§À»j´ç»
+×£;\ f×£»j´ç»pº\80;wº\80»]:\b¼EHJ;Y^\97»]:\b¼oº\80;Ò§À»j´ç;
+×£;\ f×£»j´ç;ɧÀ;˧À»\9b\f¶;O^\97;ò\89â»\9b\f¶;O^\97;ò\89â»\9b\f¶»É§À;˧À»\9b\f¶»
+×£;\ f×£»j´ç»oº\80;Ò§À»j´ç»BHJ;V^\97»]:\b<nº\80;tº\80»]:\b<
+×£;\ f×£»j´ç;oº\80;Ò§À»j´ç;
+1¨;r·û» Ëz»7\11Ö;>\11Ö» Ëz»É§À;˧À»\9b\f¶»O^\97;ò\89â»\9b\f¶»\9dU\v;f\87P»R^\17<ÏV1;ÛV1»R^\17<nº\80;tº\80»]:\b<BHJ;V^\97»]:\b<ɧÀ;˧À»\9b\f¶;î\89â;Q^\97»\9b\f¶;j·û;\121¨»\99Ëz;7\11Ö;>\11Ö»\99Ëz;
+×£;\ f×£»j´ç»Ë§À;tº\80»j´ç»Q^\97;SHJ»]:\b¼pº\80;wº\80»]:\b¼
+×£;\ f×£»j´ç;˧À;tº\80»j´ç;î\89â;Q^\97»\9b\f¶;ɧÀ;˧À»\9b\f¶;ɧÀ;˧À»\9b\f¶»î\89â;Q^\97»\9b\f¶»Ë§À;tº\80»j´ç»
+×£;\ f×£»j´ç»nº\80;tº\80»]:\b<O^\97;MHJ»]:\b<˧À;tº\80»j´ç;
+×£;\ f×£»j´ç;7\11Ö;>\11Ö» Ëz»j·û;\121¨» Ëz»î\89â;Q^\97»\9b\f¶»É§À;˧À»\9b\f¶»ÏV1;ÛV1»R^\17<Y\87P;§U\v»R^\17<O^\97;MHJ»]:\b<nº\80;tº\80»]:\b<§@ã;ª@ã»uµÿº@\9c\ 5<\1c\8d²»uµÿºj·û;\121¨» Ëz»7\11Ö;>\11Ö» Ëz»8д:Tдº\1e± <0\9dÔ:\87\10\8eº\1e± <Y\87P;§U\v»R^\17<ÏV1;ÛV1»R^\17<l´ç;n´ç»ì\86O°]:\b<\9e\f¶»ì\86O°@\9c\ 5<\1c\8d²»uµÿº§@ã;ª@ã»uµÿº§@ã;ª@ã»iµÿ:@\9c\ 5<\1c\8d²»iµÿ:]:\b<\9e\f¶»ì\86O°l´ç;n´ç»ì\86O°ÒV1;ÞV1»P^\17¼]\87P;«U\v»P^\17¼@\9dÔ:\91\10\8eº\1d± ¼Fд:aдº\1d± ¼7\11Ö;>\11Ö»\99Ëz;j·û;\121¨»\99Ëz;@\9c\ 5<\1c\8d²»iµÿ:§@ã;ª@ã»iµÿ:pº\80;wº\80»]:\b¼Q^\97;SHJ»]:\b¼]\87P;«U\v»P^\17¼ÒV1;ÞV1»P^\17¼0\9dÔ:\87\10\8eº\1e± <x>ì:7¶Cº\1e± <e´g;eó¿ºR^\17<Y\87P;§U\v»R^\17<]:\b<\9e\f¶»ì\86O°P^\17<¥Ëz»ì\86O°ºu\14<÷ùu»uµÿº@\9c\ 5<\1c\8d²»uµÿº@\9c\ 5<\1c\8d²»iµÿ:ºu\14<÷ùu»iµÿ:P^\17<¥Ëz»ì\86O°]:\b<\9e\f¶»ì\86O°]\87P;«U\v»P^\17¼i´g;jó¿ºP^\17¼\8a>ì:F¶Cº\1d± ¼@\9dÔ:\91\10\8eº\1d± ¼j·û;\121¨»\99Ëz;\9fØ\v<x´g»\99Ëz;ºu\14<÷ùu»iµÿ:@\9c\ 5<\1c\8d²»iµÿ:Q^\97;SHJ»]:\b¼\v1¨;U\v»]:\b¼i´g;jó¿ºP^\17¼]\87P;«U\v»P^\17¼î\89â;Q^\97»\9b\f¶;e·û;^\87P»\9b\f¶;\9fØ\v<x´g»\99Ëz;j·û;\121¨»\99Ëz;˧À;tº\80»j´ç»8\11Ö;ÛV1»j´ç»\v1¨;U\v»]:\b¼Q^\97;SHJ»]:\b¼Ë§À;tº\80»j´ç;8\11Ö;ÛV1»j´ç;e·û;^\87P»\9b\f¶;î\89â;Q^\97»\9b\f¶;î\89â;Q^\97»\9b\f¶»e·û;^\87P»\9b\f¶»8\11Ö;ÛV1»j´ç»Ë§À;tº\80»j´ç»O^\97;MHJ»]:\b< 1¨;©U\v»]:\b<8\11Ö;ÛV1»j´ç;˧À;tº\80»j´ç;j·û;\121¨» Ëz»\9fØ\v<x´g» Ëz»e·û;^\87P»\9b\f¶»î\89â;Q^\97»\9b\f¶»Y\87P;§U\v»R^\17<e´g;eó¿ºR^\17< 1¨;©U\v»]:\b<O^\97;MHJ»]:\b<@\9c\ 5<\1c\8d²»uµÿººu\14<÷ùu»uµÿº\9fØ\v<x´g» Ëz»j·û;\121¨» Ëz»8\11Ö;ÛV1»j´ç;ª@ã;Mдºj´ç;?\9c\ 5<;\9dÔº\9b\f¶;e·û;^\87P»\9b\f¶;e·û;^\87P»\9b\f¶»?\9c\ 5<;\9dÔº\9b\f¶»ª@ã;Mдºj´ç»8\11Ö;ÛV1»j´ç» 1¨;©U\v»]:\b<\e\8d²;\84\10\8eº]:\b<ª@ã;Mдºj´ç;8\11Ö;ÛV1»j´ç;\9fØ\v<x´g» Ëz»½u\14<\99>ìº Ëz»?\9c\ 5<;\9dÔº\9b\f¶»e·û;^\87P»\9b\f¶»e´g;eó¿ºR^\17<òùu;-¶CºR^\17<\e\8d²;\84\10\8eº]:\b< 1¨;©U\v»]:\b<ºu\14<÷ùu»uµÿº©\9a\1d<¢Ëúºuµÿº½u\14<\99>ìº Ëz»\9fØ\v<x´g» Ëz»x>ì:7¶Cº\1e± <\99Ëú:ü\8bǹ\1e± <òùu;-¶CºR^\17<e´g;eó¿ºR^\17<P^\17<¥Ëz»ì\86O°\1d± <}µÿºì\86O°©\9a\1d<¢Ëúºuµÿººu\14<÷ùu»uµÿººu\14<÷ùu»iµÿ:©\9a\1d<¢Ëúºiµÿ:\1d± <}µÿºì\86O°P^\17<¥Ëz»ì\86O°i´g;jó¿ºP^\17¼õùu;4¶CºP^\17¼¬Ëú:
+\8cǹ\1d± ¼\8a>ì:F¶Cº\1d± ¼\9fØ\v<x´g»\99Ëz;½u\14<\99>ìº\99Ëz;©\9a\1d<¢Ëúºiµÿ:ºu\14<÷ùu»iµÿ:\v1¨;U\v»]:\b¼\1d\8d²;\87\10\8eº]:\b¼õùu;4¶CºP^\17¼i´g;jó¿ºP^\17¼e·û;^\87P»\9b\f¶;?\9c\ 5<;\9dÔº\9b\f¶;½u\14<\99>ìº\99Ëz;\9fØ\v<x´g»\99Ëz;8\11Ö;ÛV1»j´ç»ª@ã;Mдºj´ç»\1d\8d²;\87\10\8eº]:\b¼\v1¨;U\v»]:\b¼©\9a\1d<¢Ëúºiµÿ:\19± <)|\83°iµÿ:\b×#<ÍìÀ°ì\86O°\1d± <}µÿºì\86O°õùu;4¶CºP^\17¼\9dËz;\14¾A±P^\17¼~µÿ:õ8V±\1d± ¼¬Ëú:
+\8cǹ\1d± ¼½u\14<\99>ìº\99Ëz;P^\17<®W[±\99Ëz;\19± <)|\83°iµÿ:©\9a\1d<¢Ëúºiµÿ:\1d\8d²;\87\10\8eº]:\b¼\9b\f¶;\14¾A±]:\b¼\9dËz;\14¾A±P^\17¼õùu;4¶CºP^\17¼?\9c\ 5<;\9dÔº\9b\f¶;Y:\b<ÍìÀ°\9b\f¶;P^\17<®W[±\99Ëz;½u\14<\99>ìº\99Ëz;ª@ã;Mдºj´ç»i´ç;p]þ°j´ç»\9b\f¶;\14¾A±]:\b¼\1d\8d²;\87\10\8eº]:\b¼ª@ã;Mдºj´ç;i´ç;p]þ°j´ç;Y:\b<ÍìÀ°\9b\f¶;?\9c\ 5<;\9dÔº\9b\f¶;?\9c\ 5<;\9dÔº\9b\f¶»Y:\b<ÍìÀ°\9b\f¶»i´ç;p]þ°j´ç»ª@ã;Mдºj´ç»\e\8d²;\84\10\8eº]:\b<\98\f¶;ëa2±]:\b<i´ç;p]þ°j´ç;ª@ã;Mдºj´ç;½u\14<\99>ìº Ëz»P^\17<®W[± Ëz»Y:\b<ÍìÀ°\9b\f¶»?\9c\ 5<;\9dÔº\9b\f¶»òùu;-¶CºR^\17<\98Ëz;3C-±R^\17<\98\f¶;ëa2±]:\b<\e\8d²;\84\10\8eº]:\b<©\9a\1d<¢Ëúºuµÿº\19± <)|\83°uµÿºP^\17<®W[± Ëz»½u\14<\99>ìº Ëz»\99Ëú:ü\8bǹ\1e± <lµÿ:RÈX±\1e± <\98Ëz;3C-±R^\17<òùu;-¶CºR^\17<\1d± <}µÿºì\86O°\b×#<ÍìÀ°ì\86O°\19± <)|\83°uµÿº©\9a\1d<¢ËúºuµÿºY:\b<ÍìÀ°\9b\f¶»>\9c\ 5<"\9dÔ:\9b\f¶»©@ã;+д:j´ç»i´ç;p]þ°j´ç»\98\f¶;ëa2±]:\b<\19\8d²;V\10\8e:]:\b<©@ã;+д:j´ç;i´ç;p]þ°j´ç;P^\17<®W[± Ëz»¼u\14<b>ì: Ëz»>\9c\ 5<"\9dÔ:\9b\f¶»Y:\b<ÍìÀ°\9b\f¶»\98Ëz;3C-±R^\17<ðùu;ÔµC:R^\17<\19\8d²;V\10\8e:]:\b<\98\f¶;ëa2±]:\b<\19± <)|\83°uµÿº§\9a\1d<\90Ëú:uµÿº¼u\14<b>ì: Ëz»P^\17<®W[± Ëz»lµÿ:RÈX±\1e± <\99Ëú:"\8bÇ9\1e± <ðùu;ÔµC:R^\17<\98Ëz;3C-±R^\17<\b×#<ÍìÀ°ì\86O°\e± <eµÿ:ì\86O°§\9a\1d<\90Ëú:uµÿº\19± <)|\83°uµÿº\19± <)|\83°iµÿ:§\9a\1d<\90Ëú:iµÿ:\e± <eµÿ:ì\86O°\b×#<ÍìÀ°ì\86O°\9dËz;\14¾A±P^\17¼õùu;ÓµC:P^\17¼«Ëú:2\8bÇ9\1d± ¼~µÿ:õ8V±\1d± ¼P^\17<®W[±\99Ëz;¼u\14<b>ì:\99Ëz;§\9a\1d<\90Ëú:iµÿ:\19± <)|\83°iµÿ:\9b\f¶;\14¾A±]:\b¼\1c\8d²;V\10\8e:]:\b¼õùu;ÓµC:P^\17¼\9dËz;\14¾A±P^\17¼Y:\b<ÍìÀ°\9b\f¶;>\9c\ 5<"\9dÔ:\9b\f¶;¼u\14<b>ì:\99Ëz;P^\17<®W[±\99Ëz;i´ç;p]þ°j´ç»©@ã;+д:j´ç»\1c\8d²;V\10\8e:]:\b¼\9b\f¶;\14¾A±]:\b¼i´ç;p]þ°j´ç;©@ã;+д:j´ç;>\9c\ 5<"\9dÔ:\9b\f¶;Y:\b<ÍìÀ°\9b\f¶;§\9a\1d<\90Ëú:iµÿ:·u\14<ëùu;iµÿ:M^\17<\97Ëz;ì\86O°\e± <eµÿ:ì\86O°õùu;ÓµC:P^\17¼g´g;9ó¿:P^\17¼\89>ì:صC:\1d± ¼«Ëú:2\8bÇ9\1d± ¼¼u\14<b>ì:\99Ëz;\9fØ\v<\´g;\99Ëz;·u\14<ëùu;iµÿ:§\9a\1d<\90Ëú:iµÿ:\1c\8d²;V\10\8e:]:\b¼ 1¨;\93U\v;]:\b¼g´g;9ó¿:P^\17¼õùu;ÓµC:P^\17¼>\9c\ 5<"\9dÔ:\9b\f¶;a·û;P\87P;\9b\f¶;\9fØ\v<\´g;\99Ëz;¼u\14<b>ì:\99Ëz;©@ã;+д:j´ç»5\11Ö;ÉV1;j´ç» 1¨;\93U\v;]:\b¼\1c\8d²;V\10\8e:]:\b¼©@ã;+д:j´ç;5\11Ö;ÉV1;j´ç;a·û;P\87P;\9b\f¶;>\9c\ 5<"\9dÔ:\9b\f¶;>\9c\ 5<"\9dÔ:\9b\f¶»a·û;P\87P;\9b\f¶»5\11Ö;ÉV1;j´ç»©@ã;+д:j´ç»\19\8d²;V\10\8e:]:\b<\ 61¨;\92U\v;]:\b<5\11Ö;ÉV1;j´ç;©@ã;+д:j´ç;¼u\14<b>ì: Ëz»\9fØ\v<\´g; Ëz»a·û;P\87P;\9b\f¶»>\9c\ 5<"\9dÔ:\9b\f¶»ðùu;ÔµC:R^\17<b´g;8ó¿:R^\17<\ 61¨;\92U\v;]:\b<\19\8d²;V\10\8e:]:\b<§\9a\1d<\90Ëú:uµÿº·u\14<ëùu;uµÿº\9fØ\v<\´g; Ëz»¼u\14<b>ì: Ëz»\99Ëú:"\8bÇ9\1e± <x>ì:ʵC:\1e± <b´g;8ó¿:R^\17<ðùu;ÔµC:R^\17<\e± <eµÿ:ì\86O°M^\17<\97Ëz;ì\86O°·u\14<ëùu;uµÿº§\9a\1d<\90Ëú:uµÿº\ 61¨;\92U\v;]:\b<K^\97;4HJ;]:\b<ɧÀ;jº\80;j´ç;5\11Ö;ÉV1;j´ç;\9fØ\v<\´g; Ëz»i·û;\ 41¨; Ëz»ç\89â;I^\97;\9b\f¶»a·û;P\87P;\9b\f¶»b´g;8ó¿:R^\17<T\87P;\90U\v;R^\17<K^\97;4HJ;]:\b<\ 61¨;\92U\v;]:\b<·u\14<ëùu;uµÿº=\9c\ 5<\14\8d²;uµÿºi·û;\ 41¨; Ëz»\9fØ\v<\´g; Ëz»x>ì:ʵC:\1e± </\9dÔ:O\10\8e:\1e± <T\87P;\90U\v;R^\17<b´g;8ó¿:R^\17<M^\17<\97Ëz;ì\86O°Y:\b<\95\f¶;ì\86O°=\9c\ 5<\14\8d²;uµÿº·u\14<ëùu;uµÿº·u\14<ëùu;iµÿ:=\9c\ 5<\14\8d²;iµÿ:Y:\b<\95\f¶;ì\86O°M^\17<\97Ëz;ì\86O°g´g;9ó¿:P^\17¼Y\87P;\92U\v;P^\17¼=\9dÔ:Y\10\8e:\1d± ¼\89>ì:صC:\1d± ¼\9fØ\v<\´g;\99Ëz;i·û;\ 41¨;\99Ëz;=\9c\ 5<\14\8d²;iµÿ:·u\14<ëùu;iµÿ: 1¨;\93U\v;]:\b¼N^\97;7HJ;]:\b¼Y\87P;\92U\v;P^\17¼g´g;9ó¿:P^\17¼a·û;P\87P;\9b\f¶;ç\89â;I^\97;\9b\f¶;i·û;\ 41¨;\99Ëz;\9fØ\v<\´g;\99Ëz;5\11Ö;ÉV1;j´ç»É§À;jº\80;j´ç»N^\97;7HJ;]:\b¼ 1¨;\93U\v;]:\b¼5\11Ö;ÉV1;j´ç;ɧÀ;jº\80;j´ç;ç\89â;I^\97;\9b\f¶;a·û;P\87P;\9b\f¶;a·û;P\87P;\9b\f¶»ç\89â;I^\97;\9b\f¶»É§À;jº\80;j´ç»5\11Ö;ÉV1;j´ç»Y\87P;\92U\v;P^\17¼ÍV1;ÂV1;P^\17¼Bд:)д:\1d± ¼=\9dÔ:Y\10\8e:\1d± ¼i·û;\ 41¨;\99Ëz;7\11Ö;0\11Ö;\99Ëz;\9e@ã;\9e@ã;iµÿ:=\9c\ 5<\14\8d²;iµÿ:N^\97;7HJ;]:\b¼lº\80;hº\80;]:\b¼ÍV1;ÂV1;P^\17¼Y\87P;\92U\v;P^\17¼ç\89â;I^\97;\9b\f¶;Á§À;§À;\9b\f¶;7\11Ö;0\11Ö;\99Ëz;i·û;\ 41¨;\99Ëz;ɧÀ;jº\80;j´ç»\a×£;\ 4×£;j´ç»lº\80;hº\80;]:\b¼N^\97;7HJ;]:\b¼É§À;jº\80;j´ç;\a×£;\ 4×£;j´ç;Á§À;§À;\9b\f¶;ç\89â;I^\97;\9b\f¶;ç\89â;I^\97;\9b\f¶»Á§À;§À;\9b\f¶»\a×£;\ 4×£;j´ç»É§À;jº\80;j´ç»K^\97;4HJ;]:\b<jº\80;fº\80;]:\b<\a×£;\ 4×£;j´ç;ɧÀ;jº\80;j´ç;i·û;\ 41¨; Ëz»7\11Ö;0\11Ö; Ëz»Á§À;§À;\9b\f¶»ç\89â;I^\97;\9b\f¶»T\87P;\90U\v;R^\17<ÊV1;ÀV1;R^\17<jº\80;fº\80;]:\b<K^\97;4HJ;]:\b<=\9c\ 5<\14\8d²;uµÿº\9e@ã;\9e@ã;uµÿº7\11Ö;0\11Ö; Ëz»i·û;\ 41¨; Ëz»/\9dÔ:O\10\8e:\1e± <7д:\1cд:\1e± <ÊV1;ÀV1;R^\17<T\87P;\90U\v;R^\17<Y:\b<\95\f¶;ì\86O°a´ç;b´ç;ì\86O°\9e@ã;\9e@ã;uµÿº=\9c\ 5<\14\8d²;uµÿº=\9c\ 5<\14\8d²;iµÿ:\9e@ã;\9e@ã;iµÿ:a´ç;b´ç;ì\86O°Y:\b<\95\f¶;ì\86O°7\11Ö;0\11Ö; Ëz» 1¨;b·û; Ëz»G^\97;æ\89â;\9b\f¶»Á§À;§À;\9b\f¶»ÊV1;ÀV1;R^\17<\99U\v;J\87P;R^\17<;HJ;G^\97;]:\b<jº\80;fº\80;]:\b<\9e@ã;\9e@ã;uµÿº\12\8d²;;\9c\ 5<uµÿº 1¨;b·û; Ëz»7\11Ö;0\11Ö; Ëz»7д:\1cд:\1e± <j\10\8e:\14\9dÔ:\1e± <\99U\v;J\87P;R^\17<ÊV1;ÀV1;R^\17<a´ç;b´ç;ì\86O°\93\f¶;W:\b<ì\86O°\12\8d²;;\9c\ 5<uµÿº\9e@ã;\9e@ã;uµÿº\9e@ã;\9e@ã;iµÿ:\12\8d²;;\9c\ 5<iµÿ:\93\f¶;W:\b<ì\86O°a´ç;b´ç;ì\86O°ÍV1;ÂV1;P^\17¼\9bU\v;L\87P;P^\17¼s\10\8e:"\9dÔ:\1d± ¼Bд:)д:\1d± ¼7\11Ö;0\11Ö;\99Ëz; 1¨;b·û;\99Ëz;\12\8d²;;\9c\ 5<iµÿ:\9e@ã;\9e@ã;iµÿ:lº\80;hº\80;]:\b¼=HJ;I^\97;]:\b¼\9bU\v;L\87P;P^\17¼ÍV1;ÂV1;P^\17¼Á§À;§À;\9b\f¶;G^\97;æ\89â;\9b\f¶; 1¨;b·û;\99Ëz;7\11Ö;0\11Ö;\99Ëz;\a×£;\ 4×£;j´ç»kº\80;ŧÀ;j´ç»=HJ;I^\97;]:\b¼lº\80;hº\80;]:\b¼\a×£;\ 4×£;j´ç;kº\80;ŧÀ;j´ç;G^\97;æ\89â;\9b\f¶;Á§À;§À;\9b\f¶;Á§À;§À;\9b\f¶»G^\97;æ\89â;\9b\f¶»kº\80;ŧÀ;j´ç»\a×£;\ 4×£;j´ç»jº\80;fº\80;]:\b<;HJ;G^\97;]:\b<kº\80;ŧÀ;j´ç;\a×£;\ 4×£;j´ç; 1¨;b·û;\99Ëz;f´g;\9bØ\v<\99Ëz;ãùu;´u\14<iµÿ:\12\8d²;;\9c\ 5<iµÿ:=HJ;I^\97;]:\b¼\99U\v;\ 21¨;]:\b¼Kó¿:Y´g;P^\17¼\9bU\v;L\87P;P^\17¼G^\97;æ\89â;\9b\f¶;J\87P;]·û;\9b\f¶;f´g;\9bØ\v<\99Ëz; 1¨;b·û;\99Ëz;kº\80;ŧÀ;j´ç»ÊV1;2\11Ö;j´ç»\99U\v;\ 21¨;]:\b¼=HJ;I^\97;]:\b¼kº\80;ŧÀ;j´ç;ÊV1;2\11Ö;j´ç;J\87P;]·û;\9b\f¶;G^\97;æ\89â;\9b\f¶;G^\97;æ\89â;\9b\f¶»J\87P;]·û;\9b\f¶»ÊV1;2\11Ö;j´ç»kº\80;ŧÀ;j´ç»;HJ;G^\97;]:\b<\97U\v;\01¨;]:\b<ÊV1;2\11Ö;j´ç;kº\80;ŧÀ;j´ç; 1¨;b·û; Ëz»f´g;\9bØ\v< Ëz»J\87P;]·û;\9b\f¶»G^\97;æ\89â;\9b\f¶»\99U\v;J\87P;R^\17<Ió¿:W´g;R^\17<\97U\v;\01¨;]:\b<;HJ;G^\97;]:\b<\12\8d²;;\9c\ 5<uµÿºãùu;´u\14<uµÿºf´g;\9bØ\v< Ëz» 1¨;b·û; Ëz»j\10\8e:\14\9dÔ:\1e± <þµC:]>ì:\1e± <Ió¿:W´g;R^\17<\99U\v;J\87P;R^\17<\93\f¶;W:\b<ì\86O°\8fËz;J^\17<ì\86O°ãùu;´u\14<uµÿº\12\8d²;;\9c\ 5<uµÿº\12\8d²;;\9c\ 5<iµÿ:ãùu;´u\14<iµÿ:\8fËz;J^\17<ì\86O°\93\f¶;W:\b<ì\86O°\9bU\v;L\87P;P^\17¼Kó¿:Y´g;P^\17¼
+¶C:n>ì:\1d± ¼s\10\8e:"\9dÔ:\1d± ¼Ió¿:W´g;R^\17<óµC:ãùu;R^\17<`\10\8e:\10\8d²;]:\b<\97U\v;\01¨;]:\b<ãùu;´u\14<uµÿº\80Ëú:¤\9a\1d<uµÿºw>ì:¸u\14< Ëz»f´g;\9bØ\v< Ëz»þµC:]>ì:\1e± <\8a\8bÇ9~Ëú:\1e± <óµC:ãùu;R^\17<Ió¿:W´g;R^\17<\8fËz;J^\17<ì\86O°Uµÿ:\16± <ì\86O°\80Ëú:¤\9a\1d<uµÿºãùu;´u\14<uµÿºãùu;´u\14<iµÿ:\80Ëú:¤\9a\1d<iµÿ:Uµÿ:\16± <ì\86O°\8fËz;J^\17<ì\86O°Kó¿:Y´g;P^\17¼õµC:æùu;P^\17¼\92\8bÇ9\8fËú:\1d± ¼
+¶C:n>ì:\1d± ¼f´g;\9bØ\v<\99Ëz;w>ì:¸u\14<\99Ëz;\80Ëú:¤\9a\1d<iµÿ:ãùu;´u\14<iµÿ:\99U\v;\ 21¨;]:\b¼c\10\8e:\13\8d²;]:\b¼õµC:æùu;P^\17¼Kó¿:Y´g;P^\17¼J\87P;]·û;\9b\f¶;\15\9dÔ:;\9c\ 5<\9b\f¶;w>ì:¸u\14<\99Ëz;f´g;\9bØ\v<\99Ëz;ÊV1;2\11Ö;j´ç».д:¢@ã;j´ç»c\10\8e:\13\8d²;]:\b¼\99U\v;\ 21¨;]:\b¼ÊV1;2\11Ö;j´ç;.д:¢@ã;j´ç;\15\9dÔ:;\9c\ 5<\9b\f¶;J\87P;]·û;\9b\f¶;J\87P;]·û;\9b\f¶»\15\9dÔ:;\9c\ 5<\9b\f¶».д:¢@ã;j´ç»ÊV1;2\11Ö;j´ç»\97U\v;\01¨;]:\b<`\10\8e:\10\8d²;]:\b<.д:¢@ã;j´ç;ÊV1;2\11Ö;j´ç;f´g;\9bØ\v< Ëz»w>ì:¸u\14< Ëz»\15\9dÔ:;\9c\ 5<\9b\f¶»J\87P;]·û;\9b\f¶»\15\9dÔ:;\9c\ 5<\9b\f¶;@\v;±T:\b<\9b\f¶;[¼.°K^\17<\99Ëz;w>ì:¸u\14<\99Ëz;.д:¢@ã;j´ç»u?Ò°a´ç;j´ç»ÑÎ\94°\90\f¶;]:\b¼c\10\8e:\13\8d²;]:\b¼.д:¢@ã;j´ç;u?Ò°a´ç;j´ç;@\v;±T:\b<\9b\f¶;\15\9dÔ:;\9c\ 5<\9b\f¶;\15\9dÔ:;\9c\ 5<\9b\f¶»@\v;±T:\b<\9b\f¶»u?Ò°a´ç;j´ç».д:¢@ã;j´ç»`\10\8e:\10\8d²;]:\b<³I©°\8e\f¶;]:\b<u?Ò°a´ç;j´ç;.д:¢@ã;j´ç;w>ì:¸u\14< Ëz»[¼.°K^\17< Ëz»@\v;±T:\b<\9b\f¶»\15\9dÔ:;\9c\ 5<\9b\f¶»óµC:ãùu;R^\17<\1d²W°\8aËz;R^\17<³I©°\8e\f¶;]:\b<`\10\8e:\10\8d²;]:\b<\80Ëú:¤\9a\1d<uµÿºÏÍ0±\13± <uµÿº[¼.°K^\17< Ëz»w>ì:¸u\14< Ëz»\8a\8bÇ9~Ëú:\1e± <\8av&¯Pµÿ:\1e± <\1d²W°\8aËz;R^\17<óµC:ãùu;R^\17<Uµÿ:\16± <ì\86O°@\v;±\ 1×#<ì\86O°ÏÍ0±\13± <uµÿº\80Ëú:¤\9a\1d<uµÿº\80Ëú:¤\9a\1d<iµÿ:ÏÍ0±\13± <iµÿ:@\v;±\ 1×#<ì\86O°Uµÿ:\16± <ì\86O°õµC:æùu;P^\17¼\1d²W°\8cËz;P^\17¼\8c\1cίaµÿ:\1d± ¼\92\8bÇ9\8fËú:\1d± ¼w>ì:¸u\14<\99Ëz;[¼.°K^\17<\99Ëz;ÏÍ0±\13± <iµÿ:\80Ëú:¤\9a\1d<iµÿ:c\10\8e:\13\8d²;]:\b¼ÑÎ\94°\90\f¶;]:\b¼\1d²W°\8cËz;P^\17¼õµC:æùu;P^\17¼\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0(¤Cº\0\0\0\80`µÄ<\1eÖ\1d»\0\0\0\80ÍfÖ<PþGº\0\0\0\80\0\0\0\0`´6¹\0\0\0\80\0\0\0\0Ðÿ\92;\0\0\0\80\0\0\0\0:û\83;\0\0\0\80\0\0\0\0ë\11\19<\0\0\0\80\0\0\0\0\19d<<\0\0\0\80\0\0\0\0Pî\9d¹\0\0\0\80"í¨<\92\18\85»\0\0\0\80`µÄ<\1eÖ\1d»\0\0\0\80\0\0\0\0(¤Cº\0\0\0\80\0\0\0\0,õ×:\0\0\0\80\0\0\0\0\b\80»:\0\0\0\80\0\0\0\0:û\83;\0\0\0\80\0\0\0\0Ðÿ\92;\0\0\0\80\0\0\0\0\f³\r;\0\0\0\80°\80^<=Ú¢»\0\0\0\80"í¨<\92\18\85»\0\0\0\80\0\0\0\0Pî\9d¹\0\0\0\80\0\0\0\0\80õí8\0\0\0\80\0\0\0\0\0\87\9b8\0\0\0\80\0\0\0\0\b\80»:\0\0\0\80\0\0\0\0,õ×:\0\0\0\80\0\0\0\0y¨\ 3<\0\0\0\80\966\91;ú-»\0\0\0\80°\80^<=Ú¢»\0\0\0\80\0\0\0\0\f³\r;\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\87\9b8\0\0\0\80\0\0\0\0\80õí8\0\0\0\80\0\0\0\0Rd\9b<\0\0\0\80\0\0\0\0@ E;\0\0\0\80\966\91;ú-»\0\0\0\80\0\0\0\0y¨\ 3<\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0nW¹<\0\0\0\80\0\0\0\0 ^i<\0\0\0\80\0\0\0\0@ E;\0\0\0\80\0\0\0\0Rd\9b<\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80¾Ný<\0X\ eµ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\9a[þ<À 8¸\0\0\0\80{äÿ<0\80ÿ¸\0\0\0\80½Ný¼\0Ð\rµ\0\0\0\80\99[þ¼à\1e8¸\0\0\0\80<P\0=\98ÂF¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80B\16\0=¤Vb¹\0\0\0\80kúþ<|ÂF¹\0\0\0\80ÇÒý<\10\80ÿ¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ãGý<¢ 8¸\0\0\0\80\8aJý<\0L\ eµ\0\0\0\80<Ký<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80=Ký<\0\0\0\0\0\0\0\80BKý<\0\0\0\0\0\0\0\80CKý<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80=Ký<\0\0\0\0\0\0\0\80CKý<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80CKý¼\0\0\0\0\0\0\0\80=Ký¼\0\0\0\0\0\0\0\80BKý¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80AKý¼\0\0\0\0\0\0\0\80=Ký¼\0\0\0\0\0\0\0\80<Ký¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\8aJý¼\0h\ eµ\0\0\0\80âGý¼Ë 8¸\0\0\0\80ÆÒý¼ø\7fÿ¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80kúþ¼TÂF¹\0\0\0\80A\16\0½\Vb¹\0\0\0\80;P\0½@ÂF¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80zäÿ¼P\7fÿ¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Ø\15£<\0\0\0\80\0\0\0\0jº\84<\0\0\0\80\0\0\0\0 ^i<\0\0\0\80\0\0\0\0nW¹<\0\0\0\80\0\0\0\0`´6¹\0\0\0\80ÍfÖ<PþGº\0\0\0\80¾Ný<\0X\ eµ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\19d<<\0\0\0\80\0\0\0\0ë\11\19<\0\0\0\80\0\0\0\0jº\84<\0\0\0\80\0\0\0\0Ø\15£<\0\0\0\80\0\0\0\0jº\84<\0\0\0\80\0\0\0\0Èy@;\0\0\0\80\0\0\0\0\92þ_»\0\0\0\80\0\0\0\0 ^i<\0\0\0\80ÍfÖ<PþGº\0\0\0\808\86ë<>zκ\0\0\0\80\9a[þ<À 8¸\0\0\0\80¾Ný<\0X\ eµ\0\0\0\80\0\0\0\0ë\11\19<\0\0\0\80\0\0\0\0Ê\8f\9b;\0\0\0\80\0\0\0\0Èy@;\0\0\0\80\0\0\0\0jº\84<\0\0\0\80`µÄ<\1eÖ\1d»\0\0\0\80çdä<×\93\94»\0\0\0\808\86ë<>zκ\0\0\0\80ÍfÖ<PþGº\0\0\0\80\0\0\0\0:û\83;\0\0\0\80\0\0\0\0`\1e:;\0\0\0\80\0\0\0\0Ê\8f\9b;\0\0\0\80\0\0\0\0ë\11\19<\0\0\0\80"í¨<\92\18\85»\0\0\0\80\ eþ¯<&\9dü»\0\0\0\80çdä<×\93\94»\0\0\0\80`µÄ<\1eÖ\1d»\0\0\0\80\0\0\0\0\b\80»:\0\0\0\80\0\0\0\0Àg:\0\0\0\80\0\0\0\0`\1e:;\0\0\0\80\0\0\0\0:û\83;\0\0\0\80°\80^<=Ú¢»\0\0\0\80>\aO<Lß!¼\0\0\0\80\ eþ¯<&\9dü»\0\0\0\80"í¨<\92\18\85»\0\0\0\80\0\0\0\0\0\87\9b8\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Àg:\0\0\0\80\0\0\0\0\b\80»:\0\0\0\80\966\91;ú-»\0\0\0\806¶;\ 501¼\90V¸9>\aO<Lß!¼\0\0\0\80°\80^<=Ú¢»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\87\9b8\0\0\0\80\0\0\0\0@ E;\0\0\0\80\b¾\97:Ø2\v¼\0\0\0\806¶;\ 501¼\90V¸9\966\91;ú-»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0 ^i<\0\0\0\80\0\0\0\0\92þ_»\0\0\0\80\b¾\97:Ø2\v¼\0\0\0\80\0\0\0\0@ E;\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\10\8b\959\0\0\0\80\0\0\0\0Àg:\0\0\0\806¶;\ 501¼\90V¸9a]¸;\1c\19¶¼\1eH`;\e\94\99;fΤ¼xÔ:;>\aO<Lß!¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\b¾\97:Ø2\v¼\0\0\0\80\1fan;\15n\94¼Ûþ\10;a]¸;\1c\19¶¼\1eH`;6¶;\ 501¼\90V¸9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\92þ_»\0\0\0\80\0\0\0\0\10)$¼\0\0\0\80\1fan;\15n\94¼Ûþ\10;\b¾\97:Ø2\v¼\0\0\0\80\0\0\0\0Èy@;\0\0\0\80\0\0\0\0D"¤»\0\0\0\80\0\0\0\0\10)$¼\0\0\0\80\0\0\0\0\92þ_»\0\0\0\808\86ë<>zκ\0\0\0\80dÈð<\1f$\1c»\0\0\0\80{äÿ<0\80ÿ¸\0\0\0\80\9a[þ<À 8¸\0\0\0\80\0\0\0\0Ê\8f\9b;\0\0\0\80\0\0\0\0à2û9\0\0\0\80\0\0\0\0D"¤»\0\0\0\80\0\0\0\0Èy@;\0\0\0\80çdä<×\93\94»\0\0\0\80\ 4\9e´<ÇÐØ»\0\0\0\80dÈð<\1f$\1c»\0\0\0\808\86ë<>zκ\0\0\0\80\0\0\0\0`\1e:;\0\0\0\80\0\0\0\0H$·:\0\0\0\80\0\0\0\0à2û9\0\0\0\80\0\0\0\0Ê\8f\9b;\0\0\0\80\ eþ¯<&\9dü»\0\0\0\80þ\90=;\80tp¼\90wñ:\ 4\9e´<ÇÐØ»\0\0\0\80çdä<×\93\94»\0\0\0\80\0\0\0\0Àg:\0\0\0\80\0\0\0\0\10\8b\959\0\0\0\80\0\0\0\0H$·:\0\0\0\80\0\0\0\0`\1e:;\0\0\0\80>\aO<Lß!¼\0\0\0\80\e\94\99;fΤ¼xÔ:;þ\90=;\80tp¼\90wñ:\ eþ¯<&\9dü»\0\0\0\80\0\0\0\0à2û9\0\0\0\80\0\0\0\0ó4.»\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80\0\0\0\0D"¤»\0\0\0\80\ 4\9e´<ÇÐØ»\0\0\0\80\17oF<ôE\ 5¼\0\0\0\80pÛâ<}¦B»\0\0\0\80dÈð<\1f$\1c»\0\0\0\80\0\0\0\0H$·:\0\0\0\80\0\0\0\0Àm\119\0\0\0\80\0\0\0\0ó4.»\0\0\0\80\0\0\0\0à2û9\0\0\0\80þ\90=;\80tp¼\90wñ:¨\88/;³\8a\8b¼ì\89Õ:\17oF<ôE\ 5¼\0\0\0\80\ 4\9e´<ÇÐØ»\0\0\0\80\0\0\0\0\10\8b\959\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Àm\119\0\0\0\80\0\0\0\0H$·:\0\0\0\80\e\94\99;fΤ¼xÔ:;¼\ 5þ:\16
+¼°\82\9a:¨\88/;³\8a\8b¼ì\89Õ:þ\90=;\80tp¼\90wñ:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\10\8b\959\0\0\0\80a]¸;\1c\19¶¼\1eH`;à` :èüµ¼$\1aC:¼\ 5þ:\16
+¼°\82\9a:\e\94\99;fΤ¼xÔ:;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\1fan;\15n\94¼Ûþ\10;Ê\93,;\9e\11±¼0ñÑ:à` :èüµ¼$\1aC:a]¸;\1c\19¶¼\1eH`;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\10)$¼\0\0\0\80X×¾:\98\88z¼\v)h:Ê\93,;\9e\11±¼0ñÑ:\1fan;\15n\94¼Ûþ\10;\0\0\0\0D"¤»\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80X×¾:\98\88z¼\v)h:\0\0\0\0\10)$¼\0\0\0\80dÈð<\1f$\1c»\0\0\0\80pÛâ<}¦B»\0\0\0\80<P\0=\98ÂF¹\0\0\0\80{äÿ<0\80ÿ¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Ê\93,;\9e\11±¼0ñÑ:\0:ø7\80¿¨¼Àü\967\0\0\0\0ù?»¼\0\0\0\80à` :èüµ¼$\1aC:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80X×¾:\98\88z¼\v)h:H\9cQ:\8f\1f\83¼Jþþ9\0:ø7\80¿¨¼Àü\967Ê\93,;\9e\11±¼0ñÑ:\0\0\0\0h\19ý»\0\0\0\80\0\0\0\0Åa\ e¼\0\0\0\80H\9cQ:\8f\1f\83¼Jþþ9X×¾:\98\88z¼\v)h:pÛâ<}¦B»\0\0\0\80\1f\8aÌ<ý´P»\0\0\0\80B\16\0=¤Vb¹\0\0\0\80<P\0=\98ÂF¹\0\0\0\80\0\0\0\0ó4.»\0\0\0\80\0\0\0\0 µP»\0\0\0\80\0\0\0\0Åa\ e¼\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80\17oF<ôE\ 5¼\0\0\0\80Ð\12o;üE0¼\\1c\97:\1f\8aÌ<ý´P»\0\0\0\80pÛâ<}¦B»\0\0\0\80\0\0\0\0Àm\119\0\0\0\80\0\0\0\0\80Vb¹\0\0\0\80\0\0\0\0 µP»\0\0\0\80\0\0\0\0ó4.»\0\0\0\80¨\88/;³\8a\8b¼ì\89Õ:ÜÒË:\9dà\89¼ ôw:Ð\12o;üE0¼\\1c\97:\17oF<ôE\ 5¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\80Vb¹\0\0\0\80\0\0\0\0Àm\119\0\0\0\80¼\ 5þ:\16
+¼°\82\9a:\0X!6G\81¨¼\0@Ä5ÜÒË:\9dà\89¼ ôw:¨\88/;³\8a\8b¼ì\89Õ:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80à` :èüµ¼$\1aC:\0\0\0\0ù?»¼\0\0\0\80\0X!6G\81¨¼\0@Ä5¼\ 5þ:\16
+¼°\82\9a:Ð\12o;üE0¼\\1c\97:\b8;D\89(¼¼9\9d:3À¹<~¦B»\0\0\0\80\1f\8aÌ<ý´P»\0\0\0\80\0\0\0\0\80Vb¹\0\0\0\80\0\0\0\0\0Þò¸\0\0\0\80\0\0\0\0M¯/»\0\0\0\80\0\0\0\0 µP»\0\0\0\80ÜÒË:\9dà\89¼ ôw:\80\13k:¢9w¼\88ü\ e:\b8;D\89(¼¼9\9d:Ð\12o;üE0¼\\1c\97:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0Þò¸\0\0\0\80\0\0\0\0\80Vb¹\0\0\0\80\0X!6G\81¨¼\0@Ä5\0\0\0\0]¶\9b¼\0\0\0\80\80\13k:¢9w¼\88ü\ e:ÜÒË:\9dà\89¼ ôw:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0ù?»¼\0\0\0\80\0\0\0\0e\f«¼\0\0\0\80\0\0\0\0]¶\9b¼\0\0\0\80\0X!6G\81¨¼\0@Ä5\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0:ø7\80¿¨¼Àü\967\0\0\0\0\8b\86\99¼\0\0\0\80\0\0\0\0e\f«¼\0\0\0\80\0\0\0\0ù?»¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80H\9cQ:\8f\1f\83¼Jþþ9Àâ\ 29\10»b¼F9\9f8\0\0\0\0\8b\86\99¼\0\0\0\80\0:ø7\80¿¨¼Àü\967\0\0\0\0Åa\ e¼\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80Àâ\ 29\10»b¼F9\9f8H\9cQ:\8f\1f\83¼Jþþ9\1f\8aÌ<ý´P»\0\0\0\803À¹<~¦B»\0\0\0\80kúþ<|ÂF¹\0\0\0\80B\16\0=¤Vb¹\0\0\0\80\0\0\0\0 µP»\0\0\0\80\0\0\0\0M¯/»\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80\0\0\0\0Åa\ e¼\0\0\0\80\0\0\0\0\8b\86\99¼\0\0\0\80\0°-6½Ýg¼\0@Ó5\0\0\0\0¨Ë\83¼\0\0\0\80\0\0\0\0e\f«¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Àâ\ 29\10»b¼F9\9f8\0\0\0\0\v)$¼\0\0\0\80\0°-6½Ýg¼\0@Ó5\0\0\0\0\8b\86\99¼\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80\0\0\0\0Ô\11¬»\0\0\0\80\0\0\0\0\v)$¼\0\0\0\80Àâ\ 29\10»b¼F9\9f83À¹<~¦B»\0\0\0\80\7f´¯<\1e$\1c»\0\0\0\80ÇÒý<\10\80ÿ¸\0\0\0\80kúþ<|ÂF¹\0\0\0\80\0\0\0\0M¯/»\0\0\0\80\0\0\0\0»@¿º\0\0\0\80\0\0\0\0Ô\11¬»\0\0\0\80\0\0\0\0h\19ý»\0\0\0\80\b8;D\89(¼¼9\9d:¯\10±;õì ¼0\9c\83:\7f´¯<\1e$\1c»\0\0\0\803À¹<~¦B»\0\0\0\80\0\0\0\0\0Þò¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0»@¿º\0\0\0\80\0\0\0\0M¯/»\0\0\0\80\80\13k:¢9w¼\88ü\ e:X\9e<:÷)G¼àtå9¯\10±;õì ¼0\9c\83:\b8;D\89(¼¼9\9d:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0Þò¸\0\0\0\80\0\0\0\0]¶\9b¼\0\0\0\80\0Æ\848^ðv¼\80\85!8X\9e<:÷)G¼àtå9\80\13k:¢9w¼\88ü\ e:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0e\f«¼\0\0\0\80\0\0\0\0¨Ë\83¼\0\0\0\80\0Æ\848^ðv¼\80\85!8\0\0\0\0]¶\9b¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0J\f\93¹\0\0\0\80\0\0\0\0»@¿º\0\0\0\80X\9e<:÷)G¼àtå90²Ô9\9d\8f\ 5¼ _\819²ÿ\9c;ý\a¼»\18é/:¯\10±;õì ¼0\9c\83:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0Æ\848^ðv¼\80\85!8\0C´9%\ 5(¼@J[90²Ô9\9d\8f\ 5¼ _\819X\9e<:÷)G¼àtå9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0¨Ë\83¼\0\0\0\80\0\93\ 69~%)¼ ¶£8\0C´9%\ 5(¼@J[9\0Æ\848^ðv¼\80\85!8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0°-6½Ýg¼\0@Ó5\0ø\986UI\v¼\0\12:6\0\93\ 69~%)¼ ¶£8\0\0\0\0¨Ë\83¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\v)$¼\0\0\0\80\0\0\0\0Ô\1c´»\0\0\0\80\0ø\986UI\v¼\0\12:6\0°-6½Ýg¼\0@Ó5\0\0\0\0Ô\11¬»\0\0\0\80\0\0\0\0\1f\92\19»\0\0\0\80\0\0\0\0Ô\1c´»\0\0\0\80\0\0\0\0\v)$¼\0\0\0\80\7f´¯<\1e$\1c»\0\0\0\80²ì<4zκ\0\0\0\80ãGý<¢ 8¸\0\0\0\80ÇÒý<\10\80ÿ¸\0\0\0\80\0\0\0\0»@¿º\0\0\0\80\0\0\0\0J\f\93¹\0\0\0\80\0\0\0\0\1f\92\19»\0\0\0\80\0\0\0\0Ô\11¬»\0\0\0\80¯\10±;õì ¼0\9c\83:²ÿ\9c;ý\a¼»\18é/:²ì<4zκ\0\0\0\80\7f´¯<\1e$\1c»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Ô\1c´»\0\0\0\80\0\0\0\0éoߺ\0\0\0\80\0\0\0\0\90\92b»\0\0\0\80\0ø\986UI\v¼\0\12:6\0\0\0\0\1f\92\19»\0\0\0\80\0\0\0\0\84\95 ¹\0\0\0\80\0\0\0\0éoߺ\0\0\0\80\0\0\0\0Ô\1c´»\0\0\0\80²ì<4zκ\0\0\0\80]¬±<6þGº\0\0\0\80\8aJý<\0L\ eµ\0\0\0\80ãGý<¢ 8¸\0\0\0\80\0\0\0\0J\f\93¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\84\95 ¹\0\0\0\80\0\0\0\0\1f\92\19»\0\0\0\80²ÿ\9c;ý\a¼»\18é/:\ e/\ f<¶\ e#»\0<:8]¬±<6þGº\0\0\0\80²ì<4zκ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0J\f\93¹\0\0\0\800²Ô9\9d\8f\ 5¼ _\819hn3:KÐ\8b»\80\9dï8\ e/\ f<¶\ e#»\0<:8²ÿ\9c;ý\a¼»\18é/:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0C´9%\ 5(¼@J[9\0øå8)Ʀ»\80á\8b8hn3:KÐ\8b»\80\9dï80²Ô9\9d\8f\ 5¼ _\819\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\93\ 69~%)¼ ¶£8\0\88m7\ e¡\9b»\0{\107\0øå8)Ʀ»\80á\8b8\0C´9%\ 5(¼@J[9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0ø\986UI\v¼\0\12:6\0\0\0\0\90\92b»\0\0\0\80\0\88m7\ e¡\9b»\0{\107\0\93\ 69~%)¼ ¶£8hn3:KÐ\8b»\80\9dï8\86?v;9Á\r»\0z\0:}\e<<\104Gº\0\0\0\80\ e/\ f<¶\ e#»\0<:8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0øå8)Ʀ»\80á\8b8\0À/5\8cË·º\0À©4\86?v;9Á\r»\0z\0:hn3:KÐ\8b»\80\9dï8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\88m7\ e¡\9b»\0{\107\0\0\0\0t¦\88º\0\0\0\80\0À/5\8cË·º\0À©4\0øå8)Ʀ»\80á\8b8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\90\92b»\0\0\0\80\0\0\0\088á¹\0\0\0\80\0\0\0\0t¦\88º\0\0\0\80\0\88m7\ e¡\9b»\0{\107\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0éoߺ\0\0\0\80\0\0\0\0\0ËK·\0\0\0\80\0\0\0\088á¹\0\0\0\80\0\0\0\0\90\92b»\0\0\0\80\0\0\0\0\84\95 ¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0ËK·\0\0\0\80\0\0\0\0éoߺ\0\0\0\80]¬±<6þGº\0\0\0\80v\9c·<h´6¹\0\0\0\80<Ký<\0\0\0\0\0\0\0\80\8aJý<\0L\ eµ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\84\95 ¹\0\0\0\80\ e/\ f<¶\ e#»\0<:8}\e<<\104Gº\0\0\0\80v\9c·<h´6¹\0\0\0\80]¬±<6þGº\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0ËK·\0\0\0\80\07³8\0\97ø`\ 4Z8@èk9\10»\80¹Ð}\ f9\0\0\0\088á¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\07³8\0\97ø`\ 4Z8\0\0\0\0\0ËK·\0\0\0\80v\9c·<h´6¹\0\0\0\80Oaº<\0\0\0\0\0\0\0\80=Ký<\0\0\0\0\0\0\0\80<Ký<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80}\e<<\104Gº\0\0\0\80ªhU<\0ãv·\0\0\0\80Oaº<\0\0\0\0\0\0\0\80v\9c·<h´6¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\86?v;9Á\r»\0z\0:O×Ð;\18¢îº\94Û\82:ªhU<\0ãv·\0\0\0\80}\e<<\104Gº\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0À/5\8cË·º\0À©4\b\v#:0¯¬¹`¿>9O×Ð;\18¢îº\94Û\82:\86?v;9Á\r»\0z\0:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0t¦\88º\0\0\0\80\90 \899\10¨\95¹ Ñ&9\b\v#:0¯¬¹`¿>9\0À/5\8cË·º\0À©4\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\088á¹\0\0\0\80@èk9\10»\80¹Ð}\ f9\90 \899\10¨\95¹ Ñ&9\0\0\0\0t¦\88º\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\b\v#:0¯¬¹`¿>9\ fÛ\ f;(Ê\ 5»h!\95:ãØý;\1c¦S»Ðêë:O×Ð;\18¢îº\94Û\82:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\90 \899\10¨\95¹ Ñ&9^ó ;$\8e\16»\86ѧ:\ fÛ\ f;(Ê\ 5»h!\95:\b\v#:0¯¬¹`¿>9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80@èk9\10»\80¹Ð}\ f9pÕ\r;\fË\1a»Ò\8a¬:^ó ;$\8e\16»\86ѧ:\90 \899\10¨\95¹ Ñ&9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\07³8\0\97ø`\ 4Z8\80\90Ü:°·ðºÖ(\86:pÕ\r;\fË\1a»Ò\8a¬:@èk9\10»\80¹Ð}\ f9\0\0\0\0\0\0\0\0\0\0\0\80Häh:Ð+~ºZ¨\r:\80\90Ü:°·ðºÖ(\86:\07³8\0\97ø`\ 4Z8Oaº<\0\0\0\0\0\0\0\80Oaº<\0\0\0\0\0\0\0\80BKý<\0\0\0\0\0\0\0\80=Ký<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80à\8bC9ÀiU¹`âí8Häh:Ð+~ºZ¨\r:\0\0\0\0\0\0\0\0\0\0\0\80ªhU<\0ãv·\0\0\0\80©\rV<\0\0\0\0\0\0\0\80Oaº<\0\0\0\0\0\0\0\80Oaº<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80à\8bC9ÀiU¹`âí8\0\0\0\0\0\0\0\0\0\0\0\80O×Ð;\18¢îº\94Û\82:ãØý;\1c¦S»Ðêë:©\rV<\0\0\0\0\0\0\0\80ªhU<\0ãv·\0\0\0\80Häh:Ð+~ºZ¨\r:]JP;pRc»;cý:?£\9b;¼Û©»»U=;\80\90Ü:°·ðºÖ(\86:Oaº<\0\0\0\0\0\0\0\80Raº<\0\0\0\0\0\0\0\80CKý<\0\0\0\0\0\0\0\80BKý<\0\0\0\0\0\0\0\80à\8bC9ÀiU¹`âí8\80\ 1»:´\17̺\9c~c:]JP;pRc»;cý:Häh:Ð+~ºZ¨\r:©\rV<\0\0\0\0\0\0\0\80\rV<\0\0\0\0\0\0\0\80Raº<\0\0\0\0\0\0\0\80Oaº<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 ¹Y9À\9dm¹`n\ 49\80\ 1»:´\17̺\9c~c:à\8bC9ÀiU¹`âí8ãØý;\1c¦S»Ðêë:\fhh:\b\83\8b»:\82\e;\rV<\0\0\0\0\0\0\0\80©\rV<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 ¹Y9À\9dm¹`n\ 49\0\0\0\0\0\0\0\0\0\0\0\80\ fÛ\ f;(Ê\ 5»h!\95:4\14\97;'G\99»uÚ*;\fhh:\b\83\8b»:\82\e;ãØý;\1c¦S»Ðêë:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80^ó ;$\8e\16»\86ѧ: \83©;%\0¹»£6N;4\14\97;'G\99»uÚ*;\ fÛ\ f;(Ê\ 5»h!\95:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80pÕ\r;\fË\1a»Ò\8a¬:÷Ö´;ô\Å»Rþ[; \83©;%\0¹»£6N;^ó ;$\8e\16»\86ѧ:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\80\90Ü:°·ðºÖ(\86:?£\9b;¼Û©»»U=;÷Ö´;ô\Å»Rþ[;pÕ\r;\fË\1a»Ò\8a¬:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 \83©;%\0¹»£6N;>%\r<Á
+\1a¼z´«;â\bê;<Ðó»\8câ\87;4\14\97;'G\99»uÚ*;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80÷Ö´;ô\Å»Rþ[;Ìe\19<çi'¼!\9cº;>%\r<Á
+\1a¼z´«; \83©;%\0¹»£6N;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80?£\9b;¼Û©»»U=;\1a°\b<X-\15¼FH¦;Ìe\19<çi'¼!\9cº;÷Ö´;ô\Å»Rþ[;]JP;pRc»;cý:óHÄ;:8Ö»bÈn;\1a°\b<X-\15¼FH¦;?£\9b;¼Û©»»U=;Raº<\0\0\0\0\0\0\0\80Raº<\0\0\0\0\0\0\0\80=Ký<\0\0\0\0\0\0\0\80CKý<\0\0\0\0\0\0\0\80\80\ 1»:´\17̺\9c~c:3\88Q;Td»âåþ:óHÄ;:8Ö»bÈn;]JP;pRc»;cý:\rV<\0\0\0\0\0\0\0\80²\rV<\0\0\0\0\0\0\0\80Raº<\0\0\0\0\0\0\0\80Raº<\0\0\0\0\0\0\0\80 ¹Y9À\9dm¹`n\ 49 Är:Py\84ºè©\13:3\88Q;Td»âåþ:\80\ 1»:´\17̺\9c~c:\fhh:\b\83\8b»:\82\e;\84l=:&`\91»~\v";²\rV<\0\0\0\0\0\0\0\80\rV<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 Är:Py\84ºè©\13: ¹Y9À\9dm¹`n\ 494\14\97;'G\99»uÚ*;â\bê;<Ðó»\8câ\87;\84l=:&`\91»~\v";\fhh:\b\83\8b»:\82\e;Raº<\0\0\0\0\0\0\0\80Waº<\0\0\0\0\0\0\0\80CKý<\0\0\0\0\0\0\0\80=Ký<\0\0\0\0\0\0\0\803\88Q;Td»âåþ:þ\19\9a;\8e.¨»Ww;;-\1f\b<-\8f\14¼ø\97¥;óHÄ;:8Ö»bÈn;²\rV<\0\0\0\0\0\0\0\80²\rV<\0\0\0\0\0\0\0\80Waº<\0\0\0\0\0\0\0\80Raº<\0\0\0\0\0\0\0\80 Är:Py\84ºè©\13:\88¥×:°Yëº\f+\83:þ\19\9a;\8e.¨»Ww;;3\88Q;Td»âåþ:\84l=:&`\91»~\v";¬ö·:D\fr»¦æ\ 6;²\rV<\0\0\0\0\0\0\0\80²\rV<\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80°\87\9e8À\ 3¸\0Ú@8\88¥×:°Yëº\f+\83: Är:Py\84ºè©\13:â\bê;<Ðó»\8câ\87;à]\13<q\a\e¼$ά;¬ö·:D\fr»¦æ\ 6;\84l=:&`\91»~\v";\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80°\87\9e8À\ 3¸\0Ú@8\0\0\0\0\0\0\0\0\0\0\0\80>%\r<Á
+\1a¼z´«;Zó:<J\bL¼lmã;à]\13<q\a\e¼$ά;â\bê;<Ðó»\8câ\87;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Ìe\19<çi'¼!\9cº;©øM<\81Ê`¼û\90ú;Zó:<J\bL¼lmã;>%\r<Á
+\1a¼z´«;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\1a°\b<X-\15¼FH¦;>\869<ÔyJ¼C±á;©øM<\81Ê`¼û\90ú;Ìe\19<çi'¼!\9cº;óHÄ;:8Ö»bÈn;-\1f\b<-\8f\14¼ø\97¥;>\869<ÔyJ¼C±á;\1a°\b<X-\15¼FH¦;Zó:<J\bL¼lmã;\0\0\0\0@é_¼æ\95ù;\0\0\0\0nÂ$¼Á¦·;à]\13<q\a\e¼$ά;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80©øM<\81Ê`¼û\90ú;\0\0\0\0îÙx¼V±
+<\0\0\0\0@é_¼æ\95ù;Zó:<J\bL¼lmã;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80>\869<ÔyJ¼C±á;\0\0\0\0<é_¼â\95ù;\0\0\0\0îÙx¼V±
+<©øM<\81Ê`¼û\90ú;-\1f\b<-\8f\14¼ø\97¥;\0\0\0\0pÂ$¼Â¦·;\0\0\0\0<é_¼â\95ù;>\869<ÔyJ¼C±á;Waº<\0\0\0\0\0\0\0\80\0\0\0\0\80f\16¹\0¥§8\0\0\0\0\0\0\0\0\0\0\0\80CKý<\0\0\0\0\0\0\0\80þ\19\9a;\8e.¨»Ww;;\0\0\0\0\09½»iëR;\0\0\0\0pÂ$¼Â¦·;-\1f\b<-\8f\14¼ø\97¥;²\rV<\0\0\0\0\0\0\0\80\0\0\0\0\f¯
+»ô\95\9a:\0\0\0\0\80f\16¹\0¥§8Waº<\0\0\0\0\0\0\0\80\88¥×:°Yëº\f+\83:\0\0\0\0ü®
+»ä\95\9a:\0\0\0\0\09½»iëR;þ\19\9a;\8e.¨»Ww;;¬ö·:D\fr»¦æ\ 6;\0\0\0\0\09½»iëR;\0\0\0\0\f¯
+»ô\95\9a:²\rV<\0\0\0\0\0\0\0\80°\87\9e8À\ 3¸\0Ú@8\0\0\0\0@f\16¹\0¥§8\0\0\0\0ü®
+»ä\95\9a:\88¥×:°Yëº\f+\83:à]\13<q\a\e¼$ά;\0\0\0\0nÂ$¼Á¦·;\0\0\0\0\09½»iëR;¬ö·:D\fr»¦æ\ 6;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0@f\16¹\0¥§8°\87\9e8À\ 3¸\0Ú@8\0\0\0\0\09½»iëR;ü\19\9a»\8e.¨»Ww;;/\1f\b¼.\8f\14¼ø\97¥;\0\0\0\0pÂ$¼Â¦·;\0\0\0\0\f¯
+»ô\95\9a:²\rV¼\0\0\0\0\0\0\0\80Vaº¼\0\0\0\0\0\0\0\80\0\0\0\0\80f\16¹\0¥§8\0\0\0\0ü®
+»ä\95\9a:\96¥×º¸Yëº\f+\83:ü\19\9a»\8e.¨»Ww;;\0\0\0\0\09½»iëR;\0\0\0\0\09½»iëR;±ö·ºH\fr»¦æ\ 6;²\rV¼\0\0\0\0\0\0\0\80\0\0\0\0\f¯
+»ô\95\9a:\0\0\0\0@f\16¹\0¥§8\0\88\9e¸@\ 4¸\0Ú@8\96¥×º¸Yëº\f+\83:\0\0\0\0ü®
+»ä\95\9a:\0\0\0\0nÂ$¼Á¦·;â]\13¼r\a\e¼$ά;±ö·ºH\fr»¦æ\ 6;\0\0\0\0\09½»iëR;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\88\9e¸@\ 4¸\0Ú@8\0\0\0\0@f\16¹\0¥§8\0\0\0\0@é_¼æ\95ù;Yó:¼J\bL¼lmã;â]\13¼r\a\e¼$ά;\0\0\0\0nÂ$¼Á¦·;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0îÙx¼V±
+<ªøM¼\82Ê`¼û\90ú;Yó:¼J\bL¼lmã;\0\0\0\0@é_¼æ\95ù;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0<é_¼â\95ù;B\869¼ÕyJ¼C±á;ªøM¼\82Ê`¼û\90ú;\0\0\0\0îÙx¼V±
+<\0\0\0\0pÂ$¼Â¦·;/\1f\b¼.\8f\14¼ø\97¥;B\869¼ÕyJ¼C±á;\0\0\0\0<é_¼â\95ù;\0\0\0\0\80f\16¹\0¥§8Vaº¼\0\0\0\0\0\0\0\80CKý¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ªøM¼\82Ê`¼û\90ú;Íe\19¼éi'¼!\9cº;<%\r¼Á
+\1a¼z´«;Yó:¼J\bL¼lmã;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80B\869¼ÕyJ¼C±á;\1c°\b¼Z-\15¼FH¦;Íe\19¼éi'¼!\9cº;ªøM¼\82Ê`¼û\90ú;/\1f\b¼.\8f\14¼ø\97¥;öHÄ»>8Ö»bÈn;\1c°\b¼Z-\15¼FH¦;B\869¼ÕyJ¼C±á;Vaº¼\0\0\0\0\0\0\0\80Qaº¼\0\0\0\0\0\0\0\80=Ký¼\0\0\0\0\0\0\0\80CKý¼\0\0\0\0\0\0\0\80ü\19\9a»\8e.¨»Ww;;,\88Q»Td»âåþ:öHÄ»>8Ö»bÈn;/\1f\b¼.\8f\14¼ø\97¥;²\rV¼\0\0\0\0\0\0\0\80±\rV¼\0\0\0\0\0\0\0\80Qaº¼\0\0\0\0\0\0\0\80Vaº¼\0\0\0\0\0\0\0\80\96¥×º¸Yëº\f+\83:0Ärºly\84ºè©\13:,\88Q»Td»âåþ:ü\19\9a»\8e.¨»Ww;;±ö·ºH\fr»¦æ\ 6;\8cl=º(`\91»~\v";±\rV¼\0\0\0\0\0\0\0\80²\rV¼\0\0\0\0\0\0\0\80\0\88\9e¸@\ 4¸\0Ú@8\0\0\0\0\0\0\0\0\0\0\0\800Ärºly\84ºè©\13:\96¥×º¸Yëº\f+\83:â]\13¼r\a\e¼$ά;ä\bê»CÐó»\8câ\87;\8cl=º(`\91»~\v";±ö·ºH\fr»¦æ\ 6;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\88\9e¸@\ 4¸\0Ú@8Yó:¼J\bL¼lmã;<%\r¼Á
+\1a¼z´«;ä\bê»CÐó»\8câ\87;â]\13¼r\a\e¼$ά;±\rV¼\0\0\0\0\0\0\0\80«\rV¼\0\0\0\0\0\0\0\80Qaº¼\0\0\0\0\0\0\0\80Qaº¼\0\0\0\0\0\0\0\800Ärºly\84ºè©\13:\0¹Y¹ \9em¹`n\ 49p\ 1»º¸\17̺\9c~c:,\88Q»Td»âåþ:\8cl=º(`\91»~\v";\ 4hhº
+\83\8b»:\82\e;«\rV¼\0\0\0\0\0\0\0\80±\rV¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0¹Y¹ \9em¹`n\ 490Ärºly\84ºè©\13:ä\bê»CÐó»\8câ\87;3\14\97».G\99»uÚ*;\ 4hhº
+\83\8b»:\82\e;\8cl=º(`\91»~\v";\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80<%\r¼Á
+\1a¼z´«;\1c\83©»&\0¹»£6N;3\14\97».G\99»uÚ*;ä\bê»CÐó»\8câ\87;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Íe\19¼éi'¼!\9cº;øÖ´»ú\Å»Rþ[;\1c\83©»&\0¹»£6N;<%\r¼Á
+\1a¼z´«;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\1c°\b¼Z-\15¼FH¦;A£\9b»ÂÛ©»»U=;øÖ´»ú\Å»Rþ[;Íe\19¼éi'¼!\9cº;öHÄ»>8Ö»bÈn;_JP»|Rc»;cý:A£\9b»ÂÛ©»»U=;\1c°\b¼Z-\15¼FH¦;Qaº¼\0\0\0\0\0\0\0\80Qaº¼\0\0\0\0\0\0\0\80BKý¼\0\0\0\0\0\0\0\80=Ký¼\0\0\0\0\0\0\0\80,\88Q»Td»âåþ:p\ 1»º¸\17̺\9c~c:_JP»|Rc»;cý:öHÄ»>8Ö»bÈn;øÖ´»ú\Å»Rþ[;lÕ\r»\18Ë\1a»Ò\8a¬:Tó »(\8e\16»\86ѧ:\1c\83©»&\0¹»£6N;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80A£\9b»ÂÛ©»»U=;\84\90ܺȷðºÖ(\86:lÕ\r»\18Ë\1a»Ò\8a¬:øÖ´»ú\Å»Rþ[;_JP»|Rc»;cý:8ähº\0,~ºZ¨\r:\84\90ܺȷðºÖ(\86:A£\9b»ÂÛ©»»U=;Qaº¼\0\0\0\0\0\0\0\80Paº¼\0\0\0\0\0\0\0\80AKý¼\0\0\0\0\0\0\0\80BKý¼\0\0\0\0\0\0\0\80p\ 1»º¸\17̺\9c~c:@\8bC¹\0jU¹`âí88ähº\0,~ºZ¨\r:_JP»|Rc»;cý:«\rV¼\0\0\0\0\0\0\0\80§\rV¼\0\0\0\0\0\0\0\80Paº¼\0\0\0\0\0\0\0\80Qaº¼\0\0\0\0\0\0\0\80\0¹Y¹ \9em¹`n\ 49\0\0\0\0\0\0\0\0\0\0\0\80@\8bC¹\0jU¹`âí8p\ 1»º¸\17̺\9c~c:\ 4hhº
+\83\8b»:\82\e;äØý»"¦S»Ðêë:§\rV¼\0\0\0\0\0\0\0\80«\rV¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0¹Y¹ \9em¹`n\ 493\14\97».G\99»uÚ*;\vÛ\ f»:Ê\ 5»h!\95:äØý»"¦S»Ðêë:\ 4hhº
+\83\8b»:\82\e;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\1c\83©»&\0¹»£6N;Tó »(\8e\16»\86ѧ:\vÛ\ f»:Ê\ 5»h!\95:3\14\97».G\99»uÚ*;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80@\8bC¹\0jU¹`âí8äØý»"¦S»Ðêë:K×л$¢îº\94Û\82:¨hU¼\0åv·\0\0\0\80§\rV¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\vÛ\ f»:Ê\ 5»h!\95:à
+#º°¯¬¹`¿>9K×л$¢îº\94Û\82:äØý»"¦S»Ðêë:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Tó »(\8e\16»\86ѧ:P \89¹\10¨\95¹ Ñ&9à
+#º°¯¬¹`¿>9\vÛ\ f»:Ê\ 5»h!\95:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80lÕ\r»\18Ë\1a»Ò\8a¬:Àçk¹\90»\80¹Ð}\ f9P \89¹\10¨\95¹ Ñ&9Tó »(\8e\16»\86ѧ:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\84\90ܺȷðºÖ(\86:\806³¸À\98ø`\ 4Z8Àçk¹\90»\80¹Ð}\ f9lÕ\r»\18Ë\1a»Ò\8a¬:8ähº\0,~ºZ¨\r:\0\0\0\0\0\0\0\0\0\0\0\80\806³¸À\98ø`\ 4Z8\84\90ܺȷðºÖ(\86:Paº¼\0\0\0\0\0\0\0\80Naº¼\0\0\0\0\0\0\0\80=Ký¼\0\0\0\0\0\0\0\80AKý¼\0\0\0\0\0\0\0\80@\8bC¹\0jU¹`âí8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\808ähº\0,~ºZ¨\r:§\rV¼\0\0\0\0\0\0\0\80¨hU¼\0åv·\0\0\0\80Naº¼\0\0\0\0\0\0\0\80Paº¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\806³¸À\98ø`\ 4Z8\0\0\0\0\0ÙK·\0\0\0\80\0\0\0\0¸8á¹\0\0\0\80Àçk¹\90»\80¹Ð}\ f9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0ÙK·\0\0\0\80\806³¸À\98ø`\ 4Z8Naº¼\0\0\0\0\0\0\0\80t\9c·¼Ð´6¹\0\0\0\80<Ký¼\0\0\0\0\0\0\0\80=Ký¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80¨hU¼\0åv·\0\0\0\80z\e<¼\1c4Gº\0\0\0\80t\9c·¼Ð´6¹\0\0\0\80Naº¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80K×л$¢îº\94Û\82:~?v»?Á\r»\0z\0:z\e<¼\1c4Gº\0\0\0\80¨hU¼\0åv·\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80à
+#º°¯¬¹`¿>9\0à.µ¬Ë·º\0À©4~?v»?Á\r»\0z\0:K×л$¢îº\94Û\82:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80P \89¹\10¨\95¹ Ñ&9\0\0\0\0t¦\88º\0\0\0\80\0à.µ¬Ë·º\0À©4à
+#º°¯¬¹`¿>9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Àçk¹\90»\80¹Ð}\ f9\0\0\0\0¸8á¹\0\0\0\80\0\0\0\0t¦\88º\0\0\0\80P \89¹\10¨\95¹ Ñ&9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0à.µ¬Ë·º\0À©4\80õå¸1Ʀ»\80á\8b8Hn3ºNÐ\8b»\80\9dï8~?v»?Á\r»\0z\0:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0t¦\88º\0\0\0\80\0\80m·\ e¡\9b»\0{\107\80õå¸1Ʀ»\80á\8b8\0à.µ¬Ë·º\0À©4\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0¸8á¹\0\0\0\80\0\0\0\0\9f\92b»\0\0\0\80\0\80m·\ e¡\9b»\0{\107\0\0\0\0t¦\88º\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0ÙK·\0\0\0\80\0\0\0\0\ 3pߺ\0\0\0\80\0\0\0\0\9f\92b»\0\0\0\80\0\0\0\0¸8á¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\96 ¹\0\0\0\80\0\0\0\0\ 3pߺ\0\0\0\80\0\0\0\0\0ÙK·\0\0\0\80t\9c·¼Ð´6¹\0\0\0\80\¬±¼HþGº\0\0\0\80\8aJý¼\0h\ eµ\0\0\0\80<Ký¼\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\96 ¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80z\e<¼\1c4Gº\0\0\0\80\v/\ f¼º\ e#»\0<:8\¬±¼HþGº\0\0\0\80t\9c·¼Ð´6¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80~?v»?Á\r»\0z\0:Hn3ºNÐ\8b»\80\9dï8\v/\ f¼º\ e#»\0<:8z\e<¼\1c4Gº\0\0\0\80\0\0\0\0\0\96 ¹\0\0\0\80\0\0\0\0,\92\19»\0\0\0\80\0\0\0\0Ù\1c´»\0\0\0\80\0\0\0\0\ 3pߺ\0\0\0\80\¬±¼HþGº\0\0\0\80±ì¼7zκ\0\0\0\80âGý¼Ë 8¸\0\0\0\80\8aJý¼\0h\ eµ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0+\f\93¹\0\0\0\80\0\0\0\0,\92\19»\0\0\0\80\0\0\0\0\0\96 ¹\0\0\0\80\v/\ f¼º\ e#»\0<:8¬ÿ\9c»þ\a¼»\18é/:±ì¼7zκ\0\0\0\80\¬±¼HþGº\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0+\f\93¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Hn3ºNÐ\8b»\80\9dï8à±Ô¹\9e\8f\ 5¼ _\819¬ÿ\9c»þ\a¼»\18é/:\v/\ f¼º\ e#»\0<:8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\80õå¸1Ʀ»\80á\8b8@B´¹'\ 5(¼@J[9à±Ô¹\9e\8f\ 5¼ _\819Hn3ºNÐ\8b»\80\9dï8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\80m·\ e¡\9b»\0{\107\80\92\ 6¹~%)¼ ¶£8@B´¹'\ 5(¼@J[9\80õå¸1Ʀ»\80á\8b8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\9f\92b»\0\0\0\80\0Ø\98¶XI\v¼\0\12:6\80\92\ 6¹~%)¼ ¶£8\0\80m·\ e¡\9b»\0{\107\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\ 3pߺ\0\0\0\80\0\0\0\0Ù\1c´»\0\0\0\80\0Ø\98¶XI\v¼\0\12:6\0\0\0\0\9f\92b»\0\0\0\80@B´¹'\ 5(¼@J[9\80Â\84¸_ðv¼\80\85!8(\9e<º÷)G¼àtå9à±Ô¹\9e\8f\ 5¼ _\819\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\80\92\ 6¹~%)¼ ¶£8\0\0\0\0¨Ë\83¼\0\0\0\80\80Â\84¸_ðv¼\80\85!8@B´¹'\ 5(¼@J[9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0Ø\98¶XI\v¼\0\12:6\0@-¶ÀÝg¼\0@Ó5\0\0\0\0¨Ë\83¼\0\0\0\80\80\92\ 6¹~%)¼ ¶£8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Ù\1c´»\0\0\0\80\0\0\0\0\r)$¼\0\0\0\80\0@-¶ÀÝg¼\0@Ó5\0Ø\98¶XI\v¼\0\12:6\0\0\0\0,\92\19»\0\0\0\80\0\0\0\0Ø\11¬»\0\0\0\80\0\0\0\0\r)$¼\0\0\0\80\0\0\0\0Ù\1c´»\0\0\0\80±ì¼7zκ\0\0\0\80~´¯¼\1e$\1c»\0\0\0\80ÆÒý¼ø\7fÿ¸\0\0\0\80âGý¼Ë 8¸\0\0\0\80\0\0\0\0+\f\93¹\0\0\0\80\0\0\0\0¯@¿º\0\0\0\80\0\0\0\0Ø\11¬»\0\0\0\80\0\0\0\0,\92\19»\0\0\0\80¬ÿ\9c»þ\a¼»\18é/:©\10±»õì ¼0\9c\83:~´¯¼\1e$\1c»\0\0\0\80±ì¼7zκ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0¯@¿º\0\0\0\80\0\0\0\0+\f\93¹\0\0\0\80à±Ô¹\9e\8f\ 5¼ _\819(\9e<º÷)G¼àtå9©\10±»õì ¼0\9c\83:¬ÿ\9c»þ\a¼»\18é/:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Ø\11¬»\0\0\0\80\0\0\0\0j\19ý»\0\0\0\80@á\ 2¹\11»b¼F9\9f8\0\0\0\0\r)$¼\0\0\0\80~´¯¼\1e$\1c»\0\0\0\802À¹¼x¦B»\0\0\0\80kúþ¼TÂF¹\0\0\0\80ÆÒý¼ø\7fÿ¸\0\0\0\80\0\0\0\0¯@¿º\0\0\0\80\0\0\0\0E¯/»\0\0\0\80\0\0\0\0j\19ý»\0\0\0\80\0\0\0\0Ø\11¬»\0\0\0\80©\10±»õì ¼0\9c\83:\ 18»B\89(¼¼9\9d:2À¹¼x¦B»\0\0\0\80~´¯¼\1e$\1c»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0ÀÝò¸\0\0\0\80\0\0\0\0E¯/»\0\0\0\80\0\0\0\0¯@¿º\0\0\0\80(\9e<º÷)G¼àtå9@\13kº¢9w¼\88ü\ e:\ 18»B\89(¼¼9\9d:©\10±»õì ¼0\9c\83:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0ÀÝò¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\80Â\84¸_ðv¼\80\85!8\0\0\0\0]¶\9b¼\0\0\0\80@\13kº¢9w¼\88ü\ e:(\9e<º÷)G¼àtå9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0¨Ë\83¼\0\0\0\80\0\0\0\0d\f«¼\0\0\0\80\0\0\0\0]¶\9b¼\0\0\0\80\80Â\84¸_ðv¼\80\85!8\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0@-¶ÀÝg¼\0@Ó5\0\0\0\0\8b\86\99¼\0\0\0\80\0\0\0\0d\f«¼\0\0\0\80\0\0\0\0¨Ë\83¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\r)$¼\0\0\0\80@á\ 2¹\11»b¼F9\9f8\0\0\0\0\8b\86\99¼\0\0\0\80\0@-¶ÀÝg¼\0@Ó5\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0d\f«¼\0\0\0\80\0\0\0\0ø?»¼\0\0\0\80\0Ø ¶F\81¨¼\0@Ä5\0\0\0\0]¶\9b¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\8b\86\99¼\0\0\0\80\0,ø·\80¿¨¼Àü\967\0\0\0\0ø?»¼\0\0\0\80\0\0\0\0d\f«¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80@á\ 2¹\11»b¼F9\9f8è\9bQº\8e\1f\83¼Jþþ9\0,ø·\80¿¨¼Àü\967\0\0\0\0\8b\86\99¼\0\0\0\80\0\0\0\0j\19ý»\0\0\0\80\0\0\0\0Äa\ e¼\0\0\0\80è\9bQº\8e\1f\83¼Jþþ9@á\ 2¹\11»b¼F9\9f82À¹¼x¦B»\0\0\0\80\1d\8a̼ö´P»\0\0\0\80A\16\0½\Vb¹\0\0\0\80kúþ¼TÂF¹\0\0\0\80\0\0\0\0E¯/»\0\0\0\80\0\0\0\0ÿ´P»\0\0\0\80\0\0\0\0Äa\ e¼\0\0\0\80\0\0\0\0j\19ý»\0\0\0\80\ 18»B\89(¼¼9\9d:À\12o»úE0¼\\1c\97:\1d\8a̼ö´P»\0\0\0\802À¹¼x¦B»\0\0\0\80\0\0\0\0ÀÝò¸\0\0\0\80\0\0\0\0\0Vb¹\0\0\0\80\0\0\0\0ÿ´P»\0\0\0\80\0\0\0\0E¯/»\0\0\0\80@\13kº¢9w¼\88ü\ e:ÀÒ˺\9cà\89¼ ôw:À\12o»úE0¼\\1c\97:\ 18»B\89(¼¼9\9d:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0Vb¹\0\0\0\80\0\0\0\0ÀÝò¸\0\0\0\80\0\0\0\0]¶\9b¼\0\0\0\80\0Ø ¶F\81¨¼\0@Ä5ÀÒ˺\9cà\89¼ ôw:@\13kº¢9w¼\88ü\ e:\1d\8a̼ö´P»\0\0\0\80nÛâ¼q¦B»\0\0\0\80;P\0½@ÂF¹\0\0\0\80A\16\0½\Vb¹\0\0\0\80\0\0\0\0ÿ´P»\0\0\0\80\0\0\0\0å4.»\0\0\0\80\0\0\0\0`\19ý»\0\0\0\80\0\0\0\0Äa\ e¼\0\0\0\80À\12o»úE0¼\\1c\97:\13oF¼òE\ 5¼\0\0\0\80nÛâ¼q¦B»\0\0\0\80\1d\8a̼ö´P»\0\0\0\80\0\0\0\0\0Vb¹\0\0\0\80\0\0\0\0 n\119\0\0\0\80\0\0\0\0å4.»\0\0\0\80\0\0\0\0ÿ´P»\0\0\0\80ÀÒ˺\9cà\89¼ ôw:\9a\88/»²\8a\8b¼ì\89Õ:\13oF¼òE\ 5¼\0\0\0\80À\12o»úE0¼\\1c\97:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0 n\119\0\0\0\80\0\0\0\0\0Vb¹\0\0\0\80\0Ø ¶F\81¨¼\0@Ä5\80\ 5þº\14
+¼°\82\9a:\9a\88/»²\8a\8b¼ì\89Õ:ÀÒ˺\9cà\89¼ ôw:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0ø?»¼\0\0\0\80Ì` ºéüµ¼$\1aC:\80\ 5þº\14
+¼°\82\9a:\0Ø ¶F\81¨¼\0@Ä5\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0,ø·\80¿¨¼Àü\967ª\93,»\9c\11±¼0ñÑ:Ì` ºéüµ¼$\1aC:\0\0\0\0ø?»¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80è\9bQº\8e\1f\83¼Jþþ9 ×¾º\97\88z¼\v)h:ª\93,»\9c\11±¼0ñÑ:\0,ø·\80¿¨¼Àü\967\0\0\0\0Äa\ e¼\0\0\0\80\0\0\0\0`\19ý»\0\0\0\80 ×¾º\97\88z¼\v)h:è\9bQº\8e\1f\83¼Jþþ9Ì` ºéüµ¼$\1aC:\]¸»\e\19¶¼\1eH`;\ e\94\99»dΤ¼xÔ:;\80\ 5þº\14
+¼°\82\9a:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ª\93,»\9c\11±¼0ñÑ:\ 3an»\12n\94¼Ûþ\10;\]¸»\e\19¶¼\1eH`;Ì` ºéüµ¼$\1aC:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 ×¾º\97\88z¼\v)h:\0\0\0\0\f)$¼\0\0\0\80\ 3an»\12n\94¼Ûþ\10;ª\93,»\9c\11±¼0ñÑ:\0\0\0\0`\19ý»\0\0\0\80\0\0\0\08"¤»\0\0\0\80\0\0\0\0\f)$¼\0\0\0\80 ×¾º\97\88z¼\v)h:nÛâ¼q¦B»\0\0\0\80bÈð¼\ f$\1c»\0\0\0\80zäÿ¼P\7fÿ¸\0\0\0\80;P\0½@ÂF¹\0\0\0\80\0\0\0\0å4.»\0\0\0\80\0\0\0\0`3û9\0\0\0\80\0\0\0\08"¤»\0\0\0\80\0\0\0\0`\19ý»\0\0\0\80\13oF¼òE\ 5¼\0\0\0\80\ 3\9e´¼ÁÐØ»\0\0\0\80bÈð¼\ f$\1c»\0\0\0\80nÛâ¼q¦B»\0\0\0\80\0\0\0\0 n\119\0\0\0\80\0\0\0\0p$·:\0\0\0\80\0\0\0\0`3û9\0\0\0\80\0\0\0\0å4.»\0\0\0\80\9a\88/»²\8a\8b¼ì\89Õ:î\90=»~tp¼\90wñ:\ 3\9e´¼ÁÐØ»\0\0\0\80\13oF¼òE\ 5¼\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0`\8b\959\0\0\0\80\0\0\0\0p$·:\0\0\0\80\0\0\0\0 n\119\0\0\0\80\80\ 5þº\14
+¼°\82\9a:\ e\94\99»dΤ¼xÔ:;î\90=»~tp¼\90wñ:\9a\88/»²\8a\8b¼ì\89Õ:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0`\8b\959\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0`3û9\0\0\0\80\0\0\0\0Ò\8f\9b;\0\0\0\80\0\0\0\0èy@;\0\0\0\80\0\0\0\08"¤»\0\0\0\80\ 3\9e´¼ÁÐØ»\0\0\0\80ådä¼Ï\93\94»\0\0\0\807\86ë¼\1azκ\0\0\0\80bÈð¼\ f$\1c»\0\0\0\80\0\0\0\0p$·:\0\0\0\80\0\0\0\0z\1e:;\0\0\0\80\0\0\0\0Ò\8f\9b;\0\0\0\80\0\0\0\0`3û9\0\0\0\80î\90=»~tp¼\90wñ:\fþ¯¼!\9dü»\0\0\0\80ådä¼Ï\93\94»\0\0\0\80\ 3\9e´¼ÁÐØ»\0\0\0\80\0\0\0\0`\8b\959\0\0\0\80\0\0\0\0èg:\0\0\0\80\0\0\0\0z\1e:;\0\0\0\80\0\0\0\0p$·:\0\0\0\80\ e\94\99»dΤ¼xÔ:;8\aO¼Fß!¼\0\0\0\80\fþ¯¼!\9dü»\0\0\0\80î\90=»~tp¼\90wñ:\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0èg:\0\0\0\80\0\0\0\0`\8b\959\0\0\0\80\]¸»\e\19¶¼\1eH`;0¶»\ 101¼\90V¸98\aO¼Fß!¼\0\0\0\80\ e\94\99»dΤ¼xÔ:;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\ 3an»\12n\94¼Ûþ\10;Ô½\97ºÐ2\v¼\0\0\0\800¶»\ 101¼\90V¸9\]¸»\e\19¶¼\1eH`;\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\f)$¼\0\0\0\80\0\0\0\0zþ_»\0\0\0\80Ô½\97ºÐ2\v¼\0\0\0\80\ 3an»\12n\94¼Ûþ\10;\0\0\0\08"¤»\0\0\0\80\0\0\0\0èy@;\0\0\0\80\0\0\0\0zþ_»\0\0\0\80\0\0\0\0\f)$¼\0\0\0\80bÈð¼\ f$\1c»\0\0\0\807\86ë¼\1azκ\0\0\0\80\99[þ¼à\1e8¸\0\0\0\80zäÿ¼P\7fÿ¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\8a\9b8\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Ô½\97ºÐ2\v¼\0\0\0\80\0\0\0\0d E;\0\0\0\80\936\91»æ-»\0\0\0\800¶»\ 101¼\90V¸9\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0zþ_»\0\0\0\80\0\0\0\0\10^i<\0\0\0\80\0\0\0\0d E;\0\0\0\80Ô½\97ºÐ2\v¼\0\0\0\80\0\0\0\0èy@;\0\0\0\80\0\0\0\0oº\84<\0\0\0\80\0\0\0\0\10^i<\0\0\0\80\0\0\0\0zþ_»\0\0\0\807\86ë¼\1azκ\0\0\0\80ÌfÖ¼\ 4þGº\0\0\0\80½Ný¼\0Ð\rµ\0\0\0\80\99[þ¼à\1e8¸\0\0\0\80\0\0\0\0Ò\8f\9b;\0\0\0\80\0\0\0\0ð\11\19<\0\0\0\80\0\0\0\0oº\84<\0\0\0\80\0\0\0\0èy@;\0\0\0\80ådä¼Ï\93\94»\0\0\0\80_µÄ¼
+Ö\1d»\0\0\0\80ÌfÖ¼\ 4þGº\0\0\0\807\86ë¼\1azκ\0\0\0\80\0\0\0\0z\1e:;\0\0\0\80\0\0\0\0Jû\83;\0\0\0\80\0\0\0\0ð\11\19<\0\0\0\80\0\0\0\0Ò\8f\9b;\0\0\0\80\fþ¯¼!\9dü»\0\0\0\80!í¨¼\8a\18\85»\0\0\0\80_µÄ¼
+Ö\1d»\0\0\0\80ådä¼Ï\93\94»\0\0\0\80\0\0\0\0èg:\0\0\0\80\0\0\0\0(\80»:\0\0\0\80\0\0\0\0Jû\83;\0\0\0\80\0\0\0\0z\1e:;\0\0\0\808\aO¼Fß!¼\0\0\0\80¬\80^¼-Ú¢»\0\0\0\80!í¨¼\8a\18\85»\0\0\0\80\fþ¯¼!\9dü»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\8a\9b8\0\0\0\80\0\0\0\0(\80»:\0\0\0\80\0\0\0\0èg:\0\0\0\800¶»\ 101¼\90V¸9\936\91»æ-»\0\0\0\80¬\80^¼-Ú¢»\0\0\0\808\aO¼Fß!¼\0\0\0\80\0\0\0\0Jû\83;\0\0\0\80\0\0\0\0Ðÿ\92;\0\0\0\80\0\0\0\0\19d<<\0\0\0\80\0\0\0\0ð\11\19<\0\0\0\80!í¨¼\8a\18\85»\0\0\0\80\0\0\0\0Pî\9d¹\0\0\0\80\0\0\0\0(¤Cº\0\0\0\80_µÄ¼
+Ö\1d»\0\0\0\80\0\0\0\0(\80»:\0\0\0\80\0\0\0\0,õ×:\0\0\0\80\0\0\0\0Ðÿ\92;\0\0\0\80\0\0\0\0Jû\83;\0\0\0\80¬\80^¼-Ú¢»\0\0\0\80\0\0\0\0\f³\r;\0\0\0\80\0\0\0\0Pî\9d¹\0\0\0\80!í¨¼\8a\18\85»\0\0\0\80\0\0\0\0\0\8a\9b8\0\0\0\80\0\0\0\0\80õí8\0\0\0\80\0\0\0\0,õ×:\0\0\0\80\0\0\0\0(\80»:\0\0\0\80\936\91»æ-»\0\0\0\80\0\0\0\0y¨\ 3<\0\0\0\80\0\0\0\0\f³\r;\0\0\0\80¬\80^¼-Ú¢»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\80õí8\0\0\0\80\0\0\0\0\0\8a\9b8\0\0\0\80\0\0\0\0d E;\0\0\0\80\0\0\0\0Rd\9b<\0\0\0\80\0\0\0\0y¨\ 3<\0\0\0\80\936\91»æ-»\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\10^i<\0\0\0\80\0\0\0\0nW¹<\0\0\0\80\0\0\0\0Rd\9b<\0\0\0\80\0\0\0\0d E;\0\0\0\80\0\0\0\0oº\84<\0\0\0\80\0\0\0\0Ø\15£<\0\0\0\80\0\0\0\0nW¹<\0\0\0\80\0\0\0\0\10^i<\0\0\0\80ÌfÖ¼\ 4þGº\0\0\0\80\0\0\0\0`´6¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80½Ný¼\0Ð\rµ\0\0\0\80\0\0\0\0ð\11\19<\0\0\0\80\0\0\0\0\19d<<\0\0\0\80\0\0\0\0Ø\15£<\0\0\0\80\0\0\0\0oº\84<\0\0\0\80_µÄ¼
+Ö\1d»\0\0\0\80\0\0\0\0(¤Cº\0\0\0\80\0\0\0\0`´6¹\0\0\0\80ÌfÖ¼\ 4þGº\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80Ôä\ 6» ób¹\0\0\0\80Øô\13»XéÕ¹\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0À°ß¸\0\0\0\80'¸õº\80\1c\89¸\0\0\0\80Ôä\ 6» ób¹\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\805íµº\0\80ªµ\0\0\0\80'¸õº\80\1c\89¸\0\0\0\80\0\0\0\0À°ß¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\10
+Eº\0\0\0\0\0\0\0\805íµº\0\80ªµ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80(\ 6^¹\0\0\0\0\0\0\0\80\10
+Eº\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80(\ 6^¹\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0Z\944º\0\0\0\80¦ïA»F\86\rº\0\0\0\80\0\0\0\0~±Hº\0\0\0\80yRj»4®ø¹\0\0\0\80à\9e\8a»dJÕ¹\0\0\0\80©ïA;$\86\rº\0\0\0\80~Rj;øø¹\0\0\0\80\88®\9f»Pá³¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80}²»Fý\96¹\0\0\0\80\9c\9e»Ò1\80¹\0\0\0\80n\84λT\13`¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80Ï-Ö»)®L¹\0\0\0\80LóÙ»ô«D¹\0\0\0\80w'Ú»\f%G¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80\1a\80Ö»8+U¹\0\0\0\80âÇλð+p¹\0\0\0\80¤\ 6ûL®\8c¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80,ʳ»|E¨¹\0\0\0\80Om¢»\10]ɹ\0\0\0\80\0\0\0\0d\944º\0\0\0\80\0\0\0\0~±Hº\0\0\0\80Om¢;\1c]ɹ\0\0\0\80-ʳ;\8cE¨¹\0\0\0\80¤\ 6Ã;`®\8c¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80æÇÎ; ,p¹\0\0\0\80\1c\80Ö;h+U¹\0\0\0\80z'Ú;4%G¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80OóÙ;\10¬D¹\0\0\0\80Ò-Ö;3®L¹\0\0\0\80q\84Î;H\13`¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80 \9eÂ;¾1\80¹\0\0\0\80\81²;"ý\96¹\0\0\0\80\8c®\9f;$á³¹\0\0\0\80\0\0\0\0~±Hº\0\0\0\80ã\9e\8a;,JÕ¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\93^¸\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80H\96#¹\0\0\0\0\0\0\0\80|\96¡¹\0\0\0\0\0\0\0\80< \ 2º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80¦¤7º\0\0\0\0\0\0\0\80\82üjº\0\0\0\0\0\0\0\80/Í\8aº\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\7fä\98º\0\0\0\0\0\0\0\80íÑ\9dº\0\0\0\0\0\0\0\80\7fä\98º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\804Í\8aº\0\0\0\0\0\0\0\80\81üjº\0\0\0\0\0\0\0\80¬¤7º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80®¤7:\0\0\0\0\0\0\0\80\86üj:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\808Í\8a:\0\0\0\0\0\0\0\80\84ä\98:\0\0\0\0\0\0\0\80ôÑ\9d:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\88ä\98:\0\0\0\0\0\0\0\809Í\8a:\0\0\0\0\0\0\0\80\98üj:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80º¤7:\0\0\0\0\0\0\0\80P \ 2:\0\0\0\0\0\0\0\80¤\96¡9\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\90\96#9\0\0\0\0\0\0\0\80À\94^8\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80Øô\13»XéÕ¹\0\0\0\80¦ïA»F\86\rº\0\0\0\80\0\0\0\0Z\944º\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 IѸ\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Øô\13»XéÕ¹\0\0\0\80+\V»pú¦¹\0\0\0\80yRj»4®ø¹\0\0\0\80¦ïA»F\86\rº\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Ôä\ 6» ób¹\0\0\0\80¹YK»àÛ\13¹\0\0\0\80+\V»pú¦¹\0\0\0\80Øô\13»XéÕ¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80'¸õº\80\1c\89¸\0\0\0\80I8?»\0#µ·\0\0\0\80¹YK»àÛ\13¹\0\0\0\80Ôä\ 6» ób¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\805íµº\0\80ªµ\0\0\0\80j[\14»\0\0\0\0\0\0\0\80I8?»\0#µ·\0\0\0\80'¸õº\80\1c\89¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\10
+Eº\0\0\0\0\0\0\0\80TÙ¿º\0\0\0\0\0\0\0\80j[\14»\0\0\0\0\0\0\0\805íµº\0\80ªµ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80(\ 6^¹\0\0\0\0\0\0\0\80\fÂ)º\0\0\0\0\0\0\0\80TÙ¿º\0\0\0\0\0\0\0\80\10
+Eº\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 IѸ\0\0\0\0\0\0\0\80\fÂ)º\0\0\0\0\0\0\0\80(\ 6^¹\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80TÙ¿º\0\0\0\0\0\0\0\80ħ\10»\0\0\0\0\0\0\0\80h\1f_»\0\0\0\0\0\0\0\80j[\14»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\fÂ)º\0\0\0\0\0\0\0\800Ú\96º\0\0\0\0\0\0\0\80ħ\10»\0\0\0\0\0\0\0\80TÙ¿º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\93^¸\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80 IѸ\0\0\0\0\0\0\0\80À\15¬¹\0\0\0\0\0\0\0\800Ú\96º\0\0\0\0\0\0\0\80\fÂ)º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\15¬¹\0\0\0\0\0\0\0\80 IѸ\0\0\0\0\0\0\0\80+\V»pú¦¹\0\0\0\80Ð\86\91»Àqh¹\0\0\0\80à\9e\8a»dJÕ¹\0\0\0\80yRj»4®ø¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80¹YK»àÛ\13¹\0\0\0\80jä\90»À\ 6\8b¸\0\0\0\80Ð\86\91»Àqh¹\0\0\0\80+\V»pú¦¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80I8?»\0#µ·\0\0\0\80S\9b\8b»\0\0*³\0\0\0\80jä\90»À\ 6\8b¸\0\0\0\80¹YK»àÛ\13¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80j[\14»\0\0\0\0\0\0\0\80h\1f_»\0\0\0\0\0\0\0\80S\9b\8b»\0\0*³\0\0\0\80I8?»\0#µ·\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\93Õ·\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80jä\90»À\ 6\8b¸\0\0\0\80ôa½»\0©\83·\0\0\0\80ª\8f·»\80ø\ e¹\0\0\0\80Ð\86\91»Àqh¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80S\9b\8b»\0\0*³\0\0\0\80\90X´»\0\0\0\0\0\0\0\80ôa½»\0©\83·\0\0\0\80jä\90»À\ 6\8b¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80h\1f_»\0\0\0\0\0\0\0\80è|\95»\0\0\0\0\0\0\0\80\90X´»\0\0\0\0\0\0\0\80S\9b\8b»\0\0*³\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\ 5\96¸\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ħ\10»\0\0\0\0\0\0\0\80ü(G»\0\0\0\0\0\0\0\80è|\95»\0\0\0\0\0\0\0\80h\1f_»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\90}\1e¹\0\0\0\0\0\0\0\80À\ 5\96¸\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\800Ú\96º\0\0\0\0\0\0\0\80X~̺\0\0\0\0\0\0\0\80ü(G»\0\0\0\0\0\0\0\80ħ\10»\0\0\0\0\0\0\0\80À\93^¸\0\0\0\0\0\0\0\80H\96#¹\0\0\0\0\0\0\0\80\90}\1e¹\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\15¬¹\0\0\0\0\0\0\0\80èu\ eº\0\0\0\0\0\0\0\80X~̺\0\0\0\0\0\0\0\800Ú\96º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\93Õ·\0\0\0\0\0\0\0\80èu\ eº\0\0\0\0\0\0\0\80À\15¬¹\0\0\0\0\0\0\0\80Ð\86\91»Àqh¹\0\0\0\80ª\8f·»\80ø\ e¹\0\0\0\80\88®\9f»Pá³¹\0\0\0\80à\9e\8a»dJÕ¹\0\0\0\80\90}\1e¹\0\0\0\0\0\0\0\80Ì/\ 2º\0\0\0\0\0\0\0\80¸\8f º\0\0\0\0\0\0\0\80À\ 5\96¸\0\0\0\0\0\0\0\80X~̺\0\0\0\0\0\0\0\80xäúº\0\0\0\0\0\0\0\80\92ëq»\0\0\0\0\0\0\0\80ü(G»\0\0\0\0\0\0\0\80H\96#¹\0\0\0\0\0\0\0\80|\96¡¹\0\0\0\0\0\0\0\80Ì/\ 2º\0\0\0\0\0\0\0\80\90}\1e¹\0\0\0\0\0\0\0\80èu\ eº\0\0\0\0\0\0\0\80\90~&º\0\0\0\0\0\0\0\80xäúº\0\0\0\0\0\0\0\80X~̺\0\0\0\0\0\0\0\80\0\93Õ·\0\0\0\0\0\0\0\80\0÷@¸\0\0\0\0\0\0\0\80\90~&º\0\0\0\0\0\0\0\80èu\ eº\0\0\0\0\0\0\0\80ª\8f·»\80ø\ e¹\0\0\0\80\8a\1aØ» B\9e¸\0\0\0\80}²»Fý\96¹\0\0\0\80\88®\9f»Pá³¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0÷@¸\0\0\0\0\0\0\0\80\0\93Õ·\0\0\0\0\0\0\0\80ôa½»\0©\83·\0\0\0\80ØÚá»\0\0p³\0\0\0\80\8a\1aØ» B\9e¸\0\0\0\80ª\8f·»\80ø\ e¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\87\15¹\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\90X´»\0\0\0\0\0\0\0\80p{Ó»\0\0\0\0\0\0\0\80ØÚá»\0\0p³\0\0\0\80ôa½»\0©\83·\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80àëĹ\0\0\0\0\0\0\0\80À\87\15¹\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80è|\95»\0\0\0\0\0\0\0\80ïj¯»\0\0\0\0\0\0\0\80p{Ó»\0\0\0\0\0\0\0\80\90X´»\0\0\0\0\0\0\0\80À\ 5\96¸\0\0\0\0\0\0\0\80¸\8f º\0\0\0\0\0\0\0\80àëĹ\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ü(G»\0\0\0\0\0\0\0\80\92ëq»\0\0\0\0\0\0\0\80ïj¯»\0\0\0\0\0\0\0\80è|\95»\0\0\0\0\0\0\0\80ØÚá»\0\0p³\0\0\0\80Þ\91ø»\0\0\0\0\0\0\0\80\9eëï» .)¸\0\0\0\80\8a\1aØ» B\9e¸\0\0\0\80À\87\15¹\0\0\0\0\0\0\0\808Ô\87º\0\0\0\0\0\0\0\80\10í
+º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80p{Ó»\0\0\0\0\0\0\0\80Û_ä»\0\0\0\0\0\0\0\80Þ\91ø»\0\0\0\0\0\0\0\80ØÚá»\0\0p³\0\0\0\80àëĹ\0\0\0\0\0\0\0\80\ 4@²º\0\0\0\0\0\0\0\808Ô\87º\0\0\0\0\0\0\0\80À\87\15¹\0\0\0\0\0\0\0\80ïj¯»\0\0\0\0\0\0\0\80\18ôº»\0\0\0\0\0\0\0\80Û_ä»\0\0\0\0\0\0\0\80p{Ó»\0\0\0\0\0\0\0\80¸\8f º\0\0\0\0\0\0\0\80<´°º\0\0\0\0\0\0\0\80\ 4@²º\0\0\0\0\0\0\0\80àëĹ\0\0\0\0\0\0\0\80\92ëq»\0\0\0\0\0\0\0\80\1eu\84»\0\0\0\0\0\0\0\80\18ôº»\0\0\0\0\0\0\0\80ïj¯»\0\0\0\0\0\0\0\80Ì/\ 2º\0\0\0\0\0\0\0\80 è\83º\0\0\0\0\0\0\0\80<´°º\0\0\0\0\0\0\0\80¸\8f º\0\0\0\0\0\0\0\80xäúº\0\0\0\0\0\0\0\80ØA\ f»\0\0\0\0\0\0\0\80\1eu\84»\0\0\0\0\0\0\0\80\92ëq»\0\0\0\0\0\0\0\80|\96¡¹\0\0\0\0\0\0\0\80< \ 2º\0\0\0\0\0\0\0\80 è\83º\0\0\0\0\0\0\0\80Ì/\ 2º\0\0\0\0\0\0\0\80\90~&º\0\0\0\0\0\0\0\80ÐÆ,º\0\0\0\0\0\0\0\80ØA\ f»\0\0\0\0\0\0\0\80xäúº\0\0\0\0\0\0\0\80\0÷@¸\0\0\0\0\0\0\0\80\0º\ 4¹\0\0\0\0\0\0\0\80ÐÆ,º\0\0\0\0\0\0\0\80\90~&º\0\0\0\0\0\0\0\80\8a\1aØ» B\9e¸\0\0\0\80\9eëï» .)¸\0\0\0\80\9c\9e»Ò1\80¹\0\0\0\80}²»Fý\96¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\10í
+º\0\0\0\0\0\0\0\80\0º\ 4¹\0\0\0\0\0\0\0\80\0÷@¸\0\0\0\0\0\0\0\80ØA\ f»\0\0\0\0\0\0\0\80Hò>»\0\0\0\0\0\0\0\80Ì\ 3\96»\0\0\0\0\0\0\0\80\1eu\84»\0\0\0\0\0\0\0\80< \ 2º\0\0\0\0\0\0\0\80¦¤7º\0\0\0\0\0\0\0\808êÓº\0\0\0\0\0\0\0\80 è\83º\0\0\0\0\0\0\0\80ÐÆ,º\0\0\0\0\0\0\0\80 Vº\0\0\0\0\0\0\0\80Hò>»\0\0\0\0\0\0\0\80ØA\ f»\0\0\0\0\0\0\0\80\0º\ 4¹\0\0\0\0\0\0\0\80È˲º\0\0\0\0\0\0\0\80 Vº\0\0\0\0\0\0\0\80ÐÆ,º\0\0\0\0\0\0\0\80\9eëï» .)¸\0\0\0\80\88\8cÿ»àM½·\0\0\0\80n\84λT\13`¹\0\0\0\80\9c\9e»Ò1\80¹\0\0\0\80\10í
+º\0\0\0\0\0\0\0\80x\88ÿº\0\0\0\0\0\0\0\80È˲º\0\0\0\0\0\0\0\80\0º\ 4¹\0\0\0\0\0\0\0\80Þ\91ø»\0\0\0\0\0\0\0\80_1\ 3¼\0\0\0\0\0\0\0\80\88\8cÿ»àM½·\0\0\0\80\9eëï» .)¸\0\0\0\808Ô\87º\0\0\0\0\0\0\0\80ü2*»\0\0\0\0\0\0\0\80x\88ÿº\0\0\0\0\0\0\0\80\10í
+º\0\0\0\0\0\0\0\80Û_ä»\0\0\0\0\0\0\0\80\81
+ð»\0\0\0\0\0\0\0\80_1\ 3¼\0\0\0\0\0\0\0\80Þ\91ø»\0\0\0\0\0\0\0\80\ 4@²º\0\0\0\0\0\0\0\80Þ58»\0\0\0\0\0\0\0\80ü2*»\0\0\0\0\0\0\0\808Ô\87º\0\0\0\0\0\0\0\80\18ôº»\0\0\0\0\0\0\0\80Z\16È»\0\0\0\0\0\0\0\80\81
+ð»\0\0\0\0\0\0\0\80Û_ä»\0\0\0\0\0\0\0\80<´°º\0\0\0\0\0\0\0\80.`\1f»\0\0\0\0\0\0\0\80Þ58»\0\0\0\0\0\0\0\80\ 4@²º\0\0\0\0\0\0\0\80\1eu\84»\0\0\0\0\0\0\0\80Ì\ 3\96»\0\0\0\0\0\0\0\80Z\16È»\0\0\0\0\0\0\0\80\18ôº»\0\0\0\0\0\0\0\80 è\83º\0\0\0\0\0\0\0\808êÓº\0\0\0\0\0\0\0\80.`\1f»\0\0\0\0\0\0\0\80<´°º\0\0\0\0\0\0\0\80ü2*»\0\0\0\0\0\0\0\80\16-\95»\0\0\0\0\0\0\0\80ÞÛ\84»\0\0\0\0\0\0\0\80x\88ÿº\0\0\0\0\0\0\0\80\81
+ð»\0\0\0\0\0\0\0\80°Çú»\0\0\0\0\0\0\0\80êý\a¼\0\0\0\0\0\0\0\80_1\ 3¼\0\0\0\0\0\0\0\80Þ58»\0\0\0\0\0\0\0\80\1a]\93»\0\0\0\0\0\0\0\80\16-\95»\0\0\0\0\0\0\0\80ü2*»\0\0\0\0\0\0\0\80Z\16È»\0\0\0\0\0\0\0\80\ 6<Ø»\0\0\0\0\0\0\0\80°Çú»\0\0\0\0\0\0\0\80\81
+ð»\0\0\0\0\0\0\0\80.`\1f»\0\0\0\0\0\0\0\80¼¶l»\0\0\0\0\0\0\0\80\1a]\93»\0\0\0\0\0\0\0\80Þ58»\0\0\0\0\0\0\0\80Ì\ 3\96»\0\0\0\0\0\0\0\804+®»\0\0\0\0\0\0\0\80\ 6<Ø»\0\0\0\0\0\0\0\80Z\16È»\0\0\0\0\0\0\0\808êÓº\0\0\0\0\0\0\0\80?ê\12»\0\0\0\0\0\0\0\80¼¶l»\0\0\0\0\0\0\0\80.`\1f»\0\0\0\0\0\0\0\80Hò>»\0\0\0\0\0\0\0\80bx\82»\0\0\0\0\0\0\0\804+®»\0\0\0\0\0\0\0\80Ì\ 3\96»\0\0\0\0\0\0\0\80¦¤7º\0\0\0\0\0\0\0\80\82üjº\0\0\0\0\0\0\0\80?ê\12»\0\0\0\0\0\0\0\808êÓº\0\0\0\0\0\0\0\80 Vº\0\0\0\0\0\0\0\808N[»\0\0\0\0\0\0\0\80bx\82»\0\0\0\0\0\0\0\80Hò>»\0\0\0\0\0\0\0\80È˲º\0\0\0\0\0\0\0\80¼\8ah»\0\0\0\0\0\0\0\808N[»\0\0\0\0\0\0\0\80 Vº\0\0\0\0\0\0\0\80\88\8cÿ»àM½·\0\0\0\80ì\10\ 5¼¬©Z·\0\0\0\80Ï-Ö»)®L¹\0\0\0\80n\84λT\13`¹\0\0\0\80x\88ÿº\0\0\0\0\0\0\0\80ÞÛ\84»\0\0\0\0\0\0\0\80¼\8ah»\0\0\0\0\0\0\0\80È˲º\0\0\0\0\0\0\0\80_1\ 3¼\0\0\0\0\0\0\0\80êý\a¼\0\0\0\0\0\0\0\80ì\10\ 5¼¬©Z·\0\0\0\80\88\8cÿ»àM½·\0\0\0\80\82üjº\0\0\0\0\0\0\0\80/Í\8aº\0\0\0\0\0\0\0\80Ù|6»\0\0\0\0\0\0\0\80?ê\12»\0\0\0\0\0\0\0\808N[»\0\0\0\0\0\0\0\80²ù°»\0\0\0\0\0\0\0\80ªÞ®»\0\0\0\0\0\0\0\80bx\82»\0\0\0\0\0\0\0\80¼\8ah»\0\0\0\0\0\0\0\80¸n·»\0\0\0\0\0\0\0\80²ù°»\0\0\0\0\0\0\0\808N[»\0\0\0\0\0\0\0\80ì\10\ 5¼¬©Z·\0\0\0\80ã>\b¼@}
+·\0\0\0\80LóÙ»ô«D¹\0\0\0\80Ï-Ö»)®L¹\0\0\0\80ÞÛ\84»\0\0\0\0\0\0\0\80HçÅ»\0\0\0\0\0\0\0\80¸n·»\0\0\0\0\0\0\0\80¼\8ah»\0\0\0\0\0\0\0\80êý\a¼\0\0\0\0\0\0\0\80ïS\v¼\0\0\0\0\0\0\0\80ã>\b¼@}
+·\0\0\0\80ì\10\ 5¼¬©Z·\0\0\0\80\16-\95»\0\0\0\0\0\0\0\80úlÕ»\0\0\0\0\0\0\0\80HçÅ»\0\0\0\0\0\0\0\80ÞÛ\84»\0\0\0\0\0\0\0\80°Çú»\0\0\0\0\0\0\0\80Ø*\ 2¼\0\0\0\0\0\0\0\80ïS\v¼\0\0\0\0\0\0\0\80êý\a¼\0\0\0\0\0\0\0\80\1a]\93»\0\0\0\0\0\0\0\80rjÈ»\0\0\0\0\0\0\0\80úlÕ»\0\0\0\0\0\0\0\80\16-\95»\0\0\0\0\0\0\0\80\ 6<Ø»\0\0\0\0\0\0\0\80\ 6éç»\0\0\0\0\0\0\0\80Ø*\ 2¼\0\0\0\0\0\0\0\80°Çú»\0\0\0\0\0\0\0\80¼¶l»\0\0\0\0\0\0\0\80Ö\92\99»\0\0\0\0\0\0\0\80rjÈ»\0\0\0\0\0\0\0\80\1a]\93»\0\0\0\0\0\0\0\804+®»\0\0\0\0\0\0\0\80\90\9aÆ»\0\0\0\0\0\0\0\80\ 6éç»\0\0\0\0\0\0\0\80\ 6<Ø»\0\0\0\0\0\0\0\80?ê\12»\0\0\0\0\0\0\0\80Ù|6»\0\0\0\0\0\0\0\80Ö\92\99»\0\0\0\0\0\0\0\80¼¶l»\0\0\0\0\0\0\0\80bx\82»\0\0\0\0\0\0\0\80ªÞ®»\0\0\0\0\0\0\0\80\90\9aÆ»\0\0\0\0\0\0\0\804+®»\0\0\0\0\0\0\0\80Ø*\ 2¼\0\0\0\0\0\0\0\80\ 3\95\ 6¼\0\0\0\0\0\0\0\80ä÷\r¼\0\0\0\0\0\0\0\80ïS\v¼\0\0\0\0\0\0\0\80rjÈ»\0\0\0\0\0\0\0\80:âï»\0\0\0\0\0\0\0\80h\96\ 3¼\0\0\0\0\0\0\0\80úlÕ»\0\0\0\0\0\0\0\80\ 6éç»\0\0\0\0\0\0\0\80úÍõ»\0\0\0\0\0\0\0\80\ 3\95\ 6¼\0\0\0\0\0\0\0\80Ø*\ 2¼\0\0\0\0\0\0\0\80Ö\92\99»\0\0\0\0\0\0\0\80!w²»\0\0\0\0\0\0\0\80:âï»\0\0\0\0\0\0\0\80rjÈ»\0\0\0\0\0\0\0\80\90\9aÆ»\0\0\0\0\0\0\0\80\90\9aÛ»\0\0\0\0\0\0\0\80úÍõ»\0\0\0\0\0\0\0\80\ 6éç»\0\0\0\0\0\0\0\80Ù|6»\0\0\0\0\0\0\0\80\16ºN»\0\0\0\0\0\0\0\80!w²»\0\0\0\0\0\0\0\80Ö\92\99»\0\0\0\0\0\0\0\80ªÞ®»\0\0\0\0\0\0\0\80D\ 3Ú»\0\0\0\0\0\0\0\80\90\9aÛ»\0\0\0\0\0\0\0\80\90\9aÆ»\0\0\0\0\0\0\0\80/Í\8aº\0\0\0\0\0\0\0\80\7fä\98º\0\0\0\0\0\0\0\80\16ºN»\0\0\0\0\0\0\0\80Ù|6»\0\0\0\0\0\0\0\80²ù°»\0\0\0\0\0\0\0\80Hùè»\0\0\0\0\0\0\0\80D\ 3Ú»\0\0\0\0\0\0\0\80ªÞ®»\0\0\0\0\0\0\0\80¸n·»\0\0\0\0\0\0\0\80\84?è»\0\0\0\0\0\0\0\80Hùè»\0\0\0\0\0\0\0\80²ù°»\0\0\0\0\0\0\0\80ã>\b¼@}
+·\0\0\0\806\9b ¼\0&ܶ\0\0\0\80w'Ú»\f%G¹\0\0\0\80LóÙ»ô«D¹\0\0\0\80HçÅ»\0\0\0\0\0\0\0\80juö»\0\0\0\0\0\0\0\80\84?è»\0\0\0\0\0\0\0\80¸n·»\0\0\0\0\0\0\0\80ïS\v¼\0\0\0\0\0\0\0\80ä÷\r¼\0\0\0\0\0\0\0\806\9b ¼\0&ܶ\0\0\0\80ã>\b¼@}
+·\0\0\0\80úlÕ»\0\0\0\0\0\0\0\80h\96\ 3¼\0\0\0\0\0\0\0\80juö»\0\0\0\0\0\0\0\80HçÅ»\0\0\0\0\0\0\0\80Hùè»\0\0\0\0\0\0\0\80\ 2.\ 4¼\0\0\0\0\0\0\0\80Pûò»\0\0\0\0\0\0\0\80D\ 3Ú»\0\0\0\0\0\0\0\80\84?è»\0\0\0\0\0\0\0\80î\97\ 3¼\0\0\0\0\0\0\0\80\ 2.\ 4¼\0\0\0\0\0\0\0\80Hùè»\0\0\0\0\0\0\0\806\9b ¼\0&ܶ\0\0\0\80\98ÿ\b¼\0\92\ 6·\0\0\0\80\1a\80Ö»8+U¹\0\0\0\80w'Ú»\f%G¹\0\0\0\80juö»\0\0\0\0\0\0\0\80O\v\b¼\0\0\0\0\0\0\0\80î\97\ 3¼\0\0\0\0\0\0\0\80\84?è»\0\0\0\0\0\0\0\80ä÷\r¼\0\0\0\0\0\0\0\80\91Þ\ f¼\0\0\0\0\0\0\0\80\98ÿ\b¼\0\92\ 6·\0\0\0\806\9b ¼\0&ܶ\0\0\0\80h\96\ 3¼\0\0\0\0\0\0\0\80ø-\ e¼\0\0\0\0\0\0\0\80O\v\b¼\0\0\0\0\0\0\0\80juö»\0\0\0\0\0\0\0\80\ 3\95\ 6¼\0\0\0\0\0\0\0\80\10{
+¼\0\0\0\0\0\0\0\80\91Þ\ f¼\0\0\0\0\0\0\0\80ä÷\r¼\0\0\0\0\0\0\0\80:âï»\0\0\0\0\0\0\0\80iÑþ»\0\0\0\0\0\0\0\80ø-\ e¼\0\0\0\0\0\0\0\80h\96\ 3¼\0\0\0\0\0\0\0\80úÍõ»\0\0\0\0\0\0\0\80°`\0¼\0\0\0\0\0\0\0\80\10{
+¼\0\0\0\0\0\0\0\80\ 3\95\ 6¼\0\0\0\0\0\0\0\80!w²»\0\0\0\0\0\0\0\80z~»»\0\0\0\0\0\0\0\80iÑþ»\0\0\0\0\0\0\0\80:âï»\0\0\0\0\0\0\0\80\90\9aÛ»\0\0\0\0\0\0\0\80¶ìé»\0\0\0\0\0\0\0\80°`\0¼\0\0\0\0\0\0\0\80úÍõ»\0\0\0\0\0\0\0\80\16ºN»\0\0\0\0\0\0\0\80*UW»\0\0\0\0\0\0\0\80z~»»\0\0\0\0\0\0\0\80!w²»\0\0\0\0\0\0\0\80D\ 3Ú»\0\0\0\0\0\0\0\80Pûò»\0\0\0\0\0\0\0\80¶ìé»\0\0\0\0\0\0\0\80\90\9aÛ»\0\0\0\0\0\0\0\80\7fä\98º\0\0\0\0\0\0\0\80íÑ\9dº\0\0\0\0\0\0\0\80*UW»\0\0\0\0\0\0\0\80\16ºN»\0\0\0\0\0\0\0\80iÑþ»\0\0\0\0\0\0\0\80§ßñ»\0\0\0\0\0\0\0\80\18\9a\b¼\0\0\0\0\0\0\0\80ø-\ e¼\0\0\0\0\0\0\0\80°`\0¼\0\0\0\0\0\0\0\80æè\ 1¼\0\0\0\0\0\0\0\80Z-\f¼\0\0\0\0\0\0\0\80\10{
+¼\0\0\0\0\0\0\0\80z~»»\0\0\0\0\0\0\0\80"w²»\0\0\0\0\0\0\0\80§ßñ»\0\0\0\0\0\0\0\80iÑþ»\0\0\0\0\0\0\0\80¶ìé»\0\0\0\0\0\0\0\80¨¡ã»\0\0\0\0\0\0\0\80æè\ 1¼\0\0\0\0\0\0\0\80°`\0¼\0\0\0\0\0\0\0\80*UW»\0\0\0\0\0\0\0\80\17ºN»\0\0\0\0\0\0\0\80"w²»\0\0\0\0\0\0\0\80z~»»\0\0\0\0\0\0\0\80Pûò»\0\0\0\0\0\0\0\80\aÐâ»\0\0\0\0\0\0\0\80¨¡ã»\0\0\0\0\0\0\0\80¶ìé»\0\0\0\0\0\0\0\80íÑ\9dº\0\0\0\0\0\0\0\80\7fä\98º\0\0\0\0\0\0\0\80\17ºN»\0\0\0\0\0\0\0\80*UW»\0\0\0\0\0\0\0\80\ 2.\ 4¼\0\0\0\0\0\0\0\80\86Ñ\0¼\0\0\0\0\0\0\0\80\aÐâ»\0\0\0\0\0\0\0\80Pûò»\0\0\0\0\0\0\0\80î\97\ 3¼\0\0\0\0\0\0\0\80Êí\a¼\0\0\0\0\0\0\0\80\86Ñ\0¼\0\0\0\0\0\0\0\80\ 2.\ 4¼\0\0\0\0\0\0\0\80\98ÿ\b¼\0\92\ 6·\0\0\0\80\7f\96\ 5¼\0¼\82·\0\0\0\80âÇλð+p¹\0\0\0\80\1a\80Ö»8+U¹\0\0\0\80O\v\b¼\0\0\0\0\0\0\0\80ö\e ¼\0\0\0\0\0\0\0\80Êí\a¼\0\0\0\0\0\0\0\80î\97\ 3¼\0\0\0\0\0\0\0\80\91Þ\ f¼\0\0\0\0\0\0\0\80k¯\ f¼\0\0\0\0\0\0\0\80\7f\96\ 5¼\0¼\82·\0\0\0\80\98ÿ\b¼\0\92\ 6·\0\0\0\80ø-\ e¼\0\0\0\0\0\0\0\80\18\9a\b¼\0\0\0\0\0\0\0\80ö\e ¼\0\0\0\0\0\0\0\80O\v\b¼\0\0\0\0\0\0\0\80\10{
+¼\0\0\0\0\0\0\0\80Z-\f¼\0\0\0\0\0\0\0\80k¯\ f¼\0\0\0\0\0\0\0\80\91Þ\ f¼\0\0\0\0\0\0\0\80Êí\a¼\0\0\0\0\0\0\0\80}2é»\0\0\0\0\0\0\0\80\ 4YÁ»\0\0\0\0\0\0\0\80\86Ñ\0¼\0\0\0\0\0\0\0\80\7f\96\ 5¼\0¼\82·\0\0\0\80\80Ðû»\80ý\1e¸\0\0\0\80¤\ 6ûL®\8c¹\0\0\0\80âÇλð+p¹\0\0\0\80ö\e ¼\0\0\0\0\0\0\0\80<Võ»\0\0\0\0\0\0\0\80}2é»\0\0\0\0\0\0\0\80Êí\a¼\0\0\0\0\0\0\0\80k¯\ f¼\0\0\0\0\0\0\0\80©^
+¼\0\0\0\0\0\0\0\80\80Ðû»\80ý\1e¸\0\0\0\80\7f\96\ 5¼\0¼\82·\0\0\0\80\18\9a\b¼\0\0\0\0\0\0\0\80øIí»\0\0\0\0\0\0\0\80<Võ»\0\0\0\0\0\0\0\80ö\e ¼\0\0\0\0\0\0\0\80Z-\f¼\0\0\0\0\0\0\0\80\7fº\a¼\0\0\0\0\0\0\0\80©^
+¼\0\0\0\0\0\0\0\80k¯\ f¼\0\0\0\0\0\0\0\80§ßñ»\0\0\0\0\0\0\0\80\ 2bÍ»\0\0\0\0\0\0\0\80øIí»\0\0\0\0\0\0\0\80\18\9a\b¼\0\0\0\0\0\0\0\80æè\ 1¼\0\0\0\0\0\0\0\80`\1cò»\0\0\0\0\0\0\0\80\7fº\a¼\0\0\0\0\0\0\0\80Z-\f¼\0\0\0\0\0\0\0\80"w²»\0\0\0\0\0\0\0\80Ñ\92\99»\0\0\0\0\0\0\0\80\ 2bÍ»\0\0\0\0\0\0\0\80§ßñ»\0\0\0\0\0\0\0\80¨¡ã»\0\0\0\0\0\0\0\80ºß¿»\0\0\0\0\0\0\0\80`\1cò»\0\0\0\0\0\0\0\80æè\ 1¼\0\0\0\0\0\0\0\80\17ºN»\0\0\0\0\0\0\0\80Ú|6»\0\0\0\0\0\0\0\80Ñ\92\99»\0\0\0\0\0\0\0\80"w²»\0\0\0\0\0\0\0\80\aÐâ»\0\0\0\0\0\0\0\80/Q¨»\0\0\0\0\0\0\0\80ºß¿»\0\0\0\0\0\0\0\80¨¡ã»\0\0\0\0\0\0\0\80\7fä\98º\0\0\0\0\0\0\0\804Í\8aº\0\0\0\0\0\0\0\80Ú|6»\0\0\0\0\0\0\0\80\17ºN»\0\0\0\0\0\0\0\80\86Ñ\0¼\0\0\0\0\0\0\0\80\ 4YÁ»\0\0\0\0\0\0\0\80/Q¨»\0\0\0\0\0\0\0\80\aÐâ»\0\0\0\0\0\0\0\80Ñ\92\99»\0\0\0\0\0\0\0\80½¶l»\0\0\0\0\0\0\0\80}'\95»\0\0\0\0\0\0\0\80\ 2bÍ»\0\0\0\0\0\0\0\80ºß¿»\0\0\0\0\0\0\0\80e1\87»\0\0\0\0\0\0\0\80*\9aû\0\0\0\0\0\0\0\80`\1cò»\0\0\0\0\0\0\0\80Ú|6»\0\0\0\0\0\0\0\80<ê\12»\0\0\0\0\0\0\0\80½¶l»\0\0\0\0\0\0\0\80Ñ\92\99»\0\0\0\0\0\0\0\80/Q¨»\0\0\0\0\0\0\0\80\89\7f.»\0\0\0\0\0\0\0\80e1\87»\0\0\0\0\0\0\0\80ºß¿»\0\0\0\0\0\0\0\804Í\8aº\0\0\0\0\0\0\0\80\81üjº\0\0\0\0\0\0\0\80<ê\12»\0\0\0\0\0\0\0\80Ú|6»\0\0\0\0\0\0\0\80\ 4YÁ»\0\0\0\0\0\0\0\80\86$4»\0\0\0\0\0\0\0\80\89\7f.»\0\0\0\0\0\0\0\80/Q¨»\0\0\0\0\0\0\0\80}2é»\0\0\0\0\0\0\0\80®¨\86»\0\0\0\0\0\0\0\80\86$4»\0\0\0\0\0\0\0\80\ 4YÁ»\0\0\0\0\0\0\0\80\80Ðû»\80ý\1e¸\0\0\0\805"á»\80}¼¸\0\0\0\80,ʳ»|E¨¹\0\0\0\80¤\ 6ûL®\8c¹\0\0\0\80<Võ»\0\0\0\0\0\0\0\80µÎ£»\0\0\0\0\0\0\0\80®¨\86»\0\0\0\0\0\0\0\80}2é»\0\0\0\0\0\0\0\80©^
+¼\0\0\0\0\0\0\0\80\ 3\ e÷»\0\0\0\0\0\0\0\805"á»\80}¼¸\0\0\0\80\80Ðû»\80ý\1e¸\0\0\0\80øIí»\0\0\0\0\0\0\0\80\1aQ§»\0\0\0\0\0\0\0\80µÎ£»\0\0\0\0\0\0\0\80<Võ»\0\0\0\0\0\0\0\80\7fº\a¼\0\0\0\0\0\0\0\80þ\1dî»\0\0\0\0\0\0\0\80\ 3\ e÷»\0\0\0\0\0\0\0\80©^
+¼\0\0\0\0\0\0\0\80\ 2bÍ»\0\0\0\0\0\0\0\80}'\95»\0\0\0\0\0\0\0\80\1aQ§»\0\0\0\0\0\0\0\80øIí»\0\0\0\0\0\0\0\80`\1cò»\0\0\0\0\0\0\0\80*\9aû\0\0\0\0\0\0\0\80þ\1dî»\0\0\0\0\0\0\0\80\7fº\a¼\0\0\0\0\0\0\0\805"á»\80}¼¸\0\0\0\80`×»»ð6?¹\0\0\0\80Om¢»\10]ɹ\0\0\0\80,ʳ»|E¨¹\0\0\0\80µÎ£»\0\0\0\0\0\0\0\80Òº\ 3»\0\0\0\0\0\0\0\80ûO\95º\0\0\0\0\0\0\0\80®¨\86»\0\0\0\0\0\0\0\80\ 3\ e÷»\0\0\0\0\0\0\0\80¼òû\80\9f-¸\0\0\0\80`×»»ð6?¹\0\0\0\805"á»\80}¼¸\0\0\0\80\1aQ§»\0\0\0\0\0\0\0\80T?+»\0\0\0\0\0\0\0\80Òº\ 3»\0\0\0\0\0\0\0\80µÎ£»\0\0\0\0\0\0\0\80þ\1dî»\0\0\0\0\0\0\0\80Dð±»\0\0\0\0\0\0\0\80¼òû\80\9f-¸\0\0\0\80\ 3\ e÷»\0\0\0\0\0\0\0\80}'\95»\0\0\0\0\0\0\0\80â58»\0\0\0\0\0\0\0\80T?+»\0\0\0\0\0\0\0\80\1aQ§»\0\0\0\0\0\0\0\80*\9aû\0\0\0\0\0\0\0\805L\83»\0\0\0\0\0\0\0\80Dð±»\0\0\0\0\0\0\0\80þ\1dî»\0\0\0\0\0\0\0\80½¶l»\0\0\0\0\0\0\0\80,`\1f»\0\0\0\0\0\0\0\80â58»\0\0\0\0\0\0\0\80}'\95»\0\0\0\0\0\0\0\80e1\87»\0\0\0\0\0\0\0\80®>\16»\0\0\0\0\0\0\0\805L\83»\0\0\0\0\0\0\0\80*\9aû\0\0\0\0\0\0\0\80<ê\12»\0\0\0\0\0\0\0\80:êÓº\0\0\0\0\0\0\0\80,`\1f»\0\0\0\0\0\0\0\80½¶l»\0\0\0\0\0\0\0\80\89\7f.»\0\0\0\0\0\0\0\802\11Uº\0\0\0\0\0\0\0\80®>\16»\0\0\0\0\0\0\0\80e1\87»\0\0\0\0\0\0\0\80\81üjº\0\0\0\0\0\0\0\80¬¤7º\0\0\0\0\0\0\0\80:êÓº\0\0\0\0\0\0\0\80<ê\12»\0\0\0\0\0\0\0\80\86$4»\0\0\0\0\0\0\0\80\b\r͹\0\0\0\0\0\0\0\802\11Uº\0\0\0\0\0\0\0\80\89\7f.»\0\0\0\0\0\0\0\80®¨\86»\0\0\0\0\0\0\0\80ûO\95º\0\0\0\0\0\0\0\80\b\r͹\0\0\0\0\0\0\0\80\86$4»\0\0\0\0\0\0\0\80®>\16»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\805L\83»\0\0\0\0\0\0\0\80:êÓº\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80,`\1f»\0\0\0\0\0\0\0\802\11Uº\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80®>\16»\0\0\0\0\0\0\0\80¬¤7º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80:êÓº\0\0\0\0\0\0\0\80\b\r͹\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\802\11Uº\0\0\0\0\0\0\0\80ûO\95º\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\b\r͹\0\0\0\0\0\0\0\80`×»»ð6?¹\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80\0\0\0\0d\944º\0\0\0\80Om¢»\10]ɹ\0\0\0\80Òº\ 3»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ûO\95º\0\0\0\0\0\0\0\80¼òû\80\9f-¸\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80`×»»ð6?¹\0\0\0\80T?+»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Òº\ 3»\0\0\0\0\0\0\0\80Dð±»\0\0\0\0\0\0\0\80\0\0\0\0\0±ß¸\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80¼òû\80\9f-¸\0\0\0\80â58»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80T?+»\0\0\0\0\0\0\0\805L\83»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0±ß¸\0\0\0\80Dð±»\0\0\0\0\0\0\0\80,`\1f»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80â58»\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Öº\ 3;\0\0\0\0\0\0\0\80ïO\95:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80¾òÃ;\80\9f-¸\0\0\0\80b×»;\107?¹\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80L?+;\0\0\0\0\0\0\0\80Öº\ 3;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0±ß¸\0\0\0\80Bð±;\0\0\0\0\0\0\0\80¾òÃ;\80\9f-¸\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ß58;\0\0\0\0\0\0\0\80L?+;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\802L\83;\0\0\0\0\0\0\0\80Bð±;\0\0\0\0\0\0\0\80\0\0\0\0\0±ß¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80+`\1f;\0\0\0\0\0\0\0\80ß58;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80´>\16;\0\0\0\0\0\0\0\802L\83;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80>êÓ:\0\0\0\0\0\0\0\80+`\1f;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\1a\11U:\0\0\0\0\0\0\0\80´>\16;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80®¤7:\0\0\0\0\0\0\0\80>êÓ:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Ä\fÍ9\0\0\0\0\0\0\0\80\1a\11U:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ïO\95:\0\0\0\0\0\0\0\80Ä\fÍ9\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80b×»;\107?¹\0\0\0\80Om¢;\1c]ɹ\0\0\0\80\0\0\0\0d\944º\0\0\0\80>êÓ:\0\0\0\0\0\0\0\80=ê\12;\0\0\0\0\0\0\0\80½¶l;\0\0\0\0\0\0\0\80+`\1f;\0\0\0\0\0\0\0\80\1a\11U:\0\0\0\0\0\0\0\80\84\7f.;\0\0\0\0\0\0\0\80h1\87;\0\0\0\0\0\0\0\80´>\16;\0\0\0\0\0\0\0\80®¤7:\0\0\0\0\0\0\0\80\86üj:\0\0\0\0\0\0\0\80=ê\12;\0\0\0\0\0\0\0\80>êÓ:\0\0\0\0\0\0\0\80Ä\fÍ9\0\0\0\0\0\0\0\80~$4;\0\0\0\0\0\0\0\80\84\7f.;\0\0\0\0\0\0\0\80\1a\11U:\0\0\0\0\0\0\0\80ïO\95:\0\0\0\0\0\0\0\80¬¨\86;\0\0\0\0\0\0\0\80~$4;\0\0\0\0\0\0\0\80Ä\fÍ9\0\0\0\0\0\0\0\80b×»;\107?¹\0\0\0\807"á;\0~¼¸\0\0\0\80-ʳ;\8cE¨¹\0\0\0\80Om¢;\1c]ɹ\0\0\0\80Öº\ 3;\0\0\0\0\0\0\0\80¸Î£;\0\0\0\0\0\0\0\80¬¨\86;\0\0\0\0\0\0\0\80ïO\95:\0\0\0\0\0\0\0\80¾òÃ;\80\9f-¸\0\0\0\80\ 2\ e÷;\0\0\0\0\0\0\0\807"á;\0~¼¸\0\0\0\80b×»;\107?¹\0\0\0\80L?+;\0\0\0\0\0\0\0\80\16Q§;\0\0\0\0\0\0\0\80¸Î£;\0\0\0\0\0\0\0\80Öº\ 3;\0\0\0\0\0\0\0\80Bð±;\0\0\0\0\0\0\0\80ý\1dî;\0\0\0\0\0\0\0\80\ 2\ e÷;\0\0\0\0\0\0\0\80¾òÃ;\80\9f-¸\0\0\0\80ß58;\0\0\0\0\0\0\0\80|'\95;\0\0\0\0\0\0\0\80\16Q§;\0\0\0\0\0\0\0\80L?+;\0\0\0\0\0\0\0\802L\83;\0\0\0\0\0\0\0\80(\9aÃ;\0\0\0\0\0\0\0\80ý\1dî;\0\0\0\0\0\0\0\80Bð±;\0\0\0\0\0\0\0\80+`\1f;\0\0\0\0\0\0\0\80½¶l;\0\0\0\0\0\0\0\80|'\95;\0\0\0\0\0\0\0\80ß58;\0\0\0\0\0\0\0\80´>\16;\0\0\0\0\0\0\0\80h1\87;\0\0\0\0\0\0\0\80(\9aÃ;\0\0\0\0\0\0\0\802L\83;\0\0\0\0\0\0\0\80\ 2\ e÷;\0\0\0\0\0\0\0\80ª^
+<\0\0\0\0\0\0\0\80\82Ðû;Àþ\1e¸\0\0\0\807"á;\0~¼¸\0\0\0\80\16Q§;\0\0\0\0\0\0\0\80ùIí;\0\0\0\0\0\0\0\80@Võ;\0\0\0\0\0\0\0\80¸Î£;\0\0\0\0\0\0\0\80ý\1dî;\0\0\0\0\0\0\0\80\80º\a<\0\0\0\0\0\0\0\80ª^
+<\0\0\0\0\0\0\0\80\ 2\ e÷;\0\0\0\0\0\0\0\80|'\95;\0\0\0\0\0\0\0\80\ 3bÍ;\0\0\0\0\0\0\0\80ùIí;\0\0\0\0\0\0\0\80\16Q§;\0\0\0\0\0\0\0\80(\9aÃ;\0\0\0\0\0\0\0\80a\1cò;\0\0\0\0\0\0\0\80\80º\a<\0\0\0\0\0\0\0\80ý\1dî;\0\0\0\0\0\0\0\80½¶l;\0\0\0\0\0\0\0\80Ò\92\99;\0\0\0\0\0\0\0\80\ 3bÍ;\0\0\0\0\0\0\0\80|'\95;\0\0\0\0\0\0\0\80h1\87;\0\0\0\0\0\0\0\80¾ß¿;\0\0\0\0\0\0\0\80a\1cò;\0\0\0\0\0\0\0\80(\9aÃ;\0\0\0\0\0\0\0\80=ê\12;\0\0\0\0\0\0\0\80Ý|6;\0\0\0\0\0\0\0\80Ò\92\99;\0\0\0\0\0\0\0\80½¶l;\0\0\0\0\0\0\0\80\84\7f.;\0\0\0\0\0\0\0\80.Q¨;\0\0\0\0\0\0\0\80¾ß¿;\0\0\0\0\0\0\0\80h1\87;\0\0\0\0\0\0\0\80\86üj:\0\0\0\0\0\0\0\808Í\8a:\0\0\0\0\0\0\0\80Ý|6;\0\0\0\0\0\0\0\80=ê\12;\0\0\0\0\0\0\0\80~$4;\0\0\0\0\0\0\0\80\ 2YÁ;\0\0\0\0\0\0\0\80.Q¨;\0\0\0\0\0\0\0\80\84\7f.;\0\0\0\0\0\0\0\80¬¨\86;\0\0\0\0\0\0\0\80|2é;\0\0\0\0\0\0\0\80\ 2YÁ;\0\0\0\0\0\0\0\80~$4;\0\0\0\0\0\0\0\807"á;\0~¼¸\0\0\0\80\82Ðû;Àþ\1e¸\0\0\0\80¤\ 6Ã;`®\8c¹\0\0\0\80-ʳ;\8cE¨¹\0\0\0\80¸Î£;\0\0\0\0\0\0\0\80@Võ;\0\0\0\0\0\0\0\80|2é;\0\0\0\0\0\0\0\80¬¨\86;\0\0\0\0\0\0\0\80.Q¨;\0\0\0\0\0\0\0\80 Ðâ;\0\0\0\0\0\0\0\80¡ã;\0\0\0\0\0\0\0\80¾ß¿;\0\0\0\0\0\0\0\808Í\8a:\0\0\0\0\0\0\0\80\84ä\98:\0\0\0\0\0\0\0\80\eºN;\0\0\0\0\0\0\0\80Ý|6;\0\0\0\0\0\0\0\80\ 2YÁ;\0\0\0\0\0\0\0\80\85Ñ\0<\0\0\0\0\0\0\0\80 Ðâ;\0\0\0\0\0\0\0\80.Q¨;\0\0\0\0\0\0\0\80|2é;\0\0\0\0\0\0\0\80Êí\a<\0\0\0\0\0\0\0\80\85Ñ\0<\0\0\0\0\0\0\0\80\ 2YÁ;\0\0\0\0\0\0\0\80\82Ðû;Àþ\1e¸\0\0\0\80\80\96\ 5<\80¿\82·\0\0\0\80æÇÎ; ,p¹\0\0\0\80¤\ 6Ã;`®\8c¹\0\0\0\80@Võ;\0\0\0\0\0\0\0\80ø\e <\0\0\0\0\0\0\0\80Êí\a<\0\0\0\0\0\0\0\80|2é;\0\0\0\0\0\0\0\80ª^
+<\0\0\0\0\0\0\0\80l¯\ f<\0\0\0\0\0\0\0\80\80\96\ 5<\80¿\82·\0\0\0\80\82Ðû;Àþ\1e¸\0\0\0\80ùIí;\0\0\0\0\0\0\0\80\18\9a\b<\0\0\0\0\0\0\0\80ø\e <\0\0\0\0\0\0\0\80@Võ;\0\0\0\0\0\0\0\80\80º\a<\0\0\0\0\0\0\0\80[-\f<\0\0\0\0\0\0\0\80l¯\ f<\0\0\0\0\0\0\0\80ª^
+<\0\0\0\0\0\0\0\80\ 3bÍ;\0\0\0\0\0\0\0\80¨ßñ;\0\0\0\0\0\0\0\80\18\9a\b<\0\0\0\0\0\0\0\80ùIí;\0\0\0\0\0\0\0\80a\1cò;\0\0\0\0\0\0\0\80æè\ 1<\0\0\0\0\0\0\0\80[-\f<\0\0\0\0\0\0\0\80\80º\a<\0\0\0\0\0\0\0\80Ò\92\99;\0\0\0\0\0\0\0\80$w²;\0\0\0\0\0\0\0\80¨ßñ;\0\0\0\0\0\0\0\80\ 3bÍ;\0\0\0\0\0\0\0\80¾ß¿;\0\0\0\0\0\0\0\80¡ã;\0\0\0\0\0\0\0\80æè\ 1<\0\0\0\0\0\0\0\80a\1cò;\0\0\0\0\0\0\0\80Ý|6;\0\0\0\0\0\0\0\80\eºN;\0\0\0\0\0\0\0\80$w²;\0\0\0\0\0\0\0\80Ò\92\99;\0\0\0\0\0\0\0\80\18\9a\b<\0\0\0\0\0\0\0\80û-\ e<\0\0\0\0\0\0\0\80Q\v\b<\0\0\0\0\0\0\0\80ø\e <\0\0\0\0\0\0\0\80[-\f<\0\0\0\0\0\0\0\80\12{
+<\0\0\0\0\0\0\0\80\92Þ\ f<\0\0\0\0\0\0\0\80l¯\ f<\0\0\0\0\0\0\0\80¨ßñ;\0\0\0\0\0\0\0\80mÑþ;\0\0\0\0\0\0\0\80û-\ e<\0\0\0\0\0\0\0\80\18\9a\b<\0\0\0\0\0\0\0\80æè\ 1<\0\0\0\0\0\0\0\80²`\0<\0\0\0\0\0\0\0\80\12{
+<\0\0\0\0\0\0\0\80[-\f<\0\0\0\0\0\0\0\80$w²;\0\0\0\0\0\0\0\80}~»;\0\0\0\0\0\0\0\80mÑþ;\0\0\0\0\0\0\0\80¨ßñ;\0\0\0\0\0\0\0\80¡ã;\0\0\0\0\0\0\0\80ºìé;\0\0\0\0\0\0\0\80²`\0<\0\0\0\0\0\0\0\80æè\ 1<\0\0\0\0\0\0\0\80\eºN;\0\0\0\0\0\0\0\801UW;\0\0\0\0\0\0\0\80}~»;\0\0\0\0\0\0\0\80$w²;\0\0\0\0\0\0\0\80 Ðâ;\0\0\0\0\0\0\0\80Tûò;\0\0\0\0\0\0\0\80ºìé;\0\0\0\0\0\0\0\80¡ã;\0\0\0\0\0\0\0\80\84ä\98:\0\0\0\0\0\0\0\80ôÑ\9d:\0\0\0\0\0\0\0\801UW;\0\0\0\0\0\0\0\80\eºN;\0\0\0\0\0\0\0\80\85Ñ\0<\0\0\0\0\0\0\0\80\ 3.\ 4<\0\0\0\0\0\0\0\80Tûò;\0\0\0\0\0\0\0\80 Ðâ;\0\0\0\0\0\0\0\80Êí\a<\0\0\0\0\0\0\0\80ð\97\ 3<\0\0\0\0\0\0\0\80\ 3.\ 4<\0\0\0\0\0\0\0\80\85Ñ\0<\0\0\0\0\0\0\0\80\80\96\ 5<\80¿\82·\0\0\0\80\9bÿ\b<\0\99\ 6·\0\0\0\80\1c\80Ö;h+U¹\0\0\0\80æÇÎ; ,p¹\0\0\0\80ø\e <\0\0\0\0\0\0\0\80Q\v\b<\0\0\0\0\0\0\0\80ð\97\ 3<\0\0\0\0\0\0\0\80Êí\a<\0\0\0\0\0\0\0\80l¯\ f<\0\0\0\0\0\0\0\80\92Þ\ f<\0\0\0\0\0\0\0\80\9bÿ\b<\0\99\ 6·\0\0\0\80\80\96\ 5<\80¿\82·\0\0\0\80ôÑ\9d:\0\0\0\0\0\0\0\80\88ä\98:\0\0\0\0\0\0\0\80\1fºN;\0\0\0\0\0\0\0\801UW;\0\0\0\0\0\0\0\80\ 3.\ 4<\0\0\0\0\0\0\0\80Lùè;\0\0\0\0\0\0\0\80H\ 3Ú;\0\0\0\0\0\0\0\80Tûò;\0\0\0\0\0\0\0\80ð\97\ 3<\0\0\0\0\0\0\0\80\88?è;\0\0\0\0\0\0\0\80Lùè;\0\0\0\0\0\0\0\80\ 3.\ 4<\0\0\0\0\0\0\0\80\9bÿ\b<\0\99\ 6·\0\0\0\809\9b <\03ܶ\0\0\0\80z'Ú;4%G¹\0\0\0\80\1c\80Ö;h+U¹\0\0\0\80Q\v\b<\0\0\0\0\0\0\0\80nuö;\0\0\0\0\0\0\0\80\88?è;\0\0\0\0\0\0\0\80ð\97\ 3<\0\0\0\0\0\0\0\80\92Þ\ f<\0\0\0\0\0\0\0\80æ÷\r<\0\0\0\0\0\0\0\809\9b <\03ܶ\0\0\0\80\9bÿ\b<\0\99\ 6·\0\0\0\80û-\ e<\0\0\0\0\0\0\0\80l\96\ 3<\0\0\0\0\0\0\0\80nuö;\0\0\0\0\0\0\0\80Q\v\b<\0\0\0\0\0\0\0\80\12{
+<\0\0\0\0\0\0\0\80\ 5\95\ 6<\0\0\0\0\0\0\0\80æ÷\r<\0\0\0\0\0\0\0\80\92Þ\ f<\0\0\0\0\0\0\0\80mÑþ;\0\0\0\0\0\0\0\80>âï;\0\0\0\0\0\0\0\80l\96\ 3<\0\0\0\0\0\0\0\80û-\ e<\0\0\0\0\0\0\0\80²`\0<\0\0\0\0\0\0\0\80\ 1Îõ;\0\0\0\0\0\0\0\80\ 5\95\ 6<\0\0\0\0\0\0\0\80\12{
+<\0\0\0\0\0\0\0\80}~»;\0\0\0\0\0\0\0\80%w²;\0\0\0\0\0\0\0\80>âï;\0\0\0\0\0\0\0\80mÑþ;\0\0\0\0\0\0\0\80ºìé;\0\0\0\0\0\0\0\80\94\9aÛ;\0\0\0\0\0\0\0\80\ 1Îõ;\0\0\0\0\0\0\0\80²`\0<\0\0\0\0\0\0\0\801UW;\0\0\0\0\0\0\0\80\1fºN;\0\0\0\0\0\0\0\80%w²;\0\0\0\0\0\0\0\80}~»;\0\0\0\0\0\0\0\80Tûò;\0\0\0\0\0\0\0\80H\ 3Ú;\0\0\0\0\0\0\0\80\94\9aÛ;\0\0\0\0\0\0\0\80ºìé;\0\0\0\0\0\0\0\80>âï;\0\0\0\0\0\0\0\80vjÈ;\0\0\0\0\0\0\0\80\ 4mÕ;\0\0\0\0\0\0\0\80l\96\ 3<\0\0\0\0\0\0\0\80\ 1Îõ;\0\0\0\0\0\0\0\80\10éç;\0\0\0\0\0\0\0\80Ú*\ 2<\0\0\0\0\0\0\0\80\ 5\95\ 6<\0\0\0\0\0\0\0\80%w²;\0\0\0\0\0\0\0\80Û\92\99;\0\0\0\0\0\0\0\80vjÈ;\0\0\0\0\0\0\0\80>âï;\0\0\0\0\0\0\0\80\94\9aÛ;\0\0\0\0\0\0\0\80\94\9aÆ;\0\0\0\0\0\0\0\80\10éç;\0\0\0\0\0\0\0\80\ 1Îõ;\0\0\0\0\0\0\0\80\1fºN;\0\0\0\0\0\0\0\80ä|6;\0\0\0\0\0\0\0\80Û\92\99;\0\0\0\0\0\0\0\80%w²;\0\0\0\0\0\0\0\80H\ 3Ú;\0\0\0\0\0\0\0\80²Þ®;\0\0\0\0\0\0\0\80\94\9aÆ;\0\0\0\0\0\0\0\80\94\9aÛ;\0\0\0\0\0\0\0\80\88ä\98:\0\0\0\0\0\0\0\809Í\8a:\0\0\0\0\0\0\0\80ä|6;\0\0\0\0\0\0\0\80\1fºN;\0\0\0\0\0\0\0\80Lùè;\0\0\0\0\0\0\0\80¸ù°;\0\0\0\0\0\0\0\80²Þ®;\0\0\0\0\0\0\0\80H\ 3Ú;\0\0\0\0\0\0\0\80\88?è;\0\0\0\0\0\0\0\80Àn·;\0\0\0\0\0\0\0\80¸ù°;\0\0\0\0\0\0\0\80Lùè;\0\0\0\0\0\0\0\809\9b <\03ܶ\0\0\0\80ç>\b<À\81
+·\0\0\0\80OóÙ;\10¬D¹\0\0\0\80z'Ú;4%G¹\0\0\0\80nuö;\0\0\0\0\0\0\0\80LçÅ;\0\0\0\0\0\0\0\80Àn·;\0\0\0\0\0\0\0\80\88?è;\0\0\0\0\0\0\0\80æ÷\r<\0\0\0\0\0\0\0\80òS\v<\0\0\0\0\0\0\0\80ç>\b<À\81
+·\0\0\0\809\9b <\03ܶ\0\0\0\80l\96\ 3<\0\0\0\0\0\0\0\80\ 4mÕ;\0\0\0\0\0\0\0\80LçÅ;\0\0\0\0\0\0\0\80nuö;\0\0\0\0\0\0\0\80\ 5\95\ 6<\0\0\0\0\0\0\0\80Ú*\ 2<\0\0\0\0\0\0\0\80òS\v<\0\0\0\0\0\0\0\80æ÷\r<\0\0\0\0\0\0\0\80Àn·;\0\0\0\0\0\0\0\80Ì\8ah;\0\0\0\0\0\0\0\80LN[;\0\0\0\0\0\0\0\80¸ù°;\0\0\0\0\0\0\0\80ç>\b<À\81
+·\0\0\0\80ð\10\ 5<E«Z·\0\0\0\80Ò-Ö;3®L¹\0\0\0\80OóÙ;\10¬D¹\0\0\0\80LçÅ;\0\0\0\0\0\0\0\80âÛ\84;\0\0\0\0\0\0\0\80Ì\8ah;\0\0\0\0\0\0\0\80Àn·;\0\0\0\0\0\0\0\80òS\v<\0\0\0\0\0\0\0\80îý\a<\0\0\0\0\0\0\0\80ð\10\ 5<E«Z·\0\0\0\80ç>\b<À\81
+·\0\0\0\80\ 4mÕ;\0\0\0\0\0\0\0\80"-\95;\0\0\0\0\0\0\0\80âÛ\84;\0\0\0\0\0\0\0\80LçÅ;\0\0\0\0\0\0\0\80Ú*\ 2<\0\0\0\0\0\0\0\80µÇú;\0\0\0\0\0\0\0\80îý\a<\0\0\0\0\0\0\0\80òS\v<\0\0\0\0\0\0\0\80vjÈ;\0\0\0\0\0\0\0\80\1f]\93;\0\0\0\0\0\0\0\80"-\95;\0\0\0\0\0\0\0\80\ 4mÕ;\0\0\0\0\0\0\0\80\10éç;\0\0\0\0\0\0\0\80\12<Ø;\0\0\0\0\0\0\0\80µÇú;\0\0\0\0\0\0\0\80Ú*\ 2<\0\0\0\0\0\0\0\80Û\92\99;\0\0\0\0\0\0\0\80ȶl;\0\0\0\0\0\0\0\80\1f]\93;\0\0\0\0\0\0\0\80vjÈ;\0\0\0\0\0\0\0\80\94\9aÆ;\0\0\0\0\0\0\0\808+®;\0\0\0\0\0\0\0\80\12<Ø;\0\0\0\0\0\0\0\80\10éç;\0\0\0\0\0\0\0\80ä|6;\0\0\0\0\0\0\0\80Lê\12;\0\0\0\0\0\0\0\80ȶl;\0\0\0\0\0\0\0\80Û\92\99;\0\0\0\0\0\0\0\80²Þ®;\0\0\0\0\0\0\0\80jx\82;\0\0\0\0\0\0\0\808+®;\0\0\0\0\0\0\0\80\94\9aÆ;\0\0\0\0\0\0\0\809Í\8a:\0\0\0\0\0\0\0\80\98üj:\0\0\0\0\0\0\0\80Lê\12;\0\0\0\0\0\0\0\80ä|6;\0\0\0\0\0\0\0\80¸ù°;\0\0\0\0\0\0\0\80LN[;\0\0\0\0\0\0\0\80jx\82;\0\0\0\0\0\0\0\80²Þ®;\0\0\0\0\0\0\0\80\12<Ø;\0\0\0\0\0\0\0\80h\16È;\0\0\0\0\0\0\0\80\87
+ð;\0\0\0\0\0\0\0\80µÇú;\0\0\0\0\0\0\0\80ȶl;\0\0\0\0\0\0\0\80>`\1f;\0\0\0\0\0\0\0\80ê58;\0\0\0\0\0\0\0\80\1f]\93;\0\0\0\0\0\0\0\808+®;\0\0\0\0\0\0\0\80Ò\ 3\96;\0\0\0\0\0\0\0\80h\16È;\0\0\0\0\0\0\0\80\12<Ø;\0\0\0\0\0\0\0\80Lê\12;\0\0\0\0\0\0\0\80TêÓ:\0\0\0\0\0\0\0\80>`\1f;\0\0\0\0\0\0\0\80ȶl;\0\0\0\0\0\0\0\80jx\82;\0\0\0\0\0\0\0\80dò>;\0\0\0\0\0\0\0\80Ò\ 3\96;\0\0\0\0\0\0\0\808+®;\0\0\0\0\0\0\0\80\98üj:\0\0\0\0\0\0\0\80º¤7:\0\0\0\0\0\0\0\80TêÓ:\0\0\0\0\0\0\0\80Lê\12;\0\0\0\0\0\0\0\80LN[;\0\0\0\0\0\0\0\80HVÂ:\0\0\0\0\0\0\0\80dò>;\0\0\0\0\0\0\0\80jx\82;\0\0\0\0\0\0\0\80Ì\8ah;\0\0\0\0\0\0\0\80\0̲:\0\0\0\0\0\0\0\80HVÂ:\0\0\0\0\0\0\0\80LN[;\0\0\0\0\0\0\0\80ð\10\ 5<E«Z·\0\0\0\80\90\8cÿ; M½·\0\0\0\80q\84Î;H\13`¹\0\0\0\80Ò-Ö;3®L¹\0\0\0\80âÛ\84;\0\0\0\0\0\0\0\80\90\88ÿ:\0\0\0\0\0\0\0\80\0̲:\0\0\0\0\0\0\0\80Ì\8ah;\0\0\0\0\0\0\0\80îý\a<\0\0\0\0\0\0\0\80b1\ 3<\0\0\0\0\0\0\0\80\90\8cÿ; M½·\0\0\0\80ð\10\ 5<E«Z·\0\0\0\80"-\95;\0\0\0\0\0\0\0\80\183*;\0\0\0\0\0\0\0\80\90\88ÿ:\0\0\0\0\0\0\0\80âÛ\84;\0\0\0\0\0\0\0\80µÇú;\0\0\0\0\0\0\0\80\87
+ð;\0\0\0\0\0\0\0\80b1\ 3<\0\0\0\0\0\0\0\80îý\a<\0\0\0\0\0\0\0\80\1f]\93;\0\0\0\0\0\0\0\80ê58;\0\0\0\0\0\0\0\80\183*;\0\0\0\0\0\0\0\80"-\95;\0\0\0\0\0\0\0\80\0̲:\0\0\0\0\0\0\0\80À»\ 49\0\0\0\0\0\0\0\800Ç,:\0\0\0\0\0\0\0\80HVÂ:\0\0\0\0\0\0\0\80\90\8cÿ; M½·\0\0\0\80¦ëï;@-)¸\0\0\0\80 \9eÂ;¾1\80¹\0\0\0\80q\84Î;H\13`¹\0\0\0\80\90\88ÿ:\0\0\0\0\0\0\0\800í
+:\0\0\0\0\0\0\0\80À»\ 49\0\0\0\0\0\0\0\80\0̲:\0\0\0\0\0\0\0\80b1\ 3<\0\0\0\0\0\0\0\80å\91ø;\0\0\0\0\0\0\0\80¦ëï;@-)¸\0\0\0\80\90\8cÿ; M½·\0\0\0\80\183*;\0\0\0\0\0\0\0\80tÔ\87:\0\0\0\0\0\0\0\800í
+:\0\0\0\0\0\0\0\80\90\88ÿ:\0\0\0\0\0\0\0\80\87
+ð;\0\0\0\0\0\0\0\80ã_ä;\0\0\0\0\0\0\0\80å\91ø;\0\0\0\0\0\0\0\80b1\ 3<\0\0\0\0\0\0\0\80ê58;\0\0\0\0\0\0\0\80$@²:\0\0\0\0\0\0\0\80tÔ\87:\0\0\0\0\0\0\0\80\183*;\0\0\0\0\0\0\0\80h\16È;\0\0\0\0\0\0\0\80'ôº;\0\0\0\0\0\0\0\80ã_ä;\0\0\0\0\0\0\0\80\87
+ð;\0\0\0\0\0\0\0\80>`\1f;\0\0\0\0\0\0\0\80`´°:\0\0\0\0\0\0\0\80$@²:\0\0\0\0\0\0\0\80ê58;\0\0\0\0\0\0\0\80Ò\ 3\96;\0\0\0\0\0\0\0\80"u\84;\0\0\0\0\0\0\0\80'ôº;\0\0\0\0\0\0\0\80h\16È;\0\0\0\0\0\0\0\80TêÓ:\0\0\0\0\0\0\0\80¼è\83:\0\0\0\0\0\0\0\80`´°:\0\0\0\0\0\0\0\80>`\1f;\0\0\0\0\0\0\0\80dò>;\0\0\0\0\0\0\0\80ôA\ f;\0\0\0\0\0\0\0\80"u\84;\0\0\0\0\0\0\0\80Ò\ 3\96;\0\0\0\0\0\0\0\80º¤7:\0\0\0\0\0\0\0\80P \ 2:\0\0\0\0\0\0\0\80¼è\83:\0\0\0\0\0\0\0\80TêÓ:\0\0\0\0\0\0\0\80HVÂ:\0\0\0\0\0\0\0\800Ç,:\0\0\0\0\0\0\0\80ôA\ f;\0\0\0\0\0\0\0\80dò>;\0\0\0\0\0\0\0\80`´°:\0\0\0\0\0\0\0\80\0\90 :\0\0\0\0\0\0\0\80PìÄ9\0\0\0\0\0\0\0\80$@²:\0\0\0\0\0\0\0\80"u\84;\0\0\0\0\0\0\0\80\9eëq;\0\0\0\0\0\0\0\80ÿj¯;\0\0\0\0\0\0\0\80'ôº;\0\0\0\0\0\0\0\80¼è\83:\0\0\0\0\0\0\0\80\f0\ 2:\0\0\0\0\0\0\0\80\0\90 :\0\0\0\0\0\0\0\80`´°:\0\0\0\0\0\0\0\80ôA\ f;\0\0\0\0\0\0\0\80°äú:\0\0\0\0\0\0\0\80\9eëq;\0\0\0\0\0\0\0\80"u\84;\0\0\0\0\0\0\0\80P \ 2:\0\0\0\0\0\0\0\80¤\96¡9\0\0\0\0\0\0\0\80\f0\ 2:\0\0\0\0\0\0\0\80¼è\83:\0\0\0\0\0\0\0\800Ç,:\0\0\0\0\0\0\0\80ð~&:\0\0\0\0\0\0\0\80°äú:\0\0\0\0\0\0\0\80ôA\ f;\0\0\0\0\0\0\0\80À»\ 49\0\0\0\0\0\0\0\80\0þ@8\0\0\0\0\0\0\0\80ð~&:\0\0\0\0\0\0\0\800Ç,:\0\0\0\0\0\0\0\80¦ëï;@-)¸\0\0\0\80\92\1aØ; A\9e¸\0\0\0\80\81²;"ý\96¹\0\0\0\80 \9eÂ;¾1\80¹\0\0\0\800í
+:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0þ@8\0\0\0\0\0\0\0\80À»\ 49\0\0\0\0\0\0\0\80å\91ø;\0\0\0\0\0\0\0\80àÚá;\0\0j³\0\0\0\80\92\1aØ; A\9e¸\0\0\0\80¦ëï;@-)¸\0\0\0\80tÔ\87:\0\0\0\0\0\0\0\80À\89\159\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\800í
+:\0\0\0\0\0\0\0\80ã_ä;\0\0\0\0\0\0\0\80w{Ó;\0\0\0\0\0\0\0\80àÚá;\0\0j³\0\0\0\80å\91ø;\0\0\0\0\0\0\0\80$@²:\0\0\0\0\0\0\0\80PìÄ9\0\0\0\0\0\0\0\80À\89\159\0\0\0\0\0\0\0\80tÔ\87:\0\0\0\0\0\0\0\80'ôº;\0\0\0\0\0\0\0\80ÿj¯;\0\0\0\0\0\0\0\80w{Ó;\0\0\0\0\0\0\0\80ã_ä;\0\0\0\0\0\0\0\80\92\1aØ; A\9e¸\0\0\0\80²\8f·;À÷\ e¹\0\0\0\80\8c®\9f;$á³¹\0\0\0\80\81²;"ý\96¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0£Õ7\0\0\0\0\0\0\0\80\0þ@8\0\0\0\0\0\0\0\80àÚá;\0\0j³\0\0\0\80üa½;\0¤\83·\0\0\0\80²\8f·;À÷\ e¹\0\0\0\80\92\1aØ; A\9e¸\0\0\0\80À\89\159\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80w{Ó;\0\0\0\0\0\0\0\80\97X´;\0\0\0\0\0\0\0\80üa½;\0¤\83·\0\0\0\80àÚá;\0\0j³\0\0\0\80PìÄ9\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80À\89\159\0\0\0\0\0\0\0\80ÿj¯;\0\0\0\0\0\0\0\80÷|\95;\0\0\0\0\0\0\0\80\97X´;\0\0\0\0\0\0\0\80w{Ó;\0\0\0\0\0\0\0\80\0\90 :\0\0\0\0\0\0\0\80\0\b\968\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80PìÄ9\0\0\0\0\0\0\0\80\9eëq;\0\0\0\0\0\0\0\80\ 6)G;\0\0\0\0\0\0\0\80÷|\95;\0\0\0\0\0\0\0\80ÿj¯;\0\0\0\0\0\0\0\80\f0\ 2:\0\0\0\0\0\0\0\80`~\1e9\0\0\0\0\0\0\0\80\0\b\968\0\0\0\0\0\0\0\80\0\90 :\0\0\0\0\0\0\0\80°äú:\0\0\0\0\0\0\0\80\98~Ì:\0\0\0\0\0\0\0\80\ 6)G;\0\0\0\0\0\0\0\80\9eëq;\0\0\0\0\0\0\0\80¤\96¡9\0\0\0\0\0\0\0\80\90\96#9\0\0\0\0\0\0\0\80`~\1e9\0\0\0\0\0\0\0\80\f0\ 2:\0\0\0\0\0\0\0\80ð~&:\0\0\0\0\0\0\0\80Xv\ e:\0\0\0\0\0\0\0\80\98~Ì:\0\0\0\0\0\0\0\80°äú:\0\0\0\0\0\0\0\80\0þ@8\0\0\0\0\0\0\0\80\0£Õ7\0\0\0\0\0\0\0\80Xv\ e:\0\0\0\0\0\0\0\80ð~&:\0\0\0\0\0\0\0\80\ 6)G;\0\0\0\0\0\0\0\80Χ\10;\0\0\0\0\0\0\0\80\82\1f_;\0\0\0\0\0\0\0\80÷|\95;\0\0\0\0\0\0\0\80`~\1e9\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\b\968\0\0\0\0\0\0\0\80\98~Ì:\0\0\0\0\0\0\0\80hÚ\96:\0\0\0\0\0\0\0\80Χ\10;\0\0\0\0\0\0\0\80\ 6)G;\0\0\0\0\0\0\0\80\90\96#9\0\0\0\0\0\0\0\80À\94^8\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80`~\1e9\0\0\0\0\0\0\0\80Xv\ e:\0\0\0\0\0\0\0\80\90\16¬9\0\0\0\0\0\0\0\80hÚ\96:\0\0\0\0\0\0\0\80\98~Ì:\0\0\0\0\0\0\0\80\0£Õ7\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\90\16¬9\0\0\0\0\0\0\0\80Xv\ e:\0\0\0\0\0\0\0\80²\8f·;À÷\ e¹\0\0\0\80Ö\86\91;Àph¹\0\0\0\80ã\9e\8a;,JÕ¹\0\0\0\80\8c®\9f;$á³¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0£Õ7\0\0\0\0\0\0\0\80üa½;\0¤\83·\0\0\0\80rä\90;@\ 5\8b¸\0\0\0\80Ö\86\91;Àph¹\0\0\0\80²\8f·;À÷\ e¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\97X´;\0\0\0\0\0\0\0\80[\9b\8b;\0\0 ³\0\0\0\80rä\90;@\ 5\8b¸\0\0\0\80üa½;\0¤\83·\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80÷|\95;\0\0\0\0\0\0\0\80\82\1f_;\0\0\0\0\0\0\0\80[\9b\8b;\0\0 ³\0\0\0\80\97X´;\0\0\0\0\0\0\0\80\0\b\968\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80rä\90;@\ 5\8b¸\0\0\0\80ÅYK;àÚ\13¹\0\0\0\806\V;àù¦¹\0\0\0\80Ö\86\91;Àph¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80[\9b\8b;\0\0 ³\0\0\0\80V8?;\0\1eµ·\0\0\0\80ÅYK;àÚ\13¹\0\0\0\80rä\90;@\ 5\8b¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\82\1f_;\0\0\0\0\0\0\0\80\82[\14;\0\0\0\0\0\0\0\80V8?;\0\1eµ·\0\0\0\80[\9b\8b;\0\0 ³\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Χ\10;\0\0\0\0\0\0\0\80dÙ¿:\0\0\0\0\0\0\0\80\82[\14;\0\0\0\0\0\0\0\80\82\1f_;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80hÚ\96:\0\0\0\0\0\0\0\80tÂ):\0\0\0\0\0\0\0\80dÙ¿:\0\0\0\0\0\0\0\80Χ\10;\0\0\0\0\0\0\0\80À\94^8\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\90\16¬9\0\0\0\0\0\0\0\80àKÑ8\0\0\0\0\0\0\0\80tÂ):\0\0\0\0\0\0\0\80hÚ\96:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80àKÑ8\0\0\0\0\0\0\0\80\90\16¬9\0\0\0\0\0\0\0\80Ö\86\91;Àph¹\0\0\0\806\V;àù¦¹\0\0\0\80~Rj;øø¹\0\0\0\80ã\9e\8a;,JÕ¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80tÂ):\0\0\0\0\0\0\0\80P\a^9\0\0\0\0\0\0\0\80&
+E:\0\0\0\0\0\0\0\80dÙ¿:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80àKÑ8\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80P\a^9\0\0\0\0\0\0\0\80tÂ):\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80àKÑ8\0\0\0\0\0\0\0\806\V;àù¦¹\0\0\0\80àô\13;ÀèÕ¹\0\0\0\80©ïA;$\86\rº\0\0\0\80~Rj;øø¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80ÅYK;àÚ\13¹\0\0\0\80Þä\ 6;`òb¹\0\0\0\80àô\13;ÀèÕ¹\0\0\0\806\V;àù¦¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80V8?;\0\1eµ·\0\0\0\80:¸õ:\80\1a\89¸\0\0\0\80Þä\ 6;`òb¹\0\0\0\80ÅYK;àÚ\13¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\82[\14;\0\0\0\0\0\0\0\80[íµ:\0\80©µ\0\0\0\80:¸õ:\80\1a\89¸\0\0\0\80V8?;\0\1eµ·\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80dÙ¿:\0\0\0\0\0\0\0\80&
+E:\0\0\0\0\0\0\0\80[íµ:\0\80©µ\0\0\0\80\82[\14;\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80:¸õ:\80\1a\89¸\0\0\0\80\0\0\0\0À°ß¸\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80Þä\ 6;`òb¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80[íµ:\0\80©µ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0À°ß¸\0\0\0\80:¸õ:\80\1a\89¸\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80&
+E:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80[íµ:\0\80©µ\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80P\a^9\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80&
+E:\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80P\a^9\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80àô\13;ÀèÕ¹\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80\0\0\0\0Z\944º\0\0\0\80©ïA;$\86\rº\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80Þä\ 6;`òb¹\0\0\0\80\0\0\0\0 \9a\98¹\0\0\0\80\0\0\0\0\0à\ 4º\0\0\0\80àô\13;ÀèÕ¹\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\0\0\0\0\0\0\0\0\0\0\0\80\ 2\0\ 1\0\0\0\ 3\0\ 2\0\0\0\ 6\0\ 5\0\ 4\0\a\0\ 6\0\ 4\0
+\0 \0\b\0\v\0
+\0\b\0\ e\0\r\0\f\0\ f\0\ e\0\f\0\12\0\11\0\10\0\13\0\12\0\10\0\16\0\15\0\14\0\17\0\16\0\14\0\1a\0\19\0\18\0\e\0\1a\0\18\0\1e\0\1d\0\1c\0\1f\0\1e\0\1c\0"\0!\0 \0#\0"\0 \0&\0%\0$\0'\0&\0$\0*\0)\0(\0+\0*\0(\0.\0-\0,\0.\0/\0-\0.\00\0/\0.\0,\01\0.\01\02\04\03\00\04\05\03\04\06\05\08\07\06\08\09\07\08\0:\09\0<\0;\0:\0<\0=\0;\0<\0>\0=\0@\0?\0>\0@\0A\0?\0@\0B\0A\0D\0C\0B\0D\0E\0C\0D\0F\0E\0H\0G\0F\0H\0I\0G\0H\0J\0I\0L\0K\0J\0L\0M\0K\0L\0N\0M\0P\0O\0N\0P\0Q\0O\0P\0R\0Q\0T\0S\0R\0T\0U\0S\0T\02\0U\0X\0W\0V\0W\0Y\0V\0Y\0Z\0V\0[\0X\0V\0\\0[\0V\0Z\0^\0]\0^\0_\0]\0_\0`\0]\0`\0b\0a\0b\0c\0a\0c\0d\0a\0d\0f\0e\0f\0g\0e\0g\0h\0e\0h\0j\0i\0j\0k\0i\0k\0l\0i\0l\0n\0m\0n\0o\0m\0o\0p\0m\0p\0r\0q\0r\0s\0q\0s\0t\0q\0t\0v\0u\0v\0w\0u\0w\0x\0u\0x\0z\0y\0z\0{\0y\0{\0|\0y\0|\0~\0}\0~\0\7f\0}\0\7f\0\\0}\0\82\0\81\0\80\0\83\0\82\0\80\0\86\0\85\0\84\0\87\0\86\0\84\0\8a\0\89\0\88\0\8b\0\8a\0\88\0\8e\0\8d\0\8c\0\8f\0\8e\0\8c\0\92\0\91\0\90\0\93\0\92\0\90\0\96\0\95\0\94\0\97\0\96\0\94\0\9a\0\99\0\98\0\9b\0\9a\0\98\0\9e\0\9d\0\9c\0\9f\0\9e\0\9c\0¢\0¡\0 \0£\0¢\0 \0¦\0¥\0¤\0§\0¦\0¤\0ª\0©\0¨\0«\0ª\0¨\0®\0\0¬\0¯\0®\0¬\0²\0±\0°\0³\0²\0°\0¶\0µ\0´\0·\0¶\0´\0º\0¹\0¸\0»\0º\0¸\0¾\0½\0¼\0¿\0¾\0¼\0Â\0Á\0À\0Ã\0Â\0À\0Æ\0Å\0Ä\0Ç\0Æ\0Ä\0Ê\0É\0È\0Ë\0Ê\0È\0Î\0Í\0Ì\0Ï\0Î\0Ì\0Ò\0Ñ\0Ð\0Ó\0Ò\0Ð\0Ö\0Õ\0Ô\0×\0Ö\0Ô\0Ú\0Ù\0Ø\0Û\0Ú\0Ø\0Þ\0Ý\0Ü\0ß\0Þ\0Ü\0â\0á\0à\0ã\0â\0à\0æ\0å\0ä\0ç\0æ\0ä\0ê\0é\0è\0ë\0ê\0è\0î\0í\0ì\0ï\0î\0ì\0ò\0ñ\0ð\0ó\0ò\0ð\0ö\0õ\0ô\0÷\0ö\0ô\0ú\0ù\0ø\0û\0ú\0ø\0þ\0ý\0ü\0ÿ\0þ\0ü\0\ 2\ 1\ 1\ 1\0\ 1\ 3\ 1\ 2\ 1\0\ 1\ 6\ 1\ 5\ 1\ 4\ 1\a\ 1\ 6\ 1\ 4\ 1
+\ 1 \ 1\b\ 1\v\ 1
+\ 1\b\ 1\ e\ 1\r\ 1\f\ 1\ f\ 1\ e\ 1\f\ 1\12\ 1\11\ 1\10\ 1\13\ 1\12\ 1\10\ 1\16\ 1\15\ 1\14\ 1\17\ 1\16\ 1\14\ 1\1a\ 1\19\ 1\18\ 1\e\ 1\1a\ 1\18\ 1\1e\ 1\1d\ 1\1c\ 1\1f\ 1\1e\ 1\1c\ 1"\ 1!\ 1 \ 1#\ 1"\ 1 \ 1&\ 1%\ 1$\ 1'\ 1&\ 1$\ 1*\ 1)\ 1(\ 1+\ 1*\ 1(\ 1.\ 1-\ 1,\ 1/\ 1.\ 1,\ 12\ 11\ 10\ 13\ 12\ 10\ 16\ 15\ 14\ 17\ 16\ 14\ 1:\ 19\ 18\ 1;\ 1:\ 18\ 1>\ 1=\ 1<\ 1?\ 1>\ 1<\ 1B\ 1A\ 1@\ 1C\ 1B\ 1@\ 1F\ 1E\ 1D\ 1G\ 1F\ 1D\ 1J\ 1I\ 1H\ 1K\ 1J\ 1H\ 1N\ 1M\ 1L\ 1O\ 1N\ 1L\ 1R\ 1Q\ 1P\ 1S\ 1R\ 1P\ 1V\ 1U\ 1T\ 1W\ 1V\ 1T\ 1Z\ 1Y\ 1X\ 1[\ 1Z\ 1X\ 1^\ 1]\ 1\\ 1_\ 1^\ 1\\ 1b\ 1a\ 1`\ 1c\ 1b\ 1`\ 1f\ 1e\ 1d\ 1g\ 1f\ 1d\ 1j\ 1i\ 1h\ 1k\ 1j\ 1h\ 1n\ 1m\ 1l\ 1o\ 1n\ 1l\ 1r\ 1q\ 1p\ 1s\ 1r\ 1p\ 1v\ 1u\ 1t\ 1w\ 1v\ 1t\ 1z\ 1y\ 1x\ 1{\ 1z\ 1x\ 1~\ 1}\ 1|\ 1\7f\ 1~\ 1|\ 1\82\ 1\81\ 1\80\ 1\83\ 1\82\ 1\80\ 1\86\ 1\85\ 1\84\ 1\87\ 1\86\ 1\84\ 1\8a\ 1\89\ 1\88\ 1\8b\ 1\8a\ 1\88\ 1\8e\ 1\8d\ 1\8c\ 1\8f\ 1\8e\ 1\8c\ 1\92\ 1\91\ 1\90\ 1\93\ 1\92\ 1\90\ 1\96\ 1\95\ 1\94\ 1\97\ 1\96\ 1\94\ 1\9a\ 1\99\ 1\98\ 1\9b\ 1\9a\ 1\98\ 1\9e\ 1\9d\ 1\9c\ 1\9f\ 1\9e\ 1\9c\ 1¢\ 1¡\ 1 \ 1£\ 1¢\ 1 \ 1¦\ 1¥\ 1¤\ 1§\ 1¦\ 1¤\ 1ª\ 1©\ 1¨\ 1«\ 1ª\ 1¨\ 1®\ 1\ 1¬\ 1¯\ 1®\ 1¬\ 1²\ 1±\ 1°\ 1³\ 1²\ 1°\ 1¶\ 1µ\ 1´\ 1·\ 1¶\ 1´\ 1º\ 1¹\ 1¸\ 1»\ 1º\ 1¸\ 1¾\ 1½\ 1¼\ 1¿\ 1¾\ 1¼\ 1Â\ 1Á\ 1À\ 1Ã\ 1Â\ 1À\ 1Æ\ 1Å\ 1Ä\ 1Ç\ 1Æ\ 1Ä\ 1Ê\ 1É\ 1È\ 1Ë\ 1Ê\ 1È\ 1Î\ 1Í\ 1Ì\ 1Ï\ 1Î\ 1Ì\ 1Ò\ 1Ñ\ 1Ð\ 1Ó\ 1Ò\ 1Ð\ 1Ö\ 1Õ\ 1Ô\ 1×\ 1Ö\ 1Ô\ 1Ú\ 1Ù\ 1Ø\ 1Û\ 1Ú\ 1Ø\ 1Þ\ 1Ý\ 1Ü\ 1ß\ 1Þ\ 1Ü\ 1â\ 1á\ 1à\ 1ã\ 1â\ 1à\ 1æ\ 1å\ 1ä\ 1ç\ 1æ\ 1ä\ 1ê\ 1é\ 1è\ 1ë\ 1ê\ 1è\ 1î\ 1í\ 1ì\ 1ï\ 1î\ 1ì\ 1ò\ 1ñ\ 1ð\ 1ó\ 1ò\ 1ð\ 1ö\ 1õ\ 1ô\ 1÷\ 1ö\ 1ô\ 1ú\ 1ù\ 1ø\ 1û\ 1ú\ 1ø\ 1þ\ 1ý\ 1ü\ 1ÿ\ 1þ\ 1ü\ 1\ 2\ 2\ 1\ 2\0\ 2\ 3\ 2\ 2\ 2\0\ 2\ 6\ 2\ 5\ 2\ 4\ 2\a\ 2\ 6\ 2\ 4\ 2
+\ 2 \ 2\b\ 2\v\ 2
+\ 2\b\ 2\ e\ 2\r\ 2\f\ 2\ f\ 2\ e\ 2\f\ 2\12\ 2\11\ 2\10\ 2\13\ 2\12\ 2\10\ 2\16\ 2\15\ 2\14\ 2\17\ 2\16\ 2\14\ 2\1a\ 2\19\ 2\18\ 2\e\ 2\1a\ 2\18\ 2\1e\ 2\1d\ 2\1c\ 2\1f\ 2\1e\ 2\1c\ 2"\ 2!\ 2 \ 2#\ 2"\ 2 \ 2&\ 2%\ 2$\ 2'\ 2&\ 2$\ 2*\ 2)\ 2(\ 2+\ 2*\ 2(\ 2.\ 2-\ 2,\ 2/\ 2.\ 2,\ 22\ 21\ 20\ 23\ 22\ 20\ 26\ 25\ 24\ 27\ 26\ 24\ 2:\ 29\ 28\ 2;\ 2:\ 28\ 2>\ 2=\ 2<\ 2?\ 2>\ 2<\ 2B\ 2A\ 2@\ 2C\ 2B\ 2@\ 2F\ 2E\ 2D\ 2G\ 2F\ 2D\ 2J\ 2I\ 2H\ 2K\ 2J\ 2H\ 2N\ 2M\ 2L\ 2O\ 2N\ 2L\ 2R\ 2Q\ 2P\ 2S\ 2R\ 2P\ 2V\ 2U\ 2T\ 2W\ 2V\ 2T\ 2Z\ 2Y\ 2X\ 2[\ 2Z\ 2X\ 2^\ 2]\ 2\\ 2_\ 2^\ 2\\ 2b\ 2a\ 2`\ 2c\ 2b\ 2`\ 2f\ 2e\ 2d\ 2g\ 2f\ 2d\ 2j\ 2i\ 2h\ 2k\ 2j\ 2h\ 2n\ 2m\ 2l\ 2o\ 2n\ 2l\ 2r\ 2q\ 2p\ 2s\ 2r\ 2p\ 2v\ 2u\ 2t\ 2w\ 2v\ 2t\ 2z\ 2y\ 2x\ 2{\ 2z\ 2x\ 2~\ 2}\ 2|\ 2\7f\ 2~\ 2|\ 2\82\ 2\81\ 2\80\ 2\83\ 2\82\ 2\80\ 2\86\ 2\85\ 2\84\ 2\87\ 2\86\ 2\84\ 2\8a\ 2\89\ 2\88\ 2\8b\ 2\8a\ 2\88\ 2\8e\ 2\8d\ 2\8c\ 2\8f\ 2\8e\ 2\8c\ 2\92\ 2\91\ 2\90\ 2\93\ 2\92\ 2\90\ 2\96\ 2\95\ 2\94\ 2\97\ 2\96\ 2\94\ 2\9a\ 2\99\ 2\98\ 2\9b\ 2\9a\ 2\98\ 2\9e\ 2\9d\ 2\9c\ 2\9f\ 2\9e\ 2\9c\ 2¢\ 2¡\ 2 \ 2£\ 2¢\ 2 \ 2¦\ 2¥\ 2¤\ 2§\ 2¦\ 2¤\ 2ª\ 2©\ 2¨\ 2«\ 2ª\ 2¨\ 2®\ 2\ 2¬\ 2¯\ 2®\ 2¬\ 2²\ 2±\ 2°\ 2³\ 2²\ 2°\ 2¶\ 2µ\ 2´\ 2·\ 2¶\ 2´\ 2º\ 2¹\ 2¸\ 2»\ 2º\ 2¸\ 2¾\ 2½\ 2¼\ 2¿\ 2¾\ 2¼\ 2Â\ 2Á\ 2À\ 2Ã\ 2Â\ 2À\ 2Æ\ 2Å\ 2Ä\ 2Ç\ 2Æ\ 2Ä\ 2Ê\ 2É\ 2È\ 2Ë\ 2Ê\ 2È\ 2Î\ 2Í\ 2Ì\ 2Ï\ 2Î\ 2Ì\ 2Ò\ 2Ñ\ 2Ð\ 2Ó\ 2Ò\ 2Ð\ 2Ö\ 2Õ\ 2Ô\ 2×\ 2Ö\ 2Ô\ 2Ú\ 2Ù\ 2Ø\ 2Û\ 2Ú\ 2Ø\ 2Þ\ 2Ý\ 2Ü\ 2ß\ 2Þ\ 2Ü\ 2â\ 2á\ 2à\ 2ã\ 2â\ 2à\ 2æ\ 2å\ 2ä\ 2ç\ 2æ\ 2ä\ 2ê\ 2é\ 2è\ 2ë\ 2ê\ 2è\ 2î\ 2í\ 2ì\ 2ï\ 2î\ 2ì\ 2ò\ 2ñ\ 2ð\ 2ó\ 2ò\ 2ð\ 2ö\ 2õ\ 2ô\ 2÷\ 2ö\ 2ô\ 2ú\ 2ù\ 2ø\ 2û\ 2ú\ 2ø\ 2þ\ 2ý\ 2ü\ 2ÿ\ 2þ\ 2ü\ 2\ 2\ 3\ 1\ 3\0\ 3\ 3\ 3\ 2\ 3\0\ 3\ 6\ 3\ 5\ 3\ 4\ 3\a\ 3\ 6\ 3\ 4\ 3
+\ 3 \ 3\b\ 3\v\ 3
+\ 3\b\ 3\ e\ 3\r\ 3\f\ 3\ f\ 3\ e\ 3\f\ 3\12\ 3\11\ 3\10\ 3\13\ 3\12\ 3\10\ 3\16\ 3\15\ 3\14\ 3\17\ 3\16\ 3\14\ 3\1a\ 3\19\ 3\18\ 3\e\ 3\1a\ 3\18\ 3\1e\ 3\1d\ 3\1c\ 3\1f\ 3\1e\ 3\1c\ 3"\ 3!\ 3 \ 3#\ 3"\ 3 \ 3&\ 3%\ 3$\ 3'\ 3&\ 3$\ 3*\ 3)\ 3(\ 3+\ 3*\ 3(\ 3.\ 3-\ 3,\ 3/\ 3.\ 3,\ 32\ 31\ 30\ 33\ 32\ 30\ 36\ 35\ 34\ 37\ 36\ 34\ 3:\ 39\ 38\ 3;\ 3:\ 38\ 3>\ 3=\ 3<\ 3?\ 3>\ 3<\ 3B\ 3A\ 3@\ 3C\ 3B\ 3@\ 3F\ 3E\ 3D\ 3G\ 3F\ 3D\ 3J\ 3I\ 3H\ 3K\ 3J\ 3H\ 3N\ 3M\ 3L\ 3O\ 3N\ 3L\ 3R\ 3Q\ 3P\ 3S\ 3R\ 3P\ 3V\ 3U\ 3T\ 3W\ 3V\ 3T\ 3Z\ 3Y\ 3X\ 3[\ 3Z\ 3X\ 3^\ 3]\ 3\\ 3_\ 3^\ 3\\ 3b\ 3a\ 3`\ 3c\ 3b\ 3`\ 3f\ 3e\ 3d\ 3g\ 3f\ 3d\ 3j\ 3i\ 3h\ 3k\ 3j\ 3h\ 3n\ 3m\ 3l\ 3o\ 3n\ 3l\ 3r\ 3q\ 3p\ 3s\ 3r\ 3p\ 3v\ 3u\ 3t\ 3w\ 3v\ 3t\ 3z\ 3y\ 3x\ 3{\ 3z\ 3x\ 3~\ 3}\ 3|\ 3\7f\ 3~\ 3|\ 3\82\ 3\81\ 3\80\ 3\83\ 3\82\ 3\80\ 3\86\ 3\85\ 3\84\ 3\87\ 3\86\ 3\84\ 3\8a\ 3\89\ 3\88\ 3\8b\ 3\8a\ 3\88\ 3\8e\ 3\8d\ 3\8c\ 3\8f\ 3\8e\ 3\8c\ 3\92\ 3\91\ 3\90\ 3\93\ 3\92\ 3\90\ 3\96\ 3\95\ 3\94\ 3\97\ 3\96\ 3\94\ 3\9a\ 3\99\ 3\98\ 3\9b\ 3\9a\ 3\98\ 3\9e\ 3\9d\ 3\9c\ 3\9f\ 3\9e\ 3\9c\ 3¢\ 3¡\ 3 \ 3£\ 3¢\ 3 \ 3¦\ 3¥\ 3¤\ 3§\ 3¦\ 3¤\ 3ª\ 3©\ 3¨\ 3«\ 3ª\ 3¨\ 3®\ 3\ 3¬\ 3¯\ 3®\ 3¬\ 3²\ 3±\ 3°\ 3³\ 3²\ 3°\ 3¶\ 3µ\ 3´\ 3·\ 3¶\ 3´\ 3º\ 3¹\ 3¸\ 3»\ 3º\ 3¸\ 3¾\ 3½\ 3¼\ 3¿\ 3¾\ 3¼\ 3Â\ 3Á\ 3À\ 3Ã\ 3Â\ 3À\ 3Æ\ 3Å\ 3Ä\ 3Ç\ 3Æ\ 3Ä\ 3Ê\ 3É\ 3È\ 3Ë\ 3Ê\ 3È\ 3Î\ 3Í\ 3Ì\ 3Ï\ 3Î\ 3Ì\ 3Ò\ 3Ñ\ 3Ð\ 3Ó\ 3Ò\ 3Ð\ 3Ö\ 3Õ\ 3Ô\ 3×\ 3Ö\ 3Ô\ 3Ú\ 3Ù\ 3Ø\ 3Û\ 3Ú\ 3Ø\ 3Þ\ 3Ý\ 3Ü\ 3ß\ 3Þ\ 3Ü\ 3â\ 3á\ 3à\ 3ã\ 3â\ 3à\ 3æ\ 3å\ 3ä\ 3ç\ 3æ\ 3ä\ 3ê\ 3é\ 3è\ 3ë\ 3ê\ 3è\ 3î\ 3í\ 3ì\ 3ï\ 3î\ 3ì\ 3ò\ 3ñ\ 3ð\ 3ó\ 3ò\ 3ð\ 3ö\ 3õ\ 3ô\ 3÷\ 3ö\ 3ô\ 3ú\ 3ù\ 3ø\ 3û\ 3ú\ 3ø\ 3þ\ 3ý\ 3ü\ 3ÿ\ 3þ\ 3ü\ 3\ 2\ 4\ 1\ 4\0\ 4\ 3\ 4\ 2\ 4\0\ 4\ 6\ 4\ 5\ 4\ 4\ 4\a\ 4\ 6\ 4\ 4\ 4
+\ 4 \ 4\b\ 4\v\ 4
+\ 4\b\ 4\ e\ 4\r\ 4\f\ 4\ f\ 4\ e\ 4\f\ 4\12\ 4\11\ 4\10\ 4\13\ 4\12\ 4\10\ 4\16\ 4\15\ 4\14\ 4\17\ 4\16\ 4\14\ 4\1a\ 4\19\ 4\18\ 4\e\ 4\1a\ 4\18\ 4\1e\ 4\1d\ 4\1c\ 4\1f\ 4\1e\ 4\1c\ 4"\ 4!\ 4 \ 4#\ 4"\ 4 \ 4&\ 4%\ 4$\ 4'\ 4&\ 4$\ 4*\ 4)\ 4(\ 4+\ 4*\ 4(\ 4.\ 4-\ 4,\ 4/\ 4.\ 4,\ 42\ 41\ 40\ 43\ 42\ 40\ 46\ 45\ 44\ 47\ 46\ 44\ 4:\ 49\ 48\ 4;\ 4:\ 48\ 4>\ 4=\ 4<\ 4?\ 4>\ 4<\ 4B\ 4A\ 4@\ 4C\ 4B\ 4@\ 4F\ 4E\ 4D\ 4G\ 4F\ 4D\ 4J\ 4I\ 4H\ 4K\ 4J\ 4H\ 4N\ 4M\ 4L\ 4O\ 4N\ 4L\ 4R\ 4Q\ 4P\ 4S\ 4R\ 4P\ 4V\ 4U\ 4T\ 4W\ 4V\ 4T\ 4Z\ 4Y\ 4X\ 4[\ 4Z\ 4X\ 4^\ 4]\ 4\\ 4_\ 4^\ 4\\ 4b\ 4a\ 4`\ 4c\ 4b\ 4`\ 4f\ 4e\ 4d\ 4g\ 4f\ 4d\ 4j\ 4i\ 4h\ 4k\ 4j\ 4h\ 4n\ 4m\ 4l\ 4o\ 4n\ 4l\ 4r\ 4q\ 4p\ 4s\ 4r\ 4p\ 4v\ 4u\ 4t\ 4w\ 4v\ 4t\ 4z\ 4y\ 4x\ 4{\ 4z\ 4x\ 4~\ 4}\ 4|\ 4\7f\ 4~\ 4|\ 4\82\ 4\81\ 4\80\ 4\83\ 4\82\ 4\80\ 4\86\ 4\85\ 4\84\ 4\87\ 4\86\ 4\84\ 4\8a\ 4\89\ 4\88\ 4\8b\ 4\8a\ 4\88\ 4\8e\ 4\8d\ 4\8c\ 4\8f\ 4\8e\ 4\8c\ 4\92\ 4\91\ 4\90\ 4\93\ 4\92\ 4\90\ 4\96\ 4\95\ 4\94\ 4\97\ 4\96\ 4\94\ 4\9a\ 4\99\ 4\98\ 4\9b\ 4\9a\ 4\98\ 4\9e\ 4\9d\ 4\9c\ 4\9f\ 4\9e\ 4\9c\ 4¢\ 4¡\ 4 \ 4£\ 4¢\ 4 \ 4¦\ 4¥\ 4¤\ 4§\ 4¦\ 4¤\ 4ª\ 4©\ 4¨\ 4«\ 4ª\ 4¨\ 4®\ 4\ 4¬\ 4¯\ 4®\ 4¬\ 4²\ 4±\ 4°\ 4³\ 4²\ 4°\ 4¶\ 4µ\ 4´\ 4·\ 4¶\ 4´\ 4º\ 4¹\ 4¸\ 4»\ 4º\ 4¸\ 4¾\ 4½\ 4¼\ 4¿\ 4¾\ 4¼\ 4Â\ 4Á\ 4À\ 4Ã\ 4Â\ 4À\ 4Æ\ 4Å\ 4Ä\ 4Ç\ 4Æ\ 4Ä\ 4Ê\ 4É\ 4È\ 4Ë\ 4Ê\ 4È\ 4Î\ 4Í\ 4Ì\ 4Ï\ 4Î\ 4Ì\ 4Ò\ 4Ñ\ 4Ð\ 4Ó\ 4Ò\ 4Ð\ 4Ö\ 4Õ\ 4Ô\ 4×\ 4Ö\ 4Ô\ 4Ú\ 4Ù\ 4Ø\ 4Û\ 4Ú\ 4Ø\ 4Þ\ 4Ý\ 4Ü\ 4ß\ 4Þ\ 4Ü\ 4â\ 4á\ 4à\ 4ã\ 4â\ 4à\ 4æ\ 4å\ 4ä\ 4ç\ 4æ\ 4ä\ 4ê\ 4é\ 4è\ 4ë\ 4ê\ 4è\ 4î\ 4í\ 4ì\ 4ï\ 4î\ 4ì\ 4ò\ 4ñ\ 4ð\ 4ó\ 4ò\ 4ð\ 4ö\ 4õ\ 4ô\ 4÷\ 4ö\ 4ô\ 4ú\ 4ù\ 4ø\ 4û\ 4ú\ 4ø\ 4þ\ 4ý\ 4ü\ 4ÿ\ 4þ\ 4ü\ 4\ 2\ 5\ 1\ 5\0\ 5\ 3\ 5\ 2\ 5\0\ 5\ 6\ 5\ 5\ 5\ 4\ 5\a\ 5\ 6\ 5\ 4\ 5
+\ 5 \ 5\b\ 5\v\ 5
+\ 5\b\ 5\ e\ 5\r\ 5\f\ 5\ f\ 5\ e\ 5\f\ 5\12\ 5\11\ 5\10\ 5\13\ 5\12\ 5\10\ 5\16\ 5\15\ 5\14\ 5\17\ 5\16\ 5\14\ 5\1a\ 5\19\ 5\18\ 5\e\ 5\1a\ 5\18\ 5\1e\ 5\1d\ 5\1c\ 5\1f\ 5\1e\ 5\1c\ 5"\ 5!\ 5 \ 5#\ 5"\ 5 \ 5&\ 5%\ 5$\ 5'\ 5&\ 5$\ 5*\ 5)\ 5(\ 5+\ 5*\ 5(\ 5.\ 5-\ 5,\ 5/\ 5.\ 5,\ 52\ 51\ 50\ 53\ 52\ 50\ 56\ 55\ 54\ 57\ 56\ 54\ 5:\ 59\ 58\ 5;\ 5:\ 58\ 5>\ 5=\ 5<\ 5?\ 5>\ 5<\ 5B\ 5A\ 5@\ 5C\ 5B\ 5@\ 5F\ 5E\ 5D\ 5G\ 5F\ 5D\ 5J\ 5I\ 5H\ 5K\ 5J\ 5H\ 5N\ 5M\ 5L\ 5O\ 5N\ 5L\ 5R\ 5Q\ 5P\ 5S\ 5R\ 5P\ 5V\ 5U\ 5T\ 5W\ 5V\ 5T\ 5Z\ 5Y\ 5X\ 5[\ 5Z\ 5X\ 5^\ 5]\ 5\\ 5_\ 5^\ 5\\ 5b\ 5a\ 5`\ 5c\ 5b\ 5`\ 5f\ 5e\ 5d\ 5g\ 5f\ 5d\ 5j\ 5i\ 5h\ 5k\ 5j\ 5h\ 5n\ 5m\ 5l\ 5o\ 5n\ 5l\ 5r\ 5q\ 5p\ 5s\ 5r\ 5p\ 5v\ 5u\ 5t\ 5w\ 5v\ 5t\ 5z\ 5y\ 5x\ 5{\ 5z\ 5x\ 5~\ 5}\ 5|\ 5\7f\ 5~\ 5|\ 5\82\ 5\81\ 5\80\ 5\83\ 5\82\ 5\80\ 5\86\ 5\85\ 5\84\ 5\87\ 5\86\ 5\84\ 5\8a\ 5\89\ 5\88\ 5\8b\ 5\8a\ 5\88\ 5\8e\ 5\8d\ 5\8c\ 5\8f\ 5\8e\ 5\8c\ 5\92\ 5\91\ 5\90\ 5\93\ 5\92\ 5\90\ 5\96\ 5\95\ 5\94\ 5\97\ 5\96\ 5\94\ 5\9a\ 5\99\ 5\98\ 5\9b\ 5\9a\ 5\98\ 5\9e\ 5\9d\ 5\9c\ 5\9f\ 5\9e\ 5\9c\ 5¢\ 5¡\ 5 \ 5£\ 5¢\ 5 \ 5¦\ 5¥\ 5¤\ 5§\ 5¦\ 5¤\ 5ª\ 5©\ 5¨\ 5«\ 5ª\ 5¨\ 5®\ 5\ 5¬\ 5¯\ 5®\ 5¬\ 5²\ 5±\ 5°\ 5³\ 5²\ 5°\ 5¶\ 5µ\ 5´\ 5·\ 5¶\ 5´\ 5º\ 5¹\ 5¸\ 5»\ 5º\ 5¸\ 5¾\ 5½\ 5¼\ 5¿\ 5¾\ 5¼\ 5Â\ 5Á\ 5À\ 5Ã\ 5Â\ 5À\ 5Æ\ 5Å\ 5Ä\ 5Ç\ 5Æ\ 5Ä\ 5Ê\ 5É\ 5È\ 5Ë\ 5Ê\ 5È\ 5Î\ 5Í\ 5Ì\ 5Ï\ 5Î\ 5Ì\ 5Ò\ 5Ñ\ 5Ð\ 5Ó\ 5Ò\ 5Ð\ 5Ö\ 5Õ\ 5Ô\ 5×\ 5Ö\ 5Ô\ 5Ú\ 5Ù\ 5Ø\ 5Û\ 5Ú\ 5Ø\ 5Þ\ 5Ý\ 5Ü\ 5ß\ 5Þ\ 5Ü\ 5â\ 5á\ 5à\ 5ã\ 5â\ 5à\ 5æ\ 5å\ 5ä\ 5ç\ 5æ\ 5ä\ 5ê\ 5é\ 5è\ 5ë\ 5ê\ 5è\ 5î\ 5í\ 5ì\ 5ï\ 5î\ 5ì\ 5ò\ 5ñ\ 5ð\ 5ó\ 5ò\ 5ð\ 5ö\ 5õ\ 5ô\ 5÷\ 5ö\ 5ô\ 5ú\ 5ù\ 5ø\ 5û\ 5ú\ 5ø\ 5þ\ 5ý\ 5ü\ 5ÿ\ 5þ\ 5ü\ 5\ 2\ 6\ 1\ 6\0\ 6\ 3\ 6\ 2\ 6\0\ 6\ 6\ 6\ 5\ 6\ 4\ 6\a\ 6\ 6\ 6\ 4\ 6
+\ 6 \ 6\b\ 6\v\ 6
+\ 6\b\ 6\ e\ 6\r\ 6\f\ 6\ f\ 6\ e\ 6\f\ 6\12\ 6\11\ 6\10\ 6\13\ 6\12\ 6\10\ 6\16\ 6\15\ 6\14\ 6\17\ 6\16\ 6\14\ 6\1a\ 6\19\ 6\18\ 6\e\ 6\1a\ 6\18\ 6\1e\ 6\1d\ 6\1c\ 6\1f\ 6\1e\ 6\1c\ 6"\ 6!\ 6 \ 6#\ 6"\ 6 \ 6&\ 6%\ 6$\ 6'\ 6&\ 6$\ 6*\ 6)\ 6(\ 6+\ 6*\ 6(\ 6.\ 6-\ 6,\ 6/\ 6.\ 6,\ 62\ 61\ 60\ 63\ 62\ 60\ 66\ 65\ 64\ 67\ 66\ 64\ 6:\ 69\ 68\ 6;\ 6:\ 68\ 6>\ 6=\ 6<\ 6?\ 6>\ 6<\ 6B\ 6A\ 6@\ 6C\ 6B\ 6@\ 6F\ 6E\ 6D\ 6G\ 6F\ 6D\ 6J\ 6I\ 6H\ 6K\ 6J\ 6H\ 6N\ 6M\ 6L\ 6O\ 6N\ 6L\ 6R\ 6Q\ 6P\ 6S\ 6R\ 6P\ 6V\ 6U\ 6T\ 6W\ 6V\ 6T\ 6Z\ 6Y\ 6X\ 6[\ 6Z\ 6X\ 6^\ 6]\ 6\\ 6_\ 6^\ 6\\ 6b\ 6a\ 6`\ 6c\ 6b\ 6`\ 6f\ 6e\ 6d\ 6g\ 6f\ 6d\ 6j\ 6i\ 6h\ 6k\ 6j\ 6h\ 6n\ 6m\ 6l\ 6o\ 6n\ 6l\ 6r\ 6q\ 6p\ 6s\ 6r\ 6p\ 6v\ 6u\ 6t\ 6w\ 6v\ 6t\ 6z\ 6y\ 6x\ 6{\ 6z\ 6x\ 6~\ 6}\ 6|\ 6\7f\ 6~\ 6|\ 6\82\ 6\81\ 6\80\ 6\83\ 6\82\ 6\80\ 6\86\ 6\85\ 6\84\ 6\87\ 6\86\ 6\84\ 6\8a\ 6\89\ 6\88\ 6\8b\ 6\8a\ 6\88\ 6\8e\ 6\8d\ 6\8c\ 6\8f\ 6\8e\ 6\8c\ 6\92\ 6\91\ 6\90\ 6\93\ 6\92\ 6\90\ 6\96\ 6\95\ 6\94\ 6\97\ 6\96\ 6\94\ 6\9a\ 6\99\ 6\98\ 6\9b\ 6\9a\ 6\98\ 6\9e\ 6\9d\ 6\9c\ 6\9f\ 6\9e\ 6\9c\ 6¢\ 6¡\ 6 \ 6£\ 6¢\ 6 \ 6¦\ 6¥\ 6¤\ 6§\ 6¦\ 6¤\ 6ª\ 6©\ 6¨\ 6«\ 6ª\ 6¨\ 6®\ 6\ 6¬\ 6¯\ 6®\ 6¬\ 6²\ 6±\ 6°\ 6³\ 6²\ 6°\ 6¶\ 6µ\ 6´\ 6·\ 6¶\ 6´\ 6º\ 6¹\ 6¸\ 6»\ 6º\ 6¸\ 6¾\ 6½\ 6¼\ 6¿\ 6¾\ 6¼\ 6Â\ 6Á\ 6À\ 6Ã\ 6Â\ 6À\ 6Æ\ 6Å\ 6Ä\ 6Ç\ 6Æ\ 6Ä\ 6Ê\ 6É\ 6È\ 6Ë\ 6Ê\ 6È\ 6Î\ 6Í\ 6Ì\ 6Ï\ 6Î\ 6Ì\ 6Ò\ 6Ñ\ 6Ð\ 6Ó\ 6Ò\ 6Ð\ 6Ö\ 6Õ\ 6Ô\ 6×\ 6Ö\ 6Ô\ 6Ú\ 6Ù\ 6Ø\ 6Û\ 6Ú\ 6Ø\ 6Þ\ 6Ý\ 6Ü\ 6ß\ 6Þ\ 6Ü\ 6â\ 6á\ 6à\ 6ã\ 6â\ 6à\ 6æ\ 6å\ 6ä\ 6ç\ 6æ\ 6ä\ 6ê\ 6é\ 6è\ 6ë\ 6ê\ 6è\ 6î\ 6í\ 6ì\ 6ï\ 6î\ 6ì\ 6ò\ 6ñ\ 6ð\ 6ó\ 6ò\ 6ð\ 6ö\ 6õ\ 6ô\ 6÷\ 6ö\ 6ô\ 6ú\ 6ù\ 6ø\ 6û\ 6ú\ 6ø\ 6þ\ 6ý\ 6ü\ 6ÿ\ 6þ\ 6ü\ 6\ 2\a\ 1\a\0\a\ 3\a\ 2\a\0\a\ 6\a\ 5\a\ 4\a\a\a\ 6\a\ 4\a
+\a \a\b\a\v\a
+\a\b\a\ e\a\r\a\f\a\ f\a\ e\a\f\a\12\a\11\a\10\a\13\a\12\a\10\a\16\a\15\a\14\a\17\a\16\a\14\a\1a\a\19\a\18\a\e\a\1a\a\18\a\1e\a\1d\a\1c\a\1f\a\1e\a\1c\a"\a!\a \a#\a"\a \a&\a%\a$\a'\a&\a$\a*\a)\a(\a+\a*\a(\a.\a-\a,\a/\a.\a,\a2\a1\a0\a3\a2\a0\a6\a5\a4\a7\a6\a4\a:\a9\a8\a;\a:\a8\a>\a=\a<\a?\a>\a<\aB\aA\a@\aC\aB\a@\aF\aE\aD\aG\aF\aD\aJ\aI\aH\aK\aJ\aH\aN\aM\aL\aO\aN\aL\aR\aQ\aP\aS\aR\aP\a\0\0\0\0\89\88\b=\89\88\88=ÎÌÌ=\89\88\b>«ª*>ÍÌL>ïîn>\89\88\88>\9a\99\99>«ªª>¼»»>ÍÌÌ>ÞÝÝ>ïîî>\0\0\0?\89\88\b?\12\11\11?\9b\99\19?$""?ª*?633?¿»;?HDD?ÑÌL?ZUU?ãÝ]?lff?õîn?~ww?\ 3\0\80?GD\84?\8b\88\88?ÏÌ\8c?\13\11\91?WU\95?\9b\99\99?ßÝ\9d?#"¢?gf¦?«ªª?ïî®?33³?ww·?»»»?ÿÿ¿?CDÄ?\87\88È?ËÌÌ?\ f\11Ñ?SUÕ?\97\99Ù?ÛÝÝ?\1f"â?cfæ?§ªê?ëîî?/3ó?sw÷?·»û?ûÿÿ? "\ 2@BD\ 4@df\ 6@\86\88\b@¨ª
+@ÊÌ\f@ìî\ e@\ e\11\11@03\13@RU\15@tw\17@\96\99\19@¸»\e@ÚÝ\1d@üÿ\1f@\1e""@@D$@bf&@\84\88(@¦ª*@ÈÌ,@êî.@\f\111@.33@PU5@rw7@\94\999@¶»;@ØÝ=@úÿ?@\1c"B@>DD@`fF@\82\88H@¤ªJ@ÆÌL@èîN@
+\11Q@,3S@NUU@pwW@\92\99Y@´»[@ÖÝ]@øÿ_@\1a"b@<Dd@^ff@\80\88h@¢ªj@ÄÌl@æîn@\b\11q@*3s@LUu@nww@\90\99y@²»{@ÔÝ}@öÿ\7f@\f\11\81@\1d"\82@.3\83@?D\84@PU\85@af\86@rw\87@\83\88\88@\94\99\89@¥ª\8a@¶»\8b@ÇÌ\8c@ØÝ\8d@éî\8e@úÿ\8f@\v\11\91@\1c"\92@-3\93@>D\94@OU\95@`f\96@qw\97@\82\88\98@\93\99\99@¤ª\9a@µ»\9b@ÆÌ\9c@×Ý\9d@èî\9e@ùÿ\9f@
+\11¡@\e"¢@,3£@=D¤@NU¥@_f¦@pw§@\81\88¨@\92\99©@£ªª@´»«@Å̬@ÖÝ@çî®@øÿ¯@ \11±@\1a"²@+3³@<D´@MUµ@^f¶@ow·@\80\88¸@\91\99¹@¢ªº@³»»@Ä̼@Õݽ@æî¾@÷ÿ¿@\b\11Á@\19"Â@*3Ã@;DÄ@LUÅ@]fÆ@nwÇ@\7f\88È@\90\99É@¡ªÊ@²»Ë@ÃÌÌ@ÔÝÍ@åîÎ@öÿÏ@\a\11Ñ@\18"Ò@)3Ó@:DÔ@KUÕ@\fÖ@mw×@~\88Ø@\8f\99Ù@ ªÚ@±»Û@ÂÌÜ@ÓÝÝ@äîÞ@õÿß@\ 6\11á@\17"â@(3ã@9Dä@JUå@[fæ@\0\0\0\0\0\0\0\0\0\0\0\0½\1ak:\0\0\0\0¼Xh;\0\0\0\0Ê$\ 1<\0\0\0\0»Ôb<\0\0\0\0¡\ e¯<\0\0\0\0Ñúø<\0\0\0\0EU'=\0\0\0\0ºÌW=\0\0\0\0ÈÐ\86=\0\0\0\0ÏH¤=\0\0\0\0W-Ä=\0\0\0\0L]æ=\0\0\0\0È[\ 5>\0\0\0\0\88\8d\18>\0\0\0\0Z³,>\0\0\0\0²¼A>\0\0\0\0\ 3\99W>\0\0\0\0Á7n>\0\0\0\01Ä\82>\0\0\0\0,½\8e>\0\0\0\0\8bþ\9a>\0\0\0\0\b\80§>\0\0\0\0_9´>\0\0\0\0F"Á>\0\0\0\0}2Î>\0\0\0\0ºaÛ>\0\0\0\0¶§è>\0\0\0\0-üõ>\0\0\0\0l«\ 1?\0\0\0\0¸W\b?\0\0\0\0Ùþ\ e?\0\0\0\0ª\9c\15?\0\0\0\0
+-\1c?\0\0\0\0Õ«"?\0\0\0\0è\14)?\0\0\0\0 d/?\0\0\0\0\\955?\0\0\0\0v¤;?\0\0\0\0M\8dA?\0\0\0\0»KG?\0\0\0\0¡ÛL?\0\0\0\0Ú8R?\0\0\0\0D_W?\0\0\0\0ºJ\?\0\0\0\0\e÷`?\0\0\0\0C`e?\0\0\0\0\ e\82i?\0\0\0\0[Xm?\0\0\0\0\bßp?\0\0\0\0î\11t?\0\0\0\0íìv?\0\0\0\0áky?\0\0\0\0¦\8a{?\0\0\0\0\1cE}?\0\0\0\0\1f\97~?\0\0\0\0\8a|\7f?\0\0\0\0;ñ\7f?\12þ\169\91ö\7f?óJ¨:Û«\7f?
+\8cg;t\18\7f?3Äà;w>~?±ÿ7<\ 1 }?}\1a\88<,¿{?\8f=¼<\13\1ez?£%ø<Ó>x?¤Ç\1d=\85#v?\8a\eC=HÎs?Ïìk=3Aq?Ý\f\8c=d~n?LÀ£=÷\87k?Øÿ¼=\ 5`h?¥º×=¬\be?Úßó=\ 5\84a?O¯\b>-Ô]?\a\13\18>?ûY?ª\12(>VûU?Í¥8>\8dÖQ?ýÃI>\0\8fM?Ñd[>Ì&I?Ú\7fm>
+ D?T\ 6\80>Öü??h\81\89>L?;?ó,\93>\86i6?¼\ 4\9d>¡}1?\8f\ 4§>¸},?3(±>æk'?rk»>GJ"?\13ÊÅ>ö\1a\1d?ä?Ð>\ eà\17?¬ÈÚ>ª\9b\12?2`å>çO\r?A\ 2ð>ßþ\a?£ªú>¯ª\ 2?\8fª\ 2?áªú>Àþ\a?\80\ 2ð>ÈO\r?q`å>\8c\9b\12?èÈÚ>ïß\17?!@Ð>Ø\1a\1d?QÊÅ>*J"?k»>Ék'?n(±>\9b},?Ê\ 4§>\84}1?ø\ 4\9d>ji6?,-\93>/?;?¡\81\89>ºü??\8d\ 6\80>ï\9fD?C\80m>²&I?8e[>è\8eM?aÄI>tÖQ?.¦8>=ûU?
+\13(>(ûY?a\13\18>\17Ô]?¤¯\b>ñ\83a?{àó=\97\be?H»×=ó_h?f\0½=æ\87k?ÍÀ£=T~n?\\r\8c=$Aq?Ãík=:Îs?f\1cC={#v?RÈ\1d=Ê>x?¸&ø<
+\1ez?¸>¼<%¿{?\\e\88<ú\1f}?\9a\ 18<s>~?fÆà;q\18\7f?\\8fg;Û«\7f?=J¨:\91ö\7f?Ãõ\169vù\7f?\0\0\0\0\91Å\7f?\0\0\0\0ò^\7f?\0\0\0\0ÏÆ~?\0\0\0\0_þ}?\0\0\0\0Ú\ 6}?\0\0\0\0tá{?\0\0\0\0i\8fz?\0\0\0\0ì\11y?\0\0\0\06jw?\0\0\0\0}\99u?\0\0\0\0ø s?\0\0\0\0à\81q?\0\0\0\0j=o?\0\0\0\0ÎÔl?\0\0\0\0CIj?\0\0\0\0ÿ\9bg?\0\0\0\0;Îd?\0\0\0\0,áa?\0\0\0\0
+Ö^?\0\0\0\0\ e®[?\0\0\0\0ljX?\0\0\0\0\\fU?\0\0\0\0\16\95Q?\0\0\0\0Ï\ 5N?\0\0\0\0Á_J?\0\0\0\0!¤F?\0\0\0\0(ÔB?\0\0\0\0
+ñ>?\0\0\0\0\0ü:?\0\0\0\0Aö6?\0\0\0\0\ 4á2?\0\0\0\0\80½.?\0\0\0\0ì\8c*?\0\0\0\0\7fP&?\0\0\0\0o "?\0\0\0\0ö¸\1d?\0\0\0\0H`\19?\0\0\0\0\9d\0\15?\0\0\0\0.\9b\10?\0\0\0\001\f?\0\0\0\0ÚÃ\a?\0\0\0\0dT\ 3?\0\0\0\0
+Èý>\0\0\0\0èçô>\0\0\0\0Ì
+ì>\0\0\0\0,3ã>\0\0\0\0ncÚ>\0\0\0\0\ 5\9eÑ>\0\0\0\0]åÈ>\0\0\0\0é;À>\0\0\0\0\12¤·>\0\0\0\0H ¯>\0\0\0\0ö²¦>\0\0\0\0\92^\9e>\0\0\0\0}%\96>\0\0\0\03
+\8e>\0\0\0\0\1a\ f\86>\0\0\0\0Hm|>\0\0\0\0v\ 6m>\0\0\0\0\9fî]>\0\0\0\0\9f*O>\0\0\0\0\¿@>\0\0\0\0\9f±2>\0\0\0\0R\ 6%>\0\0\0\0HÂ\17>\0\0\0\0lê
+>\0\0\0\0\14\aý=\0\0\0\0\14%å=\0\0\0\0\858Î=\0\0\0\0\1fK¸=\0\0\0\0\9af£=\0\0\0\0¸\94\8f=\0\0\0\0)¾y=\0\0\0\0H\9fV=\0\0\0\0×ß5=\0\0\0\0H\93\17=\0\0\0\0f\9a÷<\0\0\0\0ìAÅ<\0\0\0\0\0D\98<\0\0\0\0®\8fa<\0\0\0\0Rè\1d<\0\0\0\0¸¾Ë;\0\0\0\0=
+g;\0\0\0\0áúÎ:\0\0\0\0\9a\99Ð9\0\0\0\0
+×#´\0\0\0\0
\ No newline at end of file
--- /dev/null
+{\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.009999998,\r
+ 0.009999991,\r
+ 0.01\r
+ ],\r
+ "min": [\r
+ -0.0100000026,\r
+ -0.0100000035,\r
+ -0.01\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "name": "Ship"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.0313265175,\r
+ 0.0226246975,\r
+ 0.008465132\r
+ ],\r
+ "min": [\r
+ -0.0313265137,\r
+ -0.022857653,\r
+ 0.0\r
+ ],\r
+ "name": "Ship"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "name": "Ship"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "name": "Blob"\r
+ },\r
+ {\r
+ "bufferView": 7,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.008781092,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ -0.008781091,\r
+ -0.0007655843,\r
+ 0.0\r
+ ],\r
+ "name": "Blob"\r
+ },\r
+ {\r
+ "bufferView": 8,\r
+ "componentType": 5126,\r
+ "count": 1876,\r
+ "type": "VEC3",\r
+ "name": "Blob"\r
+ },\r
+ {\r
+ "bufferView": 9,\r
+ "componentType": 5123,\r
+ "count": 2880,\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 10,\r
+ "componentType": 5126,\r
+ "count": 217,\r
+ "type": "SCALAR",\r
+ "max": [\r
+ 7.19999456\r
+ ],\r
+ "min": [\r
+ 0.0\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 11,\r
+ "componentType": 5126,\r
+ "count": 434,\r
+ "type": "SCALAR"\r
+ }\r
+ ],\r
+ "animations": [\r
+ {\r
+ "channels": [\r
+ {\r
+ "sampler": 0,\r
+ "target": {\r
+ "node": 0,\r
+ "path": "weights"\r
+ }\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "input": 10,\r
+ "interpolation": "LINEAR",\r
+ "output": 11\r
+ }\r
+ ],\r
+ "name": "Globe"\r
+ }\r
+ ],\r
+ "asset": {\r
+ "generator": "glTF Tools for Unity",\r
+ "version": "2.0"\r
+ },\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 22512,\r
+ "byteLength": 30016\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 52528,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 75040,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 97552,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 120064,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 142576,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 165088,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 187600,\r
+ "byteLength": 22512\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 210112,\r
+ "byteLength": 5760\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 215872,\r
+ "byteLength": 868\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 216740,\r
+ "byteLength": 1736\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "uri": "AnimatedMorphSphere.bin",\r
+ "byteLength": 218476\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 0,\r
+ "TANGENT": 1,\r
+ "POSITION": 2\r
+ },\r
+ "indices": 9,\r
+ "material": 0,\r
+ "targets": [\r
+ {\r
+ "NORMAL": 3,\r
+ "POSITION": 4,\r
+ "TANGENT": 5\r
+ },\r
+ {\r
+ "NORMAL": 6,\r
+ "POSITION": 7,\r
+ "TANGENT": 8\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "weights": [\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "name": "Sphere"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "metallicFactor": 0.0,\r
+ "roughnessFactor": 0.5\r
+ },\r
+ "name": "No Name"\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "mesh": 0,\r
+ "rotation": [\r
+ 0.0,\r
+ 0.7071067,\r
+ -0.7071068,\r
+ 0.0\r
+ ],\r
+ "scale": [\r
+ 100.0,\r
+ 100.0,\r
+ 100.0\r
+ ],\r
+ "name": "AnimatedMorphSphere"\r
+ }\r
+ ],\r
+ "scene": 0,\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 0\r
+ ]\r
+ }\r
+ ]\r
+}
\ No newline at end of file
--- /dev/null
+{\r
+ "scene" : 0,\r
+ "scenes" : [\r
+ {\r
+ "nodes" : [ 0 ]\r
+ }\r
+ ],\r
+ \r
+ "nodes" : [\r
+ {\r
+ "mesh" : 0,\r
+ "rotation" : [ 0.0, 0.0, 0.0, 1.0 ]\r
+ }\r
+ ],\r
+ \r
+ "meshes" : [\r
+ {\r
+ "primitives" : [ {\r
+ "attributes" : {\r
+ "POSITION" : 1\r
+ },\r
+ "indices" : 0\r
+ } ]\r
+ }\r
+ ],\r
+ \r
+ "animations": [\r
+ {\r
+ "samplers" : [\r
+ {\r
+ "input" : 2,\r
+ "interpolation" : "LINEAR",\r
+ "output" : 3\r
+ }\r
+ ],\r
+ "channels" : [ {\r
+ "sampler" : 0,\r
+ "target" : {\r
+ "node" : 0,\r
+ "path" : "rotation"\r
+ }\r
+ } ]\r
+ }\r
+ ],\r
+\r
+ "buffers" : [\r
+ {\r
+ "uri" : "simpleTriangle.bin",\r
+ "byteLength" : 44\r
+ },\r
+ {\r
+ "uri" : "animation.bin",\r
+ "byteLength" : 100\r
+ }\r
+ ],\r
+ "bufferViews" : [\r
+ {\r
+ "buffer" : 0,\r
+ "byteOffset" : 0,\r
+ "byteLength" : 6,\r
+ "target" : 34963\r
+ },\r
+ {\r
+ "buffer" : 0,\r
+ "byteOffset" : 8,\r
+ "byteLength" : 36,\r
+ "target" : 34962\r
+ },\r
+ {\r
+ "buffer" : 1,\r
+ "byteOffset" : 0,\r
+ "byteLength" : 100\r
+ }\r
+ ],\r
+ "accessors" : [\r
+ {\r
+ "bufferView" : 0,\r
+ "byteOffset" : 0,\r
+ "componentType" : 5123,\r
+ "count" : 3,\r
+ "type" : "SCALAR",\r
+ "max" : [ 2 ],\r
+ "min" : [ 0 ]\r
+ },\r
+ {\r
+ "bufferView" : 1,\r
+ "byteOffset" : 0,\r
+ "componentType" : 5126,\r
+ "count" : 3,\r
+ "type" : "VEC3",\r
+ "max" : [ 1.0, 1.0, 0.0 ],\r
+ "min" : [ 0.0, 0.0, 0.0 ]\r
+ },\r
+ {\r
+ "bufferView" : 2,\r
+ "byteOffset" : 0,\r
+ "componentType" : 5126,\r
+ "count" : 5,\r
+ "type" : "SCALAR",\r
+ "max" : [ 1.0 ],\r
+ "min" : [ 0.0 ]\r
+ },\r
+ {\r
+ "bufferView" : 2,\r
+ "byteOffset" : 20,\r
+ "componentType" : 5126,\r
+ "count" : 5,\r
+ "type" : "VEC4",\r
+ "max" : [ 0.0, 0.0, 1.0, 1.0 ],\r
+ "min" : [ 0.0, 0.0, 0.0, -0.707 ]\r
+ }\r
+ ],\r
+ \r
+ "asset" : {\r
+ "version" : "2.0"\r
+ }\r
+ \r
+}\r
--- /dev/null
+{\r
+ "asset": {\r
+ "generator": "COLLADA2GLTF",\r
+ "version": "2.0"\r
+ },\r
+ "scene": 0,\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 3,\r
+ 0\r
+ ]\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "children": [\r
+ 1\r
+ ],\r
+ "rotation": [\r
+ -0.0,\r
+ -0.0,\r
+ -0.0,\r
+ -1.0\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 2\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "rotation": [\r
+ -0.0,\r
+ -0.0,\r
+ -0.0,\r
+ -1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 1\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 1,\r
+ "POSITION": 2\r
+ },\r
+ "indices": 0,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "inner_box"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 4,\r
+ "POSITION": 5\r
+ },\r
+ "indices": 3,\r
+ "mode": 4,\r
+ "material": 1\r
+ }\r
+ ],\r
+ "name": "outer_box"\r
+ }\r
+ ],\r
+ "animations": [\r
+ {\r
+ "channels": [\r
+ {\r
+ "sampler": 0,\r
+ "target": {\r
+ "node": 2,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 1,\r
+ "target": {\r
+ "node": 0,\r
+ "path": "translation"\r
+ }\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "input": 6,\r
+ "interpolation": "LINEAR",\r
+ "output": 7\r
+ },\r
+ {\r
+ "input": 8,\r
+ "interpolation": "LINEAR",\r
+ "output": 9\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 0,\r
+ "componentType": 5123,\r
+ "count": 186,\r
+ "max": [\r
+ 95\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 96,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1152,\r
+ "componentType": 5126,\r
+ "count": 96,\r
+ "max": [\r
+ 0.33504000306129458,\r
+ 0.5,\r
+ 0.33504000306129458\r
+ ],\r
+ "min": [\r
+ -0.33504000306129458,\r
+ -0.5,\r
+ -0.33504000306129458\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 372,\r
+ "componentType": 5123,\r
+ "count": 576,\r
+ "max": [\r
+ 223\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 2304,\r
+ "componentType": 5126,\r
+ "count": 224,\r
+ "max": [\r
+ 1.0,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 4992,\r
+ "componentType": 5126,\r
+ "count": 224,\r
+ "max": [\r
+ 0.5,\r
+ 0.5,\r
+ 0.5\r
+ ],\r
+ "min": [\r
+ -0.5,\r
+ -0.5,\r
+ -0.5\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 2,\r
+ "max": [\r
+ 2.5\r
+ ],\r
+ "min": [\r
+ 1.25\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 2,\r
+ "max": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 4.4896593387466768e-11\r
+ ],\r
+ "min": [\r
+ -0.0,\r
+ 0.0,\r
+ 0.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 8,\r
+ "componentType": 5126,\r
+ "count": 4,\r
+ "max": [\r
+ 3.708329916000366\r
+ ],\r
+ "min": [\r
+ 0.0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 4,\r
+ "max": [\r
+ 0.0,\r
+ 2.5199999809265138,\r
+ 0.0\r
+ ],\r
+ "min": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ],\r
+ "type": "VEC3"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.800000011920929,\r
+ 0.4159420132637024,\r
+ 0.7952920198440552,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "name": "inner"\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.3016040027141571,\r
+ 0.5335419774055481,\r
+ 0.800000011920929,\r
+ 1.0\r
+ ],\r
+ "metallicFactor": 0.0\r
+ },\r
+ "name": "outer"\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 7784,\r
+ "byteLength": 1524,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 80,\r
+ "byteLength": 7680,\r
+ "byteStride": 12,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 7760,\r
+ "byteLength": 24\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 0,\r
+ "byteLength": 32\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 32,\r
+ "byteLength": 48\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "byteLength": 9308,\r
+ "uri": "BoxAnimated0.bin"\r
+ }\r
+ ]\r
+}\r
--- /dev/null
+{\r
+ "asset": {\r
+ "generator": "COLLADA2GLTF",\r
+ "version": "2.0"\r
+ },\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 0\r
+ ]\r
+ }\r
+ ],\r
+ "scene": 0,\r
+ "nodes": [\r
+ {\r
+ "children": [\r
+ 1\r
+ ],\r
+ "matrix": [\r
+ 1,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ -1,\r
+ 0,\r
+ 0,\r
+ 1,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 1\r
+ ],\r
+ "name": "Z_UP"\r
+ },\r
+ {\r
+ "children": [\r
+ 3,\r
+ 2\r
+ ],\r
+ "matrix": [\r
+ -4.371139894487897e-8,\r
+ -1,\r
+ 0,\r
+ 0,\r
+ 1,\r
+ -4.371139894487897e-8,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 1,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 1\r
+ ],\r
+ "name": "Armature"\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "skin": 0,\r
+ "name": "Cesium_Man"\r
+ },\r
+ {\r
+ "children": [\r
+ 12,\r
+ 8,\r
+ 4\r
+ ],\r
+ "translation": [\r
+ 1.57554005397742e-8,\r
+ 0.004999836906790733,\r
+ 0.6789999008178711\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.0378035344183445,\r
+ 0,\r
+ -0.9992852210998536\r
+ ],\r
+ "name": "Skeleton_torso_joint_1",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 5\r
+ ],\r
+ "translation": [\r
+ 0.02855719067156315,\r
+ -0.06803914159536362,\r
+ -0.06295864284038544\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.6898291707038879,\r
+ 0,\r
+ -0.7239722013473511\r
+ ],\r
+ "name": "leg_joint_R_1",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 6\r
+ ],\r
+ "translation": [\r
+ 0.26089081168174744,\r
+ -0.009026050567626951,\r
+ 0.05167089030146599\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.0941137745976448,\r
+ 0,\r
+ -0.9955614805221558\r
+ ],\r
+ "scale": [\r
+ 1.0000001192092896,\r
+ 1,\r
+ 1.0000001192092896\r
+ ],\r
+ "name": "leg_joint_R_2"\r
+ },\r
+ {\r
+ "children": [\r
+ 7\r
+ ],\r
+ "translation": [\r
+ 0.27546030282974243,\r
+ -0.0014317259192466736,\r
+ -0.014104830101132391\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.8666408061981201,\r
+ 0,\r
+ 0.4989325702190399\r
+ ],\r
+ "name": "leg_joint_R_3",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "translation": [\r
+ -0.06681963056325912,\r
+ -0.001072264974936843,\r
+ 0.026351310312747955\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.3269147574901581,\r
+ 0,\r
+ -0.9450538158416748\r
+ ],\r
+ "name": "leg_joint_R_5",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 9\r
+ ],\r
+ "translation": [\r
+ 0.028519999235868457,\r
+ 0.06803944706916809,\r
+ -0.06295935809612274\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.32463353872299194,\r
+ 0,\r
+ -0.9458398818969728\r
+ ],\r
+ "name": "leg_joint_L_1",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 10\r
+ ],\r
+ "translation": [\r
+ 0.20916390419006348,\r
+ 0.009055502712726591,\r
+ -0.16426950693130493\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.5294369459152222,\r
+ 0,\r
+ -0.8483493328094482\r
+ ],\r
+ "scale": [\r
+ 1.0000001192092896,\r
+ 1,\r
+ 1.0000001192092896\r
+ ],\r
+ "name": "leg_joint_L_2"\r
+ },\r
+ {\r
+ "children": [\r
+ 11\r
+ ],\r
+ "translation": [\r
+ 0.27579009532928467,\r
+ 0.0013972519664093852,\r
+ 0.004122479818761349\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.8377647399902344,\r
+ 0,\r
+ -0.5460314750671387\r
+ ],\r
+ "scale": [\r
+ 1,\r
+ 0.9999999403953552,\r
+ 1\r
+ ],\r
+ "name": "leg_joint_L_3"\r
+ },\r
+ {\r
+ "translation": [\r
+ -0.06558381021022797,\r
+ 0.001090653007850051,\r
+ 0.02929146029055119\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.3130458891391754,\r
+ 0,\r
+ -0.9497380256652832\r
+ ],\r
+ "name": "leg_joint_L_5",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 13\r
+ ],\r
+ "translation": [\r
+ 0.0000133617004394182,\r
+ -0.000013373800356930587,\r
+ 0.14541690051555634\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.6573964357376099,\r
+ 0,\r
+ -0.7535448670387268\r
+ ],\r
+ "name": "Skeleton_torso_joint_2",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 20,\r
+ 17,\r
+ 14\r
+ ],\r
+ "translation": [\r
+ -0.2505168914794922,\r
+ 6.072219775887788e-7,\r
+ -0.00007290810026461259\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.6227028965950012,\r
+ 0,\r
+ -0.7824583649635315\r
+ ],\r
+ "name": "torso_joint_3",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 15\r
+ ],\r
+ "translation": [\r
+ -0.00003830249988823198,\r
+ -0.09098774939775468,\r
+ -0.000062032304413151\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.9909319281578064,\r
+ 0,\r
+ -0.13436488807201385\r
+ ],\r
+ "name": "Skeleton_arm_joint_R",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 16\r
+ ],\r
+ "translation": [\r
+ -0.03554634004831314,\r
+ -0.2154989987611771,\r
+ 0.10423289984464645\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.8961479663848877,\r
+ 0,\r
+ 0.4437553286552429\r
+ ],\r
+ "scale": [\r
+ 0.9999999403953552,\r
+ 1,\r
+ 0.9999999403953552\r
+ ],\r
+ "name": "Skeleton_arm_joint_R__2_"\r
+ },\r
+ {\r
+ "translation": [\r
+ 0.03137021884322167,\r
+ -0.1430010050535202,\r
+ -0.11761169880628586\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.3792171180248261,\r
+ 0,\r
+ -0.9253078103065492\r
+ ],\r
+ "scale": [\r
+ 1.0000001192092896,\r
+ 1,\r
+ 1.0000001192092896\r
+ ],\r
+ "name": "Skeleton_arm_joint_R__3_"\r
+ },\r
+ {\r
+ "children": [\r
+ 18\r
+ ],\r
+ "translation": [\r
+ -0.00003837469921563752,\r
+ 0.091013602912426,\r
+ -0.00006143339851405472\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.9959768652915956,\r
+ 0,\r
+ 0.08961082249879837\r
+ ],\r
+ "name": "Skeleton_arm_joint_L__4_",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 19\r
+ ],\r
+ "translation": [\r
+ 0.01322161965072155,\r
+ 0.21549950540065768,\r
+ 0.10933209955692293\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.0711694285273552,\r
+ 0,\r
+ -0.9974642395973206\r
+ ],\r
+ "name": "Skeleton_arm_joint_L__3_",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "translation": [\r
+ -0.09332461655139924,\r
+ 0.1430000960826874,\r
+ 0.07814791053533554\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.02254222705960274,\r
+ 0,\r
+ -0.9997459053993224\r
+ ],\r
+ "name": "Skeleton_arm_joint_L__2_",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 21\r
+ ],\r
+ "translation": [\r
+ -0.000002366030003031483,\r
+ 0.000002413989932392724,\r
+ 0.06483621150255203\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ -0.660634458065033,\r
+ 0,\r
+ -0.750707745552063\r
+ ],\r
+ "name": "Skeleton_neck_joint_1",\r
+ "scale": [\r
+ 1,\r
+ 1,\r
+ 1\r
+ ]\r
+ },\r
+ {\r
+ "translation": [\r
+ -0.05204017087817192,\r
+ -3.3993298842460724e-8,\r
+ -0.0000026607899599184748\r
+ ],\r
+ "rotation": [\r
+ 0,\r
+ 0.9996904730796814,\r
+ 0,\r
+ 0.024879230186343193\r
+ ],\r
+ "scale": [\r
+ 1.0000001192092896,\r
+ 1,\r
+ 1.0000001192092896\r
+ ],\r
+ "name": "Skeleton_neck_joint_2"\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "JOINTS_0": 1,\r
+ "NORMAL": 2,\r
+ "POSITION": 3,\r
+ "TEXCOORD_0": 4,\r
+ "WEIGHTS_0": 5\r
+ },\r
+ "indices": 0,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "Cesium_Man"\r
+ }\r
+ ],\r
+ "animations": [\r
+ {\r
+ "channels": [\r
+ {\r
+ "sampler": 0,\r
+ "target": {\r
+ "node": 3,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 1,\r
+ "target": {\r
+ "node": 3,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 2,\r
+ "target": {\r
+ "node": 3,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 3,\r
+ "target": {\r
+ "node": 12,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 4,\r
+ "target": {\r
+ "node": 12,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 5,\r
+ "target": {\r
+ "node": 12,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 6,\r
+ "target": {\r
+ "node": 13,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 7,\r
+ "target": {\r
+ "node": 13,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 8,\r
+ "target": {\r
+ "node": 13,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 9,\r
+ "target": {\r
+ "node": 20,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 10,\r
+ "target": {\r
+ "node": 20,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 11,\r
+ "target": {\r
+ "node": 20,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 12,\r
+ "target": {\r
+ "node": 21,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 13,\r
+ "target": {\r
+ "node": 21,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 14,\r
+ "target": {\r
+ "node": 21,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 15,\r
+ "target": {\r
+ "node": 17,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 16,\r
+ "target": {\r
+ "node": 17,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 17,\r
+ "target": {\r
+ "node": 17,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 18,\r
+ "target": {\r
+ "node": 18,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 19,\r
+ "target": {\r
+ "node": 18,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 20,\r
+ "target": {\r
+ "node": 18,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 21,\r
+ "target": {\r
+ "node": 19,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 22,\r
+ "target": {\r
+ "node": 19,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 23,\r
+ "target": {\r
+ "node": 19,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 24,\r
+ "target": {\r
+ "node": 14,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 25,\r
+ "target": {\r
+ "node": 14,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 26,\r
+ "target": {\r
+ "node": 14,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 27,\r
+ "target": {\r
+ "node": 15,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 28,\r
+ "target": {\r
+ "node": 15,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 29,\r
+ "target": {\r
+ "node": 15,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 30,\r
+ "target": {\r
+ "node": 16,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 31,\r
+ "target": {\r
+ "node": 16,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 32,\r
+ "target": {\r
+ "node": 16,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 33,\r
+ "target": {\r
+ "node": 8,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 34,\r
+ "target": {\r
+ "node": 8,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 35,\r
+ "target": {\r
+ "node": 8,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 36,\r
+ "target": {\r
+ "node": 9,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 37,\r
+ "target": {\r
+ "node": 9,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 38,\r
+ "target": {\r
+ "node": 9,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 39,\r
+ "target": {\r
+ "node": 10,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 40,\r
+ "target": {\r
+ "node": 10,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 41,\r
+ "target": {\r
+ "node": 10,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 42,\r
+ "target": {\r
+ "node": 11,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 43,\r
+ "target": {\r
+ "node": 11,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 44,\r
+ "target": {\r
+ "node": 11,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 45,\r
+ "target": {\r
+ "node": 4,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 46,\r
+ "target": {\r
+ "node": 4,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 47,\r
+ "target": {\r
+ "node": 4,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 48,\r
+ "target": {\r
+ "node": 5,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 49,\r
+ "target": {\r
+ "node": 5,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 50,\r
+ "target": {\r
+ "node": 5,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 51,\r
+ "target": {\r
+ "node": 6,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 52,\r
+ "target": {\r
+ "node": 6,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 53,\r
+ "target": {\r
+ "node": 6,\r
+ "path": "scale"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 54,\r
+ "target": {\r
+ "node": 7,\r
+ "path": "translation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 55,\r
+ "target": {\r
+ "node": 7,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 56,\r
+ "target": {\r
+ "node": 7,\r
+ "path": "scale"\r
+ }\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "input": 6,\r
+ "interpolation": "LINEAR",\r
+ "output": 7\r
+ },\r
+ {\r
+ "input": 6,\r
+ "interpolation": "LINEAR",\r
+ "output": 8\r
+ },\r
+ {\r
+ "input": 6,\r
+ "interpolation": "LINEAR",\r
+ "output": 9\r
+ },\r
+ {\r
+ "input": 10,\r
+ "interpolation": "LINEAR",\r
+ "output": 11\r
+ },\r
+ {\r
+ "input": 10,\r
+ "interpolation": "LINEAR",\r
+ "output": 12\r
+ },\r
+ {\r
+ "input": 10,\r
+ "interpolation": "LINEAR",\r
+ "output": 13\r
+ },\r
+ {\r
+ "input": 14,\r
+ "interpolation": "LINEAR",\r
+ "output": 15\r
+ },\r
+ {\r
+ "input": 14,\r
+ "interpolation": "LINEAR",\r
+ "output": 16\r
+ },\r
+ {\r
+ "input": 14,\r
+ "interpolation": "LINEAR",\r
+ "output": 17\r
+ },\r
+ {\r
+ "input": 18,\r
+ "interpolation": "LINEAR",\r
+ "output": 19\r
+ },\r
+ {\r
+ "input": 18,\r
+ "interpolation": "LINEAR",\r
+ "output": 20\r
+ },\r
+ {\r
+ "input": 18,\r
+ "interpolation": "LINEAR",\r
+ "output": 21\r
+ },\r
+ {\r
+ "input": 22,\r
+ "interpolation": "LINEAR",\r
+ "output": 23\r
+ },\r
+ {\r
+ "input": 22,\r
+ "interpolation": "LINEAR",\r
+ "output": 24\r
+ },\r
+ {\r
+ "input": 22,\r
+ "interpolation": "LINEAR",\r
+ "output": 25\r
+ },\r
+ {\r
+ "input": 26,\r
+ "interpolation": "LINEAR",\r
+ "output": 27\r
+ },\r
+ {\r
+ "input": 26,\r
+ "interpolation": "LINEAR",\r
+ "output": 28\r
+ },\r
+ {\r
+ "input": 26,\r
+ "interpolation": "LINEAR",\r
+ "output": 29\r
+ },\r
+ {\r
+ "input": 30,\r
+ "interpolation": "LINEAR",\r
+ "output": 31\r
+ },\r
+ {\r
+ "input": 30,\r
+ "interpolation": "LINEAR",\r
+ "output": 32\r
+ },\r
+ {\r
+ "input": 30,\r
+ "interpolation": "LINEAR",\r
+ "output": 33\r
+ },\r
+ {\r
+ "input": 34,\r
+ "interpolation": "LINEAR",\r
+ "output": 35\r
+ },\r
+ {\r
+ "input": 34,\r
+ "interpolation": "LINEAR",\r
+ "output": 36\r
+ },\r
+ {\r
+ "input": 34,\r
+ "interpolation": "LINEAR",\r
+ "output": 37\r
+ },\r
+ {\r
+ "input": 38,\r
+ "interpolation": "LINEAR",\r
+ "output": 39\r
+ },\r
+ {\r
+ "input": 38,\r
+ "interpolation": "LINEAR",\r
+ "output": 40\r
+ },\r
+ {\r
+ "input": 38,\r
+ "interpolation": "LINEAR",\r
+ "output": 41\r
+ },\r
+ {\r
+ "input": 42,\r
+ "interpolation": "LINEAR",\r
+ "output": 43\r
+ },\r
+ {\r
+ "input": 42,\r
+ "interpolation": "LINEAR",\r
+ "output": 44\r
+ },\r
+ {\r
+ "input": 42,\r
+ "interpolation": "LINEAR",\r
+ "output": 45\r
+ },\r
+ {\r
+ "input": 46,\r
+ "interpolation": "LINEAR",\r
+ "output": 47\r
+ },\r
+ {\r
+ "input": 46,\r
+ "interpolation": "LINEAR",\r
+ "output": 48\r
+ },\r
+ {\r
+ "input": 46,\r
+ "interpolation": "LINEAR",\r
+ "output": 49\r
+ },\r
+ {\r
+ "input": 50,\r
+ "interpolation": "LINEAR",\r
+ "output": 51\r
+ },\r
+ {\r
+ "input": 50,\r
+ "interpolation": "LINEAR",\r
+ "output": 52\r
+ },\r
+ {\r
+ "input": 50,\r
+ "interpolation": "LINEAR",\r
+ "output": 53\r
+ },\r
+ {\r
+ "input": 54,\r
+ "interpolation": "LINEAR",\r
+ "output": 55\r
+ },\r
+ {\r
+ "input": 54,\r
+ "interpolation": "LINEAR",\r
+ "output": 56\r
+ },\r
+ {\r
+ "input": 54,\r
+ "interpolation": "LINEAR",\r
+ "output": 57\r
+ },\r
+ {\r
+ "input": 58,\r
+ "interpolation": "LINEAR",\r
+ "output": 59\r
+ },\r
+ {\r
+ "input": 58,\r
+ "interpolation": "LINEAR",\r
+ "output": 60\r
+ },\r
+ {\r
+ "input": 58,\r
+ "interpolation": "LINEAR",\r
+ "output": 61\r
+ },\r
+ {\r
+ "input": 62,\r
+ "interpolation": "LINEAR",\r
+ "output": 63\r
+ },\r
+ {\r
+ "input": 62,\r
+ "interpolation": "LINEAR",\r
+ "output": 64\r
+ },\r
+ {\r
+ "input": 62,\r
+ "interpolation": "LINEAR",\r
+ "output": 65\r
+ },\r
+ {\r
+ "input": 66,\r
+ "interpolation": "LINEAR",\r
+ "output": 67\r
+ },\r
+ {\r
+ "input": 66,\r
+ "interpolation": "LINEAR",\r
+ "output": 68\r
+ },\r
+ {\r
+ "input": 66,\r
+ "interpolation": "LINEAR",\r
+ "output": 69\r
+ },\r
+ {\r
+ "input": 70,\r
+ "interpolation": "LINEAR",\r
+ "output": 71\r
+ },\r
+ {\r
+ "input": 70,\r
+ "interpolation": "LINEAR",\r
+ "output": 72\r
+ },\r
+ {\r
+ "input": 70,\r
+ "interpolation": "LINEAR",\r
+ "output": 73\r
+ },\r
+ {\r
+ "input": 74,\r
+ "interpolation": "LINEAR",\r
+ "output": 75\r
+ },\r
+ {\r
+ "input": 74,\r
+ "interpolation": "LINEAR",\r
+ "output": 76\r
+ },\r
+ {\r
+ "input": 74,\r
+ "interpolation": "LINEAR",\r
+ "output": 77\r
+ },\r
+ {\r
+ "input": 78,\r
+ "interpolation": "LINEAR",\r
+ "output": 79\r
+ },\r
+ {\r
+ "input": 78,\r
+ "interpolation": "LINEAR",\r
+ "output": 80\r
+ },\r
+ {\r
+ "input": 78,\r
+ "interpolation": "LINEAR",\r
+ "output": 81\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "skins": [\r
+ {\r
+ "inverseBindMatrices": 82,\r
+ "skeleton": 3,\r
+ "joints": [\r
+ 3,\r
+ 12,\r
+ 13,\r
+ 20,\r
+ 21,\r
+ 17,\r
+ 14,\r
+ 18,\r
+ 15,\r
+ 19,\r
+ 16,\r
+ 8,\r
+ 4,\r
+ 9,\r
+ 5,\r
+ 10,\r
+ 6,\r
+ 11,\r
+ 7\r
+ ],\r
+ "name": "Armature"\r
+ }\r
+ ],\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 0,\r
+ "componentType": 5123,\r
+ "count": 14016,\r
+ "max": [\r
+ 3272\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 0,\r
+ "componentType": 5123,\r
+ "count": 3273,\r
+ "max": [\r
+ 18,\r
+ 18,\r
+ 18,\r
+ 18\r
+ ],\r
+ "min": [\r
+ 0,\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 3273,\r
+ "max": [\r
+ 1,\r
+ 0.9999808073043824,\r
+ 0.9944415092468262\r
+ ],\r
+ "min": [\r
+ -1,\r
+ -0.9999808073043824,\r
+ -1\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 39276,\r
+ "componentType": 5126,\r
+ "count": 3273,\r
+ "max": [\r
+ 0.1809539943933487,\r
+ 0.569136917591095,\r
+ 1.5065499544143677\r
+ ],\r
+ "min": [\r
+ -0.13100001215934753,\r
+ -0.5691370964050293,\r
+ 0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 26184,\r
+ "componentType": 5126,\r
+ "count": 3273,\r
+ "max": [\r
+ 0.990805983543396,\r
+ 0.9880298972129822\r
+ ],\r
+ "min": [\r
+ 0.014079390093684196,\r
+ 0.008445978164672852\r
+ ],\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 3273,\r
+ "max": [\r
+ 1,\r
+ 0.989919900894165,\r
+ 0.9510763883590698,\r
+ 0.9196179509162904\r
+ ],\r
+ "min": [\r
+ 0.010080089792609217,\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 3.880559873437051e-8,\r
+ -0.02000010944902897,\r
+ 0.7110069990158081\r
+ ],\r
+ "min": [\r
+ 2.716890046272624e-9,\r
+ -0.030000129714608192,\r
+ 0.6399999856948853\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.0001435002632206306,\r
+ -0.02146764844655991,\r
+ -0.000009948204024112783,\r
+ -0.9980905055999756\r
+ ],\r
+ "min": [\r
+ -0.012384946458041668,\r
+ -0.06042621284723282,\r
+ -0.0041049933061003685,\r
+ -0.9997026920318604\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 576,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000004768371584,\r
+ 1.0000001192092896,\r
+ 1.000000238418579\r
+ ],\r
+ "min": [\r
+ 0.9999999403953552,\r
+ 0.9999998211860656,\r
+ 0.9999997615814208\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 192,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 1152,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.000013520900211005937,\r
+ 0.0009866129839792848,\r
+ 0.1454171985387802\r
+ ],\r
+ "min": [\r
+ 0.000013436199878924528,\r
+ 0.0009865909814834597,\r
+ 0.145416796207428\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 768,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.011148878373205662,\r
+ -0.7106494903564453,\r
+ 0.0006393495132215321,\r
+ -0.6787928938865662\r
+ ],\r
+ "min": [\r
+ -0.008564536459743977,\r
+ -0.7339289784431458,\r
+ -0.025856714695692062,\r
+ -0.7034341096878052\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 1728,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000004768371584,\r
+ 1.000000238418579,\r
+ 0.9999998211860656\r
+ ],\r
+ "min": [\r
+ 0.9999999403953552,\r
+ 0.9999998807907104,\r
+ 0.9999989867210388\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 384,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 2304,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.25051650404930115,\r
+ 5.923209869251878e-7,\r
+ -0.00007277730037458241\r
+ ],\r
+ "min": [\r
+ -0.25051701068878174,\r
+ 5.58793999516638e-7,\r
+ -0.00007287789776455611\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 1536,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.13804565370082855,\r
+ 0.6359269618988037,\r
+ -0.003375347936525941,\r
+ -0.7641801238059998\r
+ ],\r
+ "min": [\r
+ -0.06163197010755539,\r
+ 0.6225405335426331,\r
+ -0.0653248131275177,\r
+ -0.7825579643249512\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 2880,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.000001072883606,\r
+ 1.0000003576278689,\r
+ 1\r
+ ],\r
+ "min": [\r
+ 1.0000004768371584,\r
+ 0.9999999403953552,\r
+ 0.999999463558197\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 576,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 3456,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.000002384189883741783,\r
+ 0.000002458690005369135,\r
+ 0.06483876705169678\r
+ ],\r
+ "min": [\r
+ -0.000002536919964768458,\r
+ 0.000002384189883741783,\r
+ 0.06483828276395798\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 2304,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.0364987850189209,\r
+ -0.6325404644012451,\r
+ 0.04193282127380371,\r
+ -0.749859094619751\r
+ ],\r
+ "min": [\r
+ -0.02474863827228546,\r
+ -0.6592763066291809,\r
+ -0.03008362464606762,\r
+ -0.7735469341278076\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 4032,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1,\r
+ 1.000000238418579,\r
+ 1.000000238418579\r
+ ],\r
+ "min": [\r
+ 0.9999996423721313,\r
+ 0.9999995231628418,\r
+ 0.9999995827674866\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 768,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 4608,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.0520395003259182,\r
+ 7.450579708745408e-9,\r
+ -0.000002585350102890516\r
+ ],\r
+ "min": [\r
+ -0.05204005911946297,\r
+ -5.96045985901128e-8,\r
+ -0.0000026747600259113824\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 3072,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.04680187255144119,\r
+ 0.999507486820221,\r
+ 0.002036086050793529,\r
+ 0.09058715403079988\r
+ ],\r
+ "min": [\r
+ -0.093629889190197,\r
+ 0.9950671792030336,\r
+ -0.00258980062790215,\r
+ 0.0184526015073061\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 5184,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000003576278689,\r
+ 1.000000238418579,\r
+ 1.0000009536743164\r
+ ],\r
+ "min": [\r
+ 0.9999998807907104,\r
+ 0.9999996423721313,\r
+ 1.000000238418579\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 960,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 5760,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.00003742050103028305,\r
+ 0.08800023794174194,\r
+ -0.00005880460230400786\r
+ ],\r
+ "min": [\r
+ -0.000037621699448209256,\r
+ 0.08799994736909866,\r
+ -0.000059304802562110126\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 3840,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.2951536476612091,\r
+ 0.9301012754440308,\r
+ -0.2815393805503845,\r
+ 0.3835828900337219\r
+ ],\r
+ "min": [\r
+ -0.13552021980285645,\r
+ 0.8065234422683716,\r
+ -0.4443180561065674,\r
+ -0.17752912640571597\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 6336,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000005960464478,\r
+ 1.0000001192092896,\r
+ 1.0000003576278689\r
+ ],\r
+ "min": [\r
+ 0.9999999403953552,\r
+ 0.9999996423721313,\r
+ 0.9999998211860656\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 1152,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 6912,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.013221889734268188,\r
+ 0.215499609708786,\r
+ 0.10933230072259904\r
+ ],\r
+ "min": [\r
+ 0.01322161965072155,\r
+ 0.2154994010925293,\r
+ 0.10933209955692293\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 4608,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.023567700758576393,\r
+ 0.02101488783955574,\r
+ 0.176296666264534,\r
+ -0.971515953540802\r
+ ],\r
+ "min": [\r
+ -0.0574759915471077,\r
+ -0.18002526462078097,\r
+ -0.15063291788101196,\r
+ -0.998132348060608\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 7488,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.9999998211860656,\r
+ 0.9999998211860656,\r
+ 0.9999999403953552\r
+ ],\r
+ "min": [\r
+ 0.9999991059303284,\r
+ 0.9999993443489076,\r
+ 0.9999994039535524\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 1344,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 8064,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.09332455694675446,\r
+ 0.1430000960826874,\r
+ 0.07814794778823853\r
+ ],\r
+ "min": [\r
+ -0.09332473576068878,\r
+ 0.14299990236759189,\r
+ 0.07814773917198181\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 5376,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.03372078761458397,\r
+ 0.0026474546175450087,\r
+ 0.207317128777504,\r
+ -0.9705979824066162\r
+ ],\r
+ "min": [\r
+ 0.006105833686888218,\r
+ -0.12215615808963776,\r
+ 0.003784916130825877,\r
+ -0.9994208216667176\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 8640,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000007152557373,\r
+ 1.0000003576278689,\r
+ 1.0000008344650269\r
+ ],\r
+ "min": [\r
+ 1.0000001192092896,\r
+ 0.9999998211860656,\r
+ 1.000000238418579\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 1536,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 9216,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.00003894419933203608,\r
+ -0.0879998430609703,\r
+ -0.00005919210161664523\r
+ ],\r
+ "min": [\r
+ -0.0000392795009247493,\r
+ -0.08800008893013,\r
+ -0.00005960090129519813\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 6144,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.2377220243215561,\r
+ 0.942186713218689,\r
+ 0.37760788202285767,\r
+ 0.2007839232683182\r
+ ],\r
+ "min": [\r
+ -0.2700891792774201,\r
+ 0.8732703924179077,\r
+ 0.2710656225681305,\r
+ -0.2673804461956024\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 9792,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.000000238418579,\r
+ 1.0000003576278689,\r
+ 1.0000001192092896\r
+ ],\r
+ "min": [\r
+ 0.999999701976776,\r
+ 0.9999997615814208,\r
+ 0.9999997615814208\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 1728,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 10368,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.035546209663152695,\r
+ -0.21549880504608157,\r
+ 0.10423330217599867\r
+ ],\r
+ "min": [\r
+ -0.03554638102650643,\r
+ -0.21549910306930545,\r
+ 0.10423299670219421\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 6912,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.00792065542191267,\r
+ 0.9315358996391296,\r
+ 0.0024673622101545334,\r
+ 0.41479358077049255\r
+ ],\r
+ "min": [\r
+ -0.15234939754009247,\r
+ 0.9063802361488342,\r
+ -0.08167753368616104,\r
+ 0.3280625641345978\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 10944,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000005960464478,\r
+ 1.0000001192092896,\r
+ 1.000000238418579\r
+ ],\r
+ "min": [\r
+ 1,\r
+ 0.9999996423721313,\r
+ 0.9999996423721313\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 1920,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 11520,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.03137049078941345,\r
+ -0.1430007964372635,\r
+ -0.11761150509119034\r
+ ],\r
+ "min": [\r
+ 0.03137030825018883,\r
+ -0.1430010050535202,\r
+ -0.11761169880628586\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 7680,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.22148266434669495,\r
+ 0.3926030695438385,\r
+ 0.08952529728412628,\r
+ -0.9178923964500428\r
+ ],\r
+ "min": [\r
+ 0.055695075541734695,\r
+ 0.277910977602005,\r
+ -0.015314305201172829,\r
+ -0.9438881278038024\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 12096,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000004768371584,\r
+ 1.0000004768371584,\r
+ 1.0000004768371584\r
+ ],\r
+ "min": [\r
+ 0.9999997615814208,\r
+ 0.9999997615814208,\r
+ 0.9999998807907104\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 2112,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 12672,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.028520189225673676,\r
+ 0.06762184202671051,\r
+ -0.06295985728502274\r
+ ],\r
+ "min": [\r
+ 0.028520019724965096,\r
+ 0.06762173771858215,\r
+ -0.06296010315418243\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 8448,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.013129070401191711,\r
+ 0.10440785437822342,\r
+ 0.004284336231648922,\r
+ -0.7728573679924011\r
+ ],\r
+ "min": [\r
+ -0.013805897906422617,\r
+ -0.6344362497329712,\r
+ -0.03212129324674606,\r
+ -0.9994977116584778\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 13248,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000001192092896,\r
+ 1.0000004768371584,\r
+ 1.000000238418579\r
+ ],\r
+ "min": [\r
+ 0.9999995231628418,\r
+ 1,\r
+ 0.9999995827674866\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 2304,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 13824,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.209164097905159,\r
+ 0.009055494330823421,\r
+ -0.16426970064640045\r
+ ],\r
+ "min": [\r
+ 0.20916390419006348,\r
+ 0.009055464528501034,\r
+ -0.1642698049545288\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 9216,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.009955321438610554,\r
+ -0.2965533435344696,\r
+ 0.003957682754844427,\r
+ -0.1911347657442093\r
+ ],\r
+ "min": [\r
+ -0.00983923487365246,\r
+ -0.9813112020492554,\r
+ -0.02193812094628811,\r
+ -0.9549583792686462\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 14400,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.000000238418579,\r
+ 0.999999463558197,\r
+ 1.0000001192092896\r
+ ],\r
+ "min": [\r
+ 0.999999463558197,\r
+ 0.999998927116394,\r
+ 0.9999993443489076\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 2496,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 14976,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.2757900059223175,\r
+ 0.0013972820015624166,\r
+ 0.004122554790228605\r
+ ],\r
+ "min": [\r
+ 0.27578991651535034,\r
+ 0.0013972449814900756,\r
+ 0.004122436046600342\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 9984,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.01264618057757616,\r
+ -0.8448027968406677,\r
+ 0.03285584971308708,\r
+ -0.15347692370414737\r
+ ],\r
+ "min": [\r
+ -0.045710742473602295,\r
+ -0.9879721403121948,\r
+ 0.007757793180644512,\r
+ -0.5345877408981323\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 15552,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000008344650269,\r
+ 1.0000009536743164,\r
+ 1.0000004768371584\r
+ ],\r
+ "min": [\r
+ 1.000000238418579,\r
+ 1.0000003576278689,\r
+ 0.9999997615814208\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 2688,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 16128,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.06558377295732498,\r
+ 0.00109061598777771,\r
+ 0.029291389510035515\r
+ ],\r
+ "min": [\r
+ -0.06558384746313095,\r
+ 0.001090570935048163,\r
+ 0.029291240498423576\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 10752,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.022798636928200725,\r
+ 0.5332140922546387,\r
+ -0.003377946326509118,\r
+ -0.844382643699646\r
+ ],\r
+ "min": [\r
+ 0.007516560610383749,\r
+ 0.22626954317092896,\r
+ -0.04913739487528801,\r
+ -0.972984254360199\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 16704,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000008344650269,\r
+ 1.0000003576278689,\r
+ 1.0000003576278689\r
+ ],\r
+ "min": [\r
+ 0.9999998211860656,\r
+ 0.999999701976776,\r
+ 0.9999995231628418\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 2880,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 17280,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.028557300567626953,\r
+ -0.0684543326497078,\r
+ -0.06295845657587051\r
+ ],\r
+ "min": [\r
+ 0.028557060286402702,\r
+ -0.06845436990261078,\r
+ -0.0629587471485138\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 11520,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.04037770628929138,\r
+ -0.2803998589515686,\r
+ 0.02151232957839966,\r
+ -0.32386553287506104\r
+ ],\r
+ "min": [\r
+ -0.009615562856197357,\r
+ -0.9458208084106444,\r
+ -0.006491139996796846,\r
+ -0.9590301513671876\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 17856,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.000000238418579,\r
+ 1.0000005960464478,\r
+ 1.0000005960464478\r
+ ],\r
+ "min": [\r
+ 0.9999994039535524,\r
+ 0.9999999403953552,\r
+ 0.9999998211860656\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 3072,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 18432,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.2608909010887146,\r
+ -0.00902603566646576,\r
+ 0.05167100951075554\r
+ ],\r
+ "min": [\r
+ 0.2608906924724579,\r
+ -0.009026064537465572,\r
+ 0.05167080089449883\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 12288,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.02468797937035561,\r
+ 0.19154119491577148,\r
+ 0.017835097387433052,\r
+ -0.6250466108322144\r
+ ],\r
+ "min": [\r
+ -0.013421673327684404,\r
+ -0.7804162502288818,\r
+ -0.031287722289562225,\r
+ -0.9999792575836182\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 19008,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000003576278689,\r
+ 1.0000007152557373,\r
+ 1.000001072883606\r
+ ],\r
+ "min": [\r
+ 0.999999463558197,\r
+ 1,\r
+ 0.999999701976776\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 3264,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 19584,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.2754603922367096,\r
+ -0.0014316890155896544,\r
+ -0.014104750007390976\r
+ ],\r
+ "min": [\r
+ 0.27546021342277527,\r
+ -0.0014317409368231893,\r
+ -0.014104840345680714\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 13056,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.022092316299676895,\r
+ 0.9990847110748292,\r
+ 0.04779285565018654,\r
+ 0.4428757429122925\r
+ ],\r
+ "min": [\r
+ -0.001671039150096476,\r
+ 0.8965795040130615,\r
+ 0.002310338197275996,\r
+ 0.0384783074259758\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 20160,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.9999999403953552,\r
+ 0.9999996423721313,\r
+ 1.000000238418579\r
+ ],\r
+ "min": [\r
+ 0.9999994039535524,\r
+ 0.9999991655349731,\r
+ 0.9999996423721313\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "byteOffset": 3456,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 2\r
+ ],\r
+ "min": [\r
+ 0.04166661947965622\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 20736,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ -0.06681966781616211,\r
+ -0.0010721459984779358,\r
+ 0.026351390406489372\r
+ ],\r
+ "min": [\r
+ -0.06681978702545166,\r
+ -0.001072190934792161,\r
+ 0.02635126002132893\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "byteOffset": 13824,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 0.003402489935979247,\r
+ 0.4966025054454804,\r
+ 0.1101396307349205,\r
+ -0.8675833940505981\r
+ ],\r
+ "min": [\r
+ -0.027623889967799187,\r
+ 0.26874634623527527,\r
+ -0.02591408602893353,\r
+ -0.9565747380256652\r
+ ],\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "byteOffset": 21312,\r
+ "componentType": 5126,\r
+ "count": 48,\r
+ "max": [\r
+ 1.0000004768371584,\r
+ 0.9999998211860656,\r
+ 0.9999994039535524\r
+ ],\r
+ "min": [\r
+ 0.9999995231628418,\r
+ 0.999999225139618,\r
+ 0.9999986886978148\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 7,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 19,\r
+ "max": [\r
+ 0.9971418380737304,\r
+ -4.371139894487897e-8,\r
+ 0.9996265172958374,\r
+ 0,\r
+ 4.3586464215650273e-8,\r
+ 1,\r
+ 4.3695074225524884e-8,\r
+ 0,\r
+ 0.9999366402626038,\r
+ 0,\r
+ 0.9971418380737304,\r
+ 0,\r
+ 1.1374080181121828,\r
+ 0.44450080394744873,\r
+ 1.0739599466323853,\r
+ 1\r
+ ],\r
+ "min": [\r
+ -0.9999089241027832,\r
+ -4.371139894487897e-8,\r
+ -0.9999366402626038,\r
+ 0,\r
+ -4.3707416352845037e-8,\r
+ 1,\r
+ -4.37086278282095e-8,\r
+ 0,\r
+ -0.9996265172958374,\r
+ 0,\r
+ -0.9999089241027832,\r
+ 0,\r
+ -1.189831018447876,\r
+ -0.45450031757354736,\r
+ -1.058603048324585,\r
+ 1\r
+ ],\r
+ "type": "MAT4"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorTexture": {\r
+ "index": 0,\r
+ "texCoord": 0\r
+ },\r
+ "metallicFactor": 0,\r
+ "baseColorFactor": [\r
+ 1,\r
+ 1,\r
+ 1,\r
+ 1\r
+ ],\r
+ "roughnessFactor": 1\r
+ },\r
+ "emissiveFactor": [\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "name": "Cesium_Man-effect",\r
+ "alphaMode": "OPAQUE",\r
+ "doubleSided": false\r
+ }\r
+ ],\r
+ "textures": [\r
+ {\r
+ "sampler": 0,\r
+ "source": 0\r
+ }\r
+ ],\r
+ "images": [\r
+ {\r
+ "uri": "CesiumMan_img0.jpg"\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "magFilter": 9729,\r
+ "minFilter": 9986,\r
+ "wrapS": 10497,\r
+ "wrapT": 10497\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 0,\r
+ "byteLength": 28032,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 28032,\r
+ "byteLength": 52368,\r
+ "byteStride": 8,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 80400,\r
+ "byteLength": 78552,\r
+ "byteStride": 12,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 158952,\r
+ "byteLength": 52368,\r
+ "byteStride": 16,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 211320,\r
+ "byteLength": 3648\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 214968,\r
+ "byteLength": 21888\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 236856,\r
+ "byteLength": 14592\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 251448,\r
+ "byteLength": 1216\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "uri": "CesiumMan_data.bin",\r
+ "byteLength": 252664\r
+ }\r
+ ]\r
+}
\ No newline at end of file
--- /dev/null
+{\r
+ "asset": {\r
+ "generator": "Khronos glTF Blender I/O v1.0.5",\r
+ "version": "2.0"\r
+ },\r
+ "scene": 0,\r
+ "scenes": [\r
+ {\r
+ "name": "Scene",\r
+ "nodes": [\r
+ 5\r
+ ]\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "mesh": 0,\r
+ "name": "Wheels",\r
+ "rotation": [\r
+ 0,\r
+ 0.08848588913679123,\r
+ 0,\r
+ -0.9960774183273315\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 0\r
+ ],\r
+ "name": "Node",\r
+ "translation": [\r
+ 1.432669997215271,\r
+ 0,\r
+ -0.4277220070362091\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "name": "Wheels.001",\r
+ "rotation": [\r
+ 0,\r
+ 0.08848588913679123,\r
+ 0,\r
+ -0.9960774183273315\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 2\r
+ ],\r
+ "name": "Node.001",\r
+ "translation": [\r
+ -1.352329969406128,\r
+ 0,\r
+ -0.4277220070362091\r
+ ]\r
+ },\r
+ {\r
+ "children": [\r
+ 1,\r
+ 3\r
+ ],\r
+ "mesh": 1,\r
+ "name": "Cesium_Milk_Truck"\r
+ },\r
+ {\r
+ "children": [\r
+ 4\r
+ ],\r
+ "name": "Yup2Zup",\r
+ "rotation": [\r
+ 0.4999999701976776,\r
+ -0.5,\r
+ 0.5,\r
+ 0.4999999701976776\r
+ ]\r
+ }\r
+ ],\r
+ "animations": [\r
+ {\r
+ "channels": [\r
+ {\r
+ "sampler": 0,\r
+ "target": {\r
+ "node": 0,\r
+ "path": "rotation"\r
+ }\r
+ },\r
+ {\r
+ "sampler": 1,\r
+ "target": {\r
+ "node": 2,\r
+ "path": "rotation"\r
+ }\r
+ }\r
+ ],\r
+ "name": "Wheels",\r
+ "samplers": [\r
+ {\r
+ "input": 16,\r
+ "interpolation": "LINEAR",\r
+ "output": 17\r
+ },\r
+ {\r
+ "input": 16,\r
+ "interpolation": "LINEAR",\r
+ "output": 18\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "name": "wheels",\r
+ "pbrMetallicRoughness": {\r
+ "baseColorTexture": {\r
+ "index": 0,\r
+ "texCoord": 0\r
+ },\r
+ "metallicFactor": 0,\r
+ "roughnessFactor": 1\r
+ }\r
+ },\r
+ {\r
+ "name": "truck",\r
+ "pbrMetallicRoughness": {\r
+ "baseColorTexture": {\r
+ "index": 1,\r
+ "texCoord": 0\r
+ },\r
+ "metallicFactor": 0,\r
+ "roughnessFactor": 1\r
+ }\r
+ },\r
+ {\r
+ "name": "glass",\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0,\r
+ 0.04050629958510399,\r
+ 0.021240700036287308,\r
+ 1\r
+ ],\r
+ "metallicFactor": 0,\r
+ "roughnessFactor": 1\r
+ }\r
+ },\r
+ {\r
+ "name": "window_trim",\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.06400000303983688,\r
+ 0.06400000303983688,\r
+ 0.06400000303983688,\r
+ 1\r
+ ],\r
+ "metallicFactor": 0,\r
+ "roughnessFactor": 1\r
+ }\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "name": "Wheels",\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "POSITION": 0,\r
+ "NORMAL": 1,\r
+ "TEXCOORD_0": 2\r
+ },\r
+ "indices": 3,\r
+ "material": 0\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "name": "Cesium_Milk_Truck",\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "POSITION": 4,\r
+ "NORMAL": 5,\r
+ "TEXCOORD_0": 6\r
+ },\r
+ "indices": 7,\r
+ "material": 1\r
+ },\r
+ {\r
+ "attributes": {\r
+ "POSITION": 8,\r
+ "NORMAL": 9,\r
+ "TEXCOORD_0": 10\r
+ },\r
+ "indices": 11,\r
+ "material": 2\r
+ },\r
+ {\r
+ "attributes": {\r
+ "POSITION": 12,\r
+ "NORMAL": 13,\r
+ "TEXCOORD_0": 14\r
+ },\r
+ "indices": 15,\r
+ "material": 3\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "textures": [\r
+ {\r
+ "source": 0\r
+ },\r
+ {\r
+ "source": 0\r
+ }\r
+ ],\r
+ "images": [\r
+ {\r
+ "name": "CesiumMilkTruck.jpg",\r
+ "uri": "CesiumMilkTruck.jpg"\r
+ }\r
+ ],\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "componentType": 5126,\r
+ "count": 828,\r
+ "max": [\r
+ 0.4277999997138977,\r
+ 1.0579999685287476,\r
+ 0.4277999997138977\r
+ ],\r
+ "min": [\r
+ -0.4277999997138977,\r
+ -1.0579999685287476,\r
+ -0.4277999997138977\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "componentType": 5126,\r
+ "count": 828,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "componentType": 5126,\r
+ "count": 828,\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "componentType": 5123,\r
+ "count": 2304,\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "componentType": 5126,\r
+ "count": 2366,\r
+ "max": [\r
+ 2.437999963760376,\r
+ 1.3960000276565552,\r
+ -0.2667999863624573\r
+ ],\r
+ "min": [\r
+ -2.430910110473633,\r
+ -1.3960000276565552,\r
+ -2.5843698978424072\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "componentType": 5126,\r
+ "count": 2366,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "componentType": 5126,\r
+ "count": 2366,\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 7,\r
+ "componentType": 5123,\r
+ "count": 5232,\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 8,\r
+ "componentType": 5126,\r
+ "count": 151,\r
+ "max": [\r
+ 1.6011799573898315,\r
+ 1.3960000276565552,\r
+ -1.631850004196167\r
+ ],\r
+ "min": [\r
+ 0.22885000705718994,\r
+ -1.3960000276565552,\r
+ -2.3545401096343994\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 9,\r
+ "componentType": 5126,\r
+ "count": 151,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 10,\r
+ "componentType": 5126,\r
+ "count": 151,\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 11,\r
+ "componentType": 5123,\r
+ "count": 168,\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 12,\r
+ "componentType": 5126,\r
+ "count": 650,\r
+ "max": [\r
+ 1.62267005443573,\r
+ 1.100000023841858,\r
+ -1.5961999893188477\r
+ ],\r
+ "min": [\r
+ 0.1932000070810318,\r
+ -1.1100000143051147,\r
+ -2.3919999599456787\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 13,\r
+ "componentType": 5126,\r
+ "count": 650,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 14,\r
+ "componentType": 5126,\r
+ "count": 650,\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 15,\r
+ "componentType": 5123,\r
+ "count": 864,\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 16,\r
+ "componentType": 5126,\r
+ "count": 31,\r
+ "max": [\r
+ 1.25\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 17,\r
+ "componentType": 5126,\r
+ "count": 31,\r
+ "type": "VEC4"\r
+ },\r
+ {\r
+ "bufferView": 18,\r
+ "componentType": 5126,\r
+ "count": 31,\r
+ "type": "VEC4"\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 9936,\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 9936,\r
+ "byteOffset": 9936\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 6624,\r
+ "byteOffset": 19872\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 4608,\r
+ "byteOffset": 26496\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 28392,\r
+ "byteOffset": 31104\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 28392,\r
+ "byteOffset": 59496\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 18928,\r
+ "byteOffset": 87888\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 10464,\r
+ "byteOffset": 106816\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 1812,\r
+ "byteOffset": 117280\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 1812,\r
+ "byteOffset": 119092\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 1208,\r
+ "byteOffset": 120904\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 336,\r
+ "byteOffset": 122112\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 7800,\r
+ "byteOffset": 122448\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 7800,\r
+ "byteOffset": 130248\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 5200,\r
+ "byteOffset": 138048\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 1728,\r
+ "byteOffset": 143248\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 124,\r
+ "byteOffset": 144976\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 496,\r
+ "byteOffset": 145100\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteLength": 496,\r
+ "byteOffset": 145596\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "uri": "CesiumMilkTruck_data.bin",\r
+ "byteLength": 146092\r
+ }\r
+ ]\r
+}\r
--- /dev/null
+{\r
+ "asset": {\r
+ "copyright": "2018 (c) Adobe Systems Inc.",\r
+ "generator": "Adobe Dimension - b417c10282aa66313155856d4a54e84f3f388647",\r
+ "version": "2.0"\r
+ },\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "componentType": 5126,\r
+ "count": 4598,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 10.647041320800782,\r
+ 1.6470409631729127,\r
+ 0.6470409631729126\r
+ ],\r
+ "min": [\r
+ -10.647041320800782,\r
+ 0.3529590368270874,\r
+ -0.6470409631729126\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "componentType": 5126,\r
+ "count": 4598,\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "componentType": 5126,\r
+ "count": 4598,\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "componentType": 5125,\r
+ "count": 25344,\r
+ "type": "SCALAR",\r
+ "max": [\r
+ 4597.0\r
+ ],\r
+ "min": [\r
+ 0.0\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "componentType": 5126,\r
+ "count": 4598,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 10.647041320800782,\r
+ -0.3529590368270874,\r
+ 0.6470409631729126\r
+ ],\r
+ "min": [\r
+ -10.647041320800782,\r
+ -1.6470409631729127,\r
+ -0.6470409631729126\r
+ ]\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "componentType": 5126,\r
+ "count": 4598,\r
+ "type": "VEC2"\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 0,\r
+ "byteLength": 55176,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 55176,\r
+ "byteLength": 55176,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 110352,\r
+ "byteLength": 36784,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 147136,\r
+ "byteLength": 101376,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 248512,\r
+ "byteLength": 55176,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 303688,\r
+ "byteLength": 36784,\r
+ "target": 34962\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "byteLength": 340472,\r
+ "uri": "EnvironmentTest_binary.bin"\r
+ }\r
+ ],\r
+ "cameras": [\r
+ {\r
+ "perspective": {\r
+ "znear": 0.0010000000474974514,\r
+ "yfov": 0.6024156808853149,\r
+ "zfar": 200.0,\r
+ "aspectRatio": 1.3333333730697632\r
+ },\r
+ "type": "perspective",\r
+ "name": "render_camera"\r
+ }\r
+ ],\r
+ "images": [\r
+ {\r
+ "name": "tmp_image_pie_dc1e_1a22_fbf9roughness_map_roughness_tmp_image_pie_dc1e_1a22_fbf9metal_map_metallic_0",\r
+ "uri": "EnvironmentTest_images/roughness_metallic_0.jpg",\r
+ "mimeType": "image/jpeg"\r
+ },\r
+ {\r
+ "name": "tmp_image_pie_b20b_ebb4_317droughness_map2_roughness_tmp_image_pie_b20b_ebb4_317dmetal_map2_metallic_1",\r
+ "uri": "EnvironmentTest_images/roughness_metallic_1.jpg",\r
+ "mimeType": "image/jpeg"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "metallicRoughnessTexture": {\r
+ "index": 0\r
+ }\r
+ },\r
+ "name": "MetallicSpheresMat",\r
+ "doubleSided": true\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "metallicRoughnessTexture": {\r
+ "index": 1\r
+ }\r
+ },\r
+ "name": "DielectricSpheresMat",\r
+ "doubleSided": true\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "metallicRoughnessTexture": {\r
+ "index": 1\r
+ }\r
+ },\r
+ "name": "DielectricSpheresMat",\r
+ "doubleSided": true\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "name": "Metallic0_N3D",\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "POSITION": 0,\r
+ "NORMAL": 1,\r
+ "TEXCOORD_0": 2\r
+ },\r
+ "indices": 3,\r
+ "material": 0\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "name": "Dielectric0_N3D2",\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "TEXCOORD_0": 5,\r
+ "NORMAL": 1,\r
+ "POSITION": 4\r
+ },\r
+ "indices": 3,\r
+ "material": 1\r
+ }\r
+ ]\r
+ },\r
+ {\r
+ "name": "Dielectric0_N3D",\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "POSITION": 4,\r
+ "NORMAL": 1,\r
+ "TEXCOORD_0": 5\r
+ },\r
+ "indices": 3,\r
+ "material": 2\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "matrix": [\r
+ 0.9999533295631409,\r
+ 3.16067598760128e-8,\r
+ 0.009662099182605744,\r
+ 0.0,\r
+ 0.0014864075928926468,\r
+ 0.9880954027175903,\r
+ -0.15383504331111909,\r
+ 0.0,\r
+ -0.009547080844640732,\r
+ 0.15384222567081452,\r
+ 0.988049328327179,\r
+ 0.0,\r
+ -0.7599077224731445,\r
+ 7.708760738372803,\r
+ 27.743375778198243,\r
+ 1.0\r
+ ],\r
+ "camera": 0,\r
+ "name": "render_camera_n3d"\r
+ },\r
+ {\r
+ "name": "ground_plane_n3d"\r
+ },\r
+ {\r
+ "children": [\r
+ 3,\r
+ 4,\r
+ 5\r
+ ],\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ -0.5564079284667969,\r
+ 4.774584770202637,\r
+ -1.0962677001953126,\r
+ 1.0\r
+ ],\r
+ "name": "ENV_Spheres"\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "name": "Metallic0"\r
+ },\r
+ {\r
+ "mesh": 1,\r
+ "name": "Dielectric0"\r
+ },\r
+ {\r
+ "matrix": [\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 0.0,\r
+ 1.0,\r
+ 0.0,\r
+ 0.0,\r
+ -1.985867977142334,\r
+ 0.0,\r
+ 1.0\r
+ ],\r
+ "mesh": 2,\r
+ "name": "Dielectric0-Black"\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {},\r
+ {}\r
+ ],\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 0,\r
+ 1,\r
+ 2\r
+ ],\r
+ "name": "scene"\r
+ }\r
+ ],\r
+ "textures": [\r
+ {\r
+ "name": "tmp_image_pie_dc1e_1a22_fbf9roughness_map_roughness_tmp_image_pie_dc1e_1a22_fbf9metal_map_metallic_0_texture",\r
+ "sampler": 0,\r
+ "source": 0\r
+ },\r
+ {\r
+ "name": "tmp_image_pie_b20b_ebb4_317droughness_map2_roughness_tmp_image_pie_b20b_ebb4_317dmetal_map2_metallic_1_texture",\r
+ "sampler": 1,\r
+ "source": 1\r
+ }\r
+ ],\r
+ "scene": 0\r
+}
\ No newline at end of file
--- /dev/null
+{\r
+ "asset": {\r
+ "copyright": "Copyright 2017 Analytical Graphics, Inc, CC-BY 4.0 https://creativecommons.org/licenses/by/4.0/ - Model and textures by Ed Mackey.",\r
+ "generator": "COLLADA2GLTF with hand-edits",\r
+ "version": "2.0"\r
+ },\r
+ "scene": 0,\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 0\r
+ ]\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "children": [\r
+ 5,\r
+ 4,\r
+ 3,\r
+ 2,\r
+ 1\r
+ ],\r
+ "matrix": [\r
+ 0.4, 0.0, 0.0, 0.0,\r
+ 0.0, 0.0, -0.4, 0.0,\r
+ 0.0, 0.4, 0.0, 0.0,\r
+ 0.0, 0.0, 0.0, 1.0\r
+ ]\r
+ },\r
+ {\r
+ "mesh": 0\r
+ },\r
+ {\r
+ "mesh": 1\r
+ },\r
+ {\r
+ "mesh": 2\r
+ },\r
+ {\r
+ "mesh": 3\r
+ },\r
+ {\r
+ "mesh": 4\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 1,\r
+ "POSITION": 2,\r
+ "TEXCOORD_0": 3\r
+ },\r
+ "indices": 0,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "Spheres.004"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 5,\r
+ "POSITION": 6,\r
+ "TEXCOORD_0": 7\r
+ },\r
+ "indices": 4,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "Spheres.003"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 9,\r
+ "POSITION": 10,\r
+ "TEXCOORD_0": 11\r
+ },\r
+ "indices": 8,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "Spheres.002"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 13,\r
+ "POSITION": 14,\r
+ "TEXCOORD_0": 15\r
+ },\r
+ "indices": 12,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "Spheres.001"\r
+ },\r
+ {\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 17,\r
+ "POSITION": 18,\r
+ "TEXCOORD_0": 19\r
+ },\r
+ "indices": 16,\r
+ "mode": 4,\r
+ "material": 0\r
+ }\r
+ ],\r
+ "name": "Spheres"\r
+ }\r
+ ],\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 2642016,\r
+ "componentType": 5123,\r
+ "count": 184320,\r
+ "max": [\r
+ 31331\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 5389968,\r
+ "componentType": 5126,\r
+ "count": 31332,\r
+ "max": [\r
+ 0.9999999403953552,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -0.9999999403953552,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 5765952,\r
+ "componentType": 5126,\r
+ "count": 31332,\r
+ "max": [\r
+ -8.0,\r
+ 9.0,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ -10.0,\r
+ -1.0,\r
+ -7.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 1796656,\r
+ "componentType": 5126,\r
+ "count": 31332,\r
+ "max": [\r
+ 0.1278132051229477,\r
+ 0.7597609758377075\r
+ ],\r
+ "min": [\r
+ 0.03436123952269554,\r
+ 0.013921022415161133\r
+ ],\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 0,\r
+ "componentType": 5123,\r
+ "count": 368640,\r
+ "max": [\r
+ 62663\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 0.9999999403953552,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -0.9999999403953552,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 751968,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ -2.0,\r
+ 9.0,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ -7.0,\r
+ -1.0,\r
+ -7.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 0,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 0.4161497056484223,\r
+ 0.7597609758377075\r
+ ],\r
+ "min": [\r
+ 0.15740810334682465,\r
+ 0.012456059455871582\r
+ ],\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 1904736,\r
+ "componentType": 5123,\r
+ "count": 368640,\r
+ "max": [\r
+ 62663\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 3886032,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 0.9999999403953552,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -0.9999999403953552,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 4638000,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 4.0,\r
+ 9.0,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ -1.0,\r
+ -1.0,\r
+ -7.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 1295344,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 0.7028239369392395,\r
+ 0.7636672854423523\r
+ ],\r
+ "min": [\r
+ 0.4482637047767639,\r
+ 0.015471160411834717\r
+ ],\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 1167456,\r
+ "componentType": 5123,\r
+ "count": 368640,\r
+ "max": [\r
+ 62663\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 2382096,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 0.9999999403953552,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -0.9999999403953552,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 3134064,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 10.0,\r
+ 9.0,\r
+ 10.0\r
+ ],\r
+ "min": [\r
+ 5.0,\r
+ -1.0,\r
+ -7.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 794032,\r
+ "componentType": 5126,\r
+ "count": 62664,\r
+ "max": [\r
+ 0.9852716326713562,\r
+ 0.7671433687210083\r
+ ],\r
+ "min": [\r
+ 0.7233805060386658,\r
+ 0.016381680965423585\r
+ ],\r
+ "type": "VEC2"\r
+ },\r
+ {\r
+ "bufferView": 0,\r
+ "byteOffset": 737280,\r
+ "componentType": 5123,\r
+ "count": 215088,\r
+ "max": [\r
+ 36589\r
+ ],\r
+ "min": [\r
+ 0\r
+ ],\r
+ "type": "SCALAR"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1503936,\r
+ "componentType": 5126,\r
+ "count": 36590,\r
+ "max": [\r
+ 0.9999999403953552,\r
+ 1.0,\r
+ 1.0\r
+ ],\r
+ "min": [\r
+ -0.9999999403953552,\r
+ -1.0,\r
+ -1.0\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "byteOffset": 1943016,\r
+ "componentType": 5126,\r
+ "count": 36590,\r
+ "max": [\r
+ 11.874730110168456,\r
+ 9.0,\r
+ 10.969940185546877\r
+ ],\r
+ "min": [\r
+ -12.186589241027832,\r
+ -1.0,\r
+ -12.35944938659668\r
+ ],\r
+ "type": "VEC3"\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "byteOffset": 501312,\r
+ "componentType": 5126,\r
+ "count": 36590,\r
+ "max": [\r
+ 0.9869875311851502,\r
+ 0.9988328814506532\r
+ ],\r
+ "min": [\r
+ 0.0013856289442628625,\r
+ 0.016568005084991456\r
+ ],\r
+ "type": "VEC2"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorTexture": {\r
+ "index": 0\r
+ },\r
+ "metallicRoughnessTexture": {\r
+ "index": 1\r
+ }\r
+ },\r
+ "emissiveFactor": [\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ]\r
+ }\r
+ ],\r
+ "textures": [\r
+ {\r
+ "sampler": 0,\r
+ "source": 0\r
+ },\r
+ {\r
+ "sampler": 0,\r
+ "source": 1\r
+ }\r
+ ],\r
+ "images": [\r
+ {\r
+ "uri": "Spheres_BaseColor.png"\r
+ },\r
+ {\r
+ "uri": "Spheres_MetalRough.png"\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "magFilter": 9729,\r
+ "minFilter": 9986,\r
+ "wrapS": 33071,\r
+ "wrapT": 33071\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 8189248,\r
+ "byteLength": 3010656,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 0,\r
+ "byteLength": 6141936,\r
+ "byteStride": 12,\r
+ "target": 34962\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 6141936,\r
+ "byteLength": 2047312,\r
+ "byteStride": 8,\r
+ "target": 34962\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "byteLength": 11199904,\r
+ "uri": "MetalRoughSpheres0.bin"\r
+ }\r
+ ]\r
+}\r
--- /dev/null
+{\r
+ "asset": {\r
+ "generator": "glTF Converter for Shade3D",\r
+ "version": "2.0",\r
+ "extras": {\r
+ "title": "multiple_primitives",\r
+ "author": "ft-lab",\r
+ "license": "CC BY-4.0 (https://creativecommons.org/licenses/by/4.0/)"\r
+ }\r
+ },\r
+ "accessors": [\r
+ {\r
+ "bufferView": 0,\r
+ "componentType": 5123,\r
+ "count": 72,\r
+ "type": "SCALAR",\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 1,\r
+ "componentType": 5126,\r
+ "count": 21,\r
+ "type": "VEC3",\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 2,\r
+ "componentType": 5126,\r
+ "count": 21,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.5,\r
+ 0,\r
+ 0.5\r
+ ],\r
+ "min": [\r
+ -0.5,\r
+ 0,\r
+ -0.5\r
+ ],\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 3,\r
+ "componentType": 5126,\r
+ "count": 21,\r
+ "type": "VEC2",\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 4,\r
+ "componentType": 5126,\r
+ "count": 21,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0,\r
+ 0.20000000298023224,\r
+ 0\r
+ ],\r
+ "min": [\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 5,\r
+ "componentType": 5123,\r
+ "count": 24,\r
+ "type": "SCALAR",\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 6,\r
+ "componentType": 5126,\r
+ "count": 9,\r
+ "type": "VEC3",\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 7,\r
+ "componentType": 5126,\r
+ "count": 9,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0.5,\r
+ 0,\r
+ 0\r
+ ],\r
+ "min": [\r
+ 0,\r
+ 0,\r
+ -0.5\r
+ ],\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 8,\r
+ "componentType": 5126,\r
+ "count": 9,\r
+ "type": "VEC2",\r
+ "byteOffset": 0\r
+ },\r
+ {\r
+ "bufferView": 9,\r
+ "componentType": 5126,\r
+ "count": 9,\r
+ "type": "VEC3",\r
+ "max": [\r
+ 0,\r
+ 0.20000000298023224,\r
+ 0\r
+ ],\r
+ "min": [\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "byteOffset": 0\r
+ }\r
+ ],\r
+ "bufferViews": [\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 0,\r
+ "byteLength": 144,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 144,\r
+ "byteLength": 252,\r
+ "target": 34962,\r
+ "byteStride": 12\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 396,\r
+ "byteLength": 252,\r
+ "target": 34962,\r
+ "byteStride": 12\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 648,\r
+ "byteLength": 168,\r
+ "target": 34962,\r
+ "byteStride": 8\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 816,\r
+ "byteLength": 252,\r
+ "target": 34962,\r
+ "byteStride": 12\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1068,\r
+ "byteLength": 48,\r
+ "target": 34963\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1116,\r
+ "byteLength": 108,\r
+ "target": 34962,\r
+ "byteStride": 12\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1224,\r
+ "byteLength": 108,\r
+ "target": 34962,\r
+ "byteStride": 12\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1332,\r
+ "byteLength": 72,\r
+ "target": 34962,\r
+ "byteStride": 8\r
+ },\r
+ {\r
+ "buffer": 0,\r
+ "byteOffset": 1404,\r
+ "byteLength": 108,\r
+ "target": 34962,\r
+ "byteStride": 12\r
+ }\r
+ ],\r
+ "buffers": [\r
+ {\r
+ "name": "MorphPrimitivesTest",\r
+ "byteLength": 1512,\r
+ "uri": "MorphPrimitivesTest.bin"\r
+ }\r
+ ],\r
+ "images": [\r
+ {\r
+ "name": "uv_texture.jpg",\r
+ "mimeType": "image/jpeg",\r
+ "uri": "uv_texture.jpg"\r
+ }\r
+ ],\r
+ "materials": [\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 1,\r
+ 0,\r
+ 0,\r
+ 1\r
+ ],\r
+ "baseColorTexture": {\r
+ "index": 0,\r
+ "texCoord": 0\r
+ },\r
+ "metallicFactor": 0,\r
+ "roughnessFactor": 1\r
+ },\r
+ "name": "red",\r
+ "emissiveFactor": [\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "alphaMode": "OPAQUE",\r
+ "doubleSided": false\r
+ },\r
+ {\r
+ "pbrMetallicRoughness": {\r
+ "baseColorFactor": [\r
+ 0,\r
+ 1,\r
+ 0,\r
+ 1\r
+ ],\r
+ "baseColorTexture": {\r
+ "index": 0,\r
+ "texCoord": 0\r
+ },\r
+ "metallicFactor": 0,\r
+ "roughnessFactor": 1\r
+ },\r
+ "name": "green",\r
+ "emissiveFactor": [\r
+ 0,\r
+ 0,\r
+ 0\r
+ ],\r
+ "alphaMode": "OPAQUE",\r
+ "doubleSided": false\r
+ }\r
+ ],\r
+ "meshes": [\r
+ {\r
+ "weights": [\r
+ 0.5\r
+ ],\r
+ "name": "mesh",\r
+ "primitives": [\r
+ {\r
+ "attributes": {\r
+ "NORMAL": 1,\r
+ "POSITION": 2,\r
+ "TEXCOORD_0": 3\r
+ },\r
+ "indices": 0,\r
+ "material": 0,\r
+ "targets": [\r
+ {\r
+ "POSITION": 4\r
+ }\r
+ ],\r
+ "mode": 4\r
+ },\r
+ {\r
+ "attributes": {\r
+ "POSITION": 7,\r
+ "NORMAL": 6,\r
+ "TEXCOORD_0": 8\r
+ },\r
+ "indices": 5,\r
+ "material": 1,\r
+ "targets": [\r
+ {\r
+ "POSITION": 9\r
+ }\r
+ ],\r
+ "mode": 4\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "nodes": [\r
+ {\r
+ "children": [\r
+ 1\r
+ ],\r
+ "name": "ルートパート"\r
+ },\r
+ {\r
+ "mesh": 0,\r
+ "name": "mesh"\r
+ }\r
+ ],\r
+ "samplers": [\r
+ {\r
+ "minFilter": 9729,\r
+ "wrapS": 10497,\r
+ "wrapT": 10497\r
+ }\r
+ ],\r
+ "scenes": [\r
+ {\r
+ "nodes": [\r
+ 0\r
+ ],\r
+ "name": "Scene"\r
+ }\r
+ ],\r
+ "textures": [\r
+ {\r
+ "sampler": 0,\r
+ "source": 0\r
+ }\r
+ ],\r
+ "scene": 0\r
+}\r
--- /dev/null
+{\r
+ "scene" : 0,\r
+ "scenes":[\r
+ {\r
+ "nodes":[\r
+ 0\r
+ ]\r
+ }\r
+ ],\r
+ "nodes":[\r
+ {\r
+ "mesh":0\r
+ }\r
+ ],\r
+ "meshes":[\r
+ {\r
+ "primitives":[\r
+ {\r
+ "attributes":{\r
+ "POSITION":1\r
+ },\r
+ "indices":0\r
+ }\r
+ ]\r
+ }\r
+ ],\r
+ "buffers":[\r
+ {\r
+ "uri":"SimpleSparseAccessor.bin",\r
+ "byteLength":284\r
+ }\r
+ ],\r
+ "bufferViews":[\r
+ {\r
+ "buffer":0,\r
+ "byteOffset":0,\r
+ "byteLength":72,\r
+ "target":34963\r
+ },\r
+ {\r
+ "buffer":0,\r
+ "byteOffset":72,\r
+ "byteLength":168\r
+ },\r
+ {\r
+ "buffer":0,\r
+ "byteOffset":240,\r
+ "byteLength":6\r
+ },\r
+ {\r
+ "buffer":0,\r
+ "byteOffset":248,\r
+ "byteLength":36\r
+ }\r
+ ],\r
+ "accessors":[\r
+ {\r
+ "bufferView":0,\r
+ "byteOffset":0,\r
+ "componentType":5123,\r
+ "count":36,\r
+ "type":"SCALAR",\r
+ "max":[\r
+ 13\r
+ ],\r
+ "min":[\r
+ 0\r
+ ]\r
+ },\r
+ {\r
+ "bufferView":1,\r
+ "byteOffset":0,\r
+ "componentType":5126,\r
+ "count":14,\r
+ "type":"VEC3",\r
+ "sparse":{\r
+ "count":3,\r
+ "indices":{\r
+ "bufferView":2,\r
+ "byteOffset":0,\r
+ "componentType":5123\r
+ },\r
+ "values":{\r
+ "bufferView":3,\r
+ "byteOffset":0\r
+ }\r
+ },\r
+ "max":[\r
+ 6.0,\r
+ 4.0,\r
+ 0.0\r
+ ],\r
+ "min":[\r
+ 0.0,\r
+ 0.0,\r
+ 0.0\r
+ ]\r
+ }\r
+ ],\r
+ "asset":{\r
+ "version":"2.0"\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+{\r
+ "scene": 0,\r
+ "scenes": [ { "nodes": [ 0 ] } ],\r
+ "nodes": [ {\r
+ "name": "root",\r
+ "children": [ 1 ]\r
+ }, {\r
+ "name": "arc",\r
+ "size": [ 2.0, 2.0 ],\r
+ "color": [ 0.5, 1.0, 0.5, 0.5 ],\r
+ "arc": {\r
+ "shader": 0,\r
+ "mesh": 0,\r
+ "startAngle" : -45.0,\r
+ "endAngle" : 135.0,\r
+ "radius" : -0.75,\r
+ "arcCaps": 3\r
+ }\r
+ } ],\r
+ "environment": [ {\r
+ } ],\r
+ "meshes": [ {\r
+ "uri": "quad",\r
+ "attributes": 0\r
+ } ],\r
+ "materials": [ {\r
+ } ],\r
+ "shaders": [ {\r
+ "vertex": "dli_arc.vsh",\r
+ "fragment": "dli_arc.fsh",\r
+ "rendererState" : "ALPHA_BLEND",\r
+ "startAngle": [ -1.0, 0.0 ],\r
+ "endAngle": [ 1.0, 0.0 ]\r
+ } ]\r
+}\r
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root"
+ } ],
+ "animations": [ {
+ "properties": [ {
+ "node": "root",
+ "property": "position",
+ "keyFramesBin": { "url": "doesntexist.bin" }
+ } ]
+ } ]
+}
--- /dev/null
+{
+ "scene": 0,
+ "scenes": [ { "nodes": [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "children": [ 1, 2, 3 ]
+ }, {
+ "name": "Alice",
+ "angle": [ 0.0, -45.0, 10.0 ],
+ "position": [ 500.0, -50.0, 0.0 ]
+ }, {
+ "name": "Bob",
+ "position": [ 1000.0, 1.0, -400.0 ],
+ "angle": [ 10.0, 0.0, -90.0 ],
+ "extras": {
+ "angularVelocity": [ -0.5, 0.0004 ]
+ }
+ }, {
+ "name": "Charlie",
+ "position": [ -400.0, 0.0, 100.0 ],
+ "constraints": {
+ "orientation": 1,
+ "position": 2,
+ "angularVelocity": 2,
+ "invalid": "zero"
+ },
+ "extras": {
+ "angularVelocity": [ 0.0, 0.0 ]
+ }
+ } ]
+}
+
--- /dev/null
+{
+ "scene": 0,
+ "scenes": [ { "nodes": [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "extras": {
+ "fudgeFactor": 9000.1,
+ "fudgeVector": [ 8, 7.0 ],
+ "fudgeVector": [ -0.25, 17.0 ],
+ "isThisTheRealLife": true,
+ "isThisJustFantasy": false,
+ "": 16384,
+ "velocity": [ 0.1, 58.0, -0.2 ],
+ "not a great extra": "this one",
+ "frameOfReference": [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ]
+ }
+ } ]
+}
+
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ { "name": "root" } ],
+ "materials": [ {
+ "environment": 0
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {} ],
+ "meshes": [ {
+ "uri": "mesh.bin",
+ "attributes": 1
+ } ]
+}
+
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {} ],
+ "meshes": [ {
+ "uri": "mesh.bin",
+ "attributes": 2
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {} ],
+ "meshes": [ {
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "model": { }
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "arc": { }
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "children": [
+ "what?"
+ ]
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "model": { }
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "children" : [ 1 ]
+ }, {
+ "name": "root"
+ } ]
+}
--- /dev/null
+{
+ "scene": 0,
+ "scenes": [ { "nodes": [ 0 ] }, { "nodes": [ 1 ] } ],
+ "nodes": [ {
+ "name": "rootA",
+ "array": [ 1, 2, 4, 8, -500 ],
+ "object": {
+ "physics": true,
+ "elasticity": 0.27,
+ "drag": 0.91,
+ "inner array": [ "why", "not", false ],
+ "inner object": {
+ "supported": true
+ }
+ },
+ "nickname": "same as name",
+ "favourite number": 63478
+ }, {
+ "name": "rootB"
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "model": {
+ "mesh": 0.5
+ }
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {
+ "name": "root",
+ "model": {
+ "mesh": 0
+ }
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [] } ],
+ "nodes": []
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : 0 } ],
+ "nodes": []
+}
--- /dev/null
+{
+ "scenes": []
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ "0" ] } ],
+ "nodes": []
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": []
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ "helloo" ]
+}
--- /dev/null
+{
+ "scenes": [],
+ "nodes": []
+}
--- /dev/null
+{
+ "": {}
+}
--- /dev/null
+{
+ "scenes": [ { } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {} ],
+ "shaders": [ {
+ "vertex": "some.vsh"
+ } ]
+}
--- /dev/null
+{
+ "scene": 0,
+ "scenes": [ { "nodes": [ 0 ] } ],
+ "nodes": [ {
+ "name": "root"
+ } ],
+ "shaders": [ {
+ "vertex": "dli_pbr.vsh",
+ "fragment": "dli_pbr.fsh",
+ "uBool": true,
+ "uInt": 255,
+ "uFloat": -0.5,
+ "uVec2": [ 100.0, -100.0 ],
+ "uVec3": [ 50.0, 0.0, -200.0 ],
+ "uVec4": [ 0.1774, 1.0, 0.5333, 0.7997 ],
+ "uMat3": [ 9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0 ],
+ "uMat4": [ 8.0, 0.0, 0.0, 0.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0.0, 8.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "invalid": "Hello, I'm a string"
+ } ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ { "name": "root" } ],
+ "shaders": [ {} ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ {} ],
+ "skeletons": [ {} ]
+}
--- /dev/null
+{
+ "scenes": [ { "nodes" : [ 0 ] } ],
+ "nodes": [ { "name": "1" } ],
+ "skeletons": [ { "node": "some-other" } ]
+}
--- /dev/null
+#version 300 es\r
+\r
+#ifdef HIGHP\r
+ precision highp float;\r
+#else\r
+ precision mediump float;\r
+#endif\r
+\r
+#define ROUND_STARTCAP 0x1\r
+#define ROUND_ENDCAP 0x2\r
+#define SQUARE_STARTCAP 0x4\r
+#define SQUARE_ENDCAP 0x8\r
+precision mediump float;\r
+\r
+in vec2 vUV;\r
+\r
+uniform vec4 uColor;\r
+uniform int antiAliasing;\r
+uniform float radius;\r
+uniform vec2 startAngle;\r
+uniform vec2 endAngle;\r
+uniform int arcCaps;\r
+\r
+out vec4 FragColor;\r
+\r
+\r
+void main()\r
+{\r
+////////////////////\r
+//Inputs\r
+ float radius1 = 1.0;\r
+ float uvPixel = length( dFdx( vUV ) ) * 2.0;\r
+ float dx = mix( 0.0001, uvPixel, antiAliasing > 0 );\r
+ float radius2 = mix( 1.0 - radius * uvPixel - dx , -radius , step( 0.0, -radius ) );\r
+////////////////////\r
+ float alpha = 0.0;\r
+ float circle = 0.0;\r
+\r
+ vec2 uv = fract(vUV) * 2.0 - 1.0;\r
+\r
+ float ang_img = endAngle.y * startAngle.x - endAngle.x * startAngle.y;\r
+ float half1 = uv.x * startAngle.x - uv.y * startAngle.y;\r
+ float half2 = uv.y * endAngle.y - uv.x * endAngle.x;\r
+ float len = length(uv);\r
+ float equalAngles = step(0.99999, dot(endAngle, startAngle));\r
+ float right_side = step(0.0, ang_img);\r
+ vec2 uv_norm = normalize(uv);\r
+ float cap_radius = -0.5 + radius2 / 2.0;\r
+ float square_cap;\r
+ float sq_plane;\r
+\r
+ /******************************************\r
+ * Equivalent to:\r
+ * if( len > radius1 || len < radius2 )\r
+ */\r
+ circle = alpha = smoothstep( len, len + dx, radius1 ) * smoothstep( -len, -len + dx, -radius2 );\r
+ float half1_step = smoothstep( -dx, 0.0, half1 );\r
+ float half2_step = smoothstep( -dx, 0.0, half2 );\r
+\r
+ float neg_angimg = max( half1_step, half2_step );\r
+ float pos_angimg = min( half1_step, half2_step );\r
+ /******************************************\r
+ * Equivalent to:\r
+ if(ang_img < 0.0)\r
+ {\r
+ alpha *= max(smoothstep( 0.0, dx, half1 ), smoothstep( 0.0, dx, half2));\r
+ }\r
+ else\r
+ {\r
+ alpha *= min(smoothstep( 0.0, dx, half1 ) , smoothstep( 0.0, dx, half2 ));\r
+ }\r
+ */\r
+ alpha *= mix( neg_angimg, pos_angimg, step(0.0, ang_img) );\r
+\r
+ alpha = mix( alpha, mix( circle, 0.0, right_side ), equalAngles );\r
+\r
+ if((arcCaps & ROUND_STARTCAP) > 0)\r
+ {\r
+ len = length(uv - normalize( vec2( startAngle.y, startAngle.x )) * (1.0 + cap_radius));\r
+ alpha = max(alpha, smoothstep(cap_radius, cap_radius + dx, -len) );\r
+ }\r
+ if((arcCaps & ROUND_ENDCAP) > 0)\r
+ {\r
+ len = length(uv - normalize( vec2( endAngle.y, endAngle.x )) * (1.0 + cap_radius));\r
+ alpha = max(alpha, smoothstep(cap_radius, cap_radius + dx, -len) );\r
+ }\r
+\r
+ if((arcCaps & SQUARE_STARTCAP) > 0)\r
+ {\r
+ sq_plane = -uv.x * startAngle.y - uv.y * startAngle.x;\r
+ square_cap = min(step( 0.0, -half1 ), smoothstep( cap_radius, cap_radius + dx, half1 ));\r
+ square_cap = min(square_cap, smoothstep( radius2, radius2 + dx, -sq_plane ));\r
+ square_cap = min(square_cap, smoothstep( -1.0, -1.0 + dx, sq_plane ));\r
+ alpha = max(square_cap, alpha);\r
+ }\r
+\r
+ if((arcCaps & SQUARE_ENDCAP) > 0)\r
+ {\r
+ sq_plane = -uv.x * endAngle.y - uv.y * endAngle.x;\r
+ square_cap = min(step( 0.0, -half2 ), smoothstep( cap_radius, cap_radius + dx, half2 ));\r
+ square_cap = min(square_cap, smoothstep( radius2, radius2 + dx, -sq_plane ));\r
+ square_cap = min(square_cap, smoothstep( -1.0, -1.0 + dx, sq_plane ));\r
+ alpha = max(square_cap, alpha);\r
+ }\r
+\r
+ if( alpha == 0.0 )\r
+ {\r
+ discard;\r
+ }\r
+\r
+ FragColor = vec4(vec3(uColor), uColor.a * alpha);\r
+}\r
--- /dev/null
+#version 300 es\r
+\r
+#ifdef HIGHP\r
+ precision highp float;\r
+#else\r
+ precision mediump float;\r
+#endif\r
+\r
+in vec3 aPosition;\r
+in vec2 aTexCoord;\r
+\r
+out vec2 vUV;\r
+\r
+uniform vec3 uSize;\r
+\r
+uniform mat4 uProjection;\r
+uniform mat4 uModelMatrix;\r
+uniform mat4 uViewMatrix;\r
+\r
+uniform vec2 uTilt;\r
+\r
+void main()\r
+{\r
+ vec4 vPosition = vec4( aPosition * uSize, 1.0);\r
+ vec4 mPosition = uModelMatrix * vPosition;\r
+\r
+ mPosition.xy += 0.3 * uTilt * mPosition.z;\r
+ gl_Position = uProjection * uViewMatrix * mPosition;\r
+\r
+#ifdef FLIP_V\r
+ vUV = vec2(aTexCoord.x, 1.0 - aTexCoord.y);\r
+#else\r
+ vUV = aTexCoord;\r
+#endif\r
+\r
+}\r
--- /dev/null
+#version 300 es\r
+\r
+#ifdef HIGHP\r
+ precision highp float;\r
+#else\r
+ precision mediump float;\r
+#endif\r
+\r
+uniform sampler2D sAlbedo;\r
+\r
+uniform vec4 uColor;\r
+\r
+#ifdef ALPHA_TEST\r
+ uniform float uAlphaThreshold;\r
+#endif //ALPHA_TEST\r
+\r
+in vec2 vUV;\r
+\r
+out vec4 FragColor;\r
+\r
+void main()\r
+{\r
+ vec4 color = texture(sAlbedo, vUV.st);\r
+#ifdef ALPHA_TEST\r
+ if (color.a <= uAlphaThreshold)\r
+ {\r
+ discard;\r
+ }\r
+#endif\r
+ FragColor = color * uColor;\r
+}\r
--- /dev/null
+#version 300 es\r
+\r
+#ifdef HIGHP\r
+ precision highp float;\r
+#else\r
+ precision mediump float;\r
+#endif\r
+\r
+in vec3 aPosition;\r
+in vec2 aTexCoord;\r
+\r
+out vec2 vUV;\r
+\r
+uniform vec3 uSize;\r
+\r
+uniform mat4 uCubeMatrix;\r
+\r
+uniform mat4 uProjection;\r
+uniform mat4 uModelMatrix;\r
+uniform mat4 uViewMatrix;\r
+\r
+uniform vec2 uTilt;\r
+\r
+void main()\r
+{\r
+ vec4 vPosition = vec4( aPosition * uSize, 1.0);\r
+ vec4 mPosition = uModelMatrix * vPosition;\r
+\r
+ mPosition.xy += 0.3 * uTilt * mPosition.z;\r
+ gl_Position = uProjection * uViewMatrix * mPosition;\r
+\r
+#ifdef FLIP_V\r
+ vUV = vec2(aTexCoord.x, 1.0 - aTexCoord.y);\r
+#else\r
+ vUV = aTexCoord;\r
+#endif\r
+}\r
--- /dev/null
+#version 300 es\r
+\r
+#ifdef HIGHP\r
+ precision highp float;\r
+#else\r
+ precision mediump float;\r
+#endif\r
+\r
+#ifdef THREE_TEX\r
+#ifdef GLTF_CHANNELS\r
+// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture\r
+#define METALLIC b\r
+#define ROUGHNESS g\r
+#else //GLTF_CHANNELS\r
+#define METALLIC r\r
+#define ROUGHNESS a\r
+#endif //GLTF_CHANNELS\r
+#endif //THREE_TEX\r
+\r
+#ifdef THREE_TEX\r
+ uniform sampler2D sAlbedoAlpha;\r
+ uniform sampler2D sMetalRoughness;\r
+ uniform sampler2D sNormal;\r
+\r
+#ifdef ALPHA_TEST\r
+ uniform float uAlphaThreshold;\r
+#endif //ALPHA_TEST\r
+\r
+#else\r
+ uniform sampler2D sAlbedoMetal;\r
+ uniform sampler2D sNormalRoughness;\r
+#endif\r
+\r
+uniform samplerCube sDiffuse;\r
+uniform samplerCube sSpecular;\r
+\r
+// Number of mip map levels in the texture\r
+uniform float uMaxLOD;\r
+\r
+// Transformation matrix of the cubemap texture\r
+uniform mat4 uCubeMatrix;\r
+\r
+uniform vec4 uColor;\r
+uniform float uMetallicFactor;\r
+uniform float uRoughnessFactor;\r
+\r
+//IBL Light intensity\r
+uniform float uIblIntensity;\r
+\r
+in vec2 vUV;\r
+in vec3 vNormal;\r
+in vec3 vTangent;\r
+in vec3 vViewVec;\r
+\r
+out vec4 FragColor;\r
+\r
+// Functions for BRDF calculation come from\r
+// https://www.unrealengine.com/blog/physically-based-shading-on-mobile\r
+// Based on the paper by Dimitar Lazarov\r
+// http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf\r
+vec3 EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV )\r
+{\r
+ const vec4 c0 = vec4( -1.0, -0.0275, -0.572, 0.022 );\r
+ const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04 );\r
+ vec4 r = Roughness * c0 + c1;\r
+ float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y;\r
+ vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw;\r
+\r
+ return SpecularColor * AB.x + AB.y;\r
+}\r
+\r
+void main()\r
+{\r
+ // We get information from the maps (albedo, normal map, roughness, metalness\r
+ // I access the maps in the order they will be used\r
+#ifdef THREE_TEX\r
+ vec4 albedoAlpha = texture(sAlbedoAlpha, vUV.st);\r
+ float alpha = albedoAlpha.a;\r
+#ifdef ALPHA_TEST\r
+ if (alpha <= uAlphaThreshold)\r
+ {\r
+ discard;\r
+ }\r
+#endif //ALPHA_TEST\r
+ vec3 albedoColor = albedoAlpha.rgb * uColor.rgb;\r
+\r
+ vec4 metalRoughness = texture(sMetalRoughness, vUV.st);\r
+ float metallic = metalRoughness.METALLIC * uMetallicFactor;\r
+ float roughness = metalRoughness.ROUGHNESS * uRoughnessFactor;\r
+\r
+ vec3 normalMap = texture(sNormal, vUV.st).rgb;\r
+#else //THREE_TEX\r
+ vec4 albedoMetal = texture(sAlbedoMetal, vUV.st);\r
+ vec3 albedoColor = albedoMetal.rgb * uColor.rgb;\r
+ float metallic = albedoMetal.a * uMetallicFactor;\r
+\r
+ vec4 normalRoughness = texture(sNormalRoughness, vUV.st);\r
+ vec3 normalMap = normalRoughness.rgb;\r
+ float roughness = normalRoughness.a * uRoughnessFactor;\r
+#endif\r
+ //Normalize vectors\r
+ vec3 normal = normalize(vNormal);\r
+ vec3 tangent = normalize(vTangent);\r
+\r
+ // NOTE: normal and tangent have to be orthogonal for the result of the cross()\r
+ // product to be a unit vector. We might find that we need to normalize().\r
+ vec3 bitangent = cross(normal, tangent);\r
+\r
+ vec3 viewVec = normalize(vViewVec);\r
+\r
+ // Create Inverse Local to world matrix\r
+ mat3 vInvTBN = mat3(tangent, bitangent, normal);\r
+\r
+ // Get normal map info in world space\r
+ normalMap = normalize(normalMap - 0.5);\r
+ vec3 newNormal = vInvTBN * normalMap.rgb;\r
+\r
+ // Calculate normal dot view vector\r
+ float NoV = max(dot(newNormal, -viewVec), 0.0);\r
+\r
+ // Reflect vector\r
+ vec3 reflectionVec = reflect(viewVec, newNormal);\r
+\r
+ //transform it now to environment coordinates (used when the environment rotates)\r
+ vec3 reflecCube = (uCubeMatrix * vec4( reflectionVec, 0.0 ) ).xyz;\r
+ reflecCube = normalize( reflecCube );\r
+\r
+ //transform it now to environment coordinates\r
+ vec3 normalCube = ( uCubeMatrix * vec4( newNormal, 0.0 ) ).xyz;\r
+ normalCube = normalize( normalCube );\r
+\r
+ // Get irradiance from diffuse cubemap\r
+ vec3 irradiance = texture( sDiffuse, normalCube ).rgb;\r
+\r
+ // Access reflection color using roughness value\r
+ float finalLod = mix( 0.0, uMaxLOD - 2.0, roughness);\r
+ vec3 reflectionColor = textureLod(sSpecular, reflecCube, finalLod).rgb;\r
+\r
+ // We are supposed to be using DielectricColor (0.04) of a plastic (almost everything)\r
+ // http://blog.selfshadow.com/publications/s2014-shading-course/hoffman/s2014_pbs_physics_math_slides.pdf\r
+ // however that seems to prevent achieving very dark tones (i.e. get dark gray blacks).\r
+ vec3 DiffuseColor = albedoColor - albedoColor * metallic; // 1 mad\r
+ vec3 SpecularColor = mix( vec3(0.04), albedoColor, metallic); // 2 mad\r
+\r
+ // Calculate specular color using Magic Function (takes original roughness and normal dot view).\r
+ vec3 specColor = reflectionColor.rgb * EnvBRDFApprox(SpecularColor, roughness, NoV );\r
+\r
+ // Multiply the result by albedo texture and do energy conservation\r
+ vec3 diffuseColor = irradiance * DiffuseColor;\r
+\r
+ // Final color is the sum of the diffuse and specular term\r
+ vec3 finalColor = diffuseColor + specColor;\r
+\r
+ finalColor = sqrt( finalColor ) * uIblIntensity;\r
+#ifdef THREE_TEX\r
+ FragColor = vec4( finalColor, alpha );\r
+#else //THREE_TEX\r
+ FragColor = vec4( finalColor, 1.0 );\r
+#endif //THREE_TEX\r
+}\r
--- /dev/null
+#version 300 es\r
+\r
+#ifdef HIGHP\r
+ precision highp float;\r
+#else\r
+ precision mediump float;\r
+#endif\r
+\r
+in vec3 aPosition;\r
+in vec2 aTexCoord;\r
+in vec3 aNormal;\r
+in vec3 aTangent;\r
+\r
+#ifdef MORPH\r
+ uniform sampler2D sBlendShapeGeometry;\r
+#endif\r
+\r
+out vec2 vUV;\r
+out vec3 vNormal;\r
+out vec3 vTangent;\r
+out vec3 vViewVec;\r
+\r
+\r
+uniform highp mat4 uMvpMatrix;\r
+uniform highp mat4 uViewMatrix;\r
+uniform mat3 uNormalMatrix;\r
+uniform mat4 uModelMatrix;\r
+uniform mat4 uModelView;\r
+uniform mat4 uProjection;\r
+\r
+#ifdef SKINNING\r
+ in vec4 aJoints;\r
+ in vec4 aWeights;\r
+ #define MAX_BONES 64\r
+ uniform mat4 uBone[MAX_BONES];\r
+#endif\r
+\r
+#ifdef MORPH\r
+#define MAX_BLEND_SHAPE_NUMBER 128\r
+uniform int uNumberOfBlendShapes; ///< Total number of blend shapes loaded.\r
+uniform float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER]; ///< The weight of each blend shape.\r
+#ifdef MORPH_VERSION_2_0\r
+uniform float uBlendShapeUnnormalizeFactor; ///< Factor used to unnormalize the geometry of the blend shape.\r
+#else\r
+uniform float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape.\r
+#endif\r
+uniform int uBlendShapeComponentSize; ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them.\r
+#endif\r
+\r
+void main()\r
+{\r
+ vec4 position = vec4(aPosition, 1.0);\r
+ vec3 normal = aNormal;\r
+ vec3 tangent = aTangent;\r
+\r
+#ifdef MORPH\r
+ int width = textureSize( sBlendShapeGeometry, 0 ).x;\r
+\r
+ int blendShapeBufferOffset = 0;\r
+ for( int index = 0; index < uNumberOfBlendShapes; ++index )\r
+ {\r
+#ifdef MORPH_POSITION\r
+ // Calculate the index to retrieve the geometry from the texture.\r
+ int vertexId = gl_VertexID + blendShapeBufferOffset;\r
+ int x = vertexId % width;\r
+ int y = vertexId / width;\r
+\r
+ vec3 diff = vec3(0.0);\r
+ // Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight.\r
+ if( 0.0 != uBlendShapeWeight[index] )\r
+ {\r
+#ifdef MORPH_VERSION_2_0\r
+ float unnormalizeFactor = uBlendShapeUnnormalizeFactor;\r
+#else\r
+ float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index];\r
+#endif\r
+\r
+ diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );\r
+ }\r
+\r
+ position.xyz += diff;\r
+\r
+ blendShapeBufferOffset += uBlendShapeComponentSize;\r
+#endif\r
+\r
+#ifdef MORPH_NORMAL\r
+ // Calculate the index to retrieve the normal from the texture.\r
+ vertexId = gl_VertexID + blendShapeBufferOffset;\r
+ x = vertexId % width;\r
+ y = vertexId / width;\r
+\r
+ // Retrieves the blend shape normal from the texture, unnormalizes it and multiply by the weight.\r
+ if( 0.0 != uBlendShapeWeight[index] )\r
+ {\r
+ diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );\r
+ }\r
+\r
+ normal += diff.xyz;\r
+\r
+ blendShapeBufferOffset += uBlendShapeComponentSize;\r
+#endif\r
+\r
+#ifdef MORPH_TANGENT\r
+ // Calculate the index to retrieve the tangent from the texture.\r
+ vertexId = gl_VertexID + blendShapeBufferOffset;\r
+ x = vertexId % width;\r
+ y = vertexId / width;\r
+\r
+ // Retrieves the blend shape tangent from the texture, unnormalizes it and multiply by the weight.\r
+ if( 0.0 != uBlendShapeWeight[index] )\r
+ {\r
+ diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 );\r
+ }\r
+\r
+ tangent += diff.xyz;\r
+\r
+ blendShapeBufferOffset += uBlendShapeComponentSize;\r
+#endif\r
+ }\r
+\r
+#endif\r
+\r
+#ifdef SKINNING\r
+ mat4 bone = uBone[int(aJoints.x)] * aWeights.x +\r
+ uBone[int(aJoints.y)] * aWeights.y +\r
+ uBone[int(aJoints.z)] * aWeights.z +\r
+ uBone[int(aJoints.w)] * aWeights.w;\r
+ position = bone * position;\r
+ normal = (bone * vec4(normal, 0.0)).xyz;\r
+ tangent = (bone * vec4(tangent, 0.0)).xyz;\r
+#endif\r
+\r
+ vec4 vPosition = uModelMatrix * position;\r
+\r
+ vNormal = normalize(uNormalMatrix * normal);\r
+\r
+ vTangent = normalize(uNormalMatrix * tangent);\r
+\r
+\r
+ vec4 viewPosition = uViewMatrix * vPosition;\r
+ gl_Position = uProjection * viewPosition;\r
+\r
+#ifdef FLIP_V\r
+ vUV = vec2(aTexCoord.x, 1.0 - aTexCoord.y);\r
+#else\r
+ vUV = aTexCoord;\r
+#endif\r
+\r
+ vViewVec = viewPosition.xyz;\r
+}\r
--- /dev/null
+{\r
+ "asset" : {\r
+ "version" : "1.0"\r
+ },\r
+ "scene" : 1,\r
+ "scenes" : [ {\r
+ "nodes" : [ 0 ]\r
+ }, {\r
+ "nodes" : [ 95 ]\r
+ } ],\r
+ "nodes" : [ {\r
+ "name" : "ExerciseDemo",\r
+ "matrix" : [ 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 1, 79, 88, 91, 92, 93, 94 ],\r
+ "behavior" : [ 4 ],\r
+ "visible" : true,\r
+ "lightingMode" : "lit"\r
+ }, {\r
+ "name" : "ReferenceShape_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 2 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hips_JNT",\r
+ "matrix" : [ 0.984536, 0.175182, 0.0, 0.0, -0.175122, 0.984198, 0.026198, 0.0, 0.004589, -0.025793, 0.999657, 0.0, 5.27538, 78.6471, -1.41421, 1.0 ],\r
+ "children" : [ 3, 69, 74 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.013219, -80.0521, 1.41421, 1.0 ]\r
+ }, {\r
+ "name" : "spine_JNT",\r
+ "matrix" : [ 0.984536, -0.175122, 0.004589, 0.0, 0.174502, 0.982682, 0.062338, 0.0, -0.015426, -0.060573, 0.998044, 0.0, 0.015846, 4.13037, 0.166239, 1.0 ],\r
+ "children" : [ 4 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.002627, -84.1824, 1.24797, 1.0 ]\r
+ }, {\r
+ "name" : "spine1_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.998172, -0.06044, 0.0, 0.0, 0.06044, 0.998172, 0.0, 0.005973, 10.694, 0.968772, 1.0 ],\r
+ "children" : [ 5 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0086, -94.8764, 0.279197, 1.0 ]\r
+ }, {\r
+ "name" : "spine2_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.998172, -0.06044, 0.0, 0.0, 0.06044, 0.998172, 0.0, 0.0, 10.1532, -0.580362, 1.0 ],\r
+ "children" : [ 6, 30, 54 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.008557, -105.03, 0.859559, 1.0 ]\r
+ }, {\r
+ "name" : "l_shoulder_JNT",\r
+ "matrix" : [ 0.949195, 0.273744, -0.155217, 0.0, -0.201691, 0.907824, 0.367663, 0.0, 0.241555, -0.317678, 0.916914, 0.0, 2.88666, 12.5391, -0.534974, 1.0 ],\r
+ "children" : [ 7 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.89521, -117.569, 1.39453, 1.0 ]\r
+ }, {\r
+ "name" : "l_arm_JNT",\r
+ "matrix" : [ 0.421571, -0.904401, -0.065849, 0.0, 0.517137, 0.180132, 0.836733, 0.0, -0.744881, -0.386795, 0.543638, 0.0, 10.2653, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 8 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -13.1738, -116.164, 1.39451, 1.0 ]\r
+ }, {\r
+ "name" : "l_forearm_JNT",\r
+ "matrix" : [ -0.073871, 0.0, 0.997268, 0.0, -3.91E-4, 1.0, 0.0, 0.0, -0.997268, -3.93E-4, -0.073871, 0.0, 25.5729, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 9 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -38.7466, -116.164, 1.39451, 1.0 ]\r
+ }, {\r
+ "name" : "l_hand_JNT",\r
+ "matrix" : [ 0.738915, 0.444766, -0.506149, 0.0, -0.59918, 0.777334, -0.191665, 0.0, 0.308201, 0.444898, 0.840879, 0.0, 19.8068, -0.345714, 1.00359, 1.0 ],\r
+ "children" : [ 10, 14, 18, 22, 26 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -58.5534, -115.818, 0.390923, 1.0 ]\r
+ }, {\r
+ "name" : "l_handThumb1_JNT",\r
+ "matrix" : [ 0.782913, -0.117863, 0.610865, 0.0, 0.011962, 0.984561, 0.174635, 0.0, -0.622017, -0.129417, 0.772235, 0.0, 2.27648, -1.65194, 3.31969, 1.0 ],\r
+ "children" : [ 11 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.707107, 0.0, -0.707107, 0.0, 0.0, 1.0, 0.0, 0.0, 0.707107, 0.0, 0.707107, 0.0, -45.0842, -114.166, 40.9423, 1.0 ]\r
+ }, {\r
+ "name" : "l_handThumb2_JNT",\r
+ "matrix" : [ 0.830425, -0.487404, -0.269872, 0.0, 0.464771, 0.873169, -0.146844, 0.0, 0.307216, -0.003486, 0.951633, 0.0, 3.0735, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 12 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.707107, 0.0, -0.707108, 0.0, 0.0, 1.0, 0.0, 0.0, 0.707108, 0.0, 0.707107, 0.0, -48.1577, -114.166, 40.9423, 1.0 ]\r
+ }, {\r
+ "name" : "l_handThumb3_JNT",\r
+ "matrix" : [ 0.98882, -0.149117, 0.0, 0.0, 0.149117, 0.98882, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 3.37693, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 13 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.707107, 0.0, -0.707108, 0.0, 0.0, 1.0, 0.0, 0.0, 0.707107, 0.0, 0.707107, 0.0, -51.5344, -114.166, 40.9423, 1.0 ]\r
+ }, {\r
+ "name" : "l_handThumb4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 3.92326, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_handIndex1_JNT",\r
+ "matrix" : [ 0.904938, -0.425377, 0.011949, 0.0, 0.425382, 0.905011, 0.002209, 0.0, -0.011754, 0.003084, 1.0, 0.0, 9.34022, -0.291901, 4.04881, 1.0 ],\r
+ "children" : [ 15 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -67.8936, -115.526, -3.65789, 1.0 ]\r
+ }, {\r
+ "name" : "l_handIndex2_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.09938, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 16 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -71.993, -115.526, -3.65788, 1.0 ]\r
+ }, {\r
+ "name" : "l_handIndex3_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.57415, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 17 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -74.5672, -115.526, -3.65788, 1.0 ]\r
+ }, {\r
+ "name" : "l_handIndex4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.56603, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_handPinky1_JNT",\r
+ "matrix" : [ 0.996226, -0.081261, -0.030513, 0.0, 0.081431, 0.996669, 0.004384, 0.0, 0.030055, -0.006852, 0.999525, 0.0, 8.45263, -1.52385, -3.88068, 1.0 ],\r
+ "children" : [ 19 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -67.0061, -114.294, 4.2716, 1.0 ]\r
+ }, {\r
+ "name" : "l_handPinky2_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 3.07304, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 20 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -70.0791, -114.294, 4.2716, 1.0 ]\r
+ }, {\r
+ "name" : "l_handPinky3_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.96712, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 21 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -72.0462, -114.294, 4.27159, 1.0 ]\r
+ }, {\r
+ "name" : "l_handPinky4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.8257, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_handRing1_JNT",\r
+ "matrix" : [ 0.980994, -0.191551, 0.030976, 0.0, 0.19168, 0.981457, -0.001225, 0.0, -0.030167, 0.007139, 0.999519, 0.0, 9.86254, -0.583908, -1.401, 1.0 ],\r
+ "children" : [ 23 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -68.416, -115.234, 1.79193, 1.0 ]\r
+ }, {\r
+ "name" : "l_handRing2_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 3.90873, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 24 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -72.3247, -115.234, 1.79192, 1.0 ]\r
+ }, {\r
+ "name" : "l_handRing3_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.36478, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 25 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -74.6895, -115.234, 1.79192, 1.0 ]\r
+ }, {\r
+ "name" : "l_handRing4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.88243, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_handMiddle1_JNT",\r
+ "matrix" : [ 0.953413, -0.301668, 0.0, 0.0, 0.301668, 0.953413, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.0737, -0.408325, 1.31404, 1.0 ],\r
+ "children" : [ 27 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -68.6272, -115.41, -0.923121, 1.0 ]\r
+ }, {\r
+ "name" : "l_handMiddle2_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973047, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.2249, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 28 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -72.8521, -115.41, -0.923118, 1.0 ]\r
+ }, {\r
+ "name" : "l_handMiddle3_JNT",\r
+ "matrix" : [ 0.973047, -0.230606, 0.0, 0.0, 0.230606, 0.973048, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.46916, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 29 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -75.3213, -115.41, -0.923117, 1.0 ]\r
+ }, {\r
+ "name" : "l_handMiddle4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 3.28131, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "r_shoulder_JNT",\r
+ "matrix" : [ 0.999696, 0.01745, -0.017452, 0.0, -0.017145, 0.999701, 0.01745, 0.0, 0.017751, -0.017145, 0.999696, 0.0, -2.88677, 12.5391, -0.53497, 1.0 ],\r
+ "children" : [ 31 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 2.87821, -117.569, 1.39453, 1.0 ]\r
+ }, {\r
+ "name" : "r_arm_JNT",\r
+ "matrix" : [ 0.148671, 0.988778, -0.014664, 0.0, -0.988733, 0.14837, -0.019851, 0.0, -0.017453, 0.01745, 0.999695, 0.0, -10.2653, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 32 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 13.1303, -116.164, 1.39455, 1.0 ]\r
+ }, {\r
+ "name" : "r_forearm_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 4.01E-4, 0.0, 0.0, -4.01E-4, 1.0, 0.0, -25.5729, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 33 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 38.7032, -116.164, 1.39456, 1.0 ]\r
+ }, {\r
+ "name" : "r_hand_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, -4.01E-4, 0.0, 0.0, 4.01E-4, 1.0, 0.0, -19.807, -0.346, 1.00358, 1.0 ],\r
+ "children" : [ 34, 38, 42, 46, 50 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 58.5102, -115.818, 0.390979, 1.0 ]\r
+ }, {\r
+ "name" : "r_handThumb1_JNT",\r
+ "matrix" : [ 0.653433, 0.24549, -0.716073, 0.0, -0.244838, 0.963648, 0.106945, 0.0, 0.716296, 0.105441, 0.689785, 0.0, -2.27647, -1.65195, 3.31969, 1.0 ],\r
+ "children" : [ 35 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.707106, 0.0, 0.707106, 0.0, 0.0, 1.0, 0.0, 0.0, -0.707106, 0.0, 0.707106, 0.0, 45.0536, -114.166, 40.9117, 1.0 ]\r
+ }, {\r
+ "name" : "r_handThumb2_JNT",\r
+ "matrix" : [ 0.867302, 0.0, 0.497783, 0.0, 0.0, 1.0, 0.0, 0.0, -0.497783, 0.0, 0.867301, 0.0, -3.0735, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 36 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.707106, 0.0, 0.707106, 0.0, 0.0, 1.0, 0.0, 0.0, -0.707106, 0.0, 0.707106, 0.0, 48.127, -114.166, 40.9117, 1.0 ]\r
+ }, {\r
+ "name" : "r_handThumb3_JNT",\r
+ "matrix" : [ 0.996311, 0.0, 0.085813, 0.0, 0.0, 1.0, 0.0, 0.0, -0.085813, 0.0, 0.996311, 0.0, -3.37693, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 37 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.707106, 0.0, 0.707107, 0.0, 0.0, 1.0, 0.0, 0.0, -0.707106, 0.0, 0.707107, 0.0, 51.504, -114.166, 40.9117, 1.0 ]\r
+ }, {\r
+ "name" : "r_handThumb4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -3.923, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "r_handRing1_JNT",\r
+ "matrix" : [ 0.915131, 0.400047, -0.049976, 0.0, -0.400717, 0.916194, -0.003754, 0.0, 0.044286, 0.023462, 0.998743, 0.0, -9.86253, -0.583984, -1.40101, 1.0 ],\r
+ "children" : [ 39 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 68.3727, -115.234, 1.79199, 1.0 ]\r
+ }, {\r
+ "name" : "r_handRing2_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -3.90872, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 40 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 72.2814, -115.234, 1.79199, 1.0 ]\r
+ }, {\r
+ "name" : "r_handRing3_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.36478, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 41 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 74.6462, -115.234, 1.792, 1.0 ]\r
+ }, {\r
+ "name" : "r_handRing4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.882, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "r_handPinky1_JNT",\r
+ "matrix" : [ 0.863063, 0.499949, -0.071924, 0.0, -0.501878, 0.864874, -0.010555, 0.0, 0.056928, 0.045207, 0.997354, 0.0, -8.45262, -1.52391, -3.88068, 1.0 ],\r
+ "children" : [ 43 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 66.9628, -114.294, 4.27166, 1.0 ]\r
+ }, {\r
+ "name" : "r_handPinky2_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -3.07304, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 44 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 70.0358, -114.294, 4.27167, 1.0 ]\r
+ }, {\r
+ "name" : "r_handPinky3_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -1.96712, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 45 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 72.0029, -114.294, 4.27168, 1.0 ]\r
+ }, {\r
+ "name" : "r_handPinky4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.826, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "r_handMiddle1_JNT",\r
+ "matrix" : [ 0.944916, 0.327312, 0.0, 0.0, -0.327312, 0.944916, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -10.0737, -0.408401, 1.31403, 1.0 ],\r
+ "children" : [ 47 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 68.5839, -115.409, -0.923056, 1.0 ]\r
+ }, {\r
+ "name" : "r_handMiddle2_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -4.2249, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 48 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 72.8088, -115.409, -0.923044, 1.0 ]\r
+ }, {\r
+ "name" : "r_handMiddle3_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.46917, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 49 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 75.278, -115.409, -0.92304, 1.0 ]\r
+ }, {\r
+ "name" : "r_handMiddle4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -3.281, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "r_handIndex1_JNT",\r
+ "matrix" : [ 0.980248, 0.186022, 0.067154, 0.0, -0.186597, 0.982434, 0.002344, 0.0, -0.065538, -0.014828, 0.99774, 0.0, -9.34022, -0.291962, 4.0488, 1.0 ],\r
+ "children" : [ 51 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 67.8504, -115.526, -3.65782, 1.0 ]\r
+ }, {\r
+ "name" : "r_handIndex2_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -4.09938, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 52 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 71.9498, -115.526, -3.65782, 1.0 ]\r
+ }, {\r
+ "name" : "r_handIndex3_JNT",\r
+ "matrix" : [ 0.94204, 0.335501, 0.0, 0.0, -0.335501, 0.94204, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.57415, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 53 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 74.5239, -115.526, -3.65782, 1.0 ]\r
+ }, {\r
+ "name" : "r_handIndex4_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -2.566, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "neck_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.998172, -0.06044, 0.0, 0.0, 0.06044, 0.998172, 0.0, 0.0, 17.0656, -0.695395, 1.0 ],\r
+ "children" : [ 55 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.008488, -122.095, 1.55495, 1.0 ]\r
+ }, {\r
+ "name" : "head_JNT",\r
+ "matrix" : [ 0.995828, 0.087837, -0.024703, 0.0, -0.081637, 0.978626, 0.188753, 0.0, 0.040755, -0.185949, 0.981714, 0.0, 0.0, 8.13757, 2.14518, 1.0 ],\r
+ "children" : [ 56, 59, 62, 65, 66, 67, 68 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.021705, -128.828, -2.00444, 1.0 ]\r
+ }, {\r
+ "name" : "hair_01_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 11.442, 24.1427, -1.69867, 1.0 ],\r
+ "children" : [ 57 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_01_01_JNT",\r
+ "matrix" : [ 0.0, 0.0, -1.0, 0.0, -0.093641, 0.995606, 0.0, 0.0, 0.995606, 0.093641, 0.0, 0.0, 0.0, -9.01569, 0.0, 1.0 ],\r
+ "children" : [ 58 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_01_02_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -11.0805, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_02_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -13.1304, 24.2143, -1.69866, 1.0 ],\r
+ "children" : [ 60 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_02_01_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -9.01563, 0.0, 1.0 ],\r
+ "children" : [ 61 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_02_02_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -11.0805, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_03_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 24.2142, -13.2264, 1.0 ],\r
+ "children" : [ 63 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_03_01_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -9.01563, 0.0, 1.0 ],\r
+ "children" : [ 64 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "hair_03_02_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, -11.0805, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_earring_accessory_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 10.936, 6.972, 0.888, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "r_earring_accessory_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -11.0026, 6.74516, 0.187242, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_eye_JNT",\r
+ "matrix" : [ 0.997963, -0.003027, 0.063724, 0.0, -0.003026, 0.995503, 0.094684, 0.0, -0.063724, -0.094684, 0.993466, 0.0, 4.68487, 12.7498, 9.96268, 1.0 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -4.74966, -141.45, -10.6596, 1.0 ]\r
+ }, {\r
+ "name" : "r_eye_JNT",\r
+ "matrix" : [ 0.997966, -0.002933, 0.063684, 0.0, -0.002932, 0.995772, 0.091809, 0.0, -0.063684, -0.091809, 0.993738, 0.0, -4.77108, 12.7498, 9.96268, 1.0 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 4.70629, -141.45, -10.6596, 1.0 ]\r
+ }, {\r
+ "name" : "r_upleg_JNT",\r
+ "matrix" : [ 0.927337, -0.198173, 0.317448, 0.0, 0.278028, 0.93264, -0.229963, 0.0, -0.250492, 0.301512, 0.919969, 0.0, -7.5159, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 70 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, -0.002495, -1.16E-4, 0.0, 0.002493, 0.999837, -0.017917, 0.0, 1.61E-4, 0.017917, 0.99984, 0.0, 7.32992, -80.0324, 2.84741, 1.0 ]\r
+ }, {\r
+ "name" : "r_leg_JNT",\r
+ "matrix" : [ 0.997732, 0.060039, 0.030441, 0.0, -0.067243, 0.9099, 0.409341, 0.0, -0.003122, -0.41046, 0.911874, 0.0, -0.724057, -37.7363, 2.80023, 1.0 ],\r
+ "children" : [ 71 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.002998, 0.0, 0.0, -0.002998, 0.999857, 0.016638, 0.0, 0.0, -0.016638, 0.999862, 0.0, 8.28614, -42.2277, -1.41208, 1.0 ]\r
+ }, {\r
+ "name" : "r_foot_JNT",\r
+ "matrix" : [ 0.964557, 0.026598, 0.262529, 0.0, 0.024923, 0.981276, -0.190988, 0.0, -0.262693, 0.190762, 0.945834, 0.0, 1.26E-4, -34.5752, -1.6048, 1.0 ],\r
+ "children" : [ 72 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 9.09E-4, 0.0, 0.0, -9.09E-4, 1.0, 0.0, 8.26299, -7.67328, 0.312986, 1.0 ]\r
+ }, {\r
+ "name" : "r_toebase_JNT",\r
+ "matrix" : [ 0.0, -0.103501, 0.994629, 0.0, 0.0, 0.994629, 0.103501, 0.0, -1.0, 0.0, 0.0, 0.0, 0.0, -6.10491, 11.1619, 1.0 ],\r
+ "children" : [ 73 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.0, 0.0, -1.0, 0.0, -0.102591, 0.994724, 0.0, 0.0, 0.994724, 0.102591, 0.0, 0.0, -10.6284, -2.68276, -8.26298, 1.0 ]\r
+ }, {\r
+ "name" : "joint1",\r
+ "matrix" : [ 0.0, 0.0, -1.0, 0.0, -0.108623, 0.994083, 0.0, 0.0, 0.994083, 0.108623, 0.0, 0.0, 5.7477, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "l_upleg_JNT",\r
+ "matrix" : [ 0.969105, -0.243372, 0.040065, 0.0, 0.242338, 0.969759, 0.028984, 0.0, -0.045907, -0.018379, 0.998777, 0.0, 7.51591, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 75 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.999881, -0.015441, 0.0, 0.0, 0.015441, 0.999881, 0.0, -7.50515, -80.0204, 2.6501, 1.0 ]\r
+ }, {\r
+ "name" : "l_leg_JNT",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.993288, -0.115665, 0.0, 0.0, 0.115665, 0.993288, 0.0, 2.16E-4, -37.7436, 2.62906, 1.0 ],\r
+ "children" : [ 76 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 0.999822, 0.018881, 0.0, 0.0, -0.018881, 0.999822, 0.0, -7.50542, -42.2526, -1.42976, 1.0 ]\r
+ }, {\r
+ "name" : "l_foot_JNT",\r
+ "matrix" : [ 0.996936, 0.072648, -0.029003, 0.0, -0.070636, 0.995367, 0.065233, 0.0, 0.033608, -0.062984, 0.997448, 0.0, 0.0, -34.5752, -1.6048, 1.0 ],\r
+ "children" : [ 77 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 9.11E-4, 0.0, 0.0, -9.11E-4, 1.0, 0.0, -7.50523, -7.67329, 0.31298, 1.0 ]\r
+ }, {\r
+ "name" : "l_toebase_JNT",\r
+ "matrix" : [ 1.9E-4, -0.10218, 0.994766, 0.0, 0.0, 0.994766, 0.10218, 0.0, -1.0, 0.0, 1.81E-4, 0.0, 0.0, -6.10494, 11.1619, 1.0 ],\r
+ "children" : [ 78 ],\r
+ "visible" : true,\r
+ "inverseBindPoseMatrix" : [ 0.0, 0.0, -1.0, 0.0, -0.102591, 0.994724, 0.0, 0.0, 0.994724, 0.102591, 0.0, 0.0, -10.6284, -2.68276, 7.50523, 1.0 ]\r
+ }, {\r
+ "name" : "joint2",\r
+ "matrix" : [ 0.0, 0.0, -1.0, 0.0, -0.104271, 0.994549, 0.0, 0.0, 0.994549, 0.104271, 0.0, 0.0, 5.91715, 0.0, 0.0, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "Model",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 80, 81, 82, 83, 84, 85, 86, 87 ],\r
+ "visible" : true,\r
+ "lightingMode" : "lit-solid"\r
+ }, {\r
+ "name" : "R_New_Eye",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 8,\r
+ "mesh" : 0,\r
+ "shader" : 1\r
+ }\r
+ }, {\r
+ "name" : "L_New_Eye",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 8,\r
+ "mesh" : 1,\r
+ "shader" : 1\r
+ }\r
+ }, {\r
+ "name" : "newhair",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 9,\r
+ "mesh" : 2,\r
+ "shader" : 1\r
+ }\r
+ }, {\r
+ "name" : "OutFit_Bottom",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 10,\r
+ "mesh" : 3,\r
+ "shader" : 1\r
+ }\r
+ }, {\r
+ "name" : "OutFit_Top",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 11,\r
+ "mesh" : 4,\r
+ "shader" : 1\r
+ }\r
+ }, {\r
+ "name" : "Shoes_Shoes01_Female_Adult_Thumbnail_GEO",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 12,\r
+ "mesh" : 5,\r
+ "shader" : 1\r
+ }\r
+ }, {\r
+ "name" : "Head_GEO",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 7,\r
+ "mesh" : 6,\r
+ "shader" : 2\r
+ }\r
+ }, {\r
+ "name" : "Body_GEO",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 6,\r
+ "mesh" : 9,\r
+ "shader" : 2\r
+ }\r
+ }, {\r
+ "name" : "directionalLight1",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 91.3751, 284.323, 1.0 ],\r
+ "visible" : true\r
+ }, {\r
+ "name" : "BackGround",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 5,\r
+ "mesh" : 7,\r
+ "shader" : 4\r
+ }\r
+ }, {\r
+ "name" : "Ground",\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 5,\r
+ "mesh" : 8,\r
+ "shader" : 4\r
+ }\r
+ }, {\r
+ "name" : "Idle",\r
+ "size" : [ 30.0, 30.0 ],\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -82.0, 64.0, -1.0, 1.0 ],\r
+ "behavior" : [ 0 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 1,\r
+ "mesh" : 10,\r
+ "shader" : 3\r
+ }\r
+ }, {\r
+ "name" : "Squat",\r
+ "size" : [ 30.0, 30.0 ],\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -85.0, 94.0, 1.0, 1.0 ],\r
+ "behavior" : [ 1 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 2,\r
+ "mesh" : 10,\r
+ "shader" : 3\r
+ }\r
+ }, {\r
+ "name" : "JumpingJack",\r
+ "size" : [ 30.0, 30.0 ],\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -75.0, 124.0, 0.0, 1.0 ],\r
+ "behavior" : [ 2 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 3,\r
+ "mesh" : 10,\r
+ "shader" : 3\r
+ }\r
+ }, {\r
+ "name" : "Lunge",\r
+ "size" : [ 30.0, 30.0 ],\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -55.0, 154.0, 0.0, 1.0 ],\r
+ "behavior" : [ 3 ],\r
+ "visible" : true,\r
+ "model" : {\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "material" : 4,\r
+ "mesh" : 10,\r
+ "shader" : 3\r
+ }\r
+ }, {\r
+ "name" : "Backdrop",\r
+ "matrix" : [ 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "children" : [ 89, 90 ],\r
+ "visible" : true,\r
+ "lightingMode" : "lit"\r
+ } ],\r
+ "meshes" : [ {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 0,\r
+ "byteLength" : 2520\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 2520,\r
+ "byteLength" : 3168\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 5688,\r
+ "byteLength" : 3168\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 8856,\r
+ "byteLength" : 2112\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 10968,\r
+ "byteLength" : 3168\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 14136,\r
+ "byteLength" : 4224\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 18360,\r
+ "byteLength" : 4224\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 22584,\r
+ "byteLength" : 2520\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 25104,\r
+ "byteLength" : 3180\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 28284,\r
+ "byteLength" : 3180\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 31464,\r
+ "byteLength" : 2120\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 33584,\r
+ "byteLength" : 3180\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 36764,\r
+ "byteLength" : 4240\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 41004,\r
+ "byteLength" : 4240\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 45244,\r
+ "byteLength" : 25938\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 71182,\r
+ "byteLength" : 34092\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 105274,\r
+ "byteLength" : 34092\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 139366,\r
+ "byteLength" : 22728\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 162094,\r
+ "byteLength" : 34092\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 196186,\r
+ "byteLength" : 45456\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 241642,\r
+ "byteLength" : 45456\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 287098,\r
+ "byteLength" : 5988\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 293086,\r
+ "byteLength" : 8412\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 301498,\r
+ "byteLength" : 8412\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 309910,\r
+ "byteLength" : 5608\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 315518,\r
+ "byteLength" : 8412\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 323930,\r
+ "byteLength" : 11216\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 335146,\r
+ "byteLength" : 11216\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 346362,\r
+ "byteLength" : 3720\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 350082,\r
+ "byteLength" : 5004\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 355086,\r
+ "byteLength" : 5004\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 360090,\r
+ "byteLength" : 3336\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 363426,\r
+ "byteLength" : 5004\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 368430,\r
+ "byteLength" : 6672\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 375102,\r
+ "byteLength" : 6672\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 381774,\r
+ "byteLength" : 5520\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 387294,\r
+ "byteLength" : 7284\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 394578,\r
+ "byteLength" : 7284\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 401862,\r
+ "byteLength" : 4856\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 406718,\r
+ "byteLength" : 7284\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 414002,\r
+ "byteLength" : 9712\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 423714,\r
+ "byteLength" : 9712\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 433426,\r
+ "byteLength" : 34524\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 467950,\r
+ "byteLength" : 37824\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 505774,\r
+ "byteLength" : 37824\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 543598,\r
+ "byteLength" : 25216\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 568814,\r
+ "byteLength" : 37824\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 606638,\r
+ "byteLength" : 50432\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 657070,\r
+ "byteLength" : 50432\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 31,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 707502,\r
+ "byteLength" : 360\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 707862,\r
+ "byteLength" : 732\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 708594,\r
+ "byteLength" : 732\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 709326,\r
+ "byteLength" : 488\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 709814,\r
+ "byteLength" : 732\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 31,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 710546,\r
+ "byteLength" : 12\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 710558,\r
+ "byteLength" : 48\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 710606,\r
+ "byteLength" : 48\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 710654,\r
+ "byteLength" : 32\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 710686,\r
+ "byteLength" : 48\r
+ }\r
+ }, {\r
+ "uri" : "exercise/model.dae.bin",\r
+ "attributes" : 223,\r
+ "primitive" : "TRIANGLES",\r
+ "indices" : {\r
+ "byteOffset" : 710734,\r
+ "byteLength" : 24312\r
+ },\r
+ "positions" : {\r
+ "byteOffset" : 735046,\r
+ "byteLength" : 33000\r
+ },\r
+ "normals" : {\r
+ "byteOffset" : 768046,\r
+ "byteLength" : 33000\r
+ },\r
+ "textures" : {\r
+ "byteOffset" : 801046,\r
+ "byteLength" : 22000\r
+ },\r
+ "tangents" : {\r
+ "byteOffset" : 823046,\r
+ "byteLength" : 33000\r
+ },\r
+ "skeleton" : 0,\r
+ "joints0" : {\r
+ "byteOffset" : 856046,\r
+ "byteLength" : 44000\r
+ },\r
+ "weights0" : {\r
+ "byteOffset" : 900046,\r
+ "byteLength" : 44000\r
+ }\r
+ }, {\r
+ "uri" : "quad",\r
+ "attributes" : 0,\r
+ "primitive" : "TRIANGLES"\r
+ } ],\r
+ "cameras" : [ {\r
+ "near" : 2.5,\r
+ "far" : 1000.0,\r
+ "matrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.9138, 5.0, 1.0 ],\r
+ "fov" : 37.8492\r
+ } ],\r
+ "lights" : [ {\r
+ "matrix" : [ 0.8950600624084473, 0.0914330929517746, 0.4364715814590454, 0.0, 0.3676385283470154, 0.4026888310909271, -0.8382623195648193, 0.0, -0.25240713357925415, 0.9107588529586792, 0.3268163800239563, 0.0, 0.0, 0.0, -1.0, 1.0 ],\r
+ "color" : [ 1.0, 1.0, 1.0 ],\r
+ "intensity" : 1.0,\r
+ "shadowMapSize" : 256,\r
+ "orthographicSize" : 4.2760005,\r
+ "shadowIntensity" : 1.0\r
+ } ],\r
+ "materials" : [ {\r
+ "name" : "No name",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Icons\\Icon_Idle.png",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : false,\r
+ "albedoMap" : "exercise/Icons/Icon_Idle.png"\r
+ }, {\r
+ "name" : "Icons\\Icon_Squat.png",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : false,\r
+ "albedoMap" : "exercise/Icons/Icon_Squat.png"\r
+ }, {\r
+ "name" : "Icons\\Icon_JJ.png",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : false,\r
+ "albedoMap" : "exercise/Icons/Icon_JJ.png"\r
+ }, {\r
+ "name" : "Icons\\Icon_Lunge.png",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : false,\r
+ "albedoMap" : "exercise/Icons/Icon_Lunge.png"\r
+ }, {\r
+ "name" : "Background",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/BG_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/BG_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Body",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/Body_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/Body_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "subsurfaceMap" : "exercise/Textures/Body_Female_Asian_Adult_SubsurfaceColor.png",\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Head",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/Head_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/Head_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "subsurfaceMap" : "exercise/Textures/Head_Female_SubsurfaceColor.png",\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Eye",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/Eye_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/Eye_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Hair",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/Hair_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/Hair_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Bottom outfit",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/FitBot_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/FitBot_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Top outfit",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/FitTop_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/FitTop_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ }, {\r
+ "name" : "Shoe",\r
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],\r
+ "normalRoughnessMap" : "exercise/Textures/Shoe_NormalRoughness.png",\r
+ "albedoMetallicMap" : "exercise/Textures/Shoe_AlbedoMetallic.png",\r
+ "roughness" : 1.0,\r
+ "metallic" : 1.0,\r
+ "mipmap" : true,\r
+ "environment" : 1\r
+ } ],\r
+ "environment" : [ {\r
+ "cubeInitialOrientation" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "iblIntensity" : 1.0\r
+ }, {\r
+ "cubeSpecular" : "Studio/Radiance.ktx",\r
+ "cubeDiffuse" : "Studio/Irradiance.ktx",\r
+ "cubeInitialOrientation" : [ 0.6716271638870239, 0.07979151606559753, -0.7365801334381104, 0.0, 0.07979151606559753, 0.9806114435195923, 0.17898204922676086, 0.0, 0.7365801334381104, -0.17898204922676086, 0.6522386074066162, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "iblIntensity" : 0.75\r
+ } ],\r
+ "shaders" : [ {\r
+ "vertex" : "dli_pbr.vsh",\r
+ "fragment" : "dli_pbr.fsh",\r
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",\r
+ "uCubeMatrix" : [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],\r
+ "uMaxLOD" : 8\r
+ }, {\r
+ "vertex" : "dli_pbr.vsh",\r
+ "fragment" : "dli_pbr.fsh",\r
+ "hints": [ "MODIFIES_GEOMETRY" ],\r
+ "defines" : [ "LIT", "SKINNING" ],\r
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",\r
+ "uCubeMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "uMaxLOD" : 6\r
+ }, {\r
+ "vertex" : "dli_pbr.vsh",\r
+ "fragment" : "dli_pbr.fsh",\r
+ "hints": [ "MODIFIES_GEOMETRY" ],\r
+ "defines" : [ "LIT", "SKINNING", "SSS" ],\r
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",\r
+ "uCubeMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "uMaxLOD" : 6\r
+ }, {\r
+ "vertex" : "dli_pbr.vsh",\r
+ "fragment" : "dli_pbr.fsh",\r
+ "rendererState" : "DEPTH_TEST|ALPHA_BLEND",\r
+ "uCubeMatrix" : [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],\r
+ "uTilt" : [ 0.0, 0.0 ]\r
+ }, {\r
+ "vertex" : "dli_pbr.vsh",\r
+ "fragment" : "dli_pbr.fsh",\r
+ "defines" : [ "LIT", "SHADOW" ],\r
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",\r
+ "uCubeMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],\r
+ "uMaxLOD" : 6\r
+ } ],\r
+ "animations" : [ {\r
+ "name" : "idleClip",\r
+ "loopCount" : 0,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 3024,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 6048,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 9072,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 12096,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 15120,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 18144,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 20592,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 23616,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 26640,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 29664,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 32688,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 35712,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 38736,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 41760,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 44784,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 47808,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 50832,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-animation.ani",\r
+ "byteOffset" : 53856,\r
+ "numKeys" : 144\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 6.0\r
+ },\r
+ "relative" : false\r
+ } ]\r
+ }, {\r
+ "name" : "squatClip_0",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 1764,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 3192,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 4956,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 6720,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 8484,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 10248,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hair_02_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 12012,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hair_03_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-0.ani",\r
+ "byteOffset" : 13776,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 1 ]\r
+ }, {\r
+ "name" : "squatClip_1",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 1596,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 3192,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 4788,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 6384,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 7980,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 9576,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 11172,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 12768,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 14364,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 15656,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 17252,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 18848,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 20444,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 22040,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 23636,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 25232,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 26828,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 28424,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 30020,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 31616,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 33212,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 34808,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 36404,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 38000,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 39596,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 41192,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 42788,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-animation-1.ani",\r
+ "byteOffset" : 44384,\r
+ "numKeys" : 76\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.16667\r
+ },\r
+ "relative" : false\r
+ } ]\r
+ }, {\r
+ "name" : "jumpingJackClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 630,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 1140,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 1770,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 2400,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 3030,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 3660,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 4290,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 4920,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 5550,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 6180,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 6810,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 7440,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 8070,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 8700,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 9330,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 9960,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 10590,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 11220,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 11850,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 12480,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 13110,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 13740,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 14370,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 15000,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 15630,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 16260,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 16890,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 17520,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 18150,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 18780,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 19410,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 20040,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 20670,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 21300,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 21930,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 22560,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 23190,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 23820,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 24450,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 25080,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 25710,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 26340,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 26970,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 27600,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 28230,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 28860,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 29490,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 30120,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 30750,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 31380,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-animation.ani",\r
+ "byteOffset" : 32010,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 4 ]\r
+ }, {\r
+ "name" : "lungeClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 1649,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 3686,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 5723,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 7760,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 9797,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 11834,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 13871,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 15908,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 17945,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 19982,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 22019,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 24056,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 26093,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 28130,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 30167,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 32204,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 34241,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 36278,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 38315,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 40352,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 42389,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 44426,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 46075,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 48112,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 50149,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 52186,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 54223,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 56260,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 58297,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 60334,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 62371,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 64408,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 66445,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-animation.ani",\r
+ "byteOffset" : 68482,\r
+ "numKeys" : 97\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 4.04167\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 7 ]\r
+ }, {\r
+ "name" : "idleToSquatClip_0",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 1932,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 3496,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 5428,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 6992,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 8924,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 10856,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 12788,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 14720,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 16652,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 18584,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 20516,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 22448,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 24380,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 26312,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 28244,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 30176,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 32108,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 34040,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 35972,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 37904,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 39836,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 41768,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 43700,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 45632,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 47564,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 49496,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 51060,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 52992,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 54924,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 56856,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 58788,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 60720,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 62652,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 64584,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 66516,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 68448,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 70380,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 72312,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 74244,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 76176,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 78108,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 80040,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 81972,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 83904,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 85836,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 87768,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 89700,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 91632,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 93564,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 95496,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 97428,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 99360,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 101292,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 103224,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 105156,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-0.ani",\r
+ "byteOffset" : 107088,\r
+ "numKeys" : 92\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.83333\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 0 ]\r
+ }, {\r
+ "name" : "idleToSquatClip_1",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hair_02_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-1.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hair_03_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-squat-animation-1.ani",\r
+ "byteOffset" : 1764,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ } ]\r
+ }, {\r
+ "name" : "squatToIdleClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 1806,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 3268,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 5074,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 6880,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 8686,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 10492,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 12298,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 14104,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 15910,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 17716,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 19522,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 21328,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 23134,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 24940,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 26746,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 28552,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 30358,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 32164,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 33970,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 35776,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 37582,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 39388,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 41194,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 43000,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 44462,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 46268,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 48074,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 49880,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 51686,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 53492,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 55298,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 57104,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 58910,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 60716,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 62522,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 64328,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 66134,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 67940,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 69746,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 71552,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 73358,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 75164,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 76970,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 78776,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hair_02_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 80582,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hair_03_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 82388,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 84194,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 86000,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 87806,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 89612,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 91418,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 93224,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 95030,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 96836,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 98642,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-idle-animation.ani",\r
+ "byteOffset" : 100448,\r
+ "numKeys" : 86\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.58333\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 2 ]\r
+ }, {\r
+ "name" : "idleToJumpingJackClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 1365,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 2470,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 3835,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 5200,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 6565,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 7930,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 9295,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 10660,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 12025,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 13390,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 14755,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 16120,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 17485,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 18850,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 20215,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 21580,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 22945,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 24310,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 25675,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 27040,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 28405,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 29770,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 31135,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 32500,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 33865,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 34970,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 36335,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 37700,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 39065,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 40430,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 41795,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 43160,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 44525,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 45890,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 47255,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 48620,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 49985,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 51350,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 52715,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 54080,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 55445,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 56810,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 58175,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 59540,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 60905,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 62270,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 63635,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 65000,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 66365,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 67730,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 69095,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 70460,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 71825,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 73190,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 74555,\r
+ "numKeys" : 65\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.70833\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 3 ]\r
+ }, {\r
+ "name" : "jumpingJackToIdleClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 1491,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 2698,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 4189,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 5680,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 7171,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 8662,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 10153,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 11644,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 13135,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 14626,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 16117,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 17608,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 19099,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 20590,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 22081,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 23572,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 25063,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 26554,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 28045,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 29536,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 31027,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 32518,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 34009,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 35500,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 36707,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 38198,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 39689,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 41180,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 42671,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 44162,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 45653,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 47144,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 48635,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 50126,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 51617,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 53108,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 54599,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 56090,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 57581,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 59072,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 60563,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 62054,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 63545,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 65036,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 66527,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 68018,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 69509,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 71000,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 72491,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 73982,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 75473,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 76964,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 78455,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-idle-animation.ani",\r
+ "byteOffset" : 79946,\r
+ "numKeys" : 71\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 2.95833\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 5 ]\r
+ }, {\r
+ "name" : "idleToLungeClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 1764,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 3192,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 4956,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 6384,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 8148,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 9912,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 11676,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 13440,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 15204,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 16968,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 18732,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 20496,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 22260,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 24024,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 25788,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 27552,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 29316,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 31080,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 32844,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 34608,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 36372,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 38136,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 39900,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 41664,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 43428,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 45192,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 46620,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 48384,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 50148,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 51912,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 53676,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 55440,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 57204,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 58968,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 60732,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 62496,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 64260,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 66024,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 67788,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 69552,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 71316,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 73080,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 74844,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 76608,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 78372,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 80136,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 81900,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 83664,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 85428,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 87192,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 88956,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 90720,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 92484,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 94248,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/idle-to-lunge-animation.ani",\r
+ "byteOffset" : 96012,\r
+ "numKeys" : 84\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.5\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 6 ]\r
+ }, {\r
+ "name" : "lungeToIdleClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 1701,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 3078,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 4779,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 6480,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_shoulder_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 8181,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 9882,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 11583,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 13284,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 14985,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 16686,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 18387,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 20088,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 21789,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 23490,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 25191,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 26892,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 28593,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 30294,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 31995,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 33696,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 35397,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 37098,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 38799,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 40500,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 41877,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 43578,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 45279,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 46980,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 48681,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 50382,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 52083,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 53784,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 55485,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 57186,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 58887,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 60588,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 62289,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 63990,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 65691,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 67392,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 69093,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 70794,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 72495,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 74196,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_eye_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 75897,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 77598,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 79299,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 81000,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 82701,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 84402,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 86103,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 87804,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-idle-animation.ani",\r
+ "byteOffset" : 89505,\r
+ "numKeys" : 81\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 3.375\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 8 ]\r
+ }, {\r
+ "name" : "jumpingJackToLungeClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 756,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 1368,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 2124,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 2736,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 3492,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 4248,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 5004,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 5760,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 6516,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 7272,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 8028,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 8784,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 9540,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 10296,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 11052,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 11808,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 12564,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 13320,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 14076,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 14832,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 15588,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 16344,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 17100,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 17856,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 18468,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 19224,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 19980,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 20736,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 21492,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 22248,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 23004,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 23760,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 24516,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 25272,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 26028,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 26784,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 27540,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 28296,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 29052,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 29808,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 30564,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 31320,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 32076,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 32832,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 33588,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 34344,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 35100,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 35856,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 36612,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 37368,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-lunge-animation.ani",\r
+ "byteOffset" : 38124,\r
+ "numKeys" : 36\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.5\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 9 ]\r
+ }, {\r
+ "name" : "jumpingJackToSquatClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 525,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 950,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 1475,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 2000,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 2525,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 3050,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 3575,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 4100,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 4625,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 5150,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 5675,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 6200,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 6725,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 7250,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 7775,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 8300,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 8825,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 9350,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 9875,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 10400,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 10925,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 11450,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 11975,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/jumping-jack-to-squat-animation.ani",\r
+ "byteOffset" : 12500,\r
+ "numKeys" : 25\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.04167\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 10 ]\r
+ }, {\r
+ "name" : "lungeToJumpingJackClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 861,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 1558,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 2419,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 3116,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 3977,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 4838,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 5699,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 6560,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 7421,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 8282,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 9143,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 10004,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 10865,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 11726,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 12587,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 13448,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 14309,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 15170,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 16031,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 16892,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 17753,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 18614,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 19475,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 20336,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 21033,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 21894,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 22755,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 23616,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 24477,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 25338,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 26199,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 27060,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 27921,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 28782,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 29643,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 30504,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 31365,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 32226,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 33087,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 33948,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 34809,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 35670,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 36531,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 37392,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 38253,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 39114,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 39975,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 40836,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 41697,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 42558,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 43419,\r
+ "numKeys" : 41\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.70833\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 11 ]\r
+ }, {\r
+ "name" : "lungeToSquatClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 546,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 988,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 1534,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 1976,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 2522,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 3068,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 3614,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 4160,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 4706,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 5252,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 5798,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 6344,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 6890,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 7436,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 7982,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 8528,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 9074,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 9620,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 10166,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 10712,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 11258,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 11804,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 12350,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 12896,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 13338,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 13884,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 14430,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 14976,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 15522,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 16068,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 16614,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 17160,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 17706,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 18252,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 18798,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 19344,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 19890,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 20436,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 20982,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 21528,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 22074,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 22620,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 23166,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 23712,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 24258,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 24804,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 25350,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 25896,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 26442,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 26988,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/lunge-to-squat-animation.ani",\r
+ "byteOffset" : 27534,\r
+ "numKeys" : 26\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.08333\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 12 ]\r
+ }, {\r
+ "name" : "squatToJumpingJackClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 630,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 1140,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 1770,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 2400,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 3030,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 3660,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 4290,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 4920,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 5550,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_shoulder_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 6180,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 6690,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 7320,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 7950,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 8580,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 9210,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 9840,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 10470,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 11100,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 11730,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 12360,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 12990,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 13620,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 14250,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 14880,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 15510,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-jumping-jack-animation.ani",\r
+ "byteOffset" : 16140,\r
+ "numKeys" : 30\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.25\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 13 ]\r
+ }, {\r
+ "name" : "squatToLungeClip",\r
+ "loopCount" : 1,\r
+ "duration" : 0.0,\r
+ "endAction" : "BAKE",\r
+ "disconnectAction" : "BAKE",\r
+ "properties" : [ {\r
+ "node" : "hips_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 0,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "hips_JNT",\r
+ "property" : "position",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 504,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 912,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 1416,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "spine2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 1920,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 2424,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 2928,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 3432,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 3936,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 4440,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 4944,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 5448,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 5952,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 6456,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 6960,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 7464,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 7968,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 8472,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 8976,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 9480,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 9984,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 10488,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 10992,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_arm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 11496,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_forearm_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 12000,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_hand_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 12504,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 13008,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 13512,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handThumb3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 14016,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 14520,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 15024,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handRing3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 15528,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 16032,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 16536,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handPinky3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 17040,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 17544,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 18048,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handMiddle3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 18552,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex1_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 19056,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex2_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 19560,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_handIndex3_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 20064,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "neck_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 20568,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "head_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 21072,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 21576,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 22080,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 22584,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "r_toebase_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 23088,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_upleg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 23592,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_leg_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 24096,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ }, {\r
+ "node" : "l_foot_JNT",\r
+ "property" : "orientation",\r
+ "keyFramesBin" : {\r
+ "url" : "exercise/squat-to-lunge-animation.ani",\r
+ "byteOffset" : 24600,\r
+ "numKeys" : 24\r
+ },\r
+ "alphaFunction" : "DEFAULT",\r
+ "timePeriod" : {\r
+ "delay" : 0.0,\r
+ "duration" : 1.0\r
+ },\r
+ "relative" : false\r
+ } ],\r
+ "finishedActions" : [ 14 ]\r
+ } ],\r
+ "animationGroups" : [ {\r
+ "name" : "Idle",\r
+ "animations" : [ "idleClip" ]\r
+ }, {\r
+ "name" : "Squat",\r
+ "animations" : [ "squatClip_0", "squatClip_1" ]\r
+ }, {\r
+ "name" : "JumpingJack",\r
+ "animations" : [ "jumpingJackClip" ]\r
+ }, {\r
+ "name" : "Lunge",\r
+ "animations" : [ "lungeClip" ]\r
+ }, {\r
+ "name" : "IdleToSquat",\r
+ "animations" : [ "idleToSquatClip_0", "idleToSquatClip_1" ]\r
+ }, {\r
+ "name" : "SquatToIdle",\r
+ "animations" : [ "squatToIdleClip" ]\r
+ }, {\r
+ "name" : "IdleToJumpingJack",\r
+ "animations" : [ "idleToJumpingJackClip" ]\r
+ }, {\r
+ "name" : "JumpingJackToIdle",\r
+ "animations" : [ "jumpingJackToIdleClip" ]\r
+ }, {\r
+ "name" : "IdleToLunge",\r
+ "animations" : [ "idleToLungeClip" ]\r
+ }, {\r
+ "name" : "LungeToIdle",\r
+ "animations" : [ "lungeToIdleClip" ]\r
+ }, {\r
+ "name" : "JumpingJackToLunge",\r
+ "animations" : [ "jumpingJackToLungeClip" ]\r
+ }, {\r
+ "name" : "JumpingJackToSquat",\r
+ "animations" : [ "jumpingJackToSquatClip" ]\r
+ }, {\r
+ "name" : "LungeToJumpingJack",\r
+ "animations" : [ "lungeToJumpingJackClip" ]\r
+ }, {\r
+ "name" : "LungeToSquat",\r
+ "animations" : [ "lungeToSquatClip" ]\r
+ }, {\r
+ "name" : "SquatToJumpingJack",\r
+ "animations" : [ "squatToJumpingJackClip" ]\r
+ }, {\r
+ "name" : "SquatToLunge",\r
+ "animations" : [ "squatToLungeClip" ]\r
+ } ],\r
+ "skeletons" : [ {\r
+ "node" : "hips_JNT"\r
+ } ]\r
+}\r
--- /dev/null
+{
+ "error": yes
+}
--- /dev/null
+{
+ "metadata" : [ {
+ "key" : "clock-type",
+ "value" : "com.samsung.watchface-01"
+ }, {
+ "key" : "tickpersecond",
+ "value" : "1"
+ }, {
+ "key" : "preview_time",
+ "value" : "10:08:32"
+ }, {
+ "key" : "tilt-mode",
+ "value" : "light"
+ } ],
+ "asset" : {
+ "version" : "1.0"
+ },
+ "scene" : 0,
+ "scenes" : [ {
+ "nodes" : [ 0 ]
+ } ],
+ "nodes" : [ {
+ "name" : "HeadTest_002",
+ "matrix" : [ 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "children" : [ 1, 2 ],
+ "visible" : true,
+ "lightingMode" : "unlit"
+ }, {
+ "name" : "head",
+ "matrix" : [ 0.819152044288992, 0.0, 0.5735764363510462, 0.0, 0.0, 1.0, 0.0, 0.0, -0.5735764363510462, 0.0, 0.819152044288992, 0.0, 0.0, -143.995, -1.1208, 1.0 ],
+ "behavior" : [ 0 ],
+ "visible" : true,
+ "lightingMode" : "lit-solid",
+ "model" : {
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],
+ "material" : 0,
+ "mesh" : 0,
+ "shader" : 3
+ }
+ }, {
+ "name" : "Cube",
+ "matrix" : [ 25.98076211353316, 0.0, -15.0, 0.0, 0.0, 30.0, 0.0, 0.0, 15.0, 0.0, 25.98076211353316, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "visible" : true,
+ "lightingMode" : "lit",
+ "model" : {
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],
+ "material" : 0,
+ "mesh" : 1,
+ "shader" : 4
+ }
+ } ],
+ "meshes" : [ {
+ "uri" : "morph/HeadTest_002.dae.bin",
+ "attributes" : 31,
+ "primitive" : "TRIANGLES",
+ "indices" : {
+ "byteOffset" : 0,
+ "byteLength" : 34524
+ },
+ "positions" : {
+ "byteOffset" : 34524,
+ "byteLength" : 37812
+ },
+ "normals" : {
+ "byteOffset" : 72336,
+ "byteLength" : 37812
+ },
+ "textures" : {
+ "byteOffset" : 110148,
+ "byteLength" : 25208
+ },
+ "tangents" : {
+ "byteOffset" : 135356,
+ "byteLength" : 37812
+ },
+ "blendShapeHeader" : {
+ "version" : "1.0",
+ "byteOffset" : 173168,
+ "byteLength" : 4
+ },
+ "blendShapes" : [ {
+ "name" : "Shape_01MeshMesh",
+ "weight" : 0.0,
+ "positions" : {
+ "byteOffset" : 173172,
+ "byteLength" : 37812
+ },
+ "normals" : {
+ "byteOffset" : 210984,
+ "byteLength" : 37812
+ }
+ }, {
+ "name" : "Shape_02MeshMesh",
+ "weight" : 0.0,
+ "positions" : {
+ "byteOffset" : 248796,
+ "byteLength" : 37812
+ },
+ "normals" : {
+ "byteOffset" : 286608,
+ "byteLength" : 37812
+ }
+ }, {
+ "name" : "Shape_03MeshMesh",
+ "weight" : 0.0,
+ "positions" : {
+ "byteOffset" : 324420,
+ "byteLength" : 37812
+ },
+ "normals" : {
+ "byteOffset" : 362232,
+ "byteLength" : 37812
+ }
+ } ]
+ }, {
+ "uri" : "morph/cube.gltf.bin",
+ "attributes" : 31,
+ "primitive" : "TRIANGLES",
+ "indices" : {
+ "byteOffset" : 0,
+ "byteLength" : 72
+ },
+ "positions" : {
+ "byteOffset" : 72,
+ "byteLength" : 288
+ },
+ "normals" : {
+ "byteOffset" : 360,
+ "byteLength" : 288
+ },
+ "textures" : {
+ "byteOffset" : 648,
+ "byteLength" : 192
+ },
+ "tangents" : {
+ "byteOffset" : 840,
+ "byteLength" : 288
+ }
+ } ],
+ "cameras" : [ {
+ "near" : 0.1,
+ "far" : 10000.0,
+ "matrix" : [ 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.0, 0.01, 0.0, 0.0, 0.0, 0.767773, 1.0 ],
+ "fov" : 54.4321
+ } ],
+ "lights" : [ {
+ "matrix" : [ 0.4999999403953552, 0.0, 0.8660255074501038, 0.0, 0.0, 1.0, 0.0, 0.0, -0.8660255074501038, 0.0, 0.4999999403953552, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "color" : [ 1.0, 1.0, 1.0 ],
+ "intensity" : 1.0,
+ "shadowMapSize" : 1024,
+ "orthographicSize" : 1.0,
+ "shadowIntensity" : 1.0
+ } ],
+ "materials" : [ {
+ "name" : "No name",
+ "color" : [ 1.0, 1.0, 1.0, 1.0 ],
+ "mipmap" : true,
+ "roughness" : 1.0,
+ "metallic" : 1.0,
+ "environment" : 1
+ } ],
+ "environment" : [ {
+ "cubeInitialOrientation" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "iblIntensity" : 1.0
+ }, {
+ "cubeSpecular" : "Studio/Radiance.ktx",
+ "cubeDiffuse" : "Studio/Irradiance.ktx",
+ "cubeInitialOrientation" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "iblIntensity" : 1.0
+ } ],
+ "shaders" : [ {
+ "vertex" : "dli_pbr.vsh",
+ "fragment" : "dli_pbr.fsh",
+ "defines" : [ "LIT" ],
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",
+ "uCubeMatrix" : [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],
+ "uMaxLOD" : 6
+ }, {
+ "vertex" : "dli_pbr.vsh",
+ "fragment" : "dli_pbr.fsh",
+ "defines" : [ "THREE_TEX" ],
+ "rendererState" : "DEPTH_TEST|ALPHA_BLEND",
+ "uCubeMatrix" : [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],
+ "uMaxLOD" : 6
+ }, {
+ "vertex" : "dli_pbr.vsh",
+ "fragment" : "dli_pbr.fsh",
+ "defines" : [ "MORPH", "MORPH_POSITION", "MORPH_NORMAL" ],
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",
+ "uCubeMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "uMaxLOD" : 6
+ }, {
+ "vertex" : "dli_pbr.vsh",
+ "fragment" : "dli_pbr.fsh",
+ "hints" : [ "MODIFIES_GEOMETRY" ],
+ "defines" : [ "MORPH", "MORPH_POSITION", "MORPH_NORMAL" ],
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_BACK|DEPTH_FUNC:LESS_EQUAL",
+ "uCubeMatrix" : [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ],
+ "uMaxLOD" : 6
+ }, {
+ "vertex" : "dli_pbr.vsh",
+ "fragment" : "dli_pbr.fsh",
+ "defines" : [ "LIT", "SHADOW" ],
+ "rendererState" : "DEPTH_TEST|DEPTH_WRITE|CULL_FRONT",
+ "uCubeMatrix" : [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ],
+ "uMaxLOD" : 6
+ } ],
+ "behaviors" : [ {
+ "url" : "head-behavior_1.lua",
+ "event" : "scene.loaded"
+ } ],
+ "animations" : [ {
+ "name" : "Morph",
+ "loopCount" : 0,
+ "duration" : 1.0,
+ "endAction" : "DISCARD",
+ "disconnectAction" : "BAKE",
+ "properties" : [ {
+ "node" : "head",
+ "property" : "uBlendShapeWeight[0]",
+ "value" : 1.0,
+ "alphaFunction" : "DEFAULT",
+ "timePeriod" : {
+ "delay" : 0.0,
+ "duration" : 0.5
+ },
+ "relative" : false
+ }, {
+ "node" : "head",
+ "property" : "uBlendShapeWeight[1]",
+ "value" : 1.0,
+ "alphaFunction" : "DEFAULT",
+ "timePeriod" : {
+ "delay" : 0.0,
+ "duration" : 0.5
+ },
+ "relative" : false
+ }, {
+ "node" : "head",
+ "property" : "uBlendShapeWeight[2]",
+ "value" : 1.0,
+ "alphaFunction" : "DEFAULT",
+ "timePeriod" : {
+ "delay" : 0.0,
+ "duration" : 0.5
+ },
+ "relative" : false
+ }, {
+ "node" : "head",
+ "property" : "uBlendShapeWeight[0]",
+ "value" : 0.0,
+ "alphaFunction" : "DEFAULT",
+ "timePeriod" : {
+ "delay" : 0.5,
+ "duration" : 0.5
+ },
+ "relative" : false
+ }, {
+ "node" : "head",
+ "property" : "uBlendShapeWeight[1]",
+ "value" : 0.0,
+ "alphaFunction" : "DEFAULT",
+ "timePeriod" : {
+ "delay" : 0.5,
+ "duration" : 0.5
+ },
+ "relative" : false
+ }, {
+ "node" : "head",
+ "property" : "uBlendShapeWeight[2]",
+ "value" : 0.0,
+ "alphaFunction" : "DEFAULT",
+ "timePeriod" : {
+ "delay" : 0.5,
+ "duration" : 0.5
+ },
+ "relative" : false
+ } ]
+ } ]
+}
--- /dev/null
+SET(PKG_NAME "dali-scene-loader-internal")
+
+SET(EXEC_NAME "tct-${PKG_NAME}-core")
+SET(RPM_NAME "core-${PKG_NAME}-tests")
+
+SET(CAPI_LIB "dali-scene-loader")
+
+# List of test case sources (Only these get parsed for test cases)
+SET(TC_SOURCES
+ utc-Dali-Gltf2Asset.cpp
+ utc-Dali-Hash.cpp
+ utc-Dali-JsonReader.cpp
+ utc-Dali-JsonUtil.cpp
+)
+
+# List of test harness files (Won't get parsed for test cases)
+SET(TEST_HARNESS_DIR "../dali-toolkit/dali-toolkit-test-utils")
+
+SET(TEST_HARNESS_SOURCES
+ ${TEST_HARNESS_DIR}/toolkit-adaptor.cpp
+ ${TEST_HARNESS_DIR}/toolkit-application.cpp
+ ${TEST_HARNESS_DIR}/toolkit-event-thread-callback.cpp
+ ${TEST_HARNESS_DIR}/toolkit-environment-variable.cpp
+ ${TEST_HARNESS_DIR}/toolkit-input-method-context.cpp
+ ${TEST_HARNESS_DIR}/toolkit-input-method-options.cpp
+ ${TEST_HARNESS_DIR}/toolkit-lifecycle-controller.cpp
+ ${TEST_HARNESS_DIR}/toolkit-orientation.cpp
+ ${TEST_HARNESS_DIR}/toolkit-style-monitor.cpp
+ ${TEST_HARNESS_DIR}/toolkit-test-application.cpp
+ ${TEST_HARNESS_DIR}/toolkit-timer.cpp
+ ${TEST_HARNESS_DIR}/toolkit-trigger-event-factory.cpp
+ ${TEST_HARNESS_DIR}/toolkit-window.cpp
+ ${TEST_HARNESS_DIR}/toolkit-scene-holder.cpp
+ ${TEST_HARNESS_DIR}/dali-test-suite-utils.cpp
+ ${TEST_HARNESS_DIR}/dali-toolkit-test-suite-utils.cpp
+ ${TEST_HARNESS_DIR}/dummy-control.cpp
+ ${TEST_HARNESS_DIR}/mesh-builder.cpp
+ ${TEST_HARNESS_DIR}/test-actor-utils.cpp
+ ${TEST_HARNESS_DIR}/test-animation-data.cpp
+ ${TEST_HARNESS_DIR}/test-application.cpp
+ ${TEST_HARNESS_DIR}/test-button.cpp
+ ${TEST_HARNESS_DIR}/test-harness.cpp
+ ${TEST_HARNESS_DIR}/test-gesture-generator.cpp
+ ${TEST_HARNESS_DIR}/test-gl-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-gl-sync-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-platform-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-render-controller.cpp
+ ${TEST_HARNESS_DIR}/test-trace-call-stack.cpp
+)
+
+PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
+ dali2-core
+ dali2-adaptor
+ dali2-toolkit
+ dali2-scene-loader
+)
+
+ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror -DDEBUG_ENABLED)
+ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
+
+ADD_DEFINITIONS(-DTEST_RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../resources\" )
+
+FOREACH(directory ${${CAPI_LIB}_LIBRARY_DIRS})
+ SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -L${directory}")
+ENDFOREACH(directory ${CAPI_LIB_LIBRARY_DIRS})
+
+INCLUDE_DIRECTORIES(
+ ../../../
+ ${${CAPI_LIB}_INCLUDE_DIRS}
+ ../dali-toolkit/dali-toolkit-test-utils
+)
+
+ADD_CUSTOM_COMMAND(
+ COMMAND ${SCRIPT_DIR}/tcheadgen.sh ${EXEC_NAME}.h ${TC_SOURCES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT ${EXEC_NAME}.h
+ COMMENT "Generating test tables"
+ )
+
+ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.h ${EXEC_NAME}.cpp ${TC_SOURCES} ${TEST_HARNESS_SOURCES})
+TARGET_LINK_LIBRARIES(${EXEC_NAME}
+ ${${CAPI_LIB}_LIBRARIES}
+ -lpthread --coverage
+)
+
+INSTALL(PROGRAMS ${EXEC_NAME}
+ DESTINATION ${BIN_DIR}/${EXEC_NAME}
+)
--- /dev/null
+#include <string.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <test-harness.h>
+#include "tct-dali-scene-loader-internal-core.h"
+
+int main(int argc, char * const argv[])
+{
+ int result = TestHarness::EXIT_STATUS_BAD_ARGUMENT;
+
+ const char* optString = "sf";
+ bool optRerunFailed(true);
+ bool optRunSerially(false);
+
+ int nextOpt = 0;
+ do
+ {
+ nextOpt = getopt( argc, argv, optString );
+ switch(nextOpt)
+ {
+ case 'f':
+ optRerunFailed = false;
+ break;
+ case 's':
+ optRunSerially = true;
+ break;
+ case '?':
+ TestHarness::Usage(argv[0]);
+ exit(TestHarness::EXIT_STATUS_BAD_ARGUMENT);
+ break;
+ }
+ } while( nextOpt != -1 );
+
+ if( optind == argc ) // no testcase name in argument list
+ {
+ if( optRunSerially )
+ {
+ result = TestHarness::RunAll( argv[0], tc_array );
+ }
+ else
+ {
+ result = TestHarness::RunAllInParallel( argv[0], tc_array, optRerunFailed );
+ }
+ }
+ else
+ {
+ // optind is index of next argument - interpret as testcase name
+ result = TestHarness::FindAndRunTestCase(tc_array, argv[optind]);
+ }
+ return result;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/internal/gltf2-asset.h"
+#include <dali-test-suite-utils.h>
+#include <string>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliGltf2AssetComponentIsUnsigned(void)
+{
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::BYTE), false);
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::UNSIGNED_BYTE), true);
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::SHORT), false);
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::UNSIGNED_SHORT), true);
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::UNSIGNED_INT), true);
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::FLOAT), false);
+ DALI_TEST_EQUAL(gltf2::Component::IsUnsigned(gltf2::Component::INVALID), false);
+
+ END_TEST;
+}
+
+int UtcDaliGltf2AssetComponentSize(void)
+{
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::BYTE), 1u);
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::UNSIGNED_BYTE), 1u);
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::SHORT), 2u);
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::UNSIGNED_SHORT), 2u);
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::UNSIGNED_INT), 4u);
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::FLOAT), 4u);
+ DALI_TEST_EQUAL(gltf2::Component::Size(gltf2::Component::INVALID), -1);
+
+ END_TEST;
+}
+
+#define FROM_STRING_HELPER(x) FromString(#x, strlen(#x))
+
+#define STRING_CHECK(type, x) DALI_TEST_EQUAL(gltf2::type:: FROM_STRING_HELPER(x), gltf2::type::x)
+
+int UtcDaliGltf2AssetAccessorType(void)
+{
+ STRING_CHECK(AccessorType, SCALAR);
+ STRING_CHECK(AccessorType, VEC2);
+ STRING_CHECK(AccessorType, VEC3);
+ STRING_CHECK(AccessorType, VEC4);
+ STRING_CHECK(AccessorType, MAT2);
+ STRING_CHECK(AccessorType, MAT3);
+ STRING_CHECK(AccessorType, MAT4);
+ DALI_TEST_EQUAL(gltf2::AccessorType::FROM_STRING_HELPER(VEC88), gltf2::AccessorType::INVALID);
+
+ END_TEST;
+}
+
+int UtcDaliGltf2AssetAlphaMode(void)
+{
+ STRING_CHECK(AlphaMode, OPAQUE);
+ STRING_CHECK(AlphaMode, MASK);
+ STRING_CHECK(AlphaMode, BLEND);
+ DALI_TEST_EQUAL(gltf2::AlphaMode::FROM_STRING_HELPER(ALPHA_SCHMALPHA), gltf2::AlphaMode::INVALID);
+
+ END_TEST;
+}
+
+int UtcDaliGltf2AssetAttribute(void)
+{
+ STRING_CHECK(Attribute, POSITION);
+ STRING_CHECK(Attribute, NORMAL);
+ STRING_CHECK(Attribute, TANGENT);
+ STRING_CHECK(Attribute, TEXCOORD_0);
+ STRING_CHECK(Attribute, TEXCOORD_1);
+ STRING_CHECK(Attribute, COLOR_0);
+ STRING_CHECK(Attribute, JOINTS_0);
+ STRING_CHECK(Attribute, WEIGHTS_0);
+ DALI_TEST_EQUAL(gltf2::Attribute::FROM_STRING_HELPER(VISCOSITY), gltf2::Attribute::INVALID);
+
+ END_TEST;
+}
+
+int UtcDaliGltf2AssetAnimationSamplerInterpolation(void)
+{
+ STRING_CHECK(Animation::Sampler::Interpolation, STEP);
+ STRING_CHECK(Animation::Sampler::Interpolation, LINEAR);
+ STRING_CHECK(Animation::Sampler::Interpolation, CUBICSPLINE);
+ DALI_TEST_EQUAL(gltf2::Animation::Sampler::Interpolation::FROM_STRING_HELPER(EASE_IN_OUT), gltf2::Animation::Sampler::Interpolation::INVALID);
+
+ END_TEST;
+}
+
+int UtcDaliGltf2AssetAnimationChannelTarget(void)
+{
+ STRING_CHECK(Animation::Channel::Target, TRANSLATION);
+ STRING_CHECK(Animation::Channel::Target, ROTATION);
+ STRING_CHECK(Animation::Channel::Target, SCALE);
+ STRING_CHECK(Animation::Channel::Target, WEIGHTS);
+ DALI_TEST_EQUAL(gltf2::Animation::Channel::Target::FROM_STRING_HELPER(FLUFFINESS), gltf2::Animation::Channel::Target::INVALID);
+
+ END_TEST;
+}
+
+int UtcDaliGltf2AssetAccessorSparse(void)
+{
+ gltf2::Accessor acc;
+ DALI_TEST_CHECK(!acc.mSparse);
+
+ std::vector<gltf2::BufferView> bufferViews;
+
+ gltf2::Accessor::Sparse sparse{ 256u };
+ sparse.mIndices.mBufferView = gltf2::Ref<gltf2::BufferView>(bufferViews, 5u);
+ sparse.mIndices.mComponentType = gltf2::Component::FLOAT;
+ sparse.mValues.mBufferView = gltf2::Ref<gltf2::BufferView>(bufferViews, 284u);
+ sparse.mValues.mByteOffset = 16532;
+ acc.SetSparse(sparse);
+
+ DALI_TEST_EQUAL(acc.mSparse->mCount, sparse.mCount);
+ DALI_TEST_EQUAL(acc.mSparse->mIndices.mBufferView, sparse.mIndices.mBufferView);
+ DALI_TEST_EQUAL(acc.mSparse->mIndices.mByteOffset, sparse.mIndices.mByteOffset);
+ DALI_TEST_EQUAL(acc.mSparse->mIndices.mComponentType, sparse.mIndices.mComponentType);
+ DALI_TEST_EQUAL(acc.mSparse->mValues.mBufferView, sparse.mValues.mBufferView);
+ DALI_TEST_EQUAL(acc.mSparse->mValues.mByteOffset, sparse.mValues.mByteOffset);
+
+ END_TEST;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/internal/hash.h"
+#include <dali-test-suite-utils.h>
+#include <string>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliHash(void)
+{
+ DALI_TEST_EQUAL(Hash(0).Add(true), 0);
+ DALI_TEST_EQUAL(Hash(0).Add(false), 1);
+
+ int32_t myInt32 = std::numeric_limits<int32_t>::min();
+ DALI_TEST_EQUAL(Hash(0).Add(myInt32), myInt32);
+
+ uint32_t myUint32 = std::numeric_limits<uint32_t>::max();
+ DALI_TEST_EQUAL(Hash(0).Add(myUint32), myUint32);
+
+ uint64_t myUint64 = std::numeric_limits<uint64_t>::max();
+ DALI_TEST_EQUAL(uint64_t(Hash(0).Add(myUint64)), myUint64);
+
+ constexpr uint32_t multiplier = 31;
+ uint64_t expected = 0;
+ float f = 1928.46852;
+ for (auto i0 = reinterpret_cast<uint8_t const*>(&f), i1 = i0 + sizeof(f); i0 != i1; ++i0)
+ {
+ expected = expected * multiplier + *i0;
+ }
+
+ DALI_TEST_EQUAL(uint64_t(Hash(0).Add(f)), expected);
+
+ END_TEST;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/internal/json-reader.h"
+#include <dali-test-suite-utils.h>
+#include <string>
+
+using namespace Dali;
+
+#define JSON_STRING(x) #x, strlen(#x)
+
+int UtcDaliJsonReaderStrCmp(void)
+{
+ json_string_s jstr[] {
+ { JSON_STRING(hello) },
+ { JSON_STRING(hellew) },
+ };
+ DALI_TEST_EQUAL(json::StrCmp(jstr[0], "hello"), 0);
+ DALI_TEST_EQUAL(json::StrCmp(jstr[1], "hello"), 'e' - 'o');
+
+ END_TEST;
+}
+
+int UtcDaliJsonReaderValidateThrow(void)
+{
+ json_value_s jval { nullptr, json_type_array };
+ DALI_TEST_THROWS(json::Validate(jval, json_type_object), std::runtime_error);
+ json::Validate(jval, json_type_array);
+
+ END_TEST;
+}
+
+int UtcDaliJsonReaderFindObjectChild(void)
+{
+ json_string_s jkey{ JSON_STRING(fudgeFactor) };
+ json_number_s jActualValue{ JSON_STRING(5.2) };
+ json_value_s jvalue { &jActualValue, json_type_number };
+ json_object_element_s jobjelem { &jkey, &jvalue, nullptr };
+
+ json_object_s jobj{ &jobjelem, 1 };
+
+ DALI_TEST_EQUAL(json::FindObjectChild(jkey.string, jobj), &jvalue);
+ DALI_TEST_EQUAL(json::FindObjectChild("fudgeFactory", jobj), static_cast<json_value_s*>(nullptr));
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/internal/json-util.h"
+#include "dali-toolkit/devel-api/builder/json-parser.h"
+#include <dali-test-suite-utils.h>
+#include <string>
+
+#define STRINGIFY(x) #x
+
+using namespace Dali;
+using namespace Dali::Toolkit;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+const std::string TEST_JSON =
+ "{ \"int\": 17834,"
+ "\"float\": 3.1415628,"
+ "\"bool\": true,"
+ "\"null\": null,"
+ "\"string\": \"hello\","
+ "\"floatArray\": [ 0.0, 0.25, 1.0, 0.75 ],"
+ "\"intArray\": [ 1, 2, 3, 5, 7, 11, 13, -1, -5 ],"
+ "\"mixedArray\": [ 1.99, \"the\", 6, \"brown\", \"fox\" ],"
+ "\"stringArray\": [ \"lorem\", \"ipsum\", \"dolor\", \"sic\", \"amet\" ],"
+ "\"object\": { \"duration\": 4.0, \"delay\": 1.0 },"
+ "\"rgb\": [ 0.5, 0.8, 0.25 ],"
+ "\"disambiguatedFloat\": { \"type\": \"float\", \"value\": 15.8 },"
+ "\"rotation1\": { \"type\": \"rotation\", \"value\": [ 15.0, 90.0, -45.0 ] },"
+ "\"rotation2\": { \"type\": \"rotation\", \"value\": [ 0.707, 0.0, 0.707, 0.0 ] },"
+ "\"matrix\": [ 1.0, 0.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 1.0, 2.0, 3.0, 4.0 ],"
+ "\"matrix3\": [ 2.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0, 1.0, 2.0 ],"
+ "\"vector2\": [ 2.0, 1.0 ]"
+ "}";
+
+template <typename T>
+struct Item
+{
+ std::string name;
+ bool readResult;
+ T result;
+};
+
+struct Document
+{
+ Document(const std::string& json)
+ : parser(JsonParser::New())
+ {
+ //DALI_TEST_CHECK(parser.Parse(json));
+ if (!parser.Parse(json))
+ {
+ auto error = parser.GetErrorDescription();
+ printf("Error: %s in {%d, %d}\n", error.c_str(), parser.GetErrorLineNumber(), parser.GetErrorColumn());
+ }
+ root = parser.GetRoot();
+ }
+
+ JsonParser parser;
+ const TreeNode* root;
+};
+
+template <typename T, size_t N>
+bool CompareArrays(const T (&array)[N], const T* p, T epsilon = T(0))
+{
+ for (auto& i: array)
+ {
+ if (std::abs(i - *p) > epsilon)
+ {
+ printf("Element %d mismatched.\n", int32_t(std::distance(array, &i)));
+ return false;
+ }
+ ++p;
+ }
+ return true;
+}
+
+}
+
+int UtcDaliJsonUtilReadBool(void)
+{
+ bool value = false;
+ DALI_TEST_CHECK(!ReadBool(nullptr, value));
+ DALI_TEST_EQUAL(value, false); // unchanged
+
+ Document doc{ TEST_JSON };
+
+ for (auto& i : {
+ Item<bool>{ "bool", true, true },
+ Item<bool>{ "int", false, true }, // value unchanged
+ Item<bool>{ "float", false, true },
+ Item<bool>{ "null", false, true },
+ Item<bool>{ "floatArray", false, true },
+ Item<bool>{ "intArray", false, true },
+ Item<bool>{ "object", false, true },
+ })
+ {
+ bool readResult = ReadBool(doc.root->GetChild(i.name), value);
+ DALI_TEST_EQUAL(readResult, i.readResult);
+ if (readResult)
+ {
+ DALI_TEST_EQUAL(value, i.result);
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadInt(void)
+{
+ int value = 0xbadbeef;
+ DALI_TEST_CHECK(!ReadInt(nullptr, value));
+ DALI_TEST_EQUAL(value, 0xbadbeef);
+
+ Document doc{ TEST_JSON };
+
+ for (auto& i : {
+ Item<int>{ "bool", false, 0xbadbeef }, // unchanged from initial
+ Item<int>{ "int", true, 17834 },
+ Item<int>{ "float", true, 3 },
+ Item<int>{ "null", false, 3 },
+ Item<int>{ "floatArray", false, 3 },
+ Item<int>{ "intArray", false, 3 },
+ Item<int>{ "object", false, 3 },
+ })
+ {
+ bool readResult = ReadInt(doc.root->GetChild(i.name), value);
+ DALI_TEST_EQUAL(readResult, i.readResult);
+ if (readResult)
+ {
+ DALI_TEST_EQUAL(value, i.result);
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadFloat(void)
+{
+ float value = 10.101f;
+ DALI_TEST_CHECK(!ReadFloat(nullptr, value));
+ DALI_TEST_EQUAL(value, 10.101f);
+
+ Document doc{ TEST_JSON };
+
+ for (auto& i : {
+ Item<float>{ "bool", false, 10.101f }, // unchanged from initial
+ Item<float>{ "int", true, 17834.f },
+ Item<float>{ "float", true, 3.1415628f },
+ Item<float>{ "null", false, 3.1415628f },
+ Item<float>{ "floatArray", false, 3.1415628f },
+ Item<float>{ "intArray", false, 3.1415628f },
+ Item<float>{ "object", false, 3.1415628f },
+ })
+ {
+ bool readResult = ReadFloat(doc.root->GetChild(i.name), value);
+ DALI_TEST_EQUAL(readResult, i.readResult);
+ if (readResult)
+ {
+ DALI_TEST_EQUAL(value, i.result);
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilNumericalArrays(void)
+{
+ Document doc{ TEST_JSON };
+
+ DALI_TEST_EQUAL(4u, GetNumericalArraySize(doc.root->GetChild("floatArray")));
+ DALI_TEST_EQUAL(9u, GetNumericalArraySize(doc.root->GetChild("intArray")));
+ DALI_TEST_EQUAL(1u, GetNumericalArraySize(doc.root->GetChild("mixedArray")));
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadVectorInt(void)
+{
+ DALI_TEST_CHECK(!ReadVector(nullptr, static_cast<int*>(nullptr), 0));
+
+ Document doc{ TEST_JSON };
+
+ int ints[9];
+ DALI_TEST_CHECK(ReadVector(doc.root->GetChild("floatArray"), ints, 4u));
+ DALI_TEST_CHECK(CompareArrays<int>({ 0, 0, 1, 0 }, ints));
+
+ DALI_TEST_CHECK(ReadVector(doc.root->GetChild("intArray"), ints, 9u));
+ DALI_TEST_CHECK(CompareArrays<int>({ 1, 2, 3, 5, 7, 11, 13, -1, -5 }, ints));
+
+ DALI_TEST_CHECK(ReadVector(doc.root->GetChild("mixedArray"), ints, 1u));
+ DALI_TEST_CHECK(CompareArrays<int>({ 1 }, ints));
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadVectorFloat(void)
+{
+ DALI_TEST_CHECK(!ReadVector(nullptr, static_cast<int*>(nullptr), 0));
+
+ Document doc{ TEST_JSON };
+
+ constexpr float e = 1e-6f;
+ float floats[9];
+ DALI_TEST_CHECK(ReadVector(doc.root->GetChild("floatArray"), floats, 4u));
+ DALI_TEST_CHECK(CompareArrays<float>({ 0.f, 0.25f, 1.f, 0.75f }, floats, e));
+
+ DALI_TEST_CHECK(ReadVector(doc.root->GetChild("intArray"), floats, 9u));
+ DALI_TEST_CHECK(CompareArrays<float>({ 1.f, 2.f, 3.f, 5.f, 7.f, 11.f, 13.f, -1.f, -5.f }, floats, e));
+
+ DALI_TEST_CHECK(ReadVector(doc.root->GetChild("mixedArray"), floats, 1u));
+ DALI_TEST_CHECK(CompareArrays<float>({ 1.99f }, floats, e));
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadColor(void)
+{
+ Vector4 color;
+ DALI_TEST_CHECK(!ReadColor(nullptr, color));
+
+ Document doc{ TEST_JSON };
+ DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("bool"), color));
+ DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("int"), color));
+ DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("float"), color));
+ DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("string"), color));
+ DALI_TEST_CHECK(!ReadColor(doc.root->GetChild("object"), color));
+
+ constexpr float e = 1e-6f;
+ DALI_TEST_CHECK(ReadColor(doc.root->GetChild("floatArray"), color));
+ DALI_TEST_CHECK(CompareArrays<float>({ 0.f, 0.25f, 1.0f, 0.75f }, color.AsFloat(), e));
+
+ DALI_TEST_CHECK(ReadColor(doc.root->GetChild("intArray"), color));
+ DALI_TEST_CHECK(CompareArrays<float>({ 1.f, 2.f, 3.f, 5.f }, color.AsFloat(), e));
+
+ DALI_TEST_CHECK(ReadColor(doc.root->GetChild("rgb"), color));
+ DALI_TEST_CHECK(CompareArrays<float>({ .5f, .8f, .25f, 1.f }, color.AsFloat(), e));
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadTimePeriod(void)
+{
+ TimePeriod value(60.f);
+ DALI_TEST_CHECK(!ReadTimePeriod(nullptr, value));
+ DALI_TEST_EQUAL(value.durationSeconds, 60.f);
+ DALI_TEST_EQUAL(value.delaySeconds, 0.f);
+
+ Document doc{ TEST_JSON };
+ DALI_TEST_CHECK(ReadTimePeriod(doc.root->GetChild("object"), value));
+ DALI_TEST_EQUAL(value.durationSeconds, 4.f);
+ DALI_TEST_EQUAL(value.delaySeconds, 1.f);
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadString(void)
+{
+ std::string value = "bye";
+ DALI_TEST_CHECK(!ReadString(nullptr, value));
+ DALI_TEST_EQUAL(value, "bye");
+
+ Document doc{ TEST_JSON };
+
+ for (auto& i : {
+ Item<std::string>{ "bool", false, "bye"}, // unchanged from initial
+ Item<std::string>{ "int", false, "bye"},
+ Item<std::string>{ "float", false, "bye"},
+ Item<std::string>{ "null", false, "bye"},
+ Item<std::string>{ "string", true, "hello"},
+ Item<std::string>{ "floatArray", false, "hello"}, // unchanged
+ Item<std::string>{ "object", false, "hello"},
+ })
+ {
+ bool readResult = ReadString(doc.root->GetChild(i.name), value);
+ DALI_TEST_EQUAL(readResult, i.readResult);
+ if (readResult)
+ {
+ DALI_TEST_EQUAL(value, i.result);
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadStringVector(void)
+{
+ std::vector<std::string> strings;
+ DALI_TEST_CHECK(!ReadStringVector(nullptr, strings));
+ DALI_TEST_CHECK(strings.empty());
+
+ Document doc{ TEST_JSON };
+
+ DALI_TEST_CHECK(!ReadStringVector(doc.root->GetChild("floatArray"), strings));
+ DALI_TEST_CHECK(strings.empty());
+
+ DALI_TEST_CHECK(!ReadStringVector(doc.root->GetChild("intArray"), strings));
+ DALI_TEST_CHECK(strings.empty());
+
+ DALI_TEST_CHECK(!ReadStringVector(doc.root->GetChild("mixedArray"), strings));
+ DALI_TEST_CHECK(strings.empty());
+
+ DALI_TEST_CHECK(ReadStringVector(doc.root->GetChild("stringArray"), strings));
+ DALI_TEST_EQUAL(strings.size(), 5u);
+
+ auto iStrings = strings.begin();
+ for (auto& i : { "lorem", "ipsum", "dolor", "sic", "amet" })
+ {
+ DALI_TEST_EQUAL(*iStrings, i);
+ ++iStrings;
+ }
+
+ END_TEST;
+}
+
+int UtcDaliJsonUtilReadAndReturnPropertyValue(void)
+{
+ Document doc{ TEST_JSON };
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("disambiguatedFloat")).Get<float>(), 15.8f);
+
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("rotation1")).Get<Quaternion>(),
+ Quaternion(Radian(Degree(15.0)), Radian(Degree(90.0)), Radian(Degree(-45.f))));
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("rotation2")).Get<Quaternion>(),
+ Quaternion(Vector4(0.707f, 0.f, 0.707f, 0.f)));
+
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("bool")).Get<bool>(), true);
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("int")).Get<int32_t>(), 17834);
+
+ const float floats[]{ 1.f, 0.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f, 0.f, 0.f, 3.f, 0.f, 1.f, 2.f, 3.f, 4.f };
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("matrix")).Get<Matrix>(), Matrix(floats));
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("matrix3")).Get<Matrix3>(), Matrix3(floats[5],
+ floats[6], floats[7], floats[8], floats[9], floats[10], floats[11], floats[12], floats[13]));
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("floatArray")).Get<Vector4>(),
+ Vector4(0.f, .25f, 1.f, .75f));
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("rgb")).Get<Vector3>(),
+ Vector3(.5f, .8f, .25f));
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("vector2")).Get<Vector2>(),
+ Vector2(2.f, 1.f));
+ DALI_TEST_EQUAL(ReadPropertyValue(*doc.root->GetChild("object")->GetChild("duration")).Get<float>(), 4.f );
+
+ END_TEST;
+}
+
+namespace
+{
+template <typename T>
+void CheckEqualityAs(Property::Value lhs, Property::Value rhs)
+{
+ DALI_TEST_EQUAL(lhs.Get<T>(), rhs.Get<T>());
+}
+
+}
+
+int UtcDaliJsonUtilReadPropertyValue(void)
+{
+ struct TypeNameValue
+ {
+ Property::Type type;
+ std::string name;
+ Property::Value value;
+ void(*compareFn)(Property::Value, Property::Value);
+ };
+
+ Document doc{ TEST_JSON };
+
+ const float floats[]{ 1.f, 0.f, 0.f, 0.f, 0.f, 2.f, 0.f, 0.f, 0.f, 0.f, 3.f, 0.f, 1.f, 2.f, 3.f, 4.f };
+ const TypeNameValue typeNameValues[] {
+ { Property::BOOLEAN, "bool", true, CheckEqualityAs<bool> },
+ { Property::FLOAT, "float", 3.1415628f, CheckEqualityAs<float> },
+ { Property::INTEGER, "int", 17834, CheckEqualityAs<int32_t> },
+ { Property::VECTOR2, "vector2", Vector2(2.f, 1.f), CheckEqualityAs<Vector2> },
+ { Property::VECTOR3, "rgb", Vector3(.5f, .8f, .25f), CheckEqualityAs<Vector3> },
+ { Property::VECTOR4, "floatArray", Vector4(.0f, .25f, 1.f, .75f), CheckEqualityAs<Vector4> },
+ { Property::MATRIX3, "matrix3", Matrix3(2.f, 0.f, 0.f, 0.f, 0.f, 3.f, 0.f, 1.f, 2.f),
+ CheckEqualityAs<Matrix3> },
+ { Property::MATRIX, "matrix", Matrix(floats), CheckEqualityAs<Matrix> },
+ { Property::RECTANGLE, "intArray", Rect<int>(1, 2, 3, 5), CheckEqualityAs<Rect<int>> },
+ { Property::EXTENTS, "intArray", Extents(1, 2, 3, 5), CheckEqualityAs<Extents> },
+ };
+ for(auto& i: typeNameValues)
+ {
+ std::cout << i.value << std::endl;
+ i.compareFn(ReadPropertyValue(i.type, *doc.root->GetChild(i.name)), i.value);
+ }
+
+ END_TEST;
+}
--- /dev/null
+SET(PKG_NAME "dali-scene-loader")
+
+SET(EXEC_NAME "tct-${PKG_NAME}-core")
+SET(RPM_NAME "core-${PKG_NAME}-tests")
+
+SET(CAPI_LIB "dali-scene-loader")
+
+# List of test case sources (Only these get parsed for test cases)
+SET(TC_SOURCES
+ utc-Dali-AlphaFunctionHelper.cpp
+ utc-Dali-AnimationDefinition.cpp
+ utc-Dali-AnimatedProperty.cpp
+ utc-Dali-CameraParameters.cpp
+ utc-Dali-DliLoader.cpp
+ utc-Dali-EnvironmentDefinition.cpp
+ utc-Dali-Gltf2Loader.cpp
+ utc-Dali-KtxLoader.cpp
+ utc-Dali-MatrixStack.cpp
+ utc-Dali-NodeDefinition.cpp
+ utc-Dali-RendererState.cpp
+ utc-Dali-ResourceBundle.cpp
+ utc-Dali-SceneDefinition.cpp
+ utc-Dali-ShaderDefinition.cpp
+ utc-Dali-ShaderDefinitionFactory.cpp
+ utc-Dali-StringCallback.cpp
+ utc-Dali-Utils.cpp
+ utc-Dali-ViewProjection.cpp
+)
+
+# List of test harness files (Won't get parsed for test cases)
+SET(TEST_HARNESS_DIR "../dali-toolkit/dali-toolkit-test-utils")
+
+SET(TEST_HARNESS_SOURCES
+ ${TEST_HARNESS_DIR}/toolkit-adaptor.cpp
+ ${TEST_HARNESS_DIR}/toolkit-application.cpp
+ ${TEST_HARNESS_DIR}/toolkit-event-thread-callback.cpp
+ ${TEST_HARNESS_DIR}/toolkit-environment-variable.cpp
+ ${TEST_HARNESS_DIR}/toolkit-input-method-context.cpp
+ ${TEST_HARNESS_DIR}/toolkit-input-method-options.cpp
+ ${TEST_HARNESS_DIR}/toolkit-lifecycle-controller.cpp
+ ${TEST_HARNESS_DIR}/toolkit-orientation.cpp
+ ${TEST_HARNESS_DIR}/toolkit-style-monitor.cpp
+ ${TEST_HARNESS_DIR}/toolkit-test-application.cpp
+ ${TEST_HARNESS_DIR}/toolkit-timer.cpp
+ ${TEST_HARNESS_DIR}/toolkit-trigger-event-factory.cpp
+ ${TEST_HARNESS_DIR}/toolkit-window.cpp
+ ${TEST_HARNESS_DIR}/toolkit-scene-holder.cpp
+ ${TEST_HARNESS_DIR}/dali-test-suite-utils.cpp
+ ${TEST_HARNESS_DIR}/dali-toolkit-test-suite-utils.cpp
+ ${TEST_HARNESS_DIR}/dummy-control.cpp
+ ${TEST_HARNESS_DIR}/mesh-builder.cpp
+ ${TEST_HARNESS_DIR}/test-actor-utils.cpp
+ ${TEST_HARNESS_DIR}/test-animation-data.cpp
+ ${TEST_HARNESS_DIR}/test-application.cpp
+ ${TEST_HARNESS_DIR}/test-button.cpp
+ ${TEST_HARNESS_DIR}/test-harness.cpp
+ ${TEST_HARNESS_DIR}/test-gesture-generator.cpp
+ ${TEST_HARNESS_DIR}/test-gl-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-gl-sync-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-platform-abstraction.cpp
+ ${TEST_HARNESS_DIR}/test-render-controller.cpp
+ ${TEST_HARNESS_DIR}/test-trace-call-stack.cpp
+)
+
+PKG_CHECK_MODULES(${CAPI_LIB} REQUIRED
+ dali2-core
+ dali2-adaptor
+ dali2-toolkit
+ dali2-scene-loader
+)
+
+ADD_COMPILE_OPTIONS( -O0 -ggdb --coverage -Wall -Werror -DDEBUG_ENABLED)
+ADD_COMPILE_OPTIONS( ${${CAPI_LIB}_CFLAGS_OTHER} )
+
+ADD_DEFINITIONS(-DTEST_RESOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}/../../resources\" )
+
+FOREACH(directory ${${CAPI_LIB}_LIBRARY_DIRS})
+ SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -L${directory}")
+ENDFOREACH(directory ${CAPI_LIB_LIBRARY_DIRS})
+
+INCLUDE_DIRECTORIES(
+ ../../../
+ ${${CAPI_LIB}_INCLUDE_DIRS}
+ ../dali-toolkit/dali-toolkit-test-utils
+)
+
+ADD_CUSTOM_COMMAND(
+ COMMAND ${SCRIPT_DIR}/tcheadgen.sh ${EXEC_NAME}.h ${TC_SOURCES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ OUTPUT ${EXEC_NAME}.h
+ COMMENT "Generating test tables"
+ )
+
+ADD_EXECUTABLE(${EXEC_NAME} ${EXEC_NAME}.h ${EXEC_NAME}.cpp ${TC_SOURCES} ${TEST_HARNESS_SOURCES})
+TARGET_LINK_LIBRARIES(${EXEC_NAME}
+ ${${CAPI_LIB}_LIBRARIES}
+ -lpthread --coverage
+)
+
+INSTALL(PROGRAMS ${EXEC_NAME}
+ DESTINATION ${BIN_DIR}/${EXEC_NAME}
+)
--- /dev/null
+#include <string.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <test-harness.h>
+#include "tct-dali-scene-loader-core.h"
+
+int main(int argc, char * const argv[])
+{
+ int result = TestHarness::EXIT_STATUS_BAD_ARGUMENT;
+
+ const char* optString = "sf";
+ bool optRerunFailed(true);
+ bool optRunSerially(false);
+
+ int nextOpt = 0;
+ do
+ {
+ nextOpt = getopt( argc, argv, optString );
+ switch(nextOpt)
+ {
+ case 'f':
+ optRerunFailed = false;
+ break;
+ case 's':
+ optRunSerially = true;
+ break;
+ case '?':
+ TestHarness::Usage(argv[0]);
+ exit(TestHarness::EXIT_STATUS_BAD_ARGUMENT);
+ break;
+ }
+ } while( nextOpt != -1 );
+
+ if( optind == argc ) // no testcase name in argument list
+ {
+ if( optRunSerially )
+ {
+ result = TestHarness::RunAll( argv[0], tc_array );
+ }
+ else
+ {
+ result = TestHarness::RunAllInParallel( argv[0], tc_array, optRerunFailed );
+ }
+ }
+ else
+ {
+ // optind is index of next argument - interpret as testcase name
+ result = TestHarness::FindAndRunTestCase(tc_array, argv[optind]);
+ }
+ return result;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/alpha-function-helper.h"
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+#define ALPHA_FN_PAIR(x) { #x, AlphaFunction::x }
+
+const std::pair<std::string, AlphaFunction::BuiltinFunction> BUILTIN_FUNCTIONS[] {
+ ALPHA_FN_PAIR(DEFAULT),
+ ALPHA_FN_PAIR(LINEAR),
+ ALPHA_FN_PAIR(REVERSE),
+ ALPHA_FN_PAIR(EASE_IN),
+ ALPHA_FN_PAIR(EASE_OUT),
+ ALPHA_FN_PAIR(EASE_IN_OUT),
+ ALPHA_FN_PAIR(EASE_IN_SQUARE),
+ ALPHA_FN_PAIR(EASE_OUT_SQUARE),
+ ALPHA_FN_PAIR(EASE_IN_SINE),
+ ALPHA_FN_PAIR(EASE_OUT_SINE),
+ ALPHA_FN_PAIR(EASE_IN_OUT_SINE),
+ ALPHA_FN_PAIR(BOUNCE),
+ ALPHA_FN_PAIR(SIN),
+ ALPHA_FN_PAIR(EASE_OUT_BACK),
+};
+
+int UtcDaliAlphaFunctionHelperGet(void)
+{
+ bool found;
+ for (auto& a: BUILTIN_FUNCTIONS)
+ {
+ auto result = GetAlphaFunction(a.first, &found);
+ DALI_TEST_EQUAL(result.GetBuiltinFunction(), a.second);
+ DALI_TEST_EQUAL(result.GetMode(), AlphaFunction::BUILTIN_FUNCTION);
+ DALI_TEST_CHECK(found);
+ }
+
+ auto result = GetAlphaFunction("made up function", &found);
+ DALI_TEST_EQUAL(result.GetBuiltinFunction(), AlphaFunction::DEFAULT);
+ DALI_TEST_EQUAL(result.GetMode(), AlphaFunction::BUILTIN_FUNCTION);
+ DALI_TEST_CHECK(!found);
+
+ END_TEST;
+}
+
+int UtcDaliAlphaFunctionHelperRegister(void)
+{
+ for (auto& a: BUILTIN_FUNCTIONS)
+ {
+ DALI_TEST_ASSERTION(RegisterAlphaFunction(a.first, AlphaFunction()), "given key already exists");
+ }
+
+ AlphaFunctionPrototype testFn = [](float f) {
+ return f > .5f ? 1.f : 0.f;
+ };
+ RegisterAlphaFunction("step", AlphaFunction(testFn));
+
+ bool found;
+ auto result = GetAlphaFunction("step", &found);
+ DALI_TEST_EQUAL(result.GetMode(), AlphaFunction::CUSTOM_FUNCTION);
+ DALI_TEST_EQUAL(result.GetCustomFunction(), testFn);
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/animated-property.h"
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliAnimatedPropertyGetPropertyType(void)
+{
+ TestApplication app;
+ auto actor = Actor::New();
+ actor.SetProperty(Actor::Property::NAME, "ChristopherPlummer");
+
+ AnimatedProperty animProp {
+ "ChristopherPlummer",
+ "position",
+ KeyFrames(),
+ std::unique_ptr<AnimatedProperty::Value>{ new AnimatedProperty::Value{
+ Property::Value{ Vector3::XAXIS * 100.f },
+ true
+ } },
+ };
+
+ Property expected(actor, Actor::Property::POSITION);
+ Property result = animProp.GetProperty(actor);
+ DALI_TEST_EQUAL(result.object, expected.object);
+ DALI_TEST_EQUAL(result.propertyIndex, expected.propertyIndex);
+ DALI_TEST_EQUAL(result.componentIndex, expected.componentIndex);
+ DALI_TEST_EQUAL(animProp.GetPropertyType(actor), Property::VECTOR3);
+
+ END_TEST;
+}
+
+
+
+
+
+
+
+
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/animation-definition.h"
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliAnimationDefinitionStopForModification(void)
+{
+ TestApplication app;
+ auto anim = Animation::New(15.f);
+ anim.Play();
+
+ auto oldEndAction = AnimationDefinition::StopForModification(anim);
+ DALI_TEST_EQUAL(anim.GetState(), Animation::STOPPED);
+ DALI_TEST_EQUAL(oldEndAction, Animation::BAKE);
+ DALI_TEST_EQUAL(anim.GetEndAction(), Animation::DISCARD);
+
+ END_TEST;
+}
+
+int UtcDaliAnimationDefinitionReAnimate(void)
+{
+ TestApplication app;
+ auto actor = Actor::New();
+ actor.SetProperty(Actor::Property::NAME, "ChristopherPlummer");
+
+ auto getActor = [&actor](const std::string& name) {
+ return actor.FindChildByName(name);
+ };
+
+ for (bool b: { false, true })
+ {
+ AnimationDefinition animDef;
+ animDef.mName = "WalkRight";
+ animDef.mDuration = 10.f;
+ animDef.mLoopCount = 2;
+ animDef.mEndAction = Animation::BAKE_FINAL;
+ animDef.mSpeedFactor = .7f;
+ animDef.mProperties.push_back(AnimatedProperty{
+ "ChristopherPlummer",
+ "position",
+ KeyFrames(),
+ std::unique_ptr<AnimatedProperty::Value>{ new AnimatedProperty::Value{
+ Property::Value{ Vector3::XAXIS * 100.f },
+ b
+ } },
+ AlphaFunction::EASE_OUT,
+ TimePeriod(animDef.mDuration)
+ });
+
+ auto anim = animDef.ReAnimate(getActor);
+ DALI_TEST_EQUAL(anim.GetDuration(), animDef.mDuration);
+ DALI_TEST_EQUAL(anim.GetEndAction(), animDef.mEndAction);
+ DALI_TEST_EQUAL(anim.GetSpeedFactor(), animDef.mSpeedFactor);
+ DALI_TEST_EQUAL(anim.GetLoopCount(), animDef.mLoopCount);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliAnimationDefinitionReAnimateKeyFrames(void)
+{
+ TestApplication app;
+ auto actor = Actor::New();
+ actor.SetProperty(Actor::Property::NAME, "ChristopherPlummer");
+
+ auto getActor = [&actor](const std::string& name) {
+ return actor.FindChildByName(name);
+ };
+
+ KeyFrames kf = KeyFrames::New();
+ kf.Add(0.f, Vector3::ZERO);
+ kf.Add(1.f, Vector3::XAXIS * 100.f);
+
+ AnimationDefinition animDef;
+ animDef.mName = "WalkRight";
+ animDef.mDuration = 10.f;
+ animDef.mLoopCount = 2;
+ animDef.mEndAction = Animation::BAKE_FINAL;
+ animDef.mSpeedFactor = .7f;
+ animDef.mProperties.push_back(AnimatedProperty{
+ "ChristopherPlummer",
+ "position",
+ kf,
+ nullptr,
+ AlphaFunction::EASE_OUT,
+ TimePeriod(animDef.mDuration)
+ });
+
+ auto anim = animDef.ReAnimate(getActor);
+ DALI_TEST_EQUAL(anim.GetDuration(), animDef.mDuration);
+ DALI_TEST_EQUAL(anim.GetEndAction(), animDef.mEndAction);
+ DALI_TEST_EQUAL(anim.GetSpeedFactor(), animDef.mSpeedFactor);
+ DALI_TEST_EQUAL(anim.GetLoopCount(), animDef.mLoopCount);
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/camera-parameters.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliCameraParameters(void)
+{
+ Quaternion qView = Quaternion(Radian(Degree(180.f)), Vector3::YAXIS);
+ CameraParameters camParams;
+ camParams.matrix.SetTransformComponents(Vector3::ONE * 2.f,
+ qView,
+ Vector3::ZAXIS * -100.f);
+ camParams.orthographicSize = Vector4{ -1.f, 1.f, -1.f, 1.f };
+ camParams.yFov = Radian(M_PI * .5).radian;
+ camParams.zNear = 1.f;
+ camParams.zFar = 1000.f;
+
+ Vector3 scale;
+ Quaternion orientation;
+ Vector3 position;
+ camParams.CalculateTransformComponents(position, orientation, scale);
+ DALI_TEST_EQUAL(scale, Vector3::ONE * 2.f);
+ DALI_TEST_EQUAL(orientation, Quaternion::IDENTITY); // 2 180 degrees rotations along y
+ DALI_TEST_EQUAL(position, Vector3::ZAXIS * -100.f);
+
+ TestApplication app;
+ CameraActor camera = CameraActor::New();
+ for (auto i : { false, true })
+ {
+ camParams.isPerspective = i;
+
+ auto viewProjection = camParams.GetViewProjection();
+ Matrix view{ false };
+ Matrix::Multiply(view, Matrix(qView), camParams.matrix);
+ view.Invert();
+ DALI_TEST_EQUAL(viewProjection.GetView(), view);
+
+ camParams.ConfigureCamera(camera);
+ DALI_TEST_EQUAL(camParams.zNear, camera.GetNearClippingPlane());
+ DALI_TEST_EQUAL(camParams.zFar, camera.GetFarClippingPlane());
+
+ DALI_TEST_EQUAL(camera.GetInvertYAxis(), true);
+ DALI_TEST_EQUAL(camera.GetProperty(Actor::Property::POSITION).Get<Vector3>(), position);
+ DALI_TEST_EQUAL(camera.GetProperty(Actor::Property::ORIENTATION).Get<Quaternion>(), orientation);
+ DALI_TEST_EQUAL(camera.GetProperty(Actor::Property::SCALE).Get<Vector3>(), scale);
+ }
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/dli-loader.h"
+#include "dali-scene-loader/public-api/resource-bundle.h"
+#include "dali-scene-loader/public-api/scene-definition.h"
+#include "dali-scene-loader/public-api/load-result.h"
+#include "dali-scene-loader/internal/json-util.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+
+void ConfigureBlendShapeShaders(ResourceBundle& resources, const SceneDefinition& scene, Actor root,
+ std::vector<BlendshapeShaderConfigurationRequest>&& requests)
+{
+ std::vector<std::string> errors;
+ auto onError = [&errors](const std::string& msg) {
+ errors.push_back(msg);
+ };
+
+ if (!scene.ConfigureBlendshapeShaders(resources, root, std::move(requests), onError))
+ {
+ ExceptionFlinger flinger(ASSERT_LOCATION);
+ for (auto& msg : errors)
+ {
+ flinger << msg << '\n';
+ }
+ }
+}
+
+struct Context
+{
+ ResourceBundle::PathProvider pathProvider = [](ResourceType::Value type) {
+ return TEST_RESOURCE_DIR "/";
+ };
+
+ ResourceBundle resources;
+ SceneDefinition scene;
+ std::vector<CameraParameters> cameraParameters;
+ std::vector<LightParameters> lights;
+ std::vector<AnimationDefinition> animations;
+ std::vector<AnimationGroupDefinition> animGroups;
+
+ LoadResult output {
+ resources,
+ scene,
+ animations,
+ animGroups,
+ cameraParameters,
+ lights
+ };
+
+ DliLoader::InputParams input {
+ pathProvider(ResourceType::Mesh),
+ nullptr,
+ {},
+ {},
+ nullptr,
+ };
+ DliLoader::LoadParams loadParams{ input, output };
+
+ std::vector<std::string> errors;
+ DliLoader loader;
+
+ StringCallback onError = [this](const std::string& error) {
+ errors.push_back(error);
+ printf("%s\n", error.c_str());
+ };
+
+ Context()
+ {
+ loader.SetErrorCallback(onError);
+ }
+};
+
+bool StringHasTokens(const char* string, const std::vector<const char*>& tokens)
+{
+ for (auto& token: tokens)
+ {
+ auto result = strstr(string, token);
+ if(nullptr == result)
+ {
+ return false;
+ }
+ string = result + strlen(token);
+ }
+ return true;
+}
+
+}
+
+int UtcDaliDliLoaderLoadSceneNotFound(void)
+{
+ Context ctx;
+
+ DALI_TEST_EQUAL(ctx.loader.LoadScene("does_not_exist.dli", ctx.loadParams), false);
+
+ auto error = ctx.loader.GetParseError();
+ DALI_TEST_CHECK(StringHasTokens(error.c_str(), { "Empty source buffer to parse." }));
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneFailParse(void)
+{
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "invalid.gltf";
+ DALI_TEST_EQUAL(ctx.loader.LoadScene(path, ctx.loadParams), false);
+
+ auto error = ctx.loader.GetParseError();
+ DALI_TEST_CHECK(StringHasTokens(error.c_str(), { "Unexpected character." }));
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneAssertions(void)
+{
+ const std::pair<std::string, std::string> pathExceptionPairs[] {
+ // from RequireChild()
+ { "scenes-nodes-missing", "Failed to find child node" },
+ { "scenes-missing", "Failed to find child node" },
+ { "nodes-missing", "Failed to find child node" },
+ // from ParseSceneInternal()
+ { "scene-out-of-bounds", "out of bounds" },
+ { "nodes-invalid-type", "invalid type; array required" },
+ { "nodes-array-empty", "must define a node id" },
+ { "root-id-invalid", "invalid value for root node index" },
+ { "root-id-out-of-bounds", "out of bounds" },
+ { "root-node-invalid-type", "invalid JSON type; object required" },
+ // from ParseSkeletons()
+ { "skeleton-node-missing", "Missing required attribute" },
+ { "skeleton-root-not-found", "not defined" },
+ // from ParseShaders()
+ { "shader-vertex-missing", "Missing vertex / fragment shader" },
+ { "shader-fragment-missing", "Missing vertex / fragment shader" },
+ // from ParseMeshes()
+ { "mesh-uri-missing", "Missing required attribute" },
+ { "mesh-indices-read-fail", "Failed to read indices" },
+ { "mesh-positions-read-fail", "Failed to read positions" },
+ // from ParseMaterials()
+ { "material-environment-out-of-bounds", "out of bounds" },
+ // from ParseNodes()
+ { "node-model-mesh-missing", "Missing mesh" },
+ { "node-arc-mesh-missing", "Missing mesh" },
+ { "node-animated-image-mesh-missing", "Missing mesh" },
+ { "node-renderable-mesh-invalid-type", "Invalid Mesh index type" },
+ { "node-renderable-mesh-out-of-bounds", "out of bounds" },
+ { "node-child-invalid-type", "invalid index type" },
+ { "node-name-already-used", "name already used" },
+ // from ParseAnimations()
+ { "animation-failed-to-open", "Failed to open animation data" }
+ };
+ for (auto& i: pathExceptionPairs)
+ {
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/" + i.first + ".dli";
+ printf("\n\n%s: %s\n", path.c_str(), i.second.c_str());
+ DALI_TEST_ASSERTION(ctx.loader.LoadScene(path, ctx.loadParams), i.second.c_str());
+ }
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneExercise(void)
+{
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "exercise.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+ DALI_TEST_CHECK(ctx.errors.empty());
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 2u);
+ DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "Backdrop"); // default scene is scene 1 - this one.
+ DALI_TEST_EQUAL(scene.GetNode(roots[1])->mName, "ExerciseDemo");
+
+ DALI_TEST_EQUAL(scene.GetNodeCount(), 96u);
+
+ auto& resources = ctx.resources;
+ DALI_TEST_EQUAL(resources.mMeshes.size(), 11u);
+ DALI_TEST_EQUAL(resources.mMaterials.size(), 13u);
+ DALI_TEST_EQUAL(resources.mShaders.size(), 5u);
+ DALI_TEST_EQUAL(resources.mEnvironmentMaps.size(), 2u);
+ DALI_TEST_EQUAL(resources.mSkeletons.size(), 1u);
+
+ DALI_TEST_EQUAL(ctx.cameraParameters.size(), 1u);
+ DALI_TEST_EQUAL(ctx.lights.size(), 1u);
+ DALI_TEST_EQUAL(ctx.animations.size(), 18u);
+ DALI_TEST_EQUAL(ctx.animGroups.size(), 16u);
+
+ ViewProjection viewProjection;
+ Transforms xforms {
+ MatrixStack{},
+ viewProjection
+ };
+ NodeDefinition::CreateParams nodeParams{
+ resources,
+ xforms,
+ };
+
+ Customization::Choices choices;
+
+ TestApplication app;
+
+ Actor root = Actor::New();
+ SetActorCentered(root);
+ for (auto iRoot : scene.GetRoots())
+ {
+ auto resourceRefs = resources.CreateRefCounter();
+ scene.CountResourceRefs(iRoot, choices, resourceRefs);
+ resources.CountEnvironmentReferences(resourceRefs);
+ resources.LoadResources(resourceRefs, ctx.pathProvider);
+ if (auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
+ {
+ scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
+ scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
+ ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
+ scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+ root.Add(actor);
+ }
+ }
+
+ DALI_TEST_EQUAL(root.GetChildCount(), 2u);
+ DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::NAME).Get<std::string>(), "Backdrop");
+ DALI_TEST_EQUAL(root.GetChildAt(1).GetProperty(Actor::Property::NAME).Get<std::string>(), "ExerciseDemo");
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneMorph(void)
+{
+ Context ctx;
+
+ std::vector<std::string> metadata;
+ uint32_t metadataCount = 0;
+ ctx.input.mPreNodeCategoryProcessors.push_back({ "metadata",
+ [&](const Property::Array& array, StringCallback) {
+ std::string key, value;
+ for (uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
+ {
+ auto& data = array.GetElementAt(i0);
+ DALI_TEST_EQUAL(data.GetType(), Property::MAP);
+
+ auto map = data.GetMap();
+ auto key = map->Find("key");
+ auto value = map->Find("value");
+ DALI_TEST_EQUAL(key->GetType(), Property::STRING);
+ DALI_TEST_EQUAL(value->GetType(), Property::STRING);
+ metadata.push_back(key->Get<std::string>() + ":" + value->Get<std::string>());
+
+ ++metadataCount;
+ }
+ }
+ });
+
+ std::vector<std::string> behaviors;
+ uint32_t behaviorCount = 0;
+ ctx.input.mPostNodeCategoryProcessors.push_back({ "behaviors",
+ [&](const Property::Array& array, StringCallback) {
+ for (uint32_t i0 = 0, i1 = array.Count(); i0 < i1; ++i0)
+ {
+ auto& data = array.GetElementAt(i0);
+ DALI_TEST_EQUAL(data.GetType(), Property::MAP);
+
+ auto map = data.GetMap();
+ auto event = map->Find("event");
+ auto url = map->Find("url");
+ DALI_TEST_EQUAL(event->GetType(), Property::STRING);
+ DALI_TEST_EQUAL(url->GetType(), Property::STRING);
+ behaviors.push_back(event->Get<std::string>() + ":" + url->Get<std::string>());
+
+ ++behaviorCount;
+ }
+ }
+ });
+
+ size_t numNodes = 0;
+ ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, const Property::Map&, StringCallback) {
+ ++numNodes;
+ };
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "morph.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+ DALI_TEST_CHECK(ctx.errors.empty());
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 1u);
+ DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "HeadTest_002");
+
+ DALI_TEST_EQUAL(numNodes, 3u);
+ DALI_TEST_EQUAL(scene.GetNodeCount(), numNodes);
+
+ auto& resources = ctx.resources;
+ DALI_TEST_EQUAL(resources.mMeshes.size(), 2u);
+ DALI_TEST_EQUAL(resources.mMaterials.size(), 1u);
+ DALI_TEST_EQUAL(resources.mShaders.size(), 5u);
+ DALI_TEST_EQUAL(resources.mEnvironmentMaps.size(), 2u);
+ DALI_TEST_EQUAL(resources.mSkeletons.size(), 0u);
+
+ DALI_TEST_EQUAL(ctx.cameraParameters.size(), 1u);
+ DALI_TEST_EQUAL(ctx.lights.size(), 1u);
+ DALI_TEST_EQUAL(ctx.animations.size(), 1u);
+ DALI_TEST_EQUAL(ctx.animGroups.size(), 0u);
+
+ DALI_TEST_EQUAL(metadata.size(), 4u);
+ DALI_TEST_EQUAL(behaviors.size(), 1u);
+
+ ViewProjection viewProjection;
+ Transforms xforms {
+ MatrixStack{},
+ viewProjection
+ };
+ NodeDefinition::CreateParams nodeParams{
+ resources,
+ xforms,
+ };
+
+ Customization::Choices choices;
+
+ TestApplication app;
+
+ Actor root = Actor::New();
+ SetActorCentered(root);
+ for (auto iRoot : scene.GetRoots())
+ {
+ auto resourceRefs = resources.CreateRefCounter();
+ scene.CountResourceRefs(iRoot, choices, resourceRefs);
+ resources.CountEnvironmentReferences(resourceRefs);
+ resources.LoadResources(resourceRefs, ctx.pathProvider);
+ if (auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
+ {
+ scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
+ scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
+ ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
+ scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+ root.Add(actor);
+ }
+ }
+
+ DALI_TEST_EQUAL(root.GetChildCount(), 1u);
+ DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::NAME).Get<std::string>(), "HeadTest_002");
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneArc(void)
+{
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "arc.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+ DALI_TEST_CHECK(ctx.errors.empty());
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 1u);
+ DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "root");
+
+ DALI_TEST_EQUAL(scene.GetNodeCount(), 2u);
+
+ auto& resources = ctx.resources;
+ DALI_TEST_EQUAL(resources.mMeshes.size(), 1u);
+ DALI_TEST_EQUAL(resources.mMaterials.size(), 1u);
+ DALI_TEST_EQUAL(resources.mShaders.size(), 1u);
+ DALI_TEST_EQUAL(resources.mEnvironmentMaps.size(), 1u);
+ DALI_TEST_EQUAL(resources.mSkeletons.size(), 0u);
+
+ DALI_TEST_EQUAL(ctx.cameraParameters.size(), 0u);
+ DALI_TEST_EQUAL(ctx.lights.size(), 0u);
+ DALI_TEST_EQUAL(ctx.animations.size(), 0u);
+ DALI_TEST_EQUAL(ctx.animGroups.size(), 0u);
+
+ ViewProjection viewProjection;
+ Transforms xforms {
+ MatrixStack{},
+ viewProjection
+ };
+ NodeDefinition::CreateParams nodeParams{
+ resources,
+ xforms,
+ };
+
+ Customization::Choices choices;
+
+ TestApplication app;
+
+ Actor root = Actor::New();
+ SetActorCentered(root);
+ for (auto iRoot : scene.GetRoots())
+ {
+ auto resourceRefs = resources.CreateRefCounter();
+ scene.CountResourceRefs(iRoot, choices, resourceRefs);
+ resources.CountEnvironmentReferences(resourceRefs);
+ resources.LoadResources(resourceRefs, ctx.pathProvider);
+ if (auto actor = scene.CreateNodes(iRoot, choices, nodeParams))
+ {
+ scene.ConfigureSkeletonJoints(iRoot, resources.mSkeletons, actor);
+ scene.ConfigureSkinningShaders(resources, actor, std::move(nodeParams.mSkinnables));
+ ConfigureBlendShapeShaders(resources, scene, actor, std::move(nodeParams.mBlendshapeRequests));
+ scene.ApplyConstraints(actor, std::move(nodeParams.mConstrainables));
+ root.Add(actor);
+ }
+ }
+
+ DALI_TEST_EQUAL(root.GetChildCount(), 1u);
+ DALI_TEST_EQUAL(root.GetChildAt(0).GetProperty(Actor::Property::NAME).Get<std::string>(), "root");
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneShaderUniforms(void)
+{
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/shader-uniforms.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+ DALI_TEST_EQUAL(ctx.errors.size(), 1u);
+ DALI_TEST_CHECK(ctx.errors[0].find("failed to infer type") != std::string::npos);
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 1u);
+ DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "root");
+
+ DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
+
+ auto& resources = ctx.resources;
+ DALI_TEST_EQUAL(resources.mMeshes.size(), 0u);
+ DALI_TEST_EQUAL(resources.mMaterials.size(), 0u);
+ DALI_TEST_EQUAL(resources.mShaders.size(), 1u);
+ DALI_TEST_EQUAL(resources.mEnvironmentMaps.size(), 0u);
+ DALI_TEST_EQUAL(resources.mSkeletons.size(), 0u);
+
+ auto raw = resources.mShaders[0].first.LoadRaw(ctx.pathProvider(ResourceType::Shader));
+
+ TestApplication app;
+
+ auto shader = resources.mShaders[0].first.Load(std::move(raw));
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uBool")).Get<float>(), 1.0f);
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uInt")).Get<float>(), 255.0f);
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uFloat")).Get<float>(), -0.5f);
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uVec2")).Get<Vector2>(), Vector2(100.0f, -100.0f));
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uVec3")).Get<Vector3>(), Vector3(50.0f, 0.f, -200.0f));
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uVec4")).Get<Vector4>(), Vector4(0.1774f, 1.0f, 0.5333f, 0.7997f));
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uMat3")).Get<Matrix3>(), Matrix3(9.0f, 8.0f, 7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f));
+
+ Matrix expectedMatrix;
+ expectedMatrix.SetTransformComponents(Vector3::ONE * 8.0, Quaternion::IDENTITY, Vector3::ZERO);
+ DALI_TEST_EQUAL(shader.GetProperty(shader.GetPropertyIndex("uMat4")).Get<Matrix>(), expectedMatrix);
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneExtras(void)
+{
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/extras.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+ DALI_TEST_EQUAL(ctx.errors.size(), 3u);
+ DALI_TEST_CHECK(ctx.errors[0].find("already defined; overriding") != std::string::npos);
+ DALI_TEST_CHECK(ctx.errors[1].find("empty string is invalid for name") != std::string::npos);
+ DALI_TEST_CHECK(ctx.errors[2].find("failed to interpret value") != std::string::npos);
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 1u);
+ DALI_TEST_EQUAL(scene.GetNode(roots[0])->mName, "root");
+
+ DALI_TEST_EQUAL(scene.GetNodeCount(), 1u);
+
+ ViewProjection viewProjection;
+ Transforms xforms {
+ MatrixStack{},
+ viewProjection
+ };
+ auto& resources = ctx.resources;
+ NodeDefinition::CreateParams nodeParams{
+ resources,
+ xforms,
+ };
+
+ Customization::Choices choices;
+
+ TestApplication app;
+ Actor actor = scene.CreateNodes(0, choices, nodeParams);
+
+ DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("fudgeFactor")).Get<float>(), 9000.1f);
+ DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("fudgeVector")).Get<Vector2>(), Vector2(-.25f, 17.f));
+ DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("isThisTheRealLife")).Get<bool>(), true);
+ DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("isThisJustFantasy")).Get<bool>(), false);
+ DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("velocity")).Get<Vector3>(), Vector3(.1f, 58.f, -.2f));
+ DALI_TEST_EQUAL(actor.GetProperty(actor.GetPropertyIndex("frameOfReference")).Get<Matrix>(), Matrix::IDENTITY);
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderLoadSceneConstraints(void)
+{
+ Context ctx;
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/constraints.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+ DALI_TEST_EQUAL(ctx.errors.size(), 1u);
+ DALI_TEST_CHECK(ctx.errors[0].find("invalid", ctx.errors[0].find("node ID")) != std::string::npos);
+
+ auto& scene = ctx.scene;
+ auto& roots = scene.GetRoots();
+ DALI_TEST_EQUAL(roots.size(), 1u);
+ DALI_TEST_EQUAL(scene.GetNode(0)->mName, "root");
+ DALI_TEST_EQUAL(scene.GetNode(1)->mName, "Alice");
+ DALI_TEST_EQUAL(scene.GetNode(2)->mName, "Bob");
+ DALI_TEST_EQUAL(scene.GetNode(3)->mName, "Charlie");
+
+ DALI_TEST_EQUAL(scene.GetNodeCount(), 4u);
+
+ ViewProjection viewProjection;
+ Transforms xforms {
+ MatrixStack{},
+ viewProjection
+ };
+ auto& resources = ctx.resources;
+ NodeDefinition::CreateParams nodeParams{
+ resources,
+ xforms,
+ };
+
+ Customization::Choices choices;
+
+ TestApplication app;
+
+ Actor root = scene.CreateNodes(0, choices, nodeParams);
+ Actor alice = root.FindChildByName("Alice");
+ Actor bob = root.FindChildByName("Bob");
+ Actor charlie = root.FindChildByName("Charlie");
+
+ DALI_TEST_EQUAL(nodeParams.mConstrainables.size(), 3u);
+ DALI_TEST_EQUAL(bob.GetProperty(bob.GetPropertyIndex("angularVelocity")).Get<Vector2>(), Vector2(-0.5, 0.0004));
+
+ ctx.errors.clear();
+ scene.ApplyConstraints(root, std::move(nodeParams.mConstrainables), ctx.onError);
+ DALI_TEST_CHECK(ctx.errors.empty());
+
+ app.GetScene().Add(root);
+ app.SendNotification();
+ app.Render();
+ app.SendNotification();
+ app.Render();
+
+ DALI_TEST_EQUAL(charlie.GetCurrentProperty(Actor::Property::ORIENTATION), alice.GetProperty(Actor::Property::ORIENTATION));
+ DALI_TEST_EQUAL(charlie.GetCurrentProperty(Actor::Property::POSITION), bob.GetProperty(Actor::Property::POSITION));
+ DALI_TEST_EQUAL(charlie.GetCurrentProperty(charlie.GetPropertyIndex("angularVelocity")), bob.GetProperty(bob.GetPropertyIndex("angularVelocity")));
+
+ END_TEST;
+}
+
+int UtcDaliDliLoaderNodeProcessor(void)
+{
+ Context ctx;
+
+ std::vector<Property::Map> nodeMaps;
+ ctx.input.mNodePropertyProcessor = [&](const NodeDefinition&, Property::Map&& map, StringCallback) {
+ nodeMaps.push_back(map);
+ };
+
+ auto path = ctx.pathProvider(ResourceType::Mesh) + "dli/node-processor.dli";
+ DALI_TEST_CHECK(ctx.loader.LoadScene(path, ctx.loadParams));
+
+ DALI_TEST_EQUAL(nodeMaps.size(), 2u);
+ DALI_TEST_EQUAL(nodeMaps[0].Count(), 5u);
+ DALI_TEST_EQUAL(nodeMaps[0].Find("name")->Get<std::string>(), "rootA");
+ DALI_TEST_EQUAL(nodeMaps[0].Find("nickname")->Get<std::string>(), "same as name");
+ DALI_TEST_EQUAL(nodeMaps[0].Find("favourite number")->Get<int32_t>(), 63478);
+
+ auto propArray = nodeMaps[0].Find("array");
+ DALI_TEST_EQUAL(propArray->GetType(), Property::ARRAY);
+
+ auto array = propArray->GetArray();
+ DALI_TEST_EQUAL(array->Count(), 5);
+ DALI_TEST_EQUAL(array->GetElementAt(0).Get<int32_t>(), 1);
+ DALI_TEST_EQUAL(array->GetElementAt(1).Get<int32_t>(), 2);
+ DALI_TEST_EQUAL(array->GetElementAt(2).Get<int32_t>(), 4);
+ DALI_TEST_EQUAL(array->GetElementAt(3).Get<int32_t>(), 8);
+ DALI_TEST_EQUAL(array->GetElementAt(4).Get<int32_t>(), -500);
+
+ auto propObject = nodeMaps[0].Find("object");
+ DALI_TEST_EQUAL(propObject->GetType(), Property::MAP);
+
+ auto object = propObject->GetMap();
+ DALI_TEST_EQUAL(object->Count(), 5);
+ DALI_TEST_EQUAL(object->Find("physics")->Get<bool>(), true);
+ DALI_TEST_EQUAL(object->Find("elasticity")->Get<float>(), .27f);
+ DALI_TEST_EQUAL(object->Find("drag")->Get<float>(), .91f);
+
+ auto propInnerArray = object->Find("inner array");
+ DALI_TEST_EQUAL(propInnerArray->GetType(), Property::ARRAY);
+
+ auto innerArray = propInnerArray->GetArray();
+ DALI_TEST_EQUAL(innerArray->Count(), 3);
+ DALI_TEST_EQUAL(innerArray->GetElementAt(0).Get<std::string>(), "why");
+ DALI_TEST_EQUAL(innerArray->GetElementAt(1).Get<std::string>(), "not");
+ DALI_TEST_EQUAL(innerArray->GetElementAt(2).Get<bool>(), false);
+
+ auto propInnerObject = object->Find("inner object");
+ DALI_TEST_EQUAL(propInnerObject->GetType(), Property::MAP);
+
+ auto innerObject = propInnerObject->GetMap();
+ DALI_TEST_EQUAL(innerObject->Count(), 1);
+ DALI_TEST_EQUAL(innerObject->Find("supported")->Get<bool>(), true);
+
+ DALI_TEST_EQUAL(nodeMaps[1].Count(), 1u);
+ DALI_TEST_EQUAL(nodeMaps[1].Find("name")->Get<std::string>(), "rootB");
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/environment-definition.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliEnvironmentDefinitionLoadRawDefault(void)
+{
+ EnvironmentDefinition envDef;
+ auto rawData = envDef.LoadRaw("");
+
+ DALI_TEST_EQUAL(rawData.mDiffuse.data.size(), 6u);
+ for (auto& face: rawData.mDiffuse.data)
+ {
+ DALI_TEST_EQUAL(face.size(), 1u);
+ }
+
+ DALI_TEST_EQUAL(rawData.mSpecular.data.size(), 6u);
+ for (auto& face: rawData.mSpecular.data)
+ {
+ DALI_TEST_EQUAL(face.size(), 1u);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliEnvironmentDefinitionLoadRawFail(void)
+{
+ for (auto name: { "nonexistent.ktx", TEST_RESOURCE_DIR "Cobe.obj" , TEST_RESOURCE_DIR "truncated.ktx" })
+ {
+ EnvironmentDefinition envDef { name, name };
+ DALI_TEST_ASSERTION(envDef.LoadRaw(""), "Failed to load cubemap texture");
+
+ envDef.mDiffuseMapPath = "";
+ DALI_TEST_ASSERTION(envDef.LoadRaw(""), "Failed to load cubemap texture"); // specular map still invalid
+ }
+
+ END_TEST;
+}
+
+int UtcDaliEnvironmentDefinitionLoadRawSuccess(void)
+{
+ EnvironmentDefinition envDef { "forest_irradiance.ktx", "forest_radiance.ktx" };
+ auto rawData = envDef.LoadRaw(TEST_RESOURCE_DIR "/");
+
+ DALI_TEST_EQUAL(rawData.mDiffuse.data.size(), 6u);
+ for (auto& face: rawData.mDiffuse.data)
+ {
+ DALI_TEST_EQUAL(face.size(), 1u);
+ uint32_t size = 64u;
+ for (auto& mipLevel : face)
+ {
+ DALI_TEST_EQUAL(mipLevel.GetPixelFormat(), Pixel::Format::RGB888);
+ DALI_TEST_EQUAL(mipLevel.GetWidth(), size);
+ DALI_TEST_EQUAL(mipLevel.GetHeight(), size);
+ size /= 2;
+ }
+ }
+
+ DALI_TEST_EQUAL(rawData.mSpecular.data.size(), 6u);
+ for (auto& face: rawData.mSpecular.data)
+ {
+ DALI_TEST_EQUAL(face.size(), 5u);
+ uint32_t size = 64u;
+ for (auto& mipLevel : face)
+ {
+ DALI_TEST_EQUAL(mipLevel.GetPixelFormat(), Pixel::Format::RGB888);
+ DALI_TEST_EQUAL(mipLevel.GetWidth(), size);
+ DALI_TEST_EQUAL(mipLevel.GetHeight(), size);
+ size /= 2;
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliEnvironmentDefinitionLoadEmptyRaw(void)
+{
+ EnvironmentDefinition::RawData rawData;
+ EnvironmentDefinition envDef;
+ auto textures = envDef.Load(std::move(rawData));
+ DALI_TEST_CHECK(!textures.mDiffuse);
+ DALI_TEST_CHECK(!textures.mSpecular);
+
+ END_TEST;
+}
+
+namespace
+{
+
+void CheckTextureDefault(Texture texture)
+{
+ DALI_TEST_CHECK(texture);
+ DALI_TEST_EQUAL(texture.GetWidth(), 1u);
+ DALI_TEST_EQUAL(texture.GetHeight(), 1u);
+}
+
+void CheckTextureNotDefault(Texture texture)
+{
+ DALI_TEST_CHECK(texture);
+ DALI_TEST_CHECK(texture.GetWidth() > 1u);
+ DALI_TEST_CHECK(texture.GetHeight() > 1u);
+}
+
+}
+
+int UtcDaliEnvironmentDefinitionLoadDefault(void)
+{
+ EnvironmentDefinition envDef{};
+ auto rawData = envDef.LoadRaw(TEST_RESOURCE_DIR "/");;
+
+ TestApplication app;
+ auto textures = envDef.Load(std::move(rawData));
+
+ CheckTextureDefault(textures.mSpecular);
+ CheckTextureDefault(textures.mDiffuse);
+
+ END_TEST;
+}
+
+int UtcDaliEnvironmentDefinitionLoadDiffuse(void)
+{
+ EnvironmentDefinition envDef{ "forest_irradiance.ktx" };
+ auto rawData = envDef.LoadRaw(TEST_RESOURCE_DIR "/");;
+
+ TestApplication app;
+ auto textures = envDef.Load(std::move(rawData));
+
+ CheckTextureNotDefault(textures.mDiffuse);
+ CheckTextureDefault(textures.mSpecular);
+
+ END_TEST;
+}
+
+int UtcDaliEnvironmentDefinitionLoadSpecular(void)
+{
+ EnvironmentDefinition envDef{ "", "forest_radiance.ktx" };
+ auto rawData = envDef.LoadRaw(TEST_RESOURCE_DIR "/");;
+
+ TestApplication app;
+ auto textures = envDef.Load(std::move(rawData));
+
+ CheckTextureDefault(textures.mDiffuse);
+ CheckTextureNotDefault(textures.mSpecular);
+
+ END_TEST;
+}
+
+int UtcDaliEnvironmentDefinitionLoadBoth(void)
+{
+ EnvironmentDefinition envDef{ "forest_irradiance.ktx", "forest_radiance.ktx" };
+ auto rawData = envDef.LoadRaw(TEST_RESOURCE_DIR "/");;
+
+ TestApplication app;
+ auto textures = envDef.Load(std::move(rawData));
+
+ CheckTextureNotDefault(textures.mDiffuse);
+ CheckTextureNotDefault(textures.mSpecular);
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/resource-bundle.h"
+#include "dali-scene-loader/public-api/scene-definition.h"
+#include "dali-scene-loader/public-api/load-result.h"
+#include "dali-scene-loader/public-api/gltf2-loader.h"
+#include "dali-scene-loader/public-api/shader-definition-factory.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+#define DALI_TEST_THROW(expression, exception, predicate) \
+ {\
+ bool daliTestThrowSuccess__ = false;\
+ try\
+ {\
+ do { expression; } while(0);\
+ printf("No exception was thrown.\n");\
+ }\
+ catch (std::decay<exception>::type& ex)\
+ {\
+ daliTestThrowSuccess__ = predicate(ex);\
+ }\
+ catch (...)\
+ {\
+ printf("Wrong type of exception thrown.\n");\
+ }\
+ DALI_TEST_CHECK(daliTestThrowSuccess__);\
+ }
+
+namespace
+{
+struct Context
+{
+ ResourceBundle resources;
+ SceneDefinition scene;
+
+ std::vector<AnimationDefinition> animations;
+ std::vector<AnimationGroupDefinition> animationGroups;
+ std::vector<CameraParameters> cameras;
+ std::vector<LightParameters> lights;
+
+ LoadResult loadResult {
+ resources,
+ scene,
+ animations,
+ animationGroups,
+ cameras,
+ lights
+ };
+};
+
+struct ExceptionMessageStartsWith
+{
+ const std::string_view expected;
+
+ bool operator()(const std::runtime_error& e)
+ {
+ const bool success = (0 == strncmp(e.what(), expected.data(), expected.size()));
+ if (!success)
+ {
+ printf("Expected: %s, got: %s.\n", expected.data(), e.what());
+ }
+ return success;
+ }
+};
+
+}
+
+int UtcDaliGltfLoaderFailedToLoad(void)
+{
+ Context ctx;
+
+ ShaderDefinitionFactory sdf;
+ sdf.SetResources(ctx.resources);
+
+ DALI_TEST_THROW(LoadGltfScene("non-existent.gltf", sdf, ctx.loadResult),
+ std::runtime_error,
+ ExceptionMessageStartsWith{"Failed to load"});
+
+ DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
+ DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
+
+ DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mShaders.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
+
+ DALI_TEST_EQUAL(0, ctx.cameras.size());
+ DALI_TEST_EQUAL(0, ctx.lights.size());
+ DALI_TEST_EQUAL(0, ctx.animations.size());
+ DALI_TEST_EQUAL(0, ctx.animationGroups.size());
+
+ END_TEST;
+}
+
+int UtcDaliGltfLoaderFailedToParse(void)
+{
+ Context ctx;
+
+ ShaderDefinitionFactory sdf;
+ sdf.SetResources(ctx.resources);
+
+ DALI_TEST_THROW(LoadGltfScene(TEST_RESOURCE_DIR "/invalid.gltf", sdf, ctx.loadResult),
+ std::runtime_error,
+ ExceptionMessageStartsWith{"Failed to parse"});
+
+ DALI_TEST_EQUAL(0, ctx.scene.GetRoots().size());
+ DALI_TEST_EQUAL(0, ctx.scene.GetNodeCount());
+
+ DALI_TEST_EQUAL(0, ctx.resources.mEnvironmentMaps.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mMaterials.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mMeshes.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mShaders.size());
+ DALI_TEST_EQUAL(0, ctx.resources.mSkeletons.size());
+
+ DALI_TEST_EQUAL(0, ctx.cameras.size());
+ DALI_TEST_EQUAL(0, ctx.lights.size());
+ DALI_TEST_EQUAL(0, ctx.animations.size());
+ DALI_TEST_EQUAL(0, ctx.animationGroups.size());
+
+ END_TEST;
+}
+
+int UtcDaliGltfLoaderSuccess1(void)
+{
+ Context ctx;
+
+ ShaderDefinitionFactory sdf;
+ sdf.SetResources(ctx.resources);
+
+ LoadGltfScene(TEST_RESOURCE_DIR "/AnimatedCube.gltf", sdf, ctx.loadResult);
+
+ DALI_TEST_EQUAL(1u, ctx.scene.GetRoots().size());
+ DALI_TEST_EQUAL(6u, ctx.scene.GetNodeCount());
+
+ DALI_TEST_EQUAL(0u, ctx.resources.mEnvironmentMaps.size());
+
+ auto& materials = ctx.resources.mMaterials;
+ DALI_TEST_EQUAL(2u, materials.size());
+ const MaterialDefinition materialGroundTruth[] {
+ {
+ MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+ MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS |
+ (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT),
+ 0,
+ Vector4(1.f, .766f, .336f, 1.f),
+ 1.f,
+ 0.f,
+ {
+ { MaterialDefinition::ALBEDO,
+ { "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
+ { MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
+ { "AnimatedCube_MetallicRoughness.png",
+ SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT) } },
+ { MaterialDefinition::NORMAL,
+ { "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
+ }
+ },
+ {
+ MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+ MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS,
+ 0,
+ Vector4(1.f, .766f, .336f, 1.f),
+ 1.f,
+ 0.f,
+ {
+ { MaterialDefinition::ALBEDO,
+ { "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
+ { MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | MaterialDefinition::GLTF_CHANNELS,
+ { "AnimatedCube_MetallicRoughness.png",
+ SamplerFlags::Encode(FilterMode::NEAREST_MIPMAP_LINEAR, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::MIRRORED_REPEAT) } },
+ { MaterialDefinition::NORMAL,
+ { "AnimatedCube_BaseColor.png",
+ SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT) } },
+ }
+ },
+ };
+
+ auto iMaterial = materials.begin();
+ for (auto& m : materialGroundTruth)
+ {
+ printf("material %ld\n", iMaterial - materials.begin());
+ auto& md = iMaterial->first;
+ DALI_TEST_EQUAL(md.mFlags, m.mFlags);
+ DALI_TEST_EQUAL(md.mEnvironmentIdx, m.mEnvironmentIdx);
+ DALI_TEST_EQUAL(md.mColor, m.mColor);
+ DALI_TEST_EQUAL(md.mMetallic, m.mMetallic);
+ DALI_TEST_EQUAL(md.mRoughness, m.mRoughness);
+
+ DALI_TEST_EQUAL(md.mTextureStages.size(), m.mTextureStages.size());
+ auto iTexture = md.mTextureStages.begin();
+ for (auto& ts: m.mTextureStages)
+ {
+ printf("texture %ld\n", iTexture - md.mTextureStages.begin());
+ DALI_TEST_EQUAL(iTexture->mSemantic, ts.mSemantic);
+ DALI_TEST_EQUAL(iTexture->mTexture.mImageUri, ts.mTexture.mImageUri);
+ DALI_TEST_EQUAL(uint32_t(iTexture->mTexture.mSamplerFlags), uint32_t(ts.mTexture.mSamplerFlags)); // don't interpret it as a character
+ ++iTexture;
+ }
+ ++iMaterial;
+ }
+
+ auto& meshes = ctx.resources.mMeshes;
+ DALI_TEST_EQUAL(2u, meshes.size());
+
+ using Blob = MeshDefinition::Blob;
+ using Accessor = MeshDefinition::Accessor;
+ const MeshDefinition meshGroundTruth[] {
+ {
+ 0,
+ Geometry::TRIANGLES,
+ "AnimatedCube.bin",
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ },
+ {
+ 0,
+ Geometry::TRIANGLES,
+ "AnimatedCube.bin",
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ Accessor{ Blob{ 0, 0 }, {} },
+ },
+ };
+
+ auto iMesh = meshes.begin();
+ for (auto& m : meshGroundTruth)
+ {
+ printf("mesh %ld\n", iMesh - meshes.begin());
+
+ auto& md = iMesh->first;
+ DALI_TEST_EQUAL(md.mFlags, m.mFlags);
+ DALI_TEST_EQUAL(md.mPrimitiveType, m.mPrimitiveType);
+ for (auto mp: {
+ &MeshDefinition::mIndices,
+ &MeshDefinition::mPositions,
+ &MeshDefinition::mNormals,
+ &MeshDefinition::mTexCoords,
+ &MeshDefinition::mTangents,
+ &MeshDefinition::mJoints0,
+ &MeshDefinition::mWeights0
+ })
+ {
+ DALI_TEST_EQUAL((md.*mp).IsDefined(), (m.*mp).IsDefined());
+ DALI_TEST_EQUAL((md.*mp).mBlob.IsDefined(), (m.*mp).mBlob.IsDefined());
+ }
+
+ DALI_TEST_EQUAL(md.mBlendShapeHeader.IsDefined(), m.mBlendShapeHeader.IsDefined());
+
+ ++iMesh;
+ }
+
+ DALI_TEST_EQUAL(2u, ctx.resources.mShaders.size());
+ DALI_TEST_EQUAL(0u, ctx.resources.mSkeletons.size());
+
+ DALI_TEST_EQUAL(3u, ctx.cameras.size());
+ DALI_TEST_EQUAL(0u, ctx.lights.size());
+ DALI_TEST_EQUAL(1u, ctx.animations.size());
+ DALI_TEST_EQUAL(0u, ctx.animationGroups.size());
+
+ END_TEST;
+}
+
+int UtcDaliGltfLoaderSuccessShort(void)
+{
+ TestApplication app;
+
+ const std::string resourcePath = TEST_RESOURCE_DIR "/";
+ auto pathProvider = [resourcePath](ResourceType::Value) {
+ return resourcePath;
+ };
+
+ Customization::Choices choices;
+ for (auto modelName : {
+ "2CylinderEngine",
+ "AnimatedMorphCube",
+ "AnimatedMorphSphere",
+ "AnimatedTriangle",
+ "BoxAnimated",
+ "CesiumMan",
+ "CesiumMilkTruck",
+ "EnvironmentTest",
+ "MetalRoughSpheres",
+ "MorphPrimitivesTest",
+ "SimpleSparseAccessor",
+ })
+ {
+ Context ctx;
+
+ ShaderDefinitionFactory sdf;
+
+ auto& resources = ctx.resources;
+ resources.mEnvironmentMaps.push_back({});
+
+ sdf.SetResources(resources);
+
+ printf("%s\n", modelName);
+ LoadGltfScene(resourcePath + modelName + ".gltf", sdf, ctx.loadResult);
+ DALI_TEST_CHECK(ctx.scene.GetNodeCount() > 0);
+
+ auto& scene = ctx.scene;
+ for (auto iRoot : scene.GetRoots())
+ {
+ struct Visitor: NodeDefinition::IVisitor
+ {
+ struct ResourceReceiver: IResourceReceiver
+ {
+ std::vector<bool> mCounts;
+
+ void Register(ResourceType::Value type, Index id) override
+ {
+ if (type == ResourceType::Mesh)
+ {
+ mCounts[id] = true;
+ }
+ }
+ } receiver;
+
+ void Start(NodeDefinition& n) override
+ {
+ if (n.mRenderable)
+ {
+ n.mRenderable->RegisterResources(receiver);
+ }
+ }
+
+ void Finish(NodeDefinition& n) override
+ {}
+ } visitor;
+ visitor.receiver.mCounts.resize(resources.mMeshes.size(), false);
+
+ scene.Visit(iRoot, choices, visitor);
+ for (uint32_t i0 = 0, i1 = resources.mMeshes.size(); i0 < i1; ++i0)
+ {
+ if (visitor.receiver.mCounts[i0])
+ {
+ auto raw = resources.mMeshes[i0].first.LoadRaw(resourcePath);
+ DALI_TEST_CHECK(!raw.mAttribs.empty());
+
+ resources.mMeshes[i0].second = resources.mMeshes[i0].first.Load(std::move(raw));
+ DALI_TEST_CHECK(resources.mMeshes[i0].second.geometry);
+ }
+ }
+ }
+ }
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/ktx-loader.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+#include <fstream>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliKtxLoaderFailNonexistent(void)
+{
+ CubeData data;
+ DALI_TEST_CHECK(!LoadCubeMapData("non-existent.ktx", data));
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderFailInvalid1(void)
+{
+ CubeData data;
+ DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/invalid.svg", data)); // file smaller than KTX header
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderFailInvalid2(void)
+{
+ CubeData data;
+ DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/anim.gif", data)); // not a KTX
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderFailTruncated(void)
+{
+ CubeData data;
+ DALI_TEST_CHECK(!LoadCubeMapData(TEST_RESOURCE_DIR "/truncated.ktx", data));
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderSuccess(void)
+{
+ CubeData cubeData;
+ auto path = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+ DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+ DALI_TEST_EQUAL(6u, cubeData.data.size());
+ for (auto& face: cubeData.data)
+ {
+ uint32_t size = 64;
+ for (auto& mipData: face)
+ {
+ DALI_TEST_EQUAL(size, mipData.GetWidth());
+ DALI_TEST_EQUAL(size, mipData.GetHeight());
+ DALI_TEST_EQUAL(Pixel::Format::RGB888, mipData.GetPixelFormat());
+ size /= 2;
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderFormats(void)
+{
+ auto resPath = TEST_RESOURCE_DIR "/";
+#define FORMAT_PATH(x) { #x, Pixel::x }
+#define FORMAT_COMPRESSED_PATH(x) { #x, Pixel::COMPRESSED_ ## x ## _KHR }
+ std::pair<std::string, Pixel::Format> pathFormats[] {
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_4x4),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_5x4),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_5x5),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_6x5),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_6x6),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_8x5),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_8x6),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_8x8),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_10x5),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_10x6),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_10x10),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_12x10),
+ FORMAT_COMPRESSED_PATH(RGBA_ASTC_12x12),
+ FORMAT_PATH(RGB16F),
+ FORMAT_PATH(RGB32F),
+ FORMAT_PATH(RGBA8888),
+ };
+ for (auto i : pathFormats)
+ {
+ CubeData cubeData;
+ DALI_TEST_CHECK(LoadCubeMapData(resPath + i.first + ".ktx", cubeData));
+ DALI_TEST_EQUAL(cubeData.data[0][0].GetPixelFormat(), i.second);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderCubeDataCreateTexture1(void)
+{
+ uint32_t pixelBufferSize = 3;
+ uint8_t* pixelBuffer = new uint8_t[pixelBufferSize];
+
+ CubeData cubeData;
+ cubeData.data.push_back({});
+
+ auto pixelData = PixelData::New(pixelBuffer, pixelBufferSize, 1, 1, Pixel::Format::RGB888, PixelData::DELETE_ARRAY);
+ cubeData.data[0].push_back(pixelData);
+
+ TestApplication app;
+ auto texture = cubeData.CreateTexture();
+
+ DALI_TEST_CHECK(texture);
+ DALI_TEST_EQUAL(1u, texture.GetWidth());
+ DALI_TEST_EQUAL(1u, texture.GetHeight());
+
+ END_TEST;
+}
+
+int UtcDaliKtxLoaderCubeDataCreateTexture2(void)
+{
+ CubeData cubeData;
+ auto path = TEST_RESOURCE_DIR "/forest_radiance.ktx";
+ DALI_TEST_CHECK(LoadCubeMapData(path, cubeData));
+
+ TestApplication app;
+ auto texture = cubeData.CreateTexture();
+
+ DALI_TEST_CHECK(texture);
+ DALI_TEST_EQUAL(64u, texture.GetWidth());
+ DALI_TEST_EQUAL(64u, texture.GetHeight());
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/matrix-stack.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliMatrixStack(void)
+{
+ MatrixStack stack;
+ DALI_TEST_CHECK(stack.IsEmpty());
+
+ Matrix testMatrix;
+ testMatrix.SetTransformComponents(Vector3::ONE * 5.f,
+ Quaternion(Radian(Degree(-45.f)), Vector3::XAXIS),
+ Vector3(100.f, 0.f, -200.f));
+
+ stack.Push(testMatrix);
+ DALI_TEST_CHECK(!stack.IsEmpty());
+ DALI_TEST_EQUAL(stack.Top(), testMatrix);
+
+ stack.Push(Matrix::IDENTITY);
+ DALI_TEST_CHECK(!stack.IsEmpty());
+ DALI_TEST_EQUAL(stack.Top(), testMatrix);
+
+ stack.Push(testMatrix);
+
+ Matrix testMatrix2;
+ Matrix::Multiply(testMatrix2, testMatrix, testMatrix);
+ DALI_TEST_CHECK(!stack.IsEmpty());
+ DALI_TEST_EQUAL(stack.Top(), testMatrix2);
+
+ stack.PopAll();
+ DALI_TEST_CHECK(stack.IsEmpty());
+
+ stack.Push(Matrix::IDENTITY);
+ DALI_TEST_EQUAL(stack.Top(), Matrix::IDENTITY);
+
+ stack.Push(testMatrix);
+ DALI_TEST_EQUAL(stack.Top(), testMatrix);
+
+ stack.Pop();
+ DALI_TEST_EQUAL(stack.Top(), Matrix::IDENTITY);
+ DALI_TEST_CHECK(!stack.IsEmpty());
+
+ stack.Pop();
+ DALI_TEST_CHECK(stack.IsEmpty());
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/node-definition.h"
+#include "dali-scene-loader/public-api/view-projection.h"
+#include <toolkit-test-application.h>
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+
+struct Context
+{
+ ResourceBundle resources;
+
+ ViewProjection viewProjection;
+ Transforms transforms { MatrixStack{}, viewProjection };
+
+ NodeDefinition::CreateParams createParams {
+ resources,
+ transforms
+ };
+};
+
+}
+
+int UtcDaliConstraintDefinitionsCompare(void)
+{
+ ConstraintDefinition cd1{ "orientation", 0 };
+ ConstraintDefinition cd2{ "position", 1 };
+
+ DALI_TEST_CHECK(cd1 < cd2);
+ DALI_TEST_CHECK(!(cd2 < cd1));
+ DALI_TEST_CHECK(!(cd1 < cd1));
+ DALI_TEST_CHECK(!(cd2 < cd2));
+
+ DALI_TEST_CHECK(cd1 == cd1);
+ DALI_TEST_CHECK(cd2 == cd2);
+
+ ConstraintDefinition cd3{ "position", 0 };
+ ConstraintDefinition cd4{ "scale", 1 };
+ ConstraintDefinition cd5{ "position", 1 };
+ DALI_TEST_CHECK(cd2 != cd3);
+ DALI_TEST_CHECK(cd2 != cd4);
+ DALI_TEST_CHECK(cd2 == cd5);
+ DALI_TEST_CHECK(cd5 == cd2);
+
+ END_TEST;
+}
+
+int UtcDaliBlendshapeShaderConfigurationRequestsCompare(void)
+{
+ TestApplication app;
+ BlendshapeShaderConfigurationRequest bsscr1{ "", 0, Shader(nullptr) };
+
+ BlendshapeShaderConfigurationRequest bsscr2{ "", 0, Shader::New(
+ "void main(){ gl_Position = vec4(0.); }",
+ "void main(){ gl_FragColor = vec4(1.); }"
+ ) };
+
+ DALI_TEST_CHECK(bsscr1 < bsscr2);
+ DALI_TEST_CHECK(!(bsscr2 < bsscr1));
+ DALI_TEST_CHECK(!(bsscr1 < bsscr1));
+ DALI_TEST_CHECK(!(bsscr2 < bsscr2));
+
+ END_TEST;
+}
+
+int UtcDaliNodeDefinitionExtrasCompare(void)
+{
+ NodeDefinition::Extra e1{ "alpha", Vector3::XAXIS * 2.f };
+ NodeDefinition::Extra e2{ "beta", 8 };
+
+ DALI_TEST_CHECK(e1 < e2);
+ DALI_TEST_CHECK(!(e1 < e1));
+ DALI_TEST_CHECK(!(e2 < e1));
+ DALI_TEST_CHECK(!(e2 < e2));
+
+ END_TEST;
+}
+
+int UtcDaliNodeDefinitionProperties(void)
+{
+ TestApplication testApp;
+ NodeDefinition nodeDef{
+ "testRootNode",
+ Vector3{ -100.f, 100.f, -500.f },
+ Quaternion{ Radian(Degree(45.f)), Vector3::ZAXIS },
+ Vector3{ 2.f, 4.f, 8.f },
+ Vector3{ 100.f, 50.f, 25.f },
+ false,
+ };
+
+ Quaternion frobnicateFactor(0.f, 1.f, 2.f, 3.f);
+ frobnicateFactor.Normalize(); // because it will be (by DALi) once it's set as a property.
+ nodeDef.mExtras.push_back(NodeDefinition::Extra{ "frobnicateFactor", frobnicateFactor });
+
+ Context ctx;
+ auto actor = nodeDef.CreateActor(ctx.createParams);
+ DALI_TEST_EQUAL(nodeDef.mName, actor.GetProperty(Actor::Property::NAME).Get<std::string>());
+ DALI_TEST_EQUAL(nodeDef.mPosition, actor.GetProperty(Actor::Property::POSITION).Get<Vector3>());
+ DALI_TEST_EQUAL(nodeDef.mOrientation, actor.GetProperty(Actor::Property::ORIENTATION).Get<Quaternion>());
+ DALI_TEST_EQUAL(nodeDef.mScale, actor.GetProperty(Actor::Property::SCALE).Get<Vector3>());
+ DALI_TEST_EQUAL(nodeDef.mSize, actor.GetProperty(Actor::Property::SIZE).Get<Vector3>());
+ DALI_TEST_EQUAL(nodeDef.mIsVisible, actor.GetProperty(Actor::Property::VISIBLE).Get<bool>());
+
+ Property::Index propFrobnicateFactor = actor.GetPropertyIndex("frobnicateFactor");
+ DALI_TEST_CHECK(propFrobnicateFactor != Property::INVALID_INDEX);
+
+ auto frobnicateFactorValue = actor.GetProperty(propFrobnicateFactor);
+ DALI_TEST_EQUAL(Property::ROTATION, frobnicateFactorValue.GetType());
+ DALI_TEST_EQUAL(frobnicateFactorValue.Get<Quaternion>(), frobnicateFactor);
+
+ DALI_TEST_EQUAL(0, actor.GetChildCount());
+ DALI_TEST_EQUAL(0, actor.GetRendererCount());
+
+ END_TEST;
+}
+
+int UtcDaliNodeDefinitionRenderableRegisterResources(void)
+{
+ NodeDefinition nodeDef;
+
+ auto renderable = new NodeDefinition::Renderable();
+ renderable->mShaderIdx = 0;
+ nodeDef.mRenderable.reset(renderable);
+
+ struct : IResourceReceiver
+ {
+ std::vector<Index> shaders;
+ uint32_t otherResources = 0;
+
+ void Register(ResourceType::Value type, Index id) override
+ {
+ switch(type)
+ {
+ case ResourceType::Shader:
+ shaders.push_back(id);
+ break;
+
+ default:
+ ++otherResources;
+ }
+ }
+ } resourceReceiver;
+
+ nodeDef.mRenderable->RegisterResources(resourceReceiver);
+ DALI_TEST_EQUAL(1u, resourceReceiver.shaders.size());
+ DALI_TEST_EQUAL(0, resourceReceiver.shaders[0]);
+ DALI_TEST_EQUAL(0, resourceReceiver.otherResources);
+
+ END_TEST;
+}
+
+int UtcDaliNodeDefinitionRenderableReflectResources(void)
+{
+ NodeDefinition nodeDef;
+
+ auto renderable = new NodeDefinition::Renderable();
+ renderable->mShaderIdx = 0;
+ nodeDef.mRenderable.reset(renderable);
+
+ struct : IResourceReflector
+ {
+ std::vector<Index*> shaders;
+ uint32_t otherResources = 0;
+
+ void Reflect(ResourceType::Value type, Index& id) override
+ {
+ switch(type)
+ {
+ case ResourceType::Shader:
+ shaders.push_back(&id);
+ break;
+
+ default:
+ ++otherResources;
+ }
+ }
+ } resourceReflector;
+
+ nodeDef.mRenderable->ReflectResources(resourceReflector);
+ DALI_TEST_EQUAL(1u, resourceReflector.shaders.size());
+ DALI_TEST_EQUAL(&renderable->mShaderIdx, resourceReflector.shaders[0]);
+ DALI_TEST_EQUAL(0, resourceReflector.otherResources);
+
+ END_TEST;
+}
+
+int UtcDaliNodeDefinitionRenderable(void)
+{
+ TestApplication testApp;
+ NodeDefinition nodeDef;
+
+ auto renderable = new NodeDefinition::Renderable();
+ renderable->mShaderIdx = 0;
+ nodeDef.mRenderable.reset(renderable);
+
+ Context ctx;
+ const auto VSH = "void main() { gl_Position = vec4(0.); }";
+ const auto FSH = "void main() { gl_FragColor = vec4(1.); }";
+ auto shader = Shader::New(VSH, FSH);
+ ctx.resources.mShaders.push_back({ ShaderDefinition{}, shader });
+
+ auto actor = nodeDef.CreateActor(ctx.createParams);
+ DALI_TEST_EQUAL(1, actor.GetRendererCount());
+
+ auto renderer = actor.GetRendererAt(0);
+ DALI_TEST_EQUAL(renderer.GetShader(), shader);
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/renderer-state.h"
+#include "dali-scene-loader/public-api/parse-renderer-state.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace sl = SceneLoader;
+namespace rs = RendererState;
+
+int UtcDaliRendererStateFromBlendFactors(void)
+{
+ rs::Type state = rs::FromBlendFactors(sl::BlendFactor::ZERO, sl::BlendFactor::ONE,
+ sl::BlendFactor::SRC_COLOR, sl::BlendFactor::ONE_MINUS_SRC_COLOR);
+
+ DALI_TEST_EQUAL((state >> rs::BLEND_FACTOR_BASE_SHIFT) & rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::ZERO));
+ DALI_TEST_EQUAL((state >> (rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS)) &
+ rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::ONE));
+ DALI_TEST_EQUAL((state >> (rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 2)) &
+ rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::SRC_COLOR));
+ DALI_TEST_EQUAL((state >> (rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 3)) &
+ rs::BLEND_FACTOR_ITEM_MASK, rs::Type(sl::BlendFactor::ONE_MINUS_SRC_COLOR));
+
+ END_TEST;
+}
+
+#define HELP_TEST_RENDERER_STATE(property, resetValue, state, checkValue, renderer)\
+ renderer.SetProperty(property, ~(resetValue));\
+ rs::Apply((state), (renderer));\
+ printf("%s %s vs %s\n", #property, #state, #checkValue);\
+ DALI_TEST_EQUAL(renderer.GetProperty(property).Get<decltype(checkValue)>(), (checkValue));
+
+int UtcDaliRendererStateApply(void)
+{
+ TestApplication app;
+ auto vsh = "void main() { gl_Position = vec4(0.); }";
+ auto fsh = "void main() { gl_FragColor = vec4(1.); }";
+ Geometry geom = Geometry::New();
+ Shader shader = Shader::New(vsh, fsh);
+ Renderer renderer = Renderer::New(geom, shader);
+
+ HELP_TEST_RENDERER_STATE(Renderer::Property::DEPTH_WRITE_MODE, DepthWriteMode::OFF, rs::DEPTH_WRITE, DepthWriteMode::ON, renderer);
+ HELP_TEST_RENDERER_STATE(Renderer::Property::DEPTH_TEST_MODE, DepthTestMode::OFF, rs::DEPTH_TEST, DepthTestMode::ON, renderer);
+
+ HELP_TEST_RENDERER_STATE(Renderer::Property::BLEND_MODE, BlendMode::OFF, rs::ALPHA_BLEND, BlendMode::ON, renderer);
+
+ HELP_TEST_RENDERER_STATE(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, rs::CULL_FRONT, FaceCullingMode::FRONT, renderer);
+ HELP_TEST_RENDERER_STATE(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, rs::CULL_BACK, FaceCullingMode::BACK, renderer);
+ HELP_TEST_RENDERER_STATE(Renderer::Property::FACE_CULLING_MODE, FaceCullingMode::NONE, rs::CULL_FRONT | rs::CULL_BACK,
+ FaceCullingMode::FRONT_AND_BACK, renderer);
+
+#define DEPTH_FUNC_PAIR(x) { Comparison::x << rs::DEPTH_FUNCTION_SHIFT, DepthFunction::x }
+ const std::pair<rs::Type, DepthFunction::Type> depthFunctionPairs[] {
+ DEPTH_FUNC_PAIR(NEVER),
+ DEPTH_FUNC_PAIR(ALWAYS),
+ DEPTH_FUNC_PAIR(LESS),
+ DEPTH_FUNC_PAIR(GREATER),
+ DEPTH_FUNC_PAIR(EQUAL),
+ DEPTH_FUNC_PAIR(NOT_EQUAL),
+ DEPTH_FUNC_PAIR(LESS_EQUAL),
+ DEPTH_FUNC_PAIR(GREATER_EQUAL),
+ };
+#undef DEPTH_FUNC_PAIR
+ for (auto& p : depthFunctionPairs)
+ {
+ HELP_TEST_RENDERER_STATE(Renderer::Property::DEPTH_FUNCTION, DepthFunction::LESS, p.first, p.second, renderer);
+ }
+
+#define BLEND_FACTOR_PAIR(x) { sl::BlendFactor::x, BlendFactor::x }
+ const std::pair<rs::Type, BlendFactor::Type> BLEND_FACTORS[] {
+ BLEND_FACTOR_PAIR(ZERO),
+ BLEND_FACTOR_PAIR(ONE),
+ BLEND_FACTOR_PAIR(SRC_COLOR),
+ BLEND_FACTOR_PAIR(ONE_MINUS_SRC_COLOR),
+ BLEND_FACTOR_PAIR(SRC_ALPHA),
+ BLEND_FACTOR_PAIR(ONE_MINUS_SRC_ALPHA),
+ BLEND_FACTOR_PAIR(DST_COLOR),
+ BLEND_FACTOR_PAIR(ONE_MINUS_DST_COLOR),
+ BLEND_FACTOR_PAIR(DST_ALPHA),
+ BLEND_FACTOR_PAIR(ONE_MINUS_DST_ALPHA),
+ BLEND_FACTOR_PAIR(SRC_ALPHA_SATURATE),
+ BLEND_FACTOR_PAIR(CONSTANT_COLOR),
+ BLEND_FACTOR_PAIR(ONE_MINUS_CONSTANT_COLOR),
+ BLEND_FACTOR_PAIR(CONSTANT_ALPHA),
+ BLEND_FACTOR_PAIR(ONE_MINUS_CONSTANT_ALPHA),
+ };
+#undef BLEND_FACTOR_PAIR
+ for (auto property: {
+ Renderer::Property::BLEND_FACTOR_SRC_RGB,
+ Renderer::Property::BLEND_FACTOR_DEST_RGB,
+ Renderer::Property::BLEND_FACTOR_SRC_ALPHA,
+ Renderer::Property::BLEND_FACTOR_DEST_ALPHA,
+ })
+ {
+ const auto itemShift = rs::BLEND_FACTOR_ITEM_BITS * (property - Renderer::Property::BLEND_FACTOR_SRC_RGB);
+ const auto shift = rs::BLEND_FACTOR_BASE_SHIFT + itemShift;
+ for (auto& value: BLEND_FACTORS)
+ {
+ HELP_TEST_RENDERER_STATE(property, BlendFactor::ZERO, value.first << shift, value.second, renderer);
+ }
+ }
+
+#define RENDER_MODE_PAIR(x) { BufferMode::x << rs::BUFFER_MODE_SHIFT, RenderMode::x }
+ std::pair<rs::Type, RenderMode::Type> renderModePairs[] {
+ // same as our reset value: RENDER_MODE_PAIR(NONE),
+ RENDER_MODE_PAIR(AUTO),
+ RENDER_MODE_PAIR(COLOR),
+ RENDER_MODE_PAIR(STENCIL),
+ RENDER_MODE_PAIR(COLOR_STENCIL),
+ };
+#undef RENDER_MODE_PAIR
+ for (auto& p: renderModePairs)
+ {
+ HELP_TEST_RENDERER_STATE(Renderer::Property::RENDER_MODE, RenderMode::NONE, p.first, p.second, renderer);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliRendererStateParseEmpty(void)
+{
+ std::string error;
+ auto onError = [&](const std::string& e) { error = e; };
+
+ DALI_TEST_EQUAL(rs::Parse("", 0, onError), uint32_t(rs::NONE));
+ DALI_TEST_CHECK(error.empty());
+ END_TEST;
+}
+
+int UtcDaliRendererStateParseInvalid(void)
+{
+ std::string error;
+ auto onError = [&](const std::string& e) { error = e; };
+
+ DALI_TEST_EQUAL(rs::Parse("definitelyNotAValidRendererState", 0, onError), uint32_t(rs::NONE));
+ DALI_TEST_CHECK(strstr(error.c_str(), "Not a valid RendererState") != nullptr);
+ END_TEST;
+}
+
+namespace
+{
+struct Option
+{
+ std::string_view name;
+ rs::Type expected;
+
+ void Apply(std::ostream& stream, uint8_t shift, uint32_t& result) const
+ {
+ stream << name;
+ result |= expected << shift;
+ }
+};
+
+struct StateGenerator
+{
+ std::string_view name;
+
+ uint8_t shift;
+ std::vector<Option> permutations;
+};
+
+#define STRING_STATE_PAIR(x, y) { #x, y::x }
+const decltype(StateGenerator::permutations) BLEND_FACTORS {
+ { "", sl::BlendFactor::OMIT },
+ STRING_STATE_PAIR(ZERO, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE, sl::BlendFactor),
+ STRING_STATE_PAIR(SRC_COLOR, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE_MINUS_SRC_COLOR, sl::BlendFactor),
+ STRING_STATE_PAIR(SRC_ALPHA, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE_MINUS_SRC_ALPHA, sl::BlendFactor),
+ STRING_STATE_PAIR(DST_COLOR, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE_MINUS_DST_COLOR, sl::BlendFactor),
+ STRING_STATE_PAIR(DST_ALPHA, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE_MINUS_DST_ALPHA, sl::BlendFactor),
+ STRING_STATE_PAIR(SRC_ALPHA_SATURATE, sl::BlendFactor),
+ STRING_STATE_PAIR(CONSTANT_COLOR, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE_MINUS_CONSTANT_COLOR, sl::BlendFactor),
+ STRING_STATE_PAIR(CONSTANT_ALPHA, sl::BlendFactor),
+ STRING_STATE_PAIR(ONE_MINUS_CONSTANT_ALPHA, sl::BlendFactor),
+};
+
+const StateGenerator PERMUTATORS[] {
+ { "DEPTH_FUNC:", rs::DEPTH_FUNCTION_SHIFT, {
+ { "", Comparison::OMIT },
+ STRING_STATE_PAIR(NEVER, Comparison),
+ STRING_STATE_PAIR(ALWAYS, Comparison),
+ STRING_STATE_PAIR(LESS, Comparison),
+ STRING_STATE_PAIR(GREATER, Comparison),
+ STRING_STATE_PAIR(EQUAL, Comparison),
+ STRING_STATE_PAIR(NOT_EQUAL, Comparison),
+ STRING_STATE_PAIR(LESS_EQUAL, Comparison),
+ STRING_STATE_PAIR(GREATER_EQUAL, Comparison),
+ } },
+ { "BLEND_SRC_RGB:", rs::BLEND_FACTOR_BASE_SHIFT, BLEND_FACTORS },
+ { "BLEND_DST_RGB:", rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS, BLEND_FACTORS },
+ { "BLEND_SRC_ALPHA:", rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 2, BLEND_FACTORS },
+ { "BLEND_DST_ALPHA:", rs::BLEND_FACTOR_BASE_SHIFT + rs::BLEND_FACTOR_ITEM_BITS * 3, BLEND_FACTORS },
+ { "BUFFER_MODE:", rs::BUFFER_MODE_SHIFT, {
+ { "", BufferMode::OMIT },
+ STRING_STATE_PAIR(NONE, BufferMode),
+ STRING_STATE_PAIR(AUTO, BufferMode),
+ STRING_STATE_PAIR(COLOR, BufferMode),
+ STRING_STATE_PAIR(STENCIL, BufferMode),
+ STRING_STATE_PAIR(COLOR_STENCIL, BufferMode),
+ } },
+ // binary options
+ { "", 0, { STRING_STATE_PAIR(DEPTH_WRITE, rs) } },
+ { "", 0, { STRING_STATE_PAIR(DEPTH_TEST, rs) } },
+ { "", 0, { STRING_STATE_PAIR(CULL_FRONT, rs) } },
+ { "", 0, { STRING_STATE_PAIR(CULL_BACK, rs) } },
+ { "", 0, { STRING_STATE_PAIR(ALPHA_BLEND, rs) } },
+};
+
+#undef STRING_STATE_PAIR
+}
+
+int UtcDaliRendererStateParseIndividual(void)
+{
+ std::string error;
+ auto onError = [&](const std::string& e) { error = e; };
+
+ char buffer[512] {};
+ for (auto& p: PERMUTATORS)
+ {
+ for (auto& o: p.permutations)
+ {
+ StreamBuffer streamBuf(buffer, sizeof(buffer));
+ std::ostream stream(&streamBuf);
+
+ stream << p.name;
+
+ uint32_t expected = 0x0;
+ o.Apply(stream, p.shift, expected);
+ stream << '\0';
+
+ printf("%s -> %d\n", buffer, expected);
+ DALI_TEST_EQUAL(rs::Parse(buffer, 0, onError), expected);
+ DALI_TEST_CHECK(error.empty());
+ }
+ }
+
+ END_TEST;
+}
+
+int UtcDaliRendererStateParseCombined(void)
+{
+ constexpr uint32_t count = std::extent<decltype(PERMUTATORS)>::value;
+ constexpr uint32_t prime = 13;
+ static_assert(prime > count);
+ constexpr uint32_t skip = 3 * count * count + 7 * count + 1;
+ static_assert(skip % prime != 0);
+
+ std::string error;
+ auto onError = [&](const std::string& e) { error = e; };
+
+ std::vector<rs::Type> expectedValues;
+
+ char buffer[512] {};
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ StreamBuffer streamBuf(buffer, sizeof(buffer));
+ std::ostream stream(&streamBuf);
+
+ uint32_t expected = 0x0;
+
+ uint32_t iTmp = i;
+ for (uint32_t j = 0; j < count; ++j)
+ {
+ iTmp = (iTmp + skip) % count;
+ DALI_TEST_CHECK(iTmp < count);
+
+ if (expected)
+ {
+ stream << "|";
+ }
+
+ auto& perm = PERMUTATORS[iTmp];
+ stream << perm.name;
+ perm.permutations.back().Apply(stream, perm.shift, expected);
+ }
+
+ stream << '\0';
+
+ DALI_TEST_EQUAL(rs::Parse(buffer, 0, onError), expected);
+ DALI_TEST_CHECK(error.empty());
+
+ auto iFind = std::lower_bound(expectedValues.begin(), expectedValues.end(), expected);
+ if (iFind == expectedValues.end() || *iFind != expected)
+ {
+ expectedValues.insert(iFind, expected);
+ }
+ DALI_TEST_EQUAL(expectedValues.size(), 1u);
+ }
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/resource-bundle.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliResourceRefCounts(void)
+{
+ ResourceBundle resourceBundle;
+ resourceBundle.mEnvironmentMaps.resize(4);
+ resourceBundle.mShaders.resize(13);
+ resourceBundle.mMeshes.resize(17);
+ resourceBundle.mMaterials.resize(19);
+
+ int i = 0;
+ std::vector<int> testEnvironmentReferences(resourceBundle.mEnvironmentMaps.size());
+ for (auto& m : resourceBundle.mMaterials)
+ {
+ Index iEnv = 0;
+ iEnv += (i % 3) == 0;
+ iEnv += ((i % 4) == 0) * 2;
+ m.first.mEnvironmentIdx = iEnv;
+
+ printf("%d : %d, ", i, iEnv);
+
+ ++testEnvironmentReferences[iEnv];
+ ++i;
+ }
+
+ auto counter = resourceBundle.CreateRefCounter();
+ DALI_TEST_EQUAL(counter[ResourceType::Environment].Size(), resourceBundle.mEnvironmentMaps.size());
+ DALI_TEST_EQUAL(counter[ResourceType::Shader].Size(), resourceBundle.mShaders.size());
+ DALI_TEST_EQUAL(counter[ResourceType::Mesh].Size(), resourceBundle.mMeshes.size());
+ DALI_TEST_EQUAL(counter[ResourceType::Material].Size(), resourceBundle.mMaterials.size());
+
+ std::fill(counter[ResourceType::Material].begin(), counter[ResourceType::Material].end(), 1u);
+ resourceBundle.CountEnvironmentReferences(counter);
+ i = 0;
+ for (auto& er: counter[ResourceType::Environment])
+ {
+ DALI_TEST_EQUAL(er, testEnvironmentReferences[i]);
+ ++i;
+ }
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/scene-definition.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliSceneDefinitionAddNode(void)
+{
+ SceneDefinition sceneDef;
+
+ DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 0u);
+ auto node = new NodeDefinition();
+ node->mName = "First";
+
+ auto result = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ node });
+ DALI_TEST_EQUAL(result, node);
+ DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 1u);
+ DALI_TEST_EQUAL(sceneDef.GetNode(0), node);
+ DALI_TEST_EQUAL(sceneDef.FindNode(node->mName), node);
+
+ auto node2 = new NodeDefinition();
+ node2->mName = node->mName;
+ result = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ node2 });
+ DALI_TEST_EQUAL(result, static_cast<NodeDefinition*>(nullptr)); // failed
+ DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 1u); // still
+ DALI_TEST_EQUAL(sceneDef.GetNode(0), node); // still
+ DALI_TEST_EQUAL(sceneDef.FindNode(node->mName), node); // still
+
+ auto child = new NodeDefinition();
+ child->mName = "Second";
+ child->mParentIdx = 0;
+
+ DALI_TEST_CHECK(node->mChildren.empty()); // these are hooked up by AddNode, base on parent idx.
+
+ result = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ child });
+ DALI_TEST_EQUAL(result, child);
+ DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 2u);
+ DALI_TEST_EQUAL(sceneDef.GetNode(1), child);
+ DALI_TEST_EQUAL(sceneDef.FindNode(child->mName), child);
+
+ DALI_TEST_EQUAL(node->mChildren[0], 1u); // these are hooked up by AddNode, base on parent idx.
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionAddRootsFail(void)
+{
+ SceneDefinition sceneDef;
+
+ DALI_TEST_ASSERTION(sceneDef.AddRootNode(0), "index out of bounds");
+ DALI_TEST_CHECK(sceneDef.GetRoots().empty());
+ DALI_TEST_EQUAL(sceneDef.GetNodeCount(), 0u);
+
+ END_TEST;
+}
+
+namespace
+{
+
+struct TestContext
+{
+ SceneDefinition sceneDef;
+ NodeDefinition* root;
+ NodeDefinition* childA;
+ NodeDefinition* childB;
+
+ TestContext()
+ : sceneDef{},
+ root{ new NodeDefinition{ "Root" }},
+ childA{ new NodeDefinition{ "A" }},
+ childB{ new NodeDefinition{ "B" }}
+ {
+ childA->mParentIdx = 0;
+ childB->mParentIdx = 0;
+
+ root = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ root });
+ childA = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ childA });
+ childB = sceneDef.AddNode(std::unique_ptr<NodeDefinition>{ childB });
+ }
+};
+
+enum Event
+{
+ DEFAULT = -1,
+ START,
+ FINISH
+};
+
+struct NodeVisitor : NodeDefinition::IVisitor
+{
+ struct Visit
+ {
+ Event event;
+ NodeDefinition* node;
+
+ bool operator==(const Visit& other) const
+ {
+ return event == other.event && node == other.node;
+ }
+ };
+
+ void Start(NodeDefinition& n) override
+ {
+ visits.push_back({ START, &n });
+ }
+
+ void Finish(NodeDefinition& n) override
+ {
+ visits.push_back({ FINISH, &n });
+ }
+
+ std::vector<Visit> visits;
+};
+
+struct ConstNodeVisitor : NodeDefinition::IConstVisitor
+{
+ struct Visit
+ {
+ Event event;
+ const NodeDefinition* node;
+
+ bool operator==(const Visit& other) const
+ {
+ return event == other.event && node == other.node;
+ }
+ };
+
+ void Start(const NodeDefinition& n) override
+ {
+ visits.push_back({ START, &n });
+ }
+
+ void Finish(const NodeDefinition& n) override
+ {
+ visits.push_back({ FINISH, &n });
+ }
+
+ std::vector<Visit> visits;
+};
+
+}
+
+int UtcDaliSceneDefinitionAddRemoveRootNode(void)
+{
+ TestContext ctx;
+
+ DALI_TEST_EQUAL(ctx.sceneDef.AddRootNode(0), 0);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetRoots().size(), 1u);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetRoots()[0], 0);
+
+ ctx.sceneDef.RemoveRootNode(0);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetRoots().size(), 0);
+
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 3u);
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionVisit(void)
+{
+ TestContext ctx;
+
+ NodeVisitor visitor;
+ ctx.sceneDef.Visit(0, Customization::Choices{}, visitor);
+
+ const NodeVisitor::Visit expected[] {
+ { START, ctx.root },
+ { START, ctx.childA },
+ { FINISH, ctx.childA },
+ { START, ctx.childB },
+ { FINISH, ctx.childB },
+ { FINISH, ctx.root },
+ };
+ DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), expected));
+
+ END_TEST;
+};
+
+int UtcDaliSceneDefinitionConstVisit(void)
+{
+ TestContext ctx;
+
+ ConstNodeVisitor visitor;
+ ctx.sceneDef.Visit(0, Customization::Choices{}, visitor);
+
+ const ConstNodeVisitor::Visit expected[] {
+ { START, ctx.root },
+ { START, ctx.childA },
+ { FINISH, ctx.childA },
+ { START, ctx.childB },
+ { FINISH, ctx.childB },
+ { FINISH, ctx.root },
+ };
+ DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), expected));
+
+ END_TEST;
+};
+
+int UtcDaliSceneDefinitionVisitCustomized(void)
+{
+ TestContext ctx;
+
+ ctx.root->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "A/B" });
+
+ const NodeVisitor::Visit expected[] {
+ { START, ctx.root },
+ { START, ctx.childB },
+ { FINISH, ctx.childB },
+ { FINISH, ctx.root },
+ };
+
+ Customization::Choices choices;
+ for (auto i : { 1, 2 })
+ {
+ choices.Set("A/B", i);
+
+ NodeVisitor visitor;
+ ctx.sceneDef.Visit(0, choices, visitor);
+
+ DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), std::begin(expected)));
+ }
+
+ END_TEST;
+};
+
+int UtcDaliSceneDefinitionConstVisitCustomized(void)
+{
+ TestContext ctx;
+
+ ctx.root->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "A/B" });
+
+ const ConstNodeVisitor::Visit expected[] {
+ { START, ctx.root },
+ { START, ctx.childB },
+ { FINISH, ctx.childB },
+ { FINISH, ctx.root },
+ };
+
+ Customization::Choices choices;
+ for (auto i : { 1, 2 })
+ {
+ choices.Set("A/B", i);
+
+ ConstNodeVisitor visitor;
+ ctx.sceneDef.Visit(0, choices, visitor);
+
+ DALI_TEST_CHECK(std::equal(visitor.visits.begin(), visitor.visits.end(), std::begin(expected)));
+ }
+
+ END_TEST;
+};
+
+int UtcDaliSceneDefinitionGetCustomizationOptions(void)
+{
+ TestContext ctx;
+
+ ctx.sceneDef.AddRootNode(0); // GetCustomizationOptions requires this.
+
+ ctx.root->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "A/B" });
+ ctx.childA->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "hello" });
+ ctx.childB->mCustomization.reset(new NodeDefinition::CustomizationDefinition{ "goodbye" });
+
+ Customization::Choices choices;
+ Customization::Map options;
+ ctx.sceneDef.GetCustomizationOptions(choices, options, &choices);
+
+ DALI_TEST_EQUAL(choices.Size(), 2u);
+ DALI_TEST_EQUAL(options.Size(), 2u);
+
+ struct TestOption
+ {
+ std::string name;
+ Customization customization;
+ Customization::OptionType choice;
+ };
+
+ std::vector<TestOption> testOptions {
+ { "A/B", { 2, { "Root" } }, 0 },
+ { "hello", { 0, { "A" } }, 0 },
+ };
+ for (auto& testOption: testOptions)
+ {
+ auto iFind = choices.Get(testOption.name);
+ DALI_TEST_EQUAL(iFind, testOption.choice);
+
+ auto iFindOption = options.Get(testOption.name);
+ DALI_TEST_CHECK(iFindOption != nullptr);
+ DALI_TEST_EQUAL(iFindOption->numOptions, testOption.customization.numOptions);
+ DALI_TEST_EQUAL(iFindOption->nodes.size(), testOption.customization.nodes.size());
+ DALI_TEST_CHECK(std::equal(iFindOption->nodes.begin(), iFindOption->nodes.end(),
+ testOption.customization.nodes.begin()));
+ }
+
+ choices.Clear();
+ choices.Set("A/B", 1);
+ *options.Get("A/B") = {};
+
+ testOptions[0].choice = 1;
+ testOptions[1].name = "goodbye";
+ testOptions[1].customization.nodes[0] = "B";
+
+ ctx.sceneDef.GetCustomizationOptions(choices, options, &choices);
+
+ DALI_TEST_EQUAL(choices.Size(), 2u);
+ DALI_TEST_EQUAL(options.Size(), 3u);
+
+ for (auto& testOption: testOptions)
+ {
+ auto iFind = choices.Get(testOption.name);
+ DALI_TEST_EQUAL(iFind, testOption.choice);
+
+ auto iFindOption = options.Get(testOption.name);
+ DALI_TEST_CHECK(iFindOption != nullptr);
+ DALI_TEST_EQUAL(iFindOption->numOptions, testOption.customization.numOptions);
+ DALI_TEST_EQUAL(iFindOption->nodes.size(), testOption.customization.nodes.size());
+ DALI_TEST_CHECK(std::equal(iFindOption->nodes.begin(), iFindOption->nodes.end(),
+ testOption.customization.nodes.begin()));
+ }
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionFindNode(void)
+{
+ TestContext ctx;
+
+ Index result = INVALID_INDEX;
+ for (auto n: { ctx.root, ctx.childA, ctx.childB })
+ {
+ ctx.sceneDef.FindNode(n->mName, &result);
+ DALI_TEST_CHECK(result != INVALID_INDEX);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNode(result), n);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionConstFindNode(void)
+{
+ TestContext ctx;
+
+ Index result = INVALID_INDEX;
+ for (auto n: { ctx.root, ctx.childA, ctx.childB })
+ {
+ const_cast<const TestContext&>(ctx).sceneDef.FindNode(n->mName, &result);
+ DALI_TEST_CHECK(result != INVALID_INDEX);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNode(result), n);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionFindNodeIndex(void)
+{
+ TestContext ctx;
+
+ Index result = INVALID_INDEX;
+ for (auto n: { ctx.root, ctx.childA, ctx.childB })
+ {
+ result = ctx.sceneDef.FindNodeIndex(*n);
+ DALI_TEST_CHECK(result != INVALID_INDEX);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNode(result), n);
+ }
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionFindNodes(void)
+{
+ TestContext ctx;
+
+ std::vector<NodeDefinition*> nodes;
+ auto nodeConsumer = [&nodes](NodeDefinition& nd) {
+ nodes.push_back(&nd);
+ };
+
+ auto nodePredicate = [](const NodeDefinition& nd) {
+ return nd.mName.length() == 1;
+ };
+
+ ctx.sceneDef.FindNodes(nodePredicate, nodeConsumer, 1);
+ DALI_TEST_EQUAL(nodes.size(), 1);
+ DALI_TEST_EQUAL(nodes[0]->mName, "A");
+ DALI_TEST_EQUAL(nodes[0], ctx.childA);
+
+ nodes.clear();
+ ctx.sceneDef.FindNodes(nodePredicate, nodeConsumer);
+
+ DALI_TEST_EQUAL(nodes.size(), 2);
+ DALI_TEST_EQUAL(nodes[0]->mName, "A");
+ DALI_TEST_EQUAL(nodes[0], ctx.childA);
+ DALI_TEST_EQUAL(nodes[1]->mName, "B");
+ DALI_TEST_EQUAL(nodes[1], ctx.childB);
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionRemoveNode(void)
+{
+ TestContext ctx;
+ DALI_TEST_EQUAL(ctx.sceneDef.RemoveNode("doesn't exist"), false);
+
+ // pre-removing A
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 3u);
+ DALI_TEST_EQUAL(ctx.root->mChildren.size(), 2u);
+
+ Index result;
+ DALI_TEST_EQUAL(ctx.sceneDef.FindNode("B", &result), ctx.childB);
+ DALI_TEST_EQUAL(result, 2);
+
+ DALI_TEST_EQUAL(ctx.sceneDef.RemoveNode("A"), true);
+
+ // post-removing A
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 2u);
+
+ result = 12345;
+ DALI_TEST_EQUAL(ctx.sceneDef.FindNode("A", &result), static_cast<NodeDefinition*>(nullptr));
+ DALI_TEST_EQUAL(result, 12345); // doesn't change
+
+ DALI_TEST_EQUAL(ctx.sceneDef.FindNode("B", &result), ctx.childB);
+ DALI_TEST_EQUAL(result, 1); // dropped
+
+ DALI_TEST_EQUAL(ctx.root->mChildren.size(), 1u);
+ DALI_TEST_EQUAL(ctx.root->mChildren[0], 1u);
+
+ // removing root
+ DALI_TEST_EQUAL(ctx.sceneDef.RemoveNode("Root"), true);
+ DALI_TEST_EQUAL(ctx.sceneDef.GetNodeCount(), 0);
+
+ END_TEST;
+}
+
+int UtcDaliSceneDefinitionReparentNode(void)
+{
+ TestContext ctx;
+
+ ctx.sceneDef.ReparentNode("B", "A", 0);
+
+ DALI_TEST_EQUAL(ctx.childB->mParentIdx, ctx.sceneDef.FindNodeIndex(*ctx.childA));
+ DALI_TEST_EQUAL(ctx.childA->mChildren.size(), 1u);
+ DALI_TEST_EQUAL(ctx.childA->mChildren[0], ctx.sceneDef.FindNodeIndex(*ctx.childB));
+
+ END_TEST;
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/shader-definition.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+int UtcDaliShaderDefinitionFailedToLoad(void)
+{
+ ShaderDefinition shaderDef;
+ shaderDef.mVertexShaderPath = "nonexistent.vsh";
+ shaderDef.mFragmentShaderPath = "nonexistent.vsh";
+
+ DALI_TEST_ASSERTION(shaderDef.LoadRaw(""), "Failed to load shader source");
+
+ shaderDef.mVertexShaderPath = "dli_pbr.vsh";
+
+ auto shaderPath = TEST_RESOURCE_DIR "/";
+ DALI_TEST_ASSERTION(shaderDef.LoadRaw(shaderPath), "Failed to load shader source");
+
+ shaderDef.mFragmentShaderPath = "dli_pbr.fsh";
+
+ shaderDef.mHints.push_back("MODIFIES_GEOMETRY");
+ shaderDef.mHints.push_back("OUTPUT_IS_TRANSPARENT");
+ auto raw = shaderDef.LoadRaw(shaderPath);
+
+ TestApplication app;
+ auto shader = shaderDef.Load(std::move(raw));
+ DALI_TEST_CHECK(shader);
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/gltf2-loader.h"
+#include "dali-scene-loader/public-api/shader-definition-factory.h"
+#include "dali-scene-loader/public-api/node-definition.h"
+#include "dali-scene-loader/public-api/resource-bundle.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+#include <set>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+
+bool EndsWith(const std::string& str, const std::string& suffix) // ends_width() is C++20
+{
+ return str.size() >= suffix.size() && str.substr(str.size() - suffix.size()).compare(suffix) == 0;
+}
+
+MaterialDefinition& NewMaterialDefinition(ResourceBundle& resources)
+{
+ resources.mMaterials.push_back({});
+ return resources.mMaterials.back().first;
+}
+
+MeshDefinition& NewMeshDefinition(ResourceBundle& resources)
+{
+ resources.mMeshes.push_back({});
+ return resources.mMeshes.back().first;
+}
+
+void ClearMeshesAndMaterials(ResourceBundle& resources)
+{
+ resources.mMaterials.clear();
+ resources.mMeshes.clear();
+}
+
+struct Context
+{
+ ResourceBundle resources;
+ ShaderDefinitionFactory factory;
+
+ Context()
+ {
+ factory.SetResources(resources);
+ }
+};
+
+struct ShaderParameters
+{
+ MeshDefinition& meshDef;
+ MaterialDefinition& materialDef;
+ NodeDefinition& nodeDef;
+};
+
+struct Permutation
+{
+ using ConfigureFn = void(*)(ShaderParameters&);
+
+ ConfigureFn configureFn;
+
+ std::set<std::string> defines;
+ RendererState::Type rendererStateSet = 0;
+ RendererState::Type rendererStateClear = 0;
+};
+
+struct PermutationSet
+{
+ std::vector<const Permutation*> permutations;
+ Index shaderIdx;
+};
+
+}
+
+int UtcDaliShaderDefinitionFactoryProduceShaderInvalid(void)
+{
+ Context ctx;
+
+ NodeDefinition nodeDef;
+ nodeDef.mRenderable.reset(new NodeDefinition::Renderable());
+
+ DALI_TEST_EQUAL(INVALID_INDEX, ctx.factory.ProduceShader(nodeDef));
+ DALI_TEST_CHECK(ctx.resources.mShaders.empty());
+
+ END_TEST;
+}
+
+int UtcDaliShaderDefinitionFactoryProduceShader(void)
+{
+ Context ctx;
+ ctx.resources.mMaterials.push_back({});
+ ctx.resources.mMeshes.push_back({});
+
+ Permutation permutations[]{
+ {
+ [](ShaderParameters& p) {},
+ {},
+ RendererState::DEPTH_TEST | RendererState::DEPTH_WRITE | RendererState::CULL_BACK,
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.mFlags |= MaterialDefinition::TRANSPARENCY;
+ },
+ { "THREE_TEX" },
+ RendererState::ALPHA_BLEND,
+ RendererState::DEPTH_WRITE,
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.mTextureStages.push_back({ MaterialDefinition::ALBEDO, {} });
+ },
+ { "THREE_TEX" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.mTextureStages.push_back({ MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS, {} });
+ },
+ { "THREE_TEX" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.mTextureStages.push_back({ MaterialDefinition::NORMAL, {} });
+ },
+ { "THREE_TEX" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.mFlags |= MaterialDefinition::SUBSURFACE;
+ },
+ { "SSS" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.SetAlphaCutoff(.5f);
+ },
+ { "ALPHA_TEST" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.SetAlphaCutoff(1.f);
+ },
+ { "ALPHA_TEST" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.materialDef.mFlags |= MaterialDefinition::GLTF_CHANNELS;
+ },
+ { "GLTF_CHANNELS" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.meshDef.mJoints0.mBlob.mOffset = 0;
+ p.meshDef.mWeights0.mBlob.mOffset = 0;
+ },
+ { "SKINNING" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.meshDef.mFlags |= MeshDefinition::FLIP_UVS_VERTICAL;
+ },
+ { "FLIP_V" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.meshDef.mBlendShapes.push_back({});
+ },
+ },
+ {
+ [](ShaderParameters& p) {
+ p.meshDef.mBlendShapes.back().deltas.mBlob.mOffset = 0;
+ },
+ { "MORPH_POSITION", "MORPH" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.meshDef.mBlendShapes.back().normals.mBlob.mOffset = 0;
+ },
+ { "MORPH_NORMAL", "MORPH" }
+ },
+ {
+ [](ShaderParameters& p) {
+ p.meshDef.mBlendShapes.back().tangents.mBlob.mOffset = 0;
+ },
+ { "MORPH_TANGENT", "MORPH" }
+ },
+ {
+ [](ShaderParameters& p) {
+ auto& blendShapes = p.meshDef.mBlendShapes;
+ DALI_ASSERT_ALWAYS(!blendShapes.empty() &&
+ (blendShapes.back().deltas.mBlob.mOffset != MeshDefinition::INVALID ||
+ blendShapes.back().normals.mBlob.mOffset != MeshDefinition::INVALID ||
+ blendShapes.back().tangents.mBlob.mOffset != MeshDefinition::INVALID));
+ p.meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
+ },
+ { "MORPH_VERSION_2_0" }
+ },
+ };
+
+ PermutationSet permSets[] {
+ // default
+ { { &permutations[0] }, 0 },
+
+ // alpha
+ { { &permutations[0], &permutations[1] }, 1 },
+
+ // three-texture setups
+ { { &permutations[0], &permutations[2] }, 2 },
+ { { &permutations[0], &permutations[3] }, 2 },
+ { { &permutations[0], &permutations[4] }, 2 },
+ { { &permutations[0], &permutations[2], &permutations[3] }, 2 },
+ { { &permutations[0], &permutations[3], &permutations[4] }, 2 },
+ { { &permutations[0], &permutations[4], &permutations[2] }, 2 },
+ { { &permutations[0], &permutations[2], &permutations[3], &permutations[4] }, 2 },
+
+ // subsurface scattering
+ { { &permutations[0], &permutations[5] }, 3 },
+
+ // alpha test
+ { { &permutations[0], &permutations[6] }, 4 },
+ { { &permutations[0], &permutations[7] }, 4 },
+
+ // glTF channels
+ { { &permutations[0], &permutations[8] }, 5 },
+
+ // skinning
+ { { &permutations[0], &permutations[9] }, 6 },
+
+ // flip uvs
+ { { &permutations[0], &permutations[10] }, 7 },
+
+ // morphing
+ { { &permutations[0], &permutations[11], &permutations[12] }, 8 },
+ { { &permutations[0], &permutations[11], &permutations[13] }, 9 },
+ { { &permutations[0], &permutations[11], &permutations[14] }, 10 },
+ { { &permutations[0], &permutations[11], &permutations[12], &permutations[13] }, 11 },
+ { { &permutations[0], &permutations[11], &permutations[13], &permutations[14] }, 12 },
+ { { &permutations[0], &permutations[11], &permutations[14], &permutations[12] }, 13 },
+ { { &permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14] }, 14 },
+
+ { { &permutations[0], &permutations[11], &permutations[12], &permutations[15] }, 15 },
+ { { &permutations[0], &permutations[11], &permutations[13], &permutations[15] }, 16 },
+ { { &permutations[0], &permutations[11], &permutations[14], &permutations[15] }, 17 },
+ { { &permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[15] }, 18 },
+ { { &permutations[0], &permutations[11], &permutations[13], &permutations[14], &permutations[15] }, 19 },
+ { { &permutations[0], &permutations[11], &permutations[14], &permutations[12], &permutations[15] }, 20 },
+ { { &permutations[0], &permutations[11], &permutations[12], &permutations[13], &permutations[14], &permutations[15] }, 21 },
+
+ // etc.
+ { { &permutations[0], &permutations[1], &permutations[2] }, 1 },
+ { { &permutations[0], &permutations[1], &permutations[3] }, 1 },
+ { { &permutations[0], &permutations[1], &permutations[2], &permutations[3] }, 1 },
+ };
+ for(auto& ps: permSets)
+ {
+ printf("%ld\n", &ps - permSets);
+
+ auto modelNode = new ModelNode();
+ modelNode->mMeshIdx = 0;
+ modelNode->mMaterialIdx = 0;
+
+ NodeDefinition nodeDef;
+ nodeDef.mRenderable.reset(modelNode);
+
+ auto& meshDef = NewMeshDefinition(ctx.resources);
+ auto& materialDef = NewMaterialDefinition(ctx.resources);
+ ShaderParameters sp{ meshDef, materialDef, nodeDef };
+
+ std::set<std::string> defines;
+ RendererState::Type rendererState = 0;
+ for (auto p : ps.permutations)
+ {
+ p->configureFn(sp);
+ defines.insert(p->defines.begin(), p->defines.end());
+ rendererState = (rendererState | p->rendererStateSet) & ~p->rendererStateClear;
+ }
+
+ auto shaderIdx = ctx.factory.ProduceShader(nodeDef);
+ DALI_TEST_EQUAL(ps.shaderIdx, shaderIdx);
+
+ auto& shaderDef = ctx.resources.mShaders[shaderIdx].first;
+ DALI_TEST_CHECK(EndsWith(shaderDef.mVertexShaderPath, ".vsh"));
+ DALI_TEST_CHECK(EndsWith(shaderDef.mFragmentShaderPath, ".fsh"));
+ DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState);
+
+ uint32_t definesUnmatched = shaderDef.mDefines.size();
+ for (auto& d: shaderDef.mDefines)
+ {
+ auto iFind = defines.find(d);
+ if (iFind != defines.end())
+ {
+ defines.erase(iFind);
+ --definesUnmatched;
+ }
+ else
+ {
+ printf("mismatched: %s\n", d.c_str());
+ break;
+ }
+ }
+
+ DALI_TEST_CHECK(defines.empty());
+ DALI_TEST_EQUAL(0, definesUnmatched);
+
+ printf("defines OK\n");
+
+ auto uMaxLOD = shaderDef.mUniforms["uMaxLOD"];
+ DALI_TEST_EQUAL(uMaxLOD.GetType(), Property::FLOAT);
+
+ auto uCubeMatrix = shaderDef.mUniforms["uCubeMatrix"];
+ DALI_TEST_EQUAL(uCubeMatrix.GetType(), Property::MATRIX);
+
+ ClearMeshesAndMaterials(ctx.resources);
+ }
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/string-callback.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+
+char sBuffer[64];
+
+void TestLogFunction(Integration::Log::DebugPriority level, std::string& str)
+{
+ snprintf(sBuffer, sizeof(sBuffer), "%d: %s", level, str.c_str());
+}
+
+}
+
+int UtcDaliUtilsDefaultStringCallback(void)
+{
+ InstallLogFunction(TestLogFunction);
+ DefaultErrorCallback("Hello world!");
+ DALI_TEST_EQUAL(std::string(sBuffer), "2: DefaultErrorCallback Hello world!");
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/utils.h"
+#include <dali-test-suite-utils.h>
+#include <string_view>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+constexpr std::string_view TEST_STRING = "The quick brown fox jumped over a lazy dog.1337true";
+}
+
+template <size_t N>
+void HelpTestStreamBuffer()
+{
+ char buffer[N];
+ StreamBuffer streamBuffer(buffer, N); // note we aren't leaving space for a terminating 0 as we're using strNcmp.
+ std::ostream stream(&streamBuffer);
+
+ stream << "The quick brown fox jumped over a lazy dog.";
+ stream << 1337;
+ stream << std::boolalpha << true;
+
+ const size_t checkLen = std::min(N, TEST_STRING.size());
+ DALI_TEST_EQUAL(0, strncmp(buffer, TEST_STRING.data(), checkLen));
+}
+
+int UtcDaliUtilsStreamBuffer(void)
+{
+ HelpTestStreamBuffer<16>();
+ HelpTestStreamBuffer<32>();
+ HelpTestStreamBuffer<64>();
+ END_TEST;
+}
+
+int UtcDaliUtilsFormatString(void)
+{
+ DALI_TEST_EQUAL(FormatString("%s", "hello"), "hello");
+ DALI_TEST_EQUAL(FormatString("%d", 1667), "1667");
+
+ DALI_TEST_EQUAL(FormatString("%s %d", "hello", 2778), "hello 2778");
+ DALI_TEST_EQUAL(FormatString("%d %s", 3889, "hello"), "3889 hello");
+
+ END_TEST;
+}
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// Enable debug log for test coverage
+#define DEBUG_ENABLED 1
+
+#include "dali-scene-loader/public-api/view-projection.h"
+#include <dali-test-suite-utils.h>
+
+using namespace Dali;
+using namespace Dali::SceneLoader;
+
+namespace
+{
+void SetPerspectiveProjection(Matrix& m)
+{
+ auto data = m.AsFloat();
+ float near = 1.f;
+ float far = 10.f;
+ float right = 1.f;
+ float left = -right;
+ float top = .75f;
+ float bottom = -top;
+ data[0] = 2.f * near / (right - left);
+ data[5] = 2.f * near / (top - bottom);
+ data[8] = (right + left) / (right - left);
+ data[9] = (top + bottom) / (top - bottom);
+ data[10] = (far + near) / (far - near);
+ data[11] = -1.f;
+ data[14] = 2 * far * near / (far - near);
+}
+
+}
+
+int UtcDaliViewProjection(void)
+{
+ ViewProjection vp;
+ Matrix viewMatrix;
+ viewMatrix.SetTransformComponents( Vector3::ONE,
+ Quaternion(Radian(Degree(90.f)), Vector3::YAXIS),
+ Vector3::XAXIS * 200.f);
+ vp.GetView() = viewMatrix;
+
+ Matrix projectionMatrix;
+ SetPerspectiveProjection(projectionMatrix);
+ vp.GetProjection() = projectionMatrix;
+
+ vp.Update();
+
+ [&](const ViewProjection& vp) {
+ DALI_TEST_EQUAL(vp.GetView(), viewMatrix);
+ DALI_TEST_EQUAL(vp.GetProjection(), projectionMatrix);
+ }(vp);
+
+ Matrix expectedViewProjection{ false };
+ Matrix::Multiply(expectedViewProjection, viewMatrix, projectionMatrix);
+ auto viewProjectionResult = vp.GetViewProjection();
+ DALI_TEST_EQUAL(viewProjectionResult, expectedViewProjection);
+
+ Matrix expectedInverseProjection{ projectionMatrix };
+ expectedInverseProjection.Invert();
+ auto inverseProjectionResult = vp.GetInverseProjection();
+ DALI_TEST_EQUAL(inverseProjectionResult, expectedInverseProjection);
+
+ END_TEST;
+}
+
+int UtcDaliViewProjectionUpdateFail(void)
+{
+ ViewProjection vp;
+ DALI_TEST_ASSERTION(vp.Update(), "Failed to find inverse");
+
+ END_TEST;
+}
OPTION(INSTALL_DOXYGEN_DOC "Install doxygen doc" ON)
OPTION(CONFIGURE_AUTOMATED_TESTS "Configure automated tests" ON)
OPTION(USE_DEFAULT_RESOURCE_DIR "Whether to use the default resource folders. Otherwise set environment variables for DALI_IMAGE_DIR, DALI_SOUND_DIR, DALI_STYLE_DIR, DALI_STYLE_IMAGE_DIR and DALI_DATA_READ_ONLY_DIR" ON)
+OPTION(BUILD_SCENE_LOADER "Whether to build dali-scene-loader." ON)
IF( ENABLE_PKG_CONFIGURE )
FIND_PACKAGE( PkgConfig REQUIRED )
ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}rename_cov_data ./rename-cov-data )
ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}cov_data ${LCOV_BIN} ${LCOV_OPTS} --base-directory . --directory . -c -o dali.info
- COMMAND ${LCOV_BIN} ${LCOV_OPTS} --remove dali.info \"*/dali-env/*\" \"/usr/include/*\" "*/dali-env/*" "*solid-color-actor*" "*/dali-toolkit/third-party/*" -o dali.info )
+ COMMAND ${LCOV_BIN} ${LCOV_OPTS} --remove dali.info \"*/dali-env/*\" \"/usr/include/*\" "*/dali-env/*" "*solid-color-actor*" "*/dali-toolkit/third-party/*" \"*/dali-scene-loader/third-party/*\" -o dali.info )
ADD_CUSTOM_TARGET( ${DALI_TOOLKIT_PREFIX}coverage genhtml ${LCOV_OPTS} -o ${COVERAGE_OUTPUT_DIR} dali.info
DEPENDS cov_data )
${ROOT_SRC_DIR}/automated-tests/CMakeLists.txt @ONLY )
ENDIF()
+IF ( BUILD_SCENE_LOADER )
+ ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/dali-scene-loader )
+ENDIF()
+
# Configuration Messages
MESSAGE( STATUS "Configuration:\n" )
MESSAGE( STATUS "Prefix: " ${PREFIX} )
MESSAGE( STATUS "Vector Based Text Rendering: " ${ENABLE_VECTOR_BASED_TEXT_RENDERING} )
MESSAGE( STATUS "Enable link test: " ${ENABLE_LINK_TEST} )
MESSAGE( STATUS "Configure automated tests: " ${CONFIGURE_AUTOMATED_TESTS} )
+MESSAGE( STATUS "Build Dali Scene Loader: " ${BUILD_SCENE_LOADER} )
MESSAGE( STATUS "CXXFLAGS: " ${CMAKE_CXX_FLAGS} )
MESSAGE( STATUS "LDFLAGS: " ${CMAKE_SHARED_LINKER_FLAGS_INIT}${CMAKE_SHARED_LINKER_FLAGS} )
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+set(name "dali2-scene-loader")
+
+project(${name} CXX)
+
+set(${name}_VERSION_MAJOR 2)
+set(${name}_VERSION_MINOR 0)
+set(${name}_VERSION_PATCH 0)
+set(${name}_VERSION ${${name}_VERSION_MAJOR}.${${name}_VERSION_MINOR}.${${name}_VERSION_PATCH} )
+
+SET(DALI_SCENE_LOADER_VERSION ${${name}_VERSION} )
+
+if(CMAKE_BUILD_TYPE MATCHES Debug)
+ add_definitions("-DDEBUG_ENABLED")
+endif()
+
+foreach(flag ${PKGS_CFLAGS})
+ set(extra_flags "${extra_flags} ${flag}")
+endforeach(flag)
+
+set(prj_cxx_std c++17)
+if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ set(extra_flags "${extra_flags} -fPIC -std=${prj_cxx_std}")
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ set(extra_flags "${extra_flags} -fPIC -std=${prj_cxx_std}")
+elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+ set(extra_flags "${extra_flags} /std:${prj_cxx_std} /vmg /D_USE_MATH_DEFINES /D_CRT_SECURE_NO_WARNINGS /MP /GS /Oi /GL /EHsc")
+endif()
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${extra_flags}")
+
+set(prefix ${CMAKE_INSTALL_PREFIX})
+
+set(repo_root_dir "${CMAKE_CURRENT_LIST_DIR}/../../../")
+set(scene_loader_dir "${repo_root_dir}/dali-scene-loader")
+
+option(ENABLE_PKG_CONFIGURE "Use pkgconfig" ON)
+option(ENABLE_COVERAGE "Coverage" OFF)
+
+IF( ENABLE_COVERAGE OR "$ENV{CXXFLAGS}" MATCHES --coverage )
+ ADD_COMPILE_OPTIONS( --coverage )
+ SET(ENABLE_COVERAGE ON)
+ SET(COVERAGE --coverage)
+ENDIF()
+
+if (ENABLE_PKG_CONFIGURE)
+ find_package(PkgConfig REQUIRED)
+
+ pkg_check_modules(DALICORE REQUIRED dali2-core)
+ pkg_check_modules(DALIADAPTOR REQUIRED dali2-adaptor)
+
+ # Configure the pkg-config file
+ # Requires the following variables to be setup:
+ # @PREFIX@ @EXEC_PREFIX@ @DALI_VERSION@ @LIB_DIR@ @DEV_INCLUDE_PATH@
+ set( LIB_DIR $ENV{libdir} )
+ if( NOT LIB_DIR )
+ set( LIB_DIR ${CMAKE_INSTALL_LIBDIR} )
+ endif()
+ if( NOT LIB_DIR )
+ set( LIB_DIR ${prefix}/lib )
+ endif()
+
+ set(PREFIX ${prefix})
+ set(EXEC_PREFIX ${CMAKE_INSTALL_PREFIX})
+ set(DEV_INCLUDE_PATH ${repo_root_dir})
+
+ set(core_pkg_cfg_file dali2-scene-loader.pc)
+ configure_file(${CMAKE_CURRENT_LIST_DIR}/${core_pkg_cfg_file}.in ${core_pkg_cfg_file} @ONLY)
+endif()
+
+if (ENABLE_COVERAGE)
+ find_program(lcov_bin "lcov")
+ if (${lcov_bin})
+ set(cov_dir ".cov")
+ set(cov_output_dir "doc/coverage")
+
+ execute_process(COMMAND bash -c "${lcov_bin} --version | cut -d' ' -f4" OUTPUT_VARIABLE lcov_version)
+ string(REPLACE "." ";" lcov_vlist ${lcov_version})
+ if (NOT $<VERSION_LESS:${lcov_version},"1.10"> )
+ set(lcov_opts --rc lcov_branch_coverage=1)
+ endif()
+
+ add_custom_target(${prefix}rename_cov_data ./rename-cov-data)
+
+ add_custom_target(${prefix}cov_data
+ ${lcov_bin} ${lcov_opts} --base-directory . --directory . -c -o dali.info
+ COMMAND ${lcov_bin} ${lcov_opts} --remove dali.info \"*/dali-env/*\" \"/usr/include/*\" \"/usr/local/include/*\" \"*/dali-env/*\" \"*/dali-scene-loader/third-party/*\" -o dali.info
+ )
+
+ add_custom_target(${prefix}coverage genhtml ${lcov_opts} -o ${cov_output_dir} dali.info)
+
+ add_custom_target(${prefix}reset_coverage @${lcov_bin} -\ --direwctory `pwd`)
+
+ add_custom_target(${prefix}distclean @echo cleaning for source distribution)
+ add_custom_command(
+ DEPENDS ${prefix}clean
+ COMMENT "distribution clean"
+ COMMAND find
+ ARGS .
+ -not -name config.cmake -and \(
+ -name tester.c -or
+ -name Testing -or
+ -name CMakeFiles -or
+ -name doc -or
+ -name cmake.depends -or
+ -name cmake.check_depends -or
+ -name CMakeCache.txt -or
+ -name cmake.check_cache -or
+ -name *.cmake -or
+ -name Makefile -or
+ -name core -or
+ -name core.* -or
+ -name gmon.out -or
+ -name install_manifest.txt -or
+ -name *.pc -or
+ -name *.gcov -or
+ -name *.gcno -or
+ -name *.gcda -or
+ -name *~ -or
+ -name libdali*.so* \)
+ | grep -v TC | xargs rm -rf
+ TARGET ${DALI_TOOLKIT_PREFIX}distclean
+ VERBATIM
+ )
+ endif()
+endif()
+
+set(scene_loader_src_files "")
+include("${scene_loader_dir}/internal/file.list")
+include("${scene_loader_dir}/public-api/file.list")
+
+set(prefix_include_dir "${prefix}/include")
+include_directories(${repo_root_dir}
+ ${prefix_include_dir}
+)
+
+add_library(${name} SHARED ${scene_loader_src_files})
+
+target_link_libraries(${name} ${DALICORE_LDFLAGS} ${DALIADAPTOR_LDFLAGS}
+ dali2-toolkit
+ ${COVERAGE})
+
+if( ANDROID )
+ target_link_libraries(${name} log)
+endif()
+
+install(TARGETS ${name} DESTINATION ${prefix}/lib)
+
+file(GLOB scene_loader_include_files ${scene_loader_public_api_dir})
+install(DIRECTORY ${scene_loader_include_files}
+ DESTINATION "${prefix_include_dir}/dali-scene-loader"
+ FILES_MATCHING PATTERN "*.h"
+)
+
+if (ENABLE_PKG_CONFIGURE)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${core_pkg_cfg_file}
+ DESTINATION ${LIB_DIR}/pkgconfig
+ )
+endif()
--- /dev/null
+#!/bin/bash
+
+git clean -xdf .
+cmake -DCMAKE_INSTALL_PREFIX=$DESKTOP_PREFIX .
+make install -j16
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+apiversion=@DALI_SCENE_LOADER_VERSION@
+libdir=@LIB_DIR@
+includedir=@DEV_INCLUDE_PATH@
+
+Name: Dali 3D Engine Scene Loader
+Description: Dali Scene Loader library
+Version: ${apiversion}
+Requires: dali2-toolkit
+Libs: -L${libdir} -ldali2-scene-loader
+Cflags: -I${includedir}
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_" />
+ </request>
+</manifest>
--- /dev/null
+<manifest>
+ <assign>
+ <filesystem path="/usr/lib/*" label="_" />
+ </assign>
+ <request>
+ <domain name="dali"/>
+ </request>
+</manifest>
--- /dev/null
+# dali-sceen-loader
+
+Provides functionality for loading scenes created in the JSON-based DLI format. DLI is most similar to glTF, but less verbose / granular, and it has a few extra features:
+
+- customizations: switch between alternative definitions of parts of the scene;
+- environment maps;
+- text, arc, and image elements;
+- etc. (TODO)
+
+Please refer to [dli-exporter](http://github.com/dalihub/dli-exporter) for converting 3D models to DLI.
+
+## Prequisites
+
+- Windows:
+
+ - Microsoft Visual Studio 2017 (or later, with 2017 build tools);
+ - [windows-dependencies](https://github.com/dalihub/windows-dependencies ) - please follow the steps in its README.md *as well as* its vcpkg-script/ReadMe.md, to install VCPKG and all dependencies;
+
+- Linux:
+
+ - GCC v9.3+;
+ - CMake v3.14+;
+ - [dali-core](https://github.com/dalihub/dali-core );
+ - [dali-adaptor](https://github.com/dalihub/dali-adaptor );
+ - [dali-toolkit](https://github.com/dalihub/dali-toolkit );
+ - configure DALi environment by following the instructions in README.md, in dali-core;
+
+## Build instructions
+
+1, build the DALi libraries;
+
+2,
+
+ - Windows: refer to the VS2017 solution in the windows-dependencies repository;
+ - Linux: run the ../build/tizen/dali-scene-loader/build.sh;
+ - Tizen:
+
+ $ gbs build -A ${target_arch}
+
+ - for debug, add: --define "%enable_debug 1"
+ - for SMACK-enabled targets, add: --define "%enable_dali_smack_rules 1"
--- /dev/null
+set(scene_loader_internal_dir "${scene_loader_dir}/internal")
+
+set(scene_loader_src_files ${scene_loader_src_files}
+ ${scene_loader_internal_dir}/gltf2-asset.cpp
+ ${scene_loader_internal_dir}/hash.cpp
+ ${scene_loader_internal_dir}/json-reader.cpp
+ ${scene_loader_internal_dir}/json-util.cpp
+)
--- /dev/null
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+#include "dali-scene-loader/internal/gltf2-asset.h"
+#include "dali/public-api/math/matrix.h"
+#include <algorithm>
+#include <map>
+
+#define ENUM_STRING_MAPPING(t, x) { #x, t::x }
+
+using namespace Dali;
+
+namespace gltf2
+{
+namespace
+{
+
+constexpr uint32_t ACCESSOR_TYPE_ELEMENT_COUNT[]{
+ 1,
+ 2,
+ 3,
+ 4,
+ 4,
+ 9,
+ 16,
+ static_cast<uint32_t>(-1)
+};
+
+const std::map<std::string_view, AccessorType::Type> ACCESSOR_TYPES{
+ ENUM_STRING_MAPPING(AccessorType, SCALAR),
+ ENUM_STRING_MAPPING(AccessorType, VEC2),
+ ENUM_STRING_MAPPING(AccessorType, VEC3),
+ ENUM_STRING_MAPPING(AccessorType, VEC4),
+ ENUM_STRING_MAPPING(AccessorType, MAT2),
+ ENUM_STRING_MAPPING(AccessorType, MAT3),
+ ENUM_STRING_MAPPING(AccessorType, MAT4),
+};
+
+const std::map<std::string_view, AlphaMode::Type> ALPHA_MODE_TYPES{
+ ENUM_STRING_MAPPING(AlphaMode::Type, OPAQUE),
+ ENUM_STRING_MAPPING(AlphaMode::Type, MASK),
+ ENUM_STRING_MAPPING(AlphaMode::Type, BLEND),
+};
+
+const std::map<std::string_view, Attribute::Type> ATTRIBUTE_TYPES{
+ ENUM_STRING_MAPPING(Attribute::Type, POSITION),
+ ENUM_STRING_MAPPING(Attribute::Type, NORMAL),
+ ENUM_STRING_MAPPING(Attribute::Type, TANGENT),
+ ENUM_STRING_MAPPING(Attribute::Type, TEXCOORD_0),
+ ENUM_STRING_MAPPING(Attribute::Type, TEXCOORD_1),
+ ENUM_STRING_MAPPING(Attribute::Type, COLOR_0),
+ ENUM_STRING_MAPPING(Attribute::Type, JOINTS_0),
+ ENUM_STRING_MAPPING(Attribute::Type, WEIGHTS_0),
+};
+
+const std::map<std::string_view, Animation::Sampler::Interpolation::Type> ANIMATION_SAMPLER_INTERPOLATION{
+ ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, STEP),
+ ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, LINEAR),
+ ENUM_STRING_MAPPING(Animation::Sampler::Interpolation::Type, CUBICSPLINE),
+};
+
+const std::map<std::string_view, Animation::Channel::Target::Type> ANIMATION_CHANNEL_TARGET_PATH_TYPES{
+ ENUM_STRING_MAPPING(Animation::Channel::Target::Type, TRANSLATION),
+ ENUM_STRING_MAPPING(Animation::Channel::Target::Type, ROTATION),
+ ENUM_STRING_MAPPING(Animation::Channel::Target::Type, SCALE),
+ ENUM_STRING_MAPPING(Animation::Channel::Target::Type, WEIGHTS),
+};
+
+}
+
+bool Component::IsUnsigned(Type t)
+{
+ return t == UNSIGNED_BYTE || t == UNSIGNED_SHORT || t == UNSIGNED_INT;
+}
+
+uint32_t Component::Size(Type t)
+{
+ switch (t)
+ {
+ case BYTE:
+ case UNSIGNED_BYTE:
+ return 1;
+ case SHORT:
+ case UNSIGNED_SHORT:
+ return 2;
+ case UNSIGNED_INT:
+ case FLOAT:
+ return 4;
+ default:
+ return -1;
+ }
+}
+
+uint32_t AccessorType::ElementCount(Type t)
+{
+ return ACCESSOR_TYPE_ELEMENT_COUNT[t];
+}
+
+AccessorType::Type AccessorType::FromString(const char* s, size_t len)
+{
+ auto iFind = ACCESSOR_TYPES.find(std::string_view(s, len));
+ if (iFind != ACCESSOR_TYPES.end())
+ {
+ return iFind->second;
+ }
+ return AccessorType::INVALID;
+}
+
+AlphaMode::Type AlphaMode::FromString(const char* s, size_t len)
+{
+ auto iFind = ALPHA_MODE_TYPES.find(std::string_view(s, len));
+ if (iFind != ALPHA_MODE_TYPES.end())
+ {
+ return iFind->second;
+ }
+ return AlphaMode::INVALID;
+}
+
+Attribute::Type Attribute::FromString(const char* s, size_t len)
+{
+ auto iFind = ATTRIBUTE_TYPES.find(std::string_view(s, len));
+ if (iFind != ATTRIBUTE_TYPES.end())
+ {
+ return iFind->second;
+ }
+ return Attribute::INVALID;
+}
+
+Animation::Sampler::Interpolation::Type Animation::Sampler::Interpolation::FromString(const char* s, size_t len)
+{
+ auto iFind = ANIMATION_SAMPLER_INTERPOLATION.find(std::string_view(s, len));
+ if (iFind != ANIMATION_SAMPLER_INTERPOLATION.end())
+ {
+ return iFind->second;
+ }
+ return Animation::Sampler::Interpolation::Type::INVALID;
+}
+
+uint32_t ComponentTypedBufferViewClient::GetBytesPerComponent() const
+{
+ return Component::Size(mComponentType);
+}
+
+Animation::Channel::Target::Type Animation::Channel::Target::FromString(const char* s, size_t len)
+{
+ std::string target(s, len);
+ std::transform(target.begin(), target.end(), target.begin(), ::toupper);
+
+ auto iFind = ANIMATION_CHANNEL_TARGET_PATH_TYPES.find(std::string_view(target.c_str(), len));
+ if (iFind != ANIMATION_CHANNEL_TARGET_PATH_TYPES.end())
+ {
+ return iFind->second;
+ }
+ return Animation::Channel::Target::INVALID;
+};
+
+void Node::SetMatrix(const Matrix& m)
+{
+ m.GetTransformComponents(mTranslation, mRotation, mScale);
+}
+
+Quaternion ReadQuaternion(const json_value_s & j)
+{
+ return Quaternion(ReadDaliVector<Vector4>(j));
+}
+
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_GLTF2_ASSET_H_
+#define DALI_SCENE_LOADER_GLTF2_ASSET_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/index.h"
+#include "dali-scene-loader/internal/json-reader.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/vector4.h"
+#include "dali/public-api/math/quaternion.h"
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/devel-api/common/map-wrapper.h"
+#include <cstdint>
+#include <memory>
+
+namespace gltf2
+{
+
+using Index = Dali::SceneLoader::Index;
+
+template <typename T>
+class Ref
+{
+public:
+ Ref() = default;
+ Ref(std::vector<T>& v, Index i)
+ : mVector(&v),
+ mIndex(i)
+ {}
+
+ /**
+ * @return The index of the object into the vector.
+ * @note It is client code responsibility to ensure that the vector is unambiguous. It should be in
+ * a glTF document, since there's one vector for each type.
+ */
+ Index GetIndex() const { return mIndex; }
+
+ /**
+ * @brief There may be scenarios in which the object, whose vector we're populating, changes, e.g.
+ * when we don't have a final one at the time of reading the references.
+ */
+ void UpdateVector(std::vector<T>& v)
+ {
+ mVector = &v;
+ }
+
+ operator bool() const { return mVector != nullptr; }
+ T* operator->() const { return &(*mVector)[mIndex]; }
+ T& operator*() const { return (*mVector)[mIndex]; }
+
+ bool operator==(const Ref<T>& other) const
+ {
+ return mVector == other.mVector && mIndex == other.mIndex;
+ }
+
+ bool operator!=(const Ref<T>& other) const
+ {
+ return !operator==(other);
+ }
+
+private:
+ std::vector<T>* mVector = nullptr;
+ Index mIndex = Dali::SceneLoader::INVALID_INDEX;
+};
+
+struct Asset
+{
+ std::string_view mVersion;
+};
+
+struct Component
+{
+ enum Type
+ {
+ BYTE = 5120,
+ UNSIGNED_BYTE = 5121,
+ SHORT = 5122,
+ UNSIGNED_SHORT = 5123,
+ UNSIGNED_INT = 5125,
+ FLOAT = 5126,
+ INVALID = -1
+ };
+
+ static bool IsUnsigned(Type t);
+ static uint32_t Size(Type t);
+
+ Component() = delete;
+};
+
+struct AccessorType
+{
+ enum Type
+ {
+ SCALAR,
+ VEC2,
+ VEC3,
+ VEC4,
+ MAT2,
+ MAT3,
+ MAT4,
+ INVALID
+ };
+
+ static uint32_t ElementCount(Type t);
+
+ static Type FromString(const char* s, size_t len);
+
+ AccessorType() = delete;
+};
+
+struct AlphaMode
+{
+ enum Type
+ {
+ OPAQUE,
+ MASK,
+ BLEND,
+ INVALID
+ };
+
+ static Type FromString(const char* s, size_t len);
+
+ AlphaMode() = delete;
+};
+
+struct Attribute
+{
+ enum Type
+ {
+ POSITION,
+ NORMAL,
+ TANGENT,
+ TEXCOORD_0,
+ TEXCOORD_1,
+ COLOR_0,
+ JOINTS_0,
+ WEIGHTS_0,
+ INVALID
+ };
+
+ static Type FromString(const char* s, size_t len);
+
+ Attribute() = delete;
+};
+
+struct Buffer
+{
+ uint32_t mByteLength;
+ std::string_view mUri;
+ //TODO: extensions
+ //TODO: extras
+};
+
+struct BufferView
+{
+ struct Target
+ {
+ enum Type
+ {
+ NONE,
+ ARRAY_BUFFER = 34962,
+ ELEMENT_ARRAY_BUFFER = 34963
+ };
+
+ Target() = delete;
+ };
+
+ Ref<Buffer> mBuffer;
+ uint32_t mByteOffset = 0;
+ uint32_t mByteLength;
+ uint32_t mByteStride = 0; // if 0 after reading, it needs to be calculated
+ uint32_t mTarget;
+ //TODO: extensions
+ //TODO: extras
+};
+
+struct BufferViewClient
+{
+ Ref<BufferView> mBufferView;
+ uint32_t mByteOffset = 0;
+};
+
+struct ComponentTypedBufferViewClient : BufferViewClient
+{
+ Component::Type mComponentType = Component::INVALID;
+
+ uint32_t GetBytesPerComponent() const;
+};
+
+struct Named
+{
+ std::string_view mName;
+
+protected:
+ Named() = default;
+};
+
+struct Accessor : ComponentTypedBufferViewClient, Named
+{
+ struct Sparse
+ {
+ uint32_t mCount;
+ ComponentTypedBufferViewClient mIndices;
+ BufferViewClient mValues;
+ //TODO: extensions
+ //TODO: extras
+ };
+
+ uint32_t mCount;
+ bool mNormalized = false;
+ AccessorType::Type mType = AccessorType::INVALID;
+ std::vector<float> mMin;
+ std::vector<float> mMax;
+ std::unique_ptr<Sparse> mSparse;
+ //TODO: extensions
+ //TODO: extras
+
+ uint32_t GetElementSizeBytes() const
+ {
+ return GetBytesPerComponent() * AccessorType::ElementCount(mType);
+ }
+
+ uint32_t GetBytesLength() const
+ {
+ return GetElementSizeBytes() * mCount;
+ }
+
+ void SetSparse(const Sparse& s)
+ {
+ mSparse.reset(new Sparse(s));
+ }
+};
+
+struct Image: Named
+{
+ std::string_view mUri;
+ std::string_view mMimeType;
+ Ref<BufferView> mBufferView;
+ //TODO: extensions
+ //TODO: extras
+};
+
+struct Filter
+{
+ enum Type
+ {
+ NEAREST = 9728,
+ LINEAR = 9729,
+ NEAREST_MIPMAP_NEAREST = 9984,
+ NEAREST_MIPMAP_LINEAR = 9985,
+ LINEAR_MIPMAP_NEAREST = 9986,
+ LINEAR_MIPMAP_LINEAR = 9987,
+ };
+
+ Filter() = delete;
+};
+
+struct Wrap
+{
+ enum Type
+ {
+ REPEAT = 10497,
+ CLAMP_TO_EDGE = 33071,
+ MIRRORED_REPEAT = 33648,
+ };
+
+ Wrap() = delete;
+};
+
+struct Sampler
+{
+ Filter::Type mMinFilter = Filter::LINEAR;
+ Filter::Type mMagFilter = Filter::LINEAR;
+ Wrap::Type mWrapS = Wrap::CLAMP_TO_EDGE;
+ Wrap::Type mWrapT = Wrap::CLAMP_TO_EDGE;
+ //TODO: extensions
+ //TODO: extras
+};
+
+struct Texture
+{
+ Ref<Image> mSource;
+ Ref<Sampler> mSampler;
+};
+
+struct TextureInfo
+{
+ Ref<gltf2::Texture> mTexture;
+ uint32_t mTexCoord = 0;
+ float mScale = 1.f;
+
+ operator bool() const
+ {
+ return !!mTexture;
+ }
+};
+
+struct Material: Named
+{
+ struct Pbr//MetallicRoughness
+ {
+ Dali::Vector4 mBaseColorFactor = Dali::Vector4::ONE;
+ TextureInfo mBaseColorTexture;
+ float mMetallicFactor = 1.f;
+ float mRoughnessFactor = 1.f;
+ TextureInfo mMetallicRoughnessTexture;
+ //TODO: extensions
+ //TODO: extras
+ };
+
+ Pbr mPbrMetallicRoughness;
+ TextureInfo mNormalTexture;
+ TextureInfo mOcclusionTexture;
+ TextureInfo mEmissiveTexture;
+ Dali::Vector3 mEmissiveFactor;
+ AlphaMode::Type mAlphaMode = AlphaMode::OPAQUE;
+ float mAlphaCutoff = .5f;
+ bool mDoubleSided = false;
+ //TODO: extensions
+ //TODO: extras
+};
+
+struct Mesh: Named
+{
+ struct Primitive
+ {
+ enum Mode
+ {
+ POINTS,
+ LINES,
+ LINE_LOOP,
+ LINE_STRIP,
+ TRIANGLES,
+ TRIANGLE_STRIP,
+ TRIANGLE_FAN,
+ INVALID
+ };
+
+ std::map<Attribute::Type, Ref<Accessor>> mAttributes;
+ std::vector<std::map<Attribute::Type, Ref<Accessor>>> mTargets;
+ Ref<Accessor> mIndices;
+ Ref<Material> mMaterial;
+ Mode mMode = TRIANGLES;
+
+ //TODO: [morph] targets
+ //TODO: extras
+ //TODO: extensions
+ };
+
+ std::vector<Primitive> mPrimitives;
+ std::vector<float> mWeights;
+ //TODO: extras
+ //TODO: extensions
+};
+
+struct Node;
+
+struct Skin : Named
+{
+ Ref<Accessor> mInverseBindMatrices;
+ Ref<Node> mSkeleton;
+ std::vector<Ref<Node>> mJoints;
+ //TODO: extras
+ //TODO: extensions
+};
+
+struct Camera: Named
+{
+ struct Perspective
+ {
+ float mAspectRatio;
+ float mYFov;
+ float mZFar;
+ float mZNear;
+ //TODO: extras
+ //TODO: extensions
+ };
+
+ struct Orthographic
+ {
+ float mXMag;
+ float mYMag;
+ float mZFar;
+ float mZNear;
+ //TODO: extras
+ //TODO: extensions
+ };
+
+ std::string_view mType;
+ Perspective mPerspective;
+ Orthographic mOrthographic;
+ //TODO: extras
+ //TODO: extensions
+};
+
+struct Node: Named
+{
+ Dali::Vector3 mTranslation = Dali::Vector3::ZERO;
+ Dali::Quaternion mRotation = Dali::Quaternion::IDENTITY;
+ Dali::Vector3 mScale = Dali::Vector3::ONE;
+
+ Ref<Camera> mCamera;
+ std::vector<Ref<Node>> mChildren;
+ Ref<Mesh> mMesh;
+
+ Ref<Skin> mSkin;
+ //TODO: [morph] weights
+ //TODO: extras
+ //TODO: extensions
+
+ void SetMatrix(const Dali::Matrix& m);
+};
+
+struct Animation : Named
+{
+ struct Sampler
+ {
+ struct Interpolation
+ {
+ enum Type
+ {
+ STEP,
+ LINEAR,
+ CUBICSPLINE,
+ INVALID
+ };
+ static Type FromString(const char* s, size_t len);
+ };
+
+ Ref<Accessor> mInput;
+ Ref<Accessor> mOutput;
+ Interpolation::Type mInterpolation;
+
+ //TODO: extras
+ //TODO: extensions
+ };
+
+ struct Channel
+ {
+ struct Target
+ {
+ enum Type
+ {
+ TRANSLATION,
+ ROTATION,
+ SCALE,
+ WEIGHTS,
+ INVALID
+ };
+
+ static Type FromString(const char* s, size_t len);
+
+ Ref<Node> mNode;
+ Type mPath;
+ };
+
+ Ref<Sampler> mSampler;
+ Target mTarget;
+ //TODO: extras
+ //TODO: extensions
+ };
+
+ std::vector<Sampler> mSamplers;
+ std::vector<Channel> mChannels;
+};
+
+struct Scene: Named
+{
+ std::vector<Ref<Node>> mNodes;
+};
+
+struct Document
+{
+ Asset mAsset;
+
+ std::vector<Buffer> mBuffers;
+ std::vector<BufferView> mBufferViews;
+ std::vector<Accessor> mAccessors;
+
+ std::vector<Image> mImages;
+ std::vector<Sampler> mSamplers;
+ std::vector<Texture> mTextures;
+ std::vector<Material> mMaterials;
+
+ std::vector<Mesh> mMeshes;
+ std::vector<Skin> mSkins;
+
+ std::vector<Camera> mCameras;
+ std::vector<Node> mNodes;
+
+ std::vector<Animation> mAnimations;
+
+ std::vector<Scene> mScenes;
+ Ref<Scene> mScene;
+
+ Document() = default;
+ Document(const Document&) = delete;
+ Document(Document&&) = default;
+
+ Document& operator=(const Document&) = delete;
+ Document& operator=(Document&&) = default;
+};
+
+/**
+ * @brief Provides a json::Property<T>::ReadFn for interpreting unsigned integers
+ * as a Ref<U> into a std::vector<U> data member of a type T.
+ */
+template <typename T>
+struct RefReader
+{
+ static T* sObject;
+
+ template <typename U, std::vector<U> T::* V>
+ static Ref<U> Read(const json_value_s& j)
+ {
+ uint32_t index = json::Read::Number<uint32_t>(j);
+ return Ref<U>(sObject->*V, index);
+ }
+};
+
+template <typename T>
+T* RefReader<T>::sObject = nullptr;
+
+/**
+ * @brief Convenience method to set the object for RefReader.
+ */
+template <typename T>
+void SetRefReaderObject(T& object)
+{
+ RefReader<T>::sObject = &object;
+}
+
+/**
+ * @brief Reads a string and attempts to convert it to an enum.
+ * @note The enum must: 1, be called Type, nested to T, 2, provide a FromString static method taking a const char*
+ * (string data) and a size_t (string length) and returning T::Type.
+ */
+template <typename T> // T must have a nested enum called Type and a static Type FromString(const char*) method.
+typename T::Type ReadStringEnum(const json_value_s& j)
+{
+ auto str = json::Read::StringView(j);
+
+ return T::FromString(str.data(), str.size());
+}
+
+/**
+ * @brief Convenience method to attempt to create a Dali vector type T from an array of floats.
+ * @note T must provide an AsFloat() member method returning the non-const array of its
+ * float components.
+ */
+template <typename T>
+inline
+T ReadDaliVector(const json_value_s& j)
+{
+ std::vector<float> floats = json::Read::Array<float, json::Read::Number<float>>(j);
+ T result;
+ std::copy(floats.begin(), std::min(floats.end(), floats.begin() + sizeof(T) / sizeof(float)), result.AsFloat());
+ return result;
+}
+
+/**
+ * @brief Convenience method to attemt to read a Quaternion, which implicitly converts
+ * to Vector4 but fails to provide an AsFloat() method.
+ */
+Dali::Quaternion ReadQuaternion(const json_value_s& j);
+
+}
+
+#endif //DALI_SCENE_LOADER_GLTF2_ASSET_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/internal/hash.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+Hash::Hash(uint64_t initial)
+: mValue(initial)
+{}
+
+Hash& Hash::Add(bool b)
+{
+ mValue = Concatenate(b ? 0 : 1);
+ return *this;
+}
+
+Hash& Hash::Add(int32_t i)
+{
+ mValue = Concatenate(i);
+ return *this;
+}
+
+Hash& Hash::Add(uint32_t i)
+{
+ mValue = Concatenate(i);
+ return *this;
+}
+
+Hash& Hash::Add(uint64_t i)
+{
+ mValue = Concatenate(i);
+ return *this;
+}
+
+Hash& Hash::Add(float f)
+{
+ return AddObjectBytes(f);
+}
+
+Hash& Hash::Add(const char * cStr)
+{
+ return Add(cStr, strlen(cStr));
+}
+
+Hash& Hash::Add(const char * cStr, size_t len)
+{
+ auto i0 = reinterpret_cast<const uint8_t*>(cStr);
+ return AddBytes(i0, i0 + len);
+}
+
+Hash& Hash::Add(const std::string & str)
+{
+ auto i0 = reinterpret_cast<const uint8_t*>(str.c_str());
+ return AddBytes(i0, i0 + str.size());
+}
+
+Hash& Hash::AddBytes(const uint8_t * i0, const uint8_t * i1)
+{
+ while (i0 != i1)
+ {
+ mValue = Concatenate(*i0);
+ ++i0;
+ }
+ return *this;
+}
+
+Hash::operator uint64_t() const
+{
+ return mValue;
+}
+
+uint64_t Hash::Concatenate(uint64_t value)
+{
+ return mValue * 31 + value;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_HASH_H_
+#define DALI_SCENE_LOADER_HASH_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <string>
+#include <cstring>
+#include <cstdint>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Rudimentary hash generator that follows a builder pattern.
+ */
+class Hash
+{
+public:
+ static constexpr uint64_t DEFAULT_SEED = 61081;
+
+ explicit Hash(uint64_t initial = DEFAULT_SEED);
+
+ /**
+ * @brief Applies a boolean to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(bool b);
+
+ /**
+ * @brief Applies a signed 32-bit integer to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(int32_t i);
+
+ /**
+ * @brief Applies an unsigned 32-bit integer to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(uint32_t i);
+
+ /**
+ * @brief Applies an unsigned 64-bit integer to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(uint64_t i);
+
+ /**
+ * @brief Applies a float to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(float f);
+
+ /**
+ * @brief Applies a c-string to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(const char* cStr);
+
+ /**
+ * @brief Applies a c-string @a cStr of @a len characters, to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(const char* cStr, size_t len);
+
+ /**
+ * @brief Applies a string to the hash.
+ * @return Its updated self.
+ */
+ Hash& Add(const std::string& str);
+
+ /**
+ * @brief Applies a series of bytes between @a i0 and @a i1 to the hash.
+ * @return Its updated self.
+ */
+ Hash& AddBytes(const uint8_t* i0, const uint8_t* i1);
+
+ /**
+ * @brief Applies the bytes of an object @a value, to the hash.
+ * @return Its updated self.
+ */
+ template <typename T>
+ Hash& AddObjectBytes(const T& value);
+
+ operator uint64_t() const;
+
+private:
+ uint64_t mValue;
+
+ uint64_t Concatenate(uint64_t value);
+};
+
+
+template<typename T>
+Hash& Hash::AddObjectBytes(const T & value)
+{
+ auto i0 = reinterpret_cast<const uint8_t*>(&value);
+ auto i1 = i0 + sizeof(T);
+ while (i0 != i1)
+ {
+ mValue = Concatenate(*i0);
+ ++i0;
+ }
+ return *this;
+}
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_HASH_H_
--- /dev/null
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+#include "dali-scene-loader/internal/json-reader.h"
+#include <algorithm>
+#include <cstring>
+
+namespace json
+{
+
+int StrCmp(const json_string_s& js, const char* s)
+{
+ auto sSize = strlen(s);
+ auto shorter = std::min(js.string_size, sSize);
+ auto base = strncmp(js.string, s, shorter);
+ return ((base != 0) || (sSize == js.string_size)) ? base : ((js.string_size < sSize) ?
+ -s[shorter] : js.string[shorter]);
+}
+
+int StrCmp(const json_string_s& js, const std::string& s)
+{
+ auto sSize = s.size();
+ auto shorter = std::min(js.string_size, sSize);
+ auto base = strncmp(js.string, s.c_str(), shorter);
+ return ((base != 0) || (sSize == js.string_size)) ? base : ((js.string_size < sSize) ?
+ -s[shorter] : js.string[shorter]);
+}
+
+void Validate(const json_value_s & jv, json_type_e type)
+{
+ if (jv.type != type)
+ {
+ throw std::runtime_error("Invalid type; expected: " + std::to_string(type) + ", got: " + std::to_string(jv.type));
+ }
+}
+
+json_value_s* FindObjectChild(const std::string& key, json_object_s& obj)
+{
+ auto i = obj.start;
+ while (i)
+ {
+ if (0 == StrCmp(*i->name, key))
+ {
+ return i->value;
+ }
+ i = i->next;
+ }
+ return nullptr;
+}
+
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_JSON_READER_H_
+#define DALI_SCENE_LOADER_JSON_READER_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/third-party/json.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include <algorithm>
+#include <map>
+#include <string_view>
+#include <sstream>
+#include <cstring>
+#include <memory>
+
+namespace json
+{
+
+/**
+ * @brief Helper for freeing the memory allocated by json_parse()
+ */
+struct json_value_deleter
+{
+ void operator()(json_value_s* p) const
+ {
+ free(p);
+ }
+};
+typedef std::unique_ptr<json_value_s, json_value_deleter> unique_ptr;
+
+/**
+ * @brief Case sensitive comparison of json_string_s and c-string.
+ * @return difference in first different character, or 0 if the strings are identical.
+ */
+int StrCmp(const json_string_s& js, const char* s);
+
+/**
+ * @brief Case sensitive comparison of json_string_s and std::string.
+ * @return difference in first different character, or 0 if the strings are identical.
+ */
+int StrCmp(const json_string_s& js, const std::string& s);
+
+/**
+ * @brief Convenience function to compare json_string_s and other supported string type,
+ * in swapped order.
+ */
+template <typename String>
+inline
+int StrCmp(String& s, const json_string_s& js)
+{
+ return -StrCmp(js, s);
+}
+
+/**
+ * @brief Checks @a jv to be the given @a type, otherwise a std::runtime_error is thrown.
+ */
+void Validate(const json_value_s& jv, json_type_e type);
+
+namespace detail
+{
+/**
+ * @brief Compile-time type-enum mapping.
+ */
+template <typename T>
+struct Type2Enum
+{};
+
+#define TYPE2ENUM(x) template<> struct Type2Enum<json_## x ##_s>\
+{\
+ enum { VALUE = json_type_## x };\
+};
+
+TYPE2ENUM(object)
+TYPE2ENUM(array)
+TYPE2ENUM(string)
+TYPE2ENUM(number)
+#undef TYPE2ENUM
+}
+
+/**
+ * @brief Casts the payload of a json_value_s to the given type.
+ */
+template <typename Out>
+inline
+const Out& Cast(const json_value_s& j)
+{
+ Validate(j, static_cast<json_type_e>(detail::Type2Enum<typename std::decay<Out>::type>::VALUE));
+ return *static_cast<const Out*>(j.payload);
+}
+
+/**
+ * @brief Casts the payload of a json_value_s to the given type.
+ * @note std::runtime_error is thrown if the value is not the given type.
+ */
+template <typename Out>
+inline
+Out& Cast(json_value_s& j)
+{
+ Validate(j, static_cast<json_type_e>(detail::Type2Enum<typename std::decay<Out>::type>::VALUE));
+ return *static_cast<Out*>(j.payload);
+}
+
+/**
+ * @brief Helper function to find a child element of @a obj mapped to @a key.
+ * @return Pointer to the element, or nullptr if it could not be found.
+ */
+json_value_s* FindObjectChild(const std::string& key, json_object_s& obj);
+
+/**
+ * @brief Helper functions for reading various value types.
+ */
+struct Read
+{
+ static bool Boolean(const json_value_s& j)
+ {
+ if (j.type == json_type_true)
+ {
+ return true;
+ }
+ else if (j.type == json_type_false)
+ {
+ return false;
+ }
+ else // try to interpret a numeric value.
+ {
+ return Number<int>(j) != 0;
+ }
+ }
+
+ template <typename T>
+ static T Number(const json_value_s& j)
+ {
+ auto& jn = Cast<const json_number_s>(j);
+ std::stringstream ss;
+ for (auto i0 = jn.number, i1 = i0 + jn.number_size; i0 != i1; ++i0)
+ {
+ ss.put(*i0);
+ }
+
+ T result;
+ if (ss >> result)
+ {
+ return result;
+ }
+ throw std::runtime_error("Failed to convert value to number");
+ }
+
+ template <typename E>
+ static E Enum(const json_value_s& j)
+ {
+ size_t number = Number<size_t>(j);
+ return static_cast<E>(number);
+ }
+
+ static std::string_view StringView(const json_value_s& j)
+ {
+ auto& js = Cast<json_string_s>(j);
+ return std::string_view(js.string, js.string_size);
+ }
+
+ static std::string String(const json_value_s& j)
+ {
+ auto& js = Cast<const json_string_s>(j);
+ return std::string(js.string, js.string_size);
+ }
+
+ template <typename T, T(*readElement)(const json_value_s&)>
+ static std::vector<T> Array(const json_value_s& j)
+ {
+ auto& ja = Cast<const json_array_s>(j);
+ std::vector<T> result;
+ result.reserve(ja.length);
+ auto i = ja.start;
+ while (i)
+ {
+ result.push_back(std::move(readElement(*i->value)));
+ i = i->next;
+ }
+ return result;
+ }
+};
+
+/**
+ * @brief Core class for object properties.
+ */
+struct PropertyCore
+{
+protected:
+ explicit PropertyCore(const std::string& key)
+ : mKey(key)
+ {}
+
+ const std::string& GetKey() const { return mKey; }
+
+private:
+ std::string mKey;
+};
+
+/**
+ * @brief Base class for the properties of a type T.
+ */
+template <typename T>
+struct PropertyBase : PropertyCore
+{
+ using PropertyCore::GetKey;
+
+ explicit PropertyBase(const std::string& key)
+ : PropertyCore(key)
+ {}
+
+ virtual ~PropertyBase()
+ {}
+
+ virtual void Read(const json_value_s& j, T& obj) = 0;
+};
+
+/**
+ * @brief Concrete property of an object to read into from JSON with a given function.
+ */
+template <class T, typename U>
+struct Property : PropertyBase<T>
+{
+ using ReadFn = U(*)(const json_value_s&);
+ using MemberPtr = U T::*;
+ using SetterArgType = typename std::conditional<sizeof(U) <= sizeof(uintptr_t), U, const U&>::type;
+ using Setter = void (T::*)(SetterArgType);
+
+ Property(const std::string& key, ReadFn read, MemberPtr ptr)
+ : PropertyBase<T>(key),
+ mRead(read),
+ mAccessor(new DirectAccessor(ptr))
+ {}
+
+ Property(const std::string& key, ReadFn read, Setter setter)
+ : PropertyBase<T>(key),
+ mRead(read),
+ mAccessor(new SetterAccessor(setter))
+ {}
+
+ ~Property()
+ {}
+
+ void Read(const json_value_s& j, T& obj) override
+ {
+ mAccessor->Set(mRead(j), obj);
+ }
+
+private:
+ struct AccessorBase
+ {
+ virtual ~AccessorBase()
+ {}
+
+ virtual void Set(U value, T& obj) const = 0;
+ };
+
+ struct DirectAccessor : AccessorBase
+ {
+ DirectAccessor(MemberPtr ptr)
+ : mPointer(ptr)
+ {}
+
+ void Set(U value, T& obj) const override
+ {
+ obj.*mPointer = std::move(value);
+ }
+
+ MemberPtr mPointer;
+ };
+
+ struct SetterAccessor : AccessorBase
+ {
+ SetterAccessor(Setter setter)
+ : mSetter(setter)
+ {}
+
+ void Set(U value, T& obj) const override
+ {
+ (obj.*mSetter)(value);
+ }
+
+ Setter mSetter;
+ };
+
+ ReadFn mRead;
+ std::unique_ptr<AccessorBase> mAccessor;
+};
+
+/**
+ * @brief Helper function to make a Property for a member of type U, of object of type T.
+ */
+template <class T, typename U>
+Property<T, U>* MakeProperty(const std::string& key, typename Property<T, U>::ReadFn readFn,
+ U T::* ptr)
+{
+ return new Property<T, U>(key, readFn, ptr);
+}
+
+/**
+ * @brief Core class for an object Reader.
+ */
+struct ReaderCore
+{
+protected:
+ std::vector<void*> mProperties;
+
+ ReaderCore() = default;
+
+ ReaderCore(const ReaderCore& other) = delete;
+ ReaderCore& operator=(const ReaderCore& other) = delete;
+
+ ReaderCore(ReaderCore&& other) = default;
+ ReaderCore& operator=(ReaderCore&& other) = default;
+};
+
+/**
+ * @brief Object Reader template for reading into an object of a given type,
+ * with properties registered for the various members.
+ */
+template <typename T>
+class Reader : protected ReaderCore
+{
+public:
+ Reader() = default;
+
+ Reader(const Reader<T>& other) = delete;
+ Reader<T>& operator=(const Reader<T>& other) = delete;
+
+ Reader(Reader<T>&& other) = default;
+ Reader<T>& operator=(Reader&& other) = default;
+
+ ~Reader()
+ {
+ for (auto& p : mProperties)
+ {
+ delete Cast(p);
+ }
+ }
+
+ Reader<T>& Register(PropertyBase<T>& prop)
+ {
+ auto iInsert = std::lower_bound(mProperties.begin(), mProperties.end(), &prop,
+ SortPredicate);
+ if (iInsert == mProperties.end() || Cast(*iInsert)->GetKey() != prop.GetKey())
+ {
+ mProperties.insert(iInsert, &prop);
+ }
+ else
+ {
+ delete Cast(*iInsert);
+ *iInsert = ∝
+ }
+ return *this;
+ }
+
+ void Read(const json_object_s& jo, T& obj) const
+ {
+ auto i = jo.start;
+ while (i)
+ {
+ auto iFind = std::lower_bound(mProperties.begin(), mProperties.end(),
+ *i->name, FindPredicate);
+ if (iFind != mProperties.end())
+ {
+ auto prop = Cast(*iFind);
+ if (0 == StrCmp(*i->name, prop->GetKey()))
+ {
+ prop->Read(*i->value, obj);
+ }
+ }
+ i = i->next;
+ }
+ }
+
+private:
+ static inline PropertyBase<T>* Cast(void* p)
+ {
+ return static_cast<PropertyBase<T>*>(p);
+ }
+
+ static bool SortPredicate(void* p, PropertyBase<T>* prop)
+ {
+ const auto prop0 = Cast(p);
+ return prop0->GetKey().compare(prop->GetKey()) < 0;
+ }
+
+ static bool FindPredicate(void* p, const json_string_s& key)
+ {
+ const auto prop = Cast(p);
+ return StrCmp(prop->GetKey(), key) < 0;
+ }
+};
+
+/**
+ * @brief Wraps a Reader<T> in a function usable as a Property<T>::ReadFn, i.e. to facilitate
+ * deserializing structures of nested objects.
+ */
+template <typename T>
+struct ObjectReader
+{
+ static const Reader<T>* sReader;
+
+ static T Read(const json_value_s& j)
+ {
+ T result;
+ auto& jo = Cast<json_object_s>(j);
+ sReader->Read(jo, result);
+ return result;
+ }
+};
+
+template <typename T>
+const Reader<T>* ObjectReader<T>::sReader = nullptr;
+
+template <typename T>
+void SetObjectReader(const Reader<T>& r)
+{
+ ObjectReader<T>::sReader = &r;
+}
+
+} // json
+
+#endif //DALI_SCENE_LOADER_JSON_READER_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/internal/json-util.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/extents.h"
+#include "dali/public-api/math/matrix3.h"
+#include "dali/public-api/math/matrix.h"
+#include "dali/public-api/math/quaternion.h"
+#include "dali/public-api/math/radian.h"
+#include "dali/public-api/math/vector2.h"
+#include "dali/public-api/math/vector3.h"
+#include "dali/public-api/object/property-value.h"
+#include "dali/devel-api/common/map-wrapper.h"
+#include <array>
+
+namespace Dali
+{
+using namespace Toolkit;
+
+namespace SceneLoader
+{
+namespace
+{
+
+template <typename T>
+Property::Value ReadPrimitiveHelper(const TreeNode* tn, bool(*reader)(const TreeNode*, T&))
+{
+ T value;
+ if (reader(tn, value))
+ {
+ return Property::Value(value);
+ }
+ return Property::Value();
+}
+
+template <typename T>
+Property::Value ReadVectorHelper(const TreeNode* tn)
+{
+ static_assert(sizeof(T) % sizeof(float) == 0, "");
+ T value;
+ if (ReadVector(tn, value.AsFloat(), sizeof(T) / sizeof(float)))
+ {
+ return Property::Value(value);
+ }
+ return Property::Value();
+}
+
+Property::Value ReadVectorSingleFloatHelper(const TreeNode* tn)
+{
+ float value;
+ if (ReadVector(tn, &value, 1u))
+ {
+ return Property::Value(value);
+ }
+ return Property::Value();
+}
+
+Property::Value ReadRotationHelper(const TreeNode* tn)
+{
+ switch (tn->Size())
+ {
+ case 3:
+ {
+ // degrees as per spec
+ Vector3 rotation;
+ ReadVector(tn, rotation.AsFloat(), 3u);
+ return Property::Value(Quaternion(Radian(Degree(rotation.x)),
+ Radian(Degree(rotation.y)),
+ Radian(Degree(rotation.z))));
+ }
+ case 4:
+ {
+ Vector4 v;
+ ReadVector(tn, v.AsFloat(), 4u);
+ //Quaternion
+ return Property::Value(Quaternion(v));
+ }
+ default:
+ return Property::Value();
+ }
+}
+
+template <typename T>
+bool ReadQuadHelper(const TreeNode* tn, const std::array<T*, 4>& quad)
+{
+ auto i = quad.begin();
+ auto iEnd = quad.end();
+ auto iJson = tn->CBegin();
+ while (iJson != tn->CEnd() && i != iEnd)
+ {
+ int value;
+ if (ReadInt(&(*iJson).second, value) && value <= std::numeric_limits<T>::max())
+ {
+ **i = value;
+ ++i;
+ ++iJson;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+const std::map<std::string, Property::Value(*)(const TreeNode*)> kTypeIds {
+ // NONE
+ { "boolean", [](const TreeNode* tn) {
+ return ReadPrimitiveHelper<bool>(tn, ReadBool);
+ }},
+ { "float", [](const TreeNode* tn) {
+ return ReadPrimitiveHelper<float>(tn, ReadFloat);
+ }},
+ { "integer", [](const TreeNode* tn) {
+ return ReadPrimitiveHelper<int>(tn, ReadInt);
+ }},
+ { "vector2", ReadVectorHelper<Vector2> },
+ { "vector3", ReadVectorHelper<Vector3> },
+ { "vector4", ReadVectorHelper<Vector4> },
+ { "matrix3", ReadVectorHelper<Matrix3> },
+ { "matrix", ReadVectorHelper<Matrix> },
+ { "rectangle", [](const TreeNode* tn) {
+ Rect<int> value;
+ if (ReadQuadHelper<int>(tn, { &value.x, &value.y, &value.width, &value.height }))
+ {
+ return Property::Value(value);
+ }
+ return Property::Value();
+ }},
+ { "rotation", ReadRotationHelper },
+ // STRING - not particularly animatable
+ // ARRAY - not particularly animatable
+ // MAP - not particularly animatable
+ { "extents", [](const TreeNode* tn) {
+ Extents value;
+ if (ReadQuadHelper<uint16_t>(tn, { &value.start, &value.end, &value.top, &value.bottom }))
+ {
+ return Property::Value(value);
+ }
+ return Property::Value();
+ }},
+};
+
+Property::Value(* const kArrayPropertyProcessors[])(const TreeNode*) {
+ ReadVectorHelper<Matrix>,
+ ReadVectorHelper<Matrix3>,
+ ReadVectorHelper<Vector4>,
+ ReadVectorHelper<Vector3>,
+ ReadVectorHelper<Vector2>,
+ ReadVectorSingleFloatHelper
+};
+
+} // nonamespace
+
+bool ReadBool(const TreeNode* node, bool& num)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if (node->GetType() == TreeNode::BOOLEAN)
+ {
+ num = node->GetBoolean();
+ returnValue = true;
+ }
+
+ return returnValue;
+}
+
+bool ReadInt(const TreeNode* node, int& num)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if (node->GetType() == TreeNode::INTEGER)
+ {
+ num = node->GetInteger();
+ returnValue = true;
+ }
+ else if (node->GetType() == TreeNode::FLOAT)
+ {
+ num = static_cast<int>(node->GetFloat());
+ returnValue = true;
+ }
+
+ return returnValue;
+}
+
+bool ReadFloat(const TreeNode* node, float& num)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if (node->GetType() == TreeNode::FLOAT)
+ {
+ num = node->GetFloat();
+ returnValue = true;
+ }
+ else if (node->GetType() == TreeNode::INTEGER)
+ {
+ num = static_cast<float>(node->GetInteger());
+ returnValue = true;
+ }
+
+ return returnValue;
+}
+
+bool ReadIndex(const Toolkit::TreeNode* node, Index& num)
+{
+ bool returnValue = node && node->GetType() == TreeNode::INTEGER;
+ if (returnValue)
+ {
+ num = static_cast<Index>(node->GetInteger());
+ }
+
+ return returnValue;
+}
+
+bool ReadBlob(const Toolkit::TreeNode* node, unsigned int& offset, unsigned int& length)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ int iOffset, iLength;
+ bool success = ReadInt(node->GetChild("byteOffset"), iOffset) &&
+ ReadInt(node->GetChild("byteLength"), iLength) &&
+ iOffset >= 0 && iLength >= 0; // 0 length might not be sensible, but is not an error at this stage.
+ if (success)
+ {
+ offset = static_cast<unsigned int>( iOffset );
+ length = static_cast<unsigned int>( iLength );
+ }
+ return success;
+}
+
+size_t GetNumericalArraySize(const TreeNode* node)
+{
+ size_t size = 0;
+ if (node->GetType() == TreeNode::ARRAY)
+ {
+ for (auto i0 = node->CBegin(), i1 = node->CEnd(); i0 != i1 &&
+ ((*i0).second.GetType() == TreeNode::FLOAT || (*i0).second.GetType() == TreeNode::INTEGER);
+ ++i0)
+ {
+ ++size;
+ }
+ }
+ return size;
+}
+
+bool ReadVector(const TreeNode* node, float* num, unsigned int size)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if ((node->Size() >= size) && (node->GetType() == TreeNode::ARRAY))
+ {
+ unsigned int offset = 0u;
+ for (TreeNode::ConstIterator it = node->CBegin(); offset < size; ++it, ++offset)
+ {
+ const TreeNode& coord = (*it).second;
+ if (!ReadFloat(&coord, *(num + offset)))
+ {
+ return false;
+ }
+ }
+ returnValue = true;
+ }
+
+ return returnValue;
+}
+
+bool ReadVector(const Toolkit::TreeNode* node, int* num, unsigned int size)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if ((node->Size() >= size) && (node->GetType() == TreeNode::ARRAY))
+ {
+ unsigned int offset = 0u;
+ for (TreeNode::ConstIterator it = node->CBegin(); offset < size; ++it, ++offset)
+ {
+ const TreeNode& coord = (*it).second;
+ if (!ReadInt(&coord, *(num + offset)))
+ {
+ return false;
+ }
+ }
+ returnValue = true;
+ }
+
+ return returnValue;
+}
+
+bool ReadColor(const TreeNode* node, Vector4& color)
+{
+ if (nullptr == node)
+ {
+ return false;
+ }
+
+ if (!ReadVector(node, color.AsFloat(), 4))
+ {
+ if (!ReadVector(node, color.AsFloat(), 3))
+ {
+ return false;
+ }
+ color.a = 1.f;
+ }
+
+ return true;
+}
+
+bool ReadTimePeriod(const TreeNode* node, TimePeriod& timePeriod)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ if (!ReadFloat(node->GetChild("delay"), timePeriod.delaySeconds) || !ReadFloat(node->GetChild("duration"), timePeriod.durationSeconds))
+ {
+ return false;
+ }
+ return true;
+}
+
+bool ReadString(const TreeNode* node, std::string& strValue)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if (node->GetType() == TreeNode::STRING)
+ {
+ strValue = node->GetString();
+ returnValue = true;
+ }
+ return returnValue;
+}
+
+bool ReadStringVector(const TreeNode* node, std::vector<std::string>& strvector)
+{
+ if (!node)
+ {
+ return false;
+ }
+
+ bool returnValue = false;
+ if (node->GetType() == TreeNode::ARRAY)
+ {
+ for (TreeNode::ConstIterator it = node->CBegin(); it != node->CEnd(); ++it)
+ {
+ const TreeNode& strNode = (*it).second;
+ if (strNode.GetType() == TreeNode::STRING)
+ {
+ strvector.push_back(strNode.GetString());
+ }
+ else
+ {
+ return false;
+ }
+ }
+ returnValue = true;
+ }
+ return returnValue;
+}
+
+Property::Value ReadPropertyValue(const Property::Type& propType, const TreeNode& tn)
+{
+ switch (propType)
+ {
+ case Property::BOOLEAN:
+ return ReadPrimitiveHelper<bool>(&tn, ReadBool);
+
+ case Property::FLOAT:
+ return ReadPrimitiveHelper<float>(&tn, ReadFloat);
+
+ case Property::INTEGER:
+ return ReadPrimitiveHelper<int>(&tn, ReadInt);
+
+ case Property::VECTOR2:
+ return ReadVectorHelper<Vector2>(&tn);
+
+ case Property::VECTOR3:
+ return ReadVectorHelper<Vector3>(&tn);
+
+ case Property::VECTOR4:
+ return ReadVectorHelper<Vector4>(&tn);
+
+ case Property::MATRIX3:
+ return ReadVectorHelper<Matrix3>(&tn);
+
+ case Property::MATRIX:
+ return ReadVectorHelper<Matrix>(&tn);
+
+ case Property::RECTANGLE:
+ {
+ Rect<int> value;
+ if (ReadQuadHelper<int>(&tn, { &value.x, &value.y, &value.width, &value.height }))
+ {
+ return Property::Value(value);
+ }
+ break;
+ }
+
+ case Property::ROTATION:
+ return ReadRotationHelper(&tn);
+
+ case Property::EXTENTS:
+ {
+ Extents value;
+ if (ReadQuadHelper<uint16_t>(&tn, { &value.start, &value.end, &value.top, &value.bottom }))
+ {
+ return Property::Value(value);
+ }
+ break;
+ }
+
+ case Property::NONE: // fall
+ default:
+ {
+ DALI_ASSERT_ALWAYS(!"Property type incorrect");
+ }
+ }
+ return Property::Value();
+}
+
+Property::Value ReadPropertyValue(const Toolkit::TreeNode& tn)
+{
+ Property::Value propValue;
+ if (tn.GetType() == TreeNode::OBJECT) // attempt to disambiguate type.
+ {
+ auto jsonType = tn.GetChild("type");
+ if (jsonType && jsonType->GetType() == TreeNode::STRING)
+ {
+ auto iFind = kTypeIds.find(jsonType->GetString());
+ if (iFind != kTypeIds.end())
+ {
+ propValue = iFind->second(tn.GetChild("value"));
+ }
+ }
+ }
+
+ if (propValue.GetType() == Property::NONE)
+ {
+ if (tn.Size() == 0)
+ {
+ switch (tn.GetType())
+ {
+ case TreeNode::BOOLEAN:
+ propValue = ReadPrimitiveHelper<bool>(&tn, ReadBool);
+ break;
+
+ case TreeNode::INTEGER:
+ propValue = ReadPrimitiveHelper<int>(&tn, ReadInt);
+ break;
+
+ case TreeNode::FLOAT:
+ propValue = ReadPrimitiveHelper<float>(&tn, ReadFloat);
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ bool allNumbers = true;
+ for (auto i0 = tn.CBegin(), i1 = tn.CEnd(); i0 != i1; ++i0)
+ {
+ auto type = (*i0).second.GetType();
+ if(!(type == TreeNode::FLOAT || type == TreeNode::INTEGER))
+ {
+ allNumbers = false;
+ break;
+ }
+ }
+
+ if (allNumbers)
+ {
+ // NOTE: rotations / rectangles / extents must be disambiguated in all circumstances.
+ for (auto& r : kArrayPropertyProcessors)
+ {
+ propValue = r(&tn);
+ if (propValue.GetType() != Property::NONE)
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+ return propValue;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_JSON_UTIL_H_
+#define DALI_SCENE_LOADER_JSON_UTIL_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/index.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/animation/time-period.h"
+#include "dali/public-api/object/property.h"
+#include "dali/public-api/math/vector4.h"
+#include "dali-toolkit/devel-api/builder/tree-node.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+bool ReadBool(const Toolkit::TreeNode* node, bool& num);
+
+bool ReadInt(const Toolkit::TreeNode* node, int& num);
+
+bool ReadFloat(const Toolkit::TreeNode* node, float& num);
+
+bool ReadIndex(const Toolkit::TreeNode* node, Index& num);
+
+bool ReadBlob(const Toolkit::TreeNode* node, unsigned int& offset, unsigned int& length);
+
+/**
+ * @brief Gets the number of numerical element of a JSON array;
+ * @return 0 if not an array, otherwise the number of float or integer elements
+ * at the front of the array.
+ */
+size_t GetNumericalArraySize(const Toolkit::TreeNode* node);
+
+bool ReadVector(const Toolkit::TreeNode* node, float* num, unsigned int size);
+
+bool ReadVector(const Toolkit::TreeNode* node, int* num, unsigned int size);
+
+/**
+ * @brief Reads a color.
+ *
+ * The node contents could be a vector of 4 floats [r,g,b,a].
+ *
+ * @param[in] node The tree node with the color.
+ * @param[out] color The RGBA color.
+ *
+ * @return true if succedded to read the color.
+ */
+bool ReadColor(const Toolkit::TreeNode* node, Vector4& color);
+
+bool ReadTimePeriod(const Toolkit::TreeNode* node, TimePeriod& timePeriod);
+
+bool ReadString(const Toolkit::TreeNode* node, std::string& strValue);
+
+bool ReadStringVector(const Toolkit::TreeNode* node, std::vector<std::string>& strvector);
+
+/**
+ * @brief Attempts to read a property of the given type from the given JSON node.
+ * @return The property value that it could interpret. If unsuccessful, its type will be NONE.
+ * @note Currently only numerical types are supported (including boolean).
+ */
+Property::Value ReadPropertyValue(const Property::Type& propType, const Toolkit::TreeNode& tn);
+
+/**
+ * @brief Attempts to read a property, whose type it will attempt to determine from the given
+ * JSON node.
+ * @return The property value that it could interpret. If unsuccessful, its type will be NONE.
+ * @note Currently only numerical types are supported (including boolean).
+ * @note Supports a disambiguation syntax, whereby the type can be specified explicitly:
+ * { "type": "rotation", "value": [...] } .
+ * @note: rotation / rectangle / extents type properties must be disambiguated in all circumstances.
+ */
+Property::Value ReadPropertyValue(const Toolkit::TreeNode& tn);
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_JSON_UTIL_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/alpha-function-helper.h"
+#include <unordered_map>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+
+#define DALI_ALPHA_FUNCTION_ENTRY(x) { #x, AlphaFunction::x }
+
+std::unordered_map<std::string, AlphaFunction> sFunctions {
+ DALI_ALPHA_FUNCTION_ENTRY(DEFAULT),
+ DALI_ALPHA_FUNCTION_ENTRY(LINEAR),
+ DALI_ALPHA_FUNCTION_ENTRY(REVERSE),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_SQUARE),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_SQUARE),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_IN),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_OUT),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_SINE),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_SINE),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_IN_OUT_SINE),
+ DALI_ALPHA_FUNCTION_ENTRY(BOUNCE),
+ DALI_ALPHA_FUNCTION_ENTRY(SIN),
+ DALI_ALPHA_FUNCTION_ENTRY(EASE_OUT_BACK),
+};
+
+#undef DALI_ALPHA_FUNCTION_ENTRY
+
+} // nonamespace
+
+AlphaFunction GetAlphaFunction(const std::string& name, bool* found)
+{
+ auto iFind = sFunctions.find(name);
+ bool success = iFind != sFunctions.end();
+ if (found)
+ {
+ *found = success;
+ }
+ return success ? iFind->second : AlphaFunction(AlphaFunction::DEFAULT);
+}
+
+void RegisterAlphaFunction(const std::string & name, AlphaFunction alphaFn)
+{
+ DALI_ASSERT_ALWAYS(sFunctions.insert({ name, alphaFn }).second &&
+ "Function with given key already exists.");
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_ALPHA_FUNCTION_HELPER_H_
+#define DALI_SCENE_LOADER_ALPHA_FUNCTION_HELPER_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "dali-scene-loader/public-api/api.h"
+
+#include "dali/public-api/animation/alpha-function.h"
+#include <string>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @return Given a name, provide a AlphaFunction; if the name was not
+ * recognised, get the default one.
+ */
+AlphaFunction DALI_SCENE_LOADER_API GetAlphaFunction(const std::string& name, bool* found = nullptr);
+
+/**
+ * @brief Registers an alpha function only if one with the same @a name has
+ * not yet been registered. Throws Exception the name isn't unique.
+ */
+void DALI_SCENE_LOADER_API RegisterAlphaFunction(const std::string& name, AlphaFunction alphaFn) noexcept(false);
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_ALPHA_FUNCTION_HELPER_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/animated-property.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+void AnimatedProperty::Animate(Animation& anim, GetActor getActor)
+{
+ if (Actor actor = getActor(mNodeName))
+ {
+ Property prop = GetProperty(actor);
+ if (mKeyFrames)
+ {
+ anim.AnimateBetween(prop, mKeyFrames, mAlphaFunction, mTimePeriod);
+ }
+ else if (mValue)
+ {
+ if (mValue->mIsRelative)
+ {
+ anim.AnimateBy(prop, mValue->mValue, mAlphaFunction, mTimePeriod);
+ }
+ else
+ {
+ anim.AnimateTo(prop, mValue->mValue, mAlphaFunction, mTimePeriod);
+ }
+ }
+ }
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_ANIMATED_PROPERTY_H
+#define DALI_SCENE_LOADER_ANIMATED_PROPERTY_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/actors/actor.h"
+#include "dali/public-api/animation/animation.h"
+#include "dali/public-api/object/property.h"
+#include <memory>
+#include <functional>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Intermediate representation for a property that's given to
+ * a Animation to animate. Since there is no getting an
+ * animated property back from the Animation (i.e. past AnimateBetween/By/To()),
+ * changing properties (e.g. from the SDK) requires the whole Animation
+ * object to be recreated with all of its properties (incl. modifications).
+ */
+struct DALI_SCENE_LOADER_API AnimatedProperty
+{
+public: // METHODS
+ /**
+ * @brief Function to obtain an Actor based on its name. Its processing will
+ * ignore empty handles returned by it.
+ */
+ using GetActor = std::function<Actor(const std::string&)>;
+
+ /**
+ * @return The Property object (of the given @a actor) whose value is being animated.
+ */
+ Property GetProperty(Actor& actor)
+ {
+ auto idx = actor.GetPropertyIndex(mPropertyName);
+ return Property(actor, idx);
+ }
+
+ /**
+ * @brief The type of the Property (of the given @a actor) that is being animated.
+ */
+ Property::Type GetPropertyType(Actor& actor)
+ {
+ auto idx = actor.GetPropertyIndex(mPropertyName);
+ return actor.GetPropertyType(idx);
+ }
+
+ /**
+ * @brief Registers the animation of this property against the given @a anim.
+ * @a getActor will be used to obtain the Actor named by this property.
+ * Failing to find the actor purely means that this property will not be
+ * animated.
+ */
+ void Animate(Animation& anim, GetActor getActor);
+
+public: // DATA
+ struct Value
+ {
+ Property::Value mValue;
+ bool mIsRelative;
+ };
+
+ std::string mNodeName;
+ std::string mPropertyName;
+
+ KeyFrames mKeyFrames;
+ std::unique_ptr<Value> mValue;
+
+ AlphaFunction mAlphaFunction = AlphaFunction::DEFAULT;
+ TimePeriod mTimePeriod = TimePeriod(0.f);
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_ANIMATED_PROPERTY_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/animation-definition.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+const float AnimationDefinition::DEFAULT_DURATION_SECONDS = 1.f;
+const float AnimationDefinition::MIN_DURATION_SECONDS = 1e-2f;
+
+Animation::EndAction AnimationDefinition::StopForModification(Animation& anim)
+{
+ const auto endAction = anim.GetEndAction();
+ anim.SetEndAction(Animation::DISCARD);
+ anim.Stop();
+ return endAction;
+}
+
+AnimationDefinition::AnimationDefinition()
+{}
+
+AnimationDefinition::AnimationDefinition(AnimationDefinition&& other)
+: mName(std::move(other.mName)),
+ mDuration(other.mDuration),
+ mLoopCount(other.mLoopCount),
+ mDisconnectAction(other.mDisconnectAction),
+ mEndAction(other.mEndAction),
+ mSpeedFactor(other.mSpeedFactor),
+ mPlayRange(other.mPlayRange),
+ mProperties(std::move(other.mProperties))
+{}
+
+void AnimationDefinition::Animate(Animation& animation, AnimatedProperty::GetActor getActor)
+{
+ DALI_ASSERT_ALWAYS(animation);
+ for (auto& ap : mProperties)
+ {
+ ap.Animate(animation, getActor);
+ }
+}
+
+Animation AnimationDefinition::ReAnimate(AnimatedProperty::GetActor getActor)
+{
+ // Create and configure new animation.
+ Animation a = Animation::New(mDuration);
+ a.SetLoopCount(mLoopCount);
+ a.SetDisconnectAction(mDisconnectAction);
+ a.SetEndAction(mEndAction);
+
+ a.SetSpeedFactor(mSpeedFactor);
+ a.SetPlayRange(mPlayRange);
+
+ Animate(a, getActor);
+ return a;
+}
+
+AnimationDefinition& AnimationDefinition::operator=(AnimationDefinition&& other)
+{
+ AnimationDefinition tmp(std::move(other));
+ mName = std::move(tmp.mName);
+ mDuration = tmp.mDuration;
+ mLoopCount = tmp.mLoopCount;
+ mDisconnectAction = tmp.mDisconnectAction;
+ mEndAction = tmp.mEndAction;
+ mSpeedFactor = tmp.mSpeedFactor;
+ mPlayRange = tmp.mPlayRange;
+ mProperties.swap(tmp.mProperties);
+ return *this;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_ANIMATION_DEFINITION_H
+#define DALI_SCENE_LOADER_ANIMATION_DEFINITION_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/animated-property.h"
+#include "dali/public-api/common/vector-wrapper.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Animation handle + name + definition of properties.
+ */
+class DALI_SCENE_LOADER_API AnimationDefinition
+{
+public: // STATIC
+ // For Animations created in the SDK.
+ static const float DEFAULT_DURATION_SECONDS;
+
+ // For parsing Animations from dli, when duration was not defined.
+ static const float MIN_DURATION_SECONDS;
+
+ /**
+ * @brief Saves the original end action of @a anim, sets the end action to
+ * Discard, then stops the animation and returns the end action.
+ */
+ static Animation::EndAction StopForModification(Animation& anim);
+
+public: // METHODS
+ AnimationDefinition();
+
+ AnimationDefinition(AnimationDefinition&& other);
+
+ /**
+ * @brief Registers the properties against the given @a animation. @a getActor
+ * will be used to obtain the Actors for each AnimatedProperty.
+ */
+ void Animate(Animation& animation, AnimatedProperty::GetActor getActor);
+
+ /**
+ * @brief Creates a new Animation and Animates() its properties. @a getActor
+ * will be used to obtain the Actors for each AnimatedProperty.
+ */
+ Animation ReAnimate(AnimatedProperty::GetActor getActor);
+
+ AnimationDefinition& operator=(AnimationDefinition&& other);
+
+public: // DATA
+ std::string mName;
+
+ float mDuration = DEFAULT_DURATION_SECONDS;
+ int mLoopCount = 1;
+ Animation::EndAction mDisconnectAction = Animation::BAKE_FINAL;
+ Animation::EndAction mEndAction = Animation::BAKE;
+ float mSpeedFactor = 1.f;
+ Vector2 mPlayRange = Vector2{ 0.f, 1.f };
+
+ std::vector<AnimatedProperty> mProperties;
+};
+
+struct AnimationGroupDefinition
+{
+ std::string mName;
+ std::vector<std::string> mAnimations;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_ANIMATION_DEFINITION_H
--- /dev/null
+#ifndef DALI_SCENE_LOADER_API_H
+#define DALI_SCENE_LOADER_API_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#if __GNUC__ >= 4
+#define DALI_SCENE_LOADER_API __attribute__((visibility("default")))
+
+#elif defined(WIN32)
+#ifdef BUILDING_DALI_SCENE_LOADER
+#define DALI_SCENE_LOADER_API __declspec(dllexport)
+#else
+#define DALI_SCENE_LOADER_API __declspec(dllimport)
+#endif // BUILDING_DALI_SCENE_LOADER
+
+#endif
+
+#endif //DALI_SCENE_LOADER_API_H
--- /dev/null
+
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+
+// FILE HEADER
+#include "dali-scene-loader/public-api/blend-shape-details.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/animation/constraints.h"
+#include "dali/public-api/object/property.h"
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/resource-bundle.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+const std::string BlendShapes::NUMBER_OF_BLEND_SHAPES("uNumberOfBlendShapes");
+const std::string BlendShapes::UNNORMALIZE_FACTOR("uBlendShapeUnnormalizeFactor");
+const std::string BlendShapes::COMPONENT_SIZE("uBlendShapeComponentSize");
+
+const std::string BlendShapes::COMPONENTS("blendShapeComponents");
+
+const std::string BlendShapes::WEIGHTS_UNIFORM("uBlendShapeWeight");
+
+void BlendShapes::ConfigureProperties(const std::pair<MeshDefinition, MeshGeometry>& mesh, Shader shader, Actor actor)
+{
+ unsigned int index = 0u;
+
+ char weightNameBuffer[32];
+ char unnormalizeFactorNameBuffer[64];
+ char* const pWeightName = weightNameBuffer + snprintf(weightNameBuffer, sizeof(weightNameBuffer), "%s", WEIGHTS_UNIFORM.c_str());
+ char* const pFactorName = unnormalizeFactorNameBuffer + snprintf(unnormalizeFactorNameBuffer, sizeof(unnormalizeFactorNameBuffer), "%s", UNNORMALIZE_FACTOR.c_str());
+ for (const auto& blendShape : mesh.first.mBlendShapes)
+ {
+ snprintf(pWeightName, sizeof(weightNameBuffer) - (pWeightName - weightNameBuffer), "[%d]", index);
+ std::string weightName{ weightNameBuffer };
+ actor.RegisterProperty(weightName, blendShape.weight);
+
+ if (mesh.first.mBlendShapeVersion == Version::VERSION_1_0)
+ {
+ snprintf(pFactorName, sizeof(unnormalizeFactorNameBuffer) - (pFactorName - unnormalizeFactorNameBuffer), "[%d]", index);
+ std::string factorName{ unnormalizeFactorNameBuffer };
+ shader.RegisterProperty(factorName, mesh.second.blendShapeUnnormalizeFactor[index]);
+ }
+
+ ++index;
+ }
+
+ if (Version::VERSION_2_0 == mesh.first.mBlendShapeVersion)
+ {
+ shader.RegisterProperty(UNNORMALIZE_FACTOR, mesh.second.blendShapeUnnormalizeFactor[0u]);
+ }
+
+ shader.RegisterProperty(NUMBER_OF_BLEND_SHAPES, Property::Value(static_cast<int>(index)));
+ shader.RegisterProperty(COMPONENT_SIZE, Property::Value(static_cast<int>(mesh.second.blendShapeBufferOffset)));
+
+ // Create a read only property to preserve the components of the blend shape.
+ int32_t components = 0x0;
+ for (auto& bs : mesh.first.mBlendShapes)
+ {
+ components |= (bs.deltas.IsDefined() * Component::POSITIONS) |
+ (bs.normals.IsDefined() * Component::NORMALS) | (bs.tangents.IsDefined() * Component::TANGENTS);
+ }
+ shader.RegisterProperty(COMPONENTS, components, Property::AccessMode::READ_ONLY);
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_BLEND_SHAPE_DETAILS_H
+#define DALI_SCENE_LOADER_BLEND_SHAPE_DETAILS_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/rendering/shader.h"
+#include "dali/public-api/actors/actor.h"
+#include <string>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+struct MeshDefinition;
+struct MeshGeometry;
+
+struct DALI_SCENE_LOADER_API BlendShapes
+{
+ enum class Version
+ {
+ VERSION_1_0,
+ VERSION_2_0,
+ INVALID
+ };
+
+ struct Component
+ {
+ enum
+ {
+ POSITIONS = 0x1,
+ NORMALS = 0x2,
+ TANGENTS = 0x4
+ };
+ };
+
+ // shader properties - animatable (uniforms)
+ static const std::string NUMBER_OF_BLEND_SHAPES; ///< Integer number of blend shapes loaded.
+ static const std::string UNNORMALIZE_FACTOR; ///< Scalar(s) for position components of blend shapes; Version 1.0: float array (1 per blend shape); Version 2.0: single float.
+ static const std::string COMPONENT_SIZE; ///< Integer offset from one component (positions / normals / tangents) of a blend shape to the next.
+
+ // shader properties - read-only (not available as uniforms)
+ static const std::string COMPONENTS; ///< Integer bitmask of the blend shape components that the shader uses; refer to the Components enum.
+
+ // actor property (instance) - animatable (uniforms)
+ static const std::string WEIGHTS_UNIFORM; ///< The weight of each blend shape in a float array
+
+ /**
+ * @brief Registers properties based on the mesh definition (and geometry) and identified by the above string constants,
+ * on the given @a shader and @a actor.
+ */
+ static void ConfigureProperties(const std::pair<MeshDefinition, MeshGeometry>& mesh, Shader shader, Actor actor);
+};
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_BLEND_SHAPE_DETAILS_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/camera-parameters.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include "dali/public-api/actors/camera-actor.h"
+#include "dali/public-api/math/quaternion.h"
+#include "dali/integration-api/debug.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+/**
+ * @brief Creates a perspective matrix.
+ *
+ * @param[out] result The perspective matrix.
+ * @param[in] left The coordinate for the left vertical clipping plane.
+ * @param[in] right The coordinate for the right vertical clipping plane.
+ * @param[in] bottom The coordinate for the bottom horizontal clipping plane.
+ * @param[in] top The coordinate for the top horizontal clipping plane.
+ * @param[in] near The distance to the near depth clipping plane.
+ * @param[in] far The distance to the far depth clipping plane.
+ * @param[in] invertYAxis Whether to invert the 'Y' axis.
+ */
+void Frustum( Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis )
+{
+ float deltaZ = farPlane - nearPlane;
+ if ((nearPlane <= 0.0f) || (farPlane <= 0.0f) || Equals(right, left) || Equals(bottom, top) || (deltaZ <= 0.0f))
+ {
+ DALI_LOG_ERROR("Invalid parameters passed into Frustum!\n");
+ DALI_ASSERT_DEBUG("Invalid parameters passed into Frustum!");
+ return;
+ }
+
+ float deltaX = right - left;
+ float deltaY = invertYAxis ? bottom - top : top - bottom;
+
+ result.SetIdentity();
+
+ float* m = result.AsFloat();
+ m[0] = -2.0f * nearPlane / deltaX;
+ m[1] = m[2] = m[3] = 0.0f;
+
+ m[5] = -2.0f * nearPlane / deltaY;
+ m[4] = m[6] = m[7] = 0.0f;
+
+ m[8] = (right + left) / deltaX;
+ m[9] = (top + bottom) / deltaY;
+ m[10] = (nearPlane + farPlane) / deltaZ;
+ m[11] = 1.0f;
+
+ m[14] = -2.0f * nearPlane * farPlane / deltaZ;
+ m[12] = m[13] = m[15] = 0.0f;
+}
+
+/**
+ * @brief Creates a perspective projection matrix.
+ *
+ * It calls Frustum()
+ *
+ * @param[out] result The perspective projection matrix.
+ * @param[in] fovy The vertical field of view.
+ * @param[in] aspect The aspect ratio.
+ * @param[in] nearPlane The distance to the near depth clipping plane.
+ * @param[in] farPlane The distance to the far depth clipping plane.
+ * @param[in] invertYAxis Whether to invert the 'Y' axis.
+ */
+void Perspective( Matrix& result, float fovy, float aspect, float nearPlane, float farPlane, bool invertYAxis )
+{
+ float frustumH = tanf( fovy * 0.5f ) * nearPlane;
+ float frustumW = frustumH * aspect;
+
+ Frustum( result, -frustumW, frustumW, -frustumH, frustumH, nearPlane, farPlane, invertYAxis );
+}
+
+/**
+* @brief Creates an orthographic projection matrix.
+*
+* @param[out] result The orthographic projection matrix.
+* @param[in] left The coordinate for the left vertical clipping plane.
+* @param[in] right The coordinate for the right vertical clipping plane.
+* @param[in] bottom The coordinate for the bottom horizontal clipping plane.
+* @param[in] top The coordinate for the top horizontal clipping plane.
+* @param[in] nearPlane The distance to the near depth clipping plane.
+* @param[in] farPlane The distance to the far depth clipping plane.
+* @param[in] invertYAxis Whether to invert the 'Y' axis.
+*/
+void Orthographic(Matrix& result, float left, float right, float bottom, float top, float nearPlane, float farPlane, bool invertYAxis)
+{
+ if (Equals(right, left) || Equals(top, bottom) || Equals(farPlane, nearPlane))
+ {
+ DALI_LOG_ERROR("Cannot create orthographic projection matrix with a zero dimension.\n");
+ DALI_ASSERT_DEBUG("Cannot create orthographic projection matrix with a zero dimension.");
+ return;
+ }
+
+ float deltaX = right - left;
+ float deltaY = invertYAxis ? bottom - top : top - bottom;
+ float deltaZ = farPlane - nearPlane;
+
+ float *m = result.AsFloat();
+ m[0] = -2.0f / deltaX;
+ m[1] = 0.0f;
+ m[2] = 0.0f;
+ m[3] = 0.0f;
+
+ m[4] = 0.0f;
+ m[5] = -2.0f / deltaY;
+ m[6] = 0.0f;
+ m[7] = 0.0f;
+
+ m[8] = 0.0f;
+ m[9] = 0.0f;
+ m[10] = 2.0f / deltaZ;
+ m[11] = 0.0f;
+ m[12] = -(right + left) / deltaX;
+ m[13] = -(top + bottom) / deltaY;
+ m[14] = -(nearPlane + farPlane) / deltaZ;
+ m[15] = 1.0f;
+}
+
+} // nonamespace
+
+ViewProjection CameraParameters::GetViewProjection() const
+{
+ ViewProjection viewProjection;
+ // The projection matrix.
+ if (isPerspective)
+ {
+ Perspective(viewProjection.GetProjection(),
+ Radian(Degree(yFov)),
+ 1.f,
+ zNear,
+ zFar,
+ true);
+ }
+ else
+ {
+ Orthographic(viewProjection.GetProjection(),
+ orthographicSize.x,
+ orthographicSize.y,
+ orthographicSize.z,
+ orthographicSize.w,
+ zNear,
+ zFar,
+ true);
+
+ }
+
+ // The view matrix.
+ const Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
+ Vector3 translation;
+ Quaternion cameraOrientation;
+ Vector3 scale;
+ matrix.GetTransformComponents(translation, cameraOrientation, scale);
+ cameraOrientation *= viewQuaternion;
+
+ viewProjection.GetView().SetInverseTransformComponents(scale,
+ cameraOrientation,
+ translation);
+
+ viewProjection.Update();
+ return viewProjection;
+}
+
+void CameraParameters::CalculateTransformComponents(Vector3 & position, Quaternion & orientation, Vector3 & scale) const
+{
+ matrix.GetTransformComponents(position, orientation, scale);
+
+ // The CameraActor is expected to look down the negative Z axis, towards the scene.
+ // Here we emulate the default direction of the camera in DALi.
+ Quaternion viewQuaternion(ANGLE_180, Vector3::YAXIS);
+ orientation *= viewQuaternion;
+}
+
+void CameraParameters::ConfigureCamera(CameraActor& camera) const
+{
+ SetActorCentered(camera);
+
+ if (isPerspective)
+ {
+ camera.SetProjectionMode(Camera::PERSPECTIVE_PROJECTION);
+ camera.SetNearClippingPlane(zNear);
+ camera.SetFarClippingPlane(zFar);
+ camera.SetFieldOfView(Radian(Degree(yFov)));
+ }
+ else
+ {
+ camera.SetProjectionMode(Camera::ORTHOGRAPHIC_PROJECTION);
+ camera.SetOrthographicProjection(orthographicSize.x,
+ orthographicSize.y,
+ orthographicSize.z,
+ orthographicSize.w,
+ zNear,
+ zFar);
+ }
+
+ // model
+ Vector3 camTranslation;
+ Vector3 camScale;
+ Quaternion camOrientation;
+ CalculateTransformComponents(camTranslation, camOrientation, camScale);
+
+ camera.SetInvertYAxis(true);
+ camera.SetProperty(Actor::Property::POSITION, camTranslation);
+ camera.SetProperty(Actor::Property::ORIENTATION, camOrientation);
+ camera.SetProperty(Actor::Property::SCALE, camScale);
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_CAMERA_PARAMETERS_H
+#define DALI_SCENE_LOADER_CAMERA_PARAMETERS_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ // INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/view-projection.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/matrix.h"
+#include "dali/public-api/math/vector3.h"
+
+namespace Dali
+{
+
+class CameraActor;
+
+namespace SceneLoader
+{
+
+struct DALI_SCENE_LOADER_API CameraParameters
+{
+ CameraParameters()
+ : matrix(Matrix::IDENTITY),
+ orthographicSize(-1.f, 1.f, 1.f, -1.f),
+ yFov(60.f),
+ zNear(0.1f),
+ zFar(1000.f),
+ isPerspective(true)
+ {}
+
+ ~CameraParameters() = default;
+
+ Matrix matrix;
+ Vector4 orthographicSize;
+ float yFov;
+ float zNear;
+ float zFar;
+ bool isPerspective;
+
+ /**
+ * @return The view-projection matrix of the camera.
+ */
+ ViewProjection GetViewProjection() const;
+
+ /**
+ * @brief Calculates the @a position, @a orientation and @a scale that's defined
+ * for this camera, and writes it into the respective variable.
+ */
+ void CalculateTransformComponents(Vector3& position, Quaternion& orientation, Vector3& scale) const;
+
+ /**
+ * @brief Configures the camera in the way that it is supposed to be used with
+ * scene-loader scenes. This means inverted Y and a rotation of 180 degrees
+ * along the Y axis, plus whatever the parameters define.
+ */
+ void ConfigureCamera(CameraActor& camera) const;
+};
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_CAMERA_PARAMETERS_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/customization.h"
+#include "dali/devel-api/common/map-wrapper.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+struct Customization::Map::Impl {
+ std::map<Tag, Customization> mCustomizations;
+};
+
+Customization::Map::Map()
+: mImpl{ new Impl }
+{}
+
+Customization::Map::~Map() = default;
+
+Customization* Customization::Map::Set(Tag tag, Customization&& customization)
+{
+ auto& result = (mImpl->mCustomizations[tag] = customization);
+ return &result;
+}
+
+const Customization* Customization::Map::Get(Tag tag) const
+{
+ auto& customizations = mImpl->mCustomizations;
+ auto iFind = customizations.find(tag);
+ if (iFind != customizations.end())
+ {
+ return &iFind->second;
+ }
+ return nullptr;
+}
+
+Customization* Customization::Map::Get(Tag tag)
+{
+ auto& customizations = mImpl->mCustomizations;
+ auto iFind = customizations.find(tag);
+ if (iFind != customizations.end())
+ {
+ return &iFind->second;
+ }
+ return nullptr;
+}
+
+uint32_t Customization::Map::Size() const
+{
+ return mImpl->mCustomizations.size();
+}
+
+void Customization::Map::Clear()
+{
+ mImpl->mCustomizations.clear();
+}
+
+struct Customization::Choices::Impl
+{
+ std::map<Tag, OptionType> mOptions;
+};
+
+Customization::Choices::Choices()
+: mImpl{ new Impl }
+{}
+
+Customization::Choices::~Choices() = default;
+
+void Customization::Choices::Set(Tag tag, OptionType option)
+{
+ mImpl->mOptions[tag] = option;
+}
+
+Customization::OptionType Customization::Choices::Get(Tag tag) const
+{
+ auto& options = mImpl->mOptions;
+ auto iFind = options.find(tag);
+ if (iFind != options.end())
+ {
+ return iFind->second;
+ }
+ return NONE;
+}
+
+uint32_t Customization::Choices::Size() const
+{
+ return mImpl->mOptions.size();
+}
+
+void Customization::Choices::Clear()
+{
+ mImpl->mOptions.clear();
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_CUSTOMIZATION_STATE_H_
+#define DALI_SCENE_LOADER_CUSTOMIZATION_STATE_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ // INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include <string>
+#include <memory>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Offers a description of an aspect of the scene that can be customized:
+ * the number of options, and the name of the nodes that are registered
+ * for the tag, whose children will be shown / hidden based on selection.
+ */
+struct DALI_SCENE_LOADER_API Customization
+{
+ using Tag = std::string;
+ using OptionType = uint32_t;
+
+ /**
+ * @brief A mapping of customizations to tags.
+ */
+ struct DALI_SCENE_LOADER_API Map
+ {
+ Map();
+ ~Map();
+
+ /**
+ * @brief Maps the given @a customization to the given @a tag, overwriting any previous mapping to the same tag.
+ * @return Pointer to the inserted (or pre-existing) Customization instance.
+ */
+ Customization* Set(Tag tag, Customization&& customization);
+
+ /**
+ * @brief Attempts to retrieve a const Customization based on the given @a tag.
+ */
+ const Customization* Get(Tag tag) const;
+
+ /**
+ * @brief Attempts to retrieve a Customization based on the given @a tag.
+ */
+ Customization* Get(Tag tag);
+
+ /**
+ * @brief Returns the number of elements.
+ */
+ uint32_t Size() const;
+
+ /*
+ * @brief Removes every element from the Map.
+ */
+ void Clear();
+
+ private:
+ struct Impl;
+ const std::unique_ptr<Impl> mImpl;
+ };
+
+ /**
+ * @brief A mapping of choices - indices of children of customization nodes to use - to tags.
+ */
+ struct DALI_SCENE_LOADER_API Choices
+ {
+ Choices();
+ ~Choices();
+
+ /**
+ * @brief Maps the given @a option to the given @a tag, overwriting any previous mapping to the same tag.
+ */
+ void Set(Tag tag, OptionType option);
+
+ /**
+ * @brief Attempts to retrieve a Customization based on the given @a tag. Returns NONE if @a tag is not known.
+ */
+ OptionType Get(Tag tag) const;
+
+ /**
+ * @brief Returns the number of elements.
+ */
+ uint32_t Size() const;
+
+ /*
+ * @brief Removes every element from the underlying map.
+ */
+ void Clear();
+
+ private:
+ struct Impl;
+ const std::unique_ptr<Impl> mImpl;
+ };
+
+ static const OptionType NONE = OptionType(-1);
+
+ OptionType numOptions = 0;
+ std::vector<std::string> nodes; // to apply option to.
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_CUSTOMIZATION_STATE_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// CLASS HEADER
+#include "dali-scene-loader/public-api/dli-loader.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/object/property-array.h"
+#include "dali/devel-api/common/map-wrapper.h"
+#include "dali-toolkit/devel-api/builder/json-parser.h"
+#include "dali/integration-api/debug.h"
+#include <fstream>
+#include <limits>
+#include <algorithm>
+#include <memory>
+#include <cmath>
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/parse-renderer-state.h"
+#include "dali-scene-loader/public-api/skinning-details.h"
+#include "dali-scene-loader/public-api/load-result.h"
+#include "dali-scene-loader/public-api/scene-definition.h"
+#include "dali-scene-loader/public-api/animation-definition.h"
+#include "dali-scene-loader/public-api/alpha-function-helper.h"
+#include "dali-scene-loader/public-api/camera-parameters.h"
+#include "dali-scene-loader/public-api/light-parameters.h"
+#include "dali-scene-loader/public-api/blend-shape-details.h"
+#include "dali-scene-loader/public-api/ktx-loader.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include "dali-scene-loader/internal/json-util.h"
+
+#define DLI_0_1_COMPATIBILITY
+
+namespace Dali
+{
+using namespace Toolkit;
+
+namespace SceneLoader
+{
+
+namespace rs = RendererState;
+
+namespace
+{
+const std::string NODES = "nodes";
+const std::string SCENES = "scenes";
+const std::string NODE = "node";
+const std::string URI = "uri";
+const std::string URL = "url";
+const std::string CUSTOMIZATION = "customization";
+const std::string HINTS = "hints";
+const std::string NAME("name");
+const std::string BLEND_SHAPE_HEADER("blendShapeHeader");
+const std::string BLEND_SHAPES("blendShapes");
+const std::string BLEND_SHAPE_VERSION_1_0("1.0");
+const std::string BLEND_SHAPE_VERSION_2_0("2.0");
+const std::string VERSION("version");
+
+const char* const SHADOW_MAP_SIZE = "shadowMapSize";
+const char* const ORTHOGRAPHIC_SIZE = "orthographicSize";
+const char* const PIXEL_UNITS = "px";
+
+const char SLASH = '/';
+
+void ReadModelTransform(const TreeNode* node, Quaternion& orientation, Vector3& translation, Vector3& scale)
+{
+ float num[16u] = { .0f };
+
+ if (ReadVector(node->GetChild("matrix"), num, 16u))
+ {
+ Matrix mat(num);
+ mat.GetTransformComponents(translation, orientation, scale);
+ }
+ else
+ {
+ if (ReadVector(node->GetChild("angle"), num, 3u))
+ {
+ orientation = Quaternion(Radian(Degree(num[0u])), Radian(Degree(num[1u])), Radian(Degree(num[2u])));
+ }
+
+ if (ReadVector(node->GetChild("position"), num, 3u))
+ {
+ translation = Vector3(num);
+ }
+ }
+}
+
+bool ReadAttribBlob(const TreeNode* node, MeshDefinition::Blob& buffer)
+{
+ return ReadBlob(node, buffer.mOffset, buffer.mLength);
+}
+
+bool ReadAttribAccessor(const TreeNode* node, MeshDefinition::Accessor& accessor)
+{
+ return ReadBlob(node, accessor.mBlob.mOffset, accessor.mBlob.mLength);
+}
+
+bool ReadColorCode(const TreeNode* node, Vector4& color,
+ DliLoader::ConvertColorCode convertColorCode)
+{
+ if (!node || !convertColorCode)
+ {
+ return false;
+ }
+
+ color = convertColorCode(node->GetString());
+
+ return true;
+}
+
+bool ReadColorCodeOrColor(const TreeNode* node, Vector4& color,
+ DliLoader::ConvertColorCode convertColorCode)
+{
+ return ReadColorCode(node->GetChild("colorCode"), color, convertColorCode) ||
+ ReadColor(node->GetChild("color"), color);
+}
+
+RendererState::Type ReadRendererState(const TreeNode& tnRendererState)
+{
+ if (tnRendererState.GetType() == TreeNode::INTEGER)
+ {
+ return static_cast<RendererState::Type>(tnRendererState.GetInteger());
+ }
+ else if (tnRendererState.GetType() == TreeNode::STRING)
+ {
+ return RendererState::Parse(tnRendererState.GetString());
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+///@brief Reads arc properties.
+void ReadArcField(const TreeNode* eArc, ArcNode& arc)
+{
+ ReadBool(eArc->GetChild("antiAliasing"), arc.mAntiAliasing);
+ ReadInt(eArc->GetChild("arcCaps"), arc.mArcCaps);
+ ReadFloat(eArc->GetChild("radius"), arc.mRadius);
+
+ arc.mStartAngleDegrees = .0f;
+ ReadFloat(eArc->GetChild("startAngle"), arc.mStartAngleDegrees);
+
+ arc.mEndAngleDegrees = .0f;
+ ReadFloat(eArc->GetChild("endAngle"), arc.mEndAngleDegrees);
+}
+
+const TreeNode *Tidx(const TreeNode *node, int index)
+{
+ int i = 0;
+ for (TreeNode::ConstIterator it = (*node).CBegin(); it != (*node).CEnd(); ++it, ++i)
+ {
+ if (i == index)
+ {
+ return &((*it).second);
+ }
+ }
+ return NULL;
+}
+
+const TreeNode* RequireChild(const TreeNode* node, const std::string& childName)
+{
+ auto child = node->GetChild(childName);
+ if (!child)
+ {
+ ExceptionFlinger flinger(ASSERT_LOCATION);
+ flinger << "Failed to find child node '" << childName << "'";
+ if (auto nodeName = node->GetName())
+ {
+ flinger << " on '" << nodeName << "'";
+ }
+ flinger << ".";
+ }
+ return child;
+}
+
+void ParseProperties(const Toolkit::TreeNode& node, Property::Array& array);
+
+void ParseProperties(const Toolkit::TreeNode& node, Property::Map& map)
+{
+ DALI_ASSERT_DEBUG(node.GetType() == TreeNode::OBJECT);
+ for (auto i0 = node.CBegin(), i1 = node.CEnd(); i0 != i1; ++i0)
+ {
+ auto kv = *i0;
+ switch (kv.second.GetType())
+ {
+ case TreeNode::ARRAY:
+ {
+ Property::Array array;
+ ParseProperties(kv.second, array);
+ map.Insert(kv.first, array);
+ } break;
+
+ case TreeNode::OBJECT:
+ {
+ Property::Map innerMap;
+ ParseProperties(kv.second, innerMap);
+ map.Insert(kv.first, innerMap);
+ } break;
+
+ case TreeNode::STRING:
+ map.Insert(kv.first, kv.second.GetString());
+ break;
+
+ case TreeNode::INTEGER:
+ map.Insert(kv.first, kv.second.GetInteger());
+ break;
+
+ case TreeNode::BOOLEAN:
+ map.Insert(kv.first, kv.second.GetBoolean());
+ break;
+
+ case TreeNode::FLOAT:
+ map.Insert(kv.first, kv.second.GetFloat());
+ break;
+
+ case TreeNode::IS_NULL:
+ break;
+ }
+ }
+}
+
+void ParseProperties(const Toolkit::TreeNode& node, Property::Array& array)
+{
+ DALI_ASSERT_DEBUG(node.GetType() == TreeNode::ARRAY);
+ for (auto i0 = node.CBegin(), i1 = node.CEnd(); i0 != i1; ++i0)
+ {
+ auto kv = *i0;
+ switch (kv.second.GetType())
+ {
+ case TreeNode::ARRAY:
+ {
+ Property::Array innerArray;
+ ParseProperties(kv.second, innerArray);
+ array.PushBack(innerArray);
+ } break;
+
+ case TreeNode::OBJECT:
+ {
+ Property::Map map;
+ ParseProperties(kv.second, map);
+ array.PushBack(map);
+ } break;
+
+ case TreeNode::STRING:
+ array.PushBack(kv.second.GetString());
+ break;
+
+ case TreeNode::INTEGER:
+ array.PushBack(kv.second.GetInteger());
+ break;
+
+ case TreeNode::BOOLEAN:
+ array.PushBack(kv.second.GetBoolean());
+ break;
+
+ case TreeNode::FLOAT:
+ array.PushBack(kv.second.GetFloat());
+ break;
+
+ case TreeNode::IS_NULL:
+ break;
+ }
+ }
+}
+
+}//namespace
+
+struct DliLoader::Impl
+{
+ StringCallback mOnError = DefaultErrorCallback;
+ Toolkit::JsonParser mParser;
+
+ void ParseScene(LoadParams& params);
+
+private:
+ std::map<Index, Matrix> mInverseBindMatrices;
+
+ /**
+ * @brief Due to .dli nodes being processed in depth-first traversal with orphans being
+ * ignored, features that rely on node indices (which is more compact and closer to
+ * glTF) require a mapping from .dli node indices to those in the resulting SceneDefinition.
+ * The index mapper is responsible for maintaing this mapping, and resolving node IDs
+ * once the processing of the nodes has finished.
+ * @note The resolution requires the whole scene graph to finish parsing, therefore any
+ * node extensions relying on node IDs will see the dli ID in their processor.
+ */
+ struct IIndexMapper
+ {
+ /**
+ * @brief Attempts to create a mapping from a node's @a dli index to its @a scene
+ * index.
+ * @return Whether the operation was successful.
+ */
+ virtual bool Map(Index iDli, Index iScene) =0;
+
+ /**
+ * @return The scene index for the node's @a dli index.
+ */
+ virtual Index Resolve(Index iDli) =0;
+ };
+
+ /**
+ * @brief Traverses the DOM tree created by LoadDocument() in an attempt to create
+ * an intermediate representation of resources and nodes.
+ */
+ void ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes,
+ const Toolkit::TreeNode* tnNodes, LoadParams& params);
+
+ void ParseSkeletons(const Toolkit::TreeNode* skeletons, SceneDefinition& scene, ResourceBundle& resources);
+ void ParseEnvironments(const Toolkit::TreeNode* environments, ResourceBundle& resources);
+ void ParseMaterials(const Toolkit::TreeNode* materials, ConvertColorCode convertColorCode,
+ ResourceBundle& resources);
+
+ void ParseNodes(const Toolkit::TreeNode* nodes, Index index, LoadParams& params);
+ void ParseNodesInternal(const Toolkit::TreeNode* nodes, Index index,
+ std::vector<Index>& inOutParentStack, LoadParams& params, IIndexMapper& indexMapper);
+
+ void ParseAnimations(const Toolkit::TreeNode* animations, LoadParams& params);
+ void ParseAnimationGroups(const Toolkit::TreeNode* animationGroups, LoadParams& params);
+
+ void ParseShaders(const Toolkit::TreeNode* shaders, ResourceBundle& resources);
+ void ParseMeshes(const Toolkit::TreeNode* meshes, ResourceBundle& resources);
+
+ void GetCameraParameters(std::vector<CameraParameters>& cameras) const;
+ void GetLightParameters(std::vector<LightParameters>& lights) const;
+};
+
+DliLoader::DliLoader()
+: mImpl{ new Impl }
+{}
+
+DliLoader::~DliLoader() = default;
+
+void DliLoader::SetErrorCallback(StringCallback onError)
+{
+ mImpl->mOnError = onError;
+}
+
+bool DliLoader::LoadScene(const std::string& uri, LoadParams& params)
+{
+ std::string daliBuffer = LoadTextFile(uri.c_str());
+
+ auto& parser = mImpl->mParser;
+ parser = JsonParser::New();
+ if (!parser.Parse(daliBuffer))
+ {
+ return false;
+ }
+
+ mImpl->ParseScene(params);
+ return true;
+}
+
+std::string DliLoader::GetParseError() const
+{
+ std::stringstream stream;
+
+ auto& parser = mImpl->mParser;
+ if (parser.ParseError())
+ {
+ stream << "position: " << parser.GetErrorPosition() << ", line: " << parser.GetErrorLineNumber() << ", column: " << parser.GetErrorColumn() << ", description: " << parser.GetErrorDescription() << ".";
+ }
+
+ return stream.str();
+}
+
+void DliLoader::Impl::ParseScene(LoadParams& params)
+{
+ auto& input = params.input;
+ auto& output = params.output;
+
+ // get index of root node.
+ auto docRoot = mParser.GetRoot();
+
+ // Process resources first - these are shared
+ if (auto environments = docRoot->GetChild("environment"))
+ {
+ ParseEnvironments(environments, output.mResources); // NOTE: must precede parsing of materials
+ }
+
+ if (auto meshes = docRoot->GetChild("meshes"))
+ {
+ ParseMeshes(meshes, output.mResources);
+ }
+
+ if (auto shaders = docRoot->GetChild("shaders"))
+ {
+ ParseShaders(shaders, output.mResources);
+ }
+
+ if (auto materials = docRoot->GetChild("materials"))
+ {
+ ParseMaterials(materials, input.mConvertColorCode, output.mResources);
+ }
+
+ for (auto& c : input.mPreNodeCategoryProcessors)
+ {
+ if (auto node = docRoot->GetChild(c.first))
+ {
+ Property::Array array;
+ ParseProperties(*node, array);
+ c.second(std::move(array), mOnError);
+ }
+ }
+
+ // Process scenes
+ Index iScene = 0; // default scene
+ ReadIndex(docRoot->GetChild("scene"), iScene);
+
+ auto tnScenes = RequireChild(docRoot, "scenes");
+ auto tnNodes = RequireChild(docRoot, "nodes");
+ ParseSceneInternal(iScene, tnScenes, tnNodes, params);
+
+ ParseSkeletons(docRoot->GetChild("skeletons"), output.mScene, output.mResources);
+
+ output.mScene.EnsureUniqueSkinningShaderInstances(output.mResources);
+ output.mScene.EnsureUniqueBlendShapeShaderInstances(output.mResources);
+
+ // Ger cameras and lights
+ GetCameraParameters(output.mCameraParameters);
+ GetLightParameters(output.mLightParameters);
+
+ // Post-node processors and animations last
+ for (auto& c : input.mPostNodeCategoryProcessors)
+ {
+ if (auto node = docRoot->GetChild(c.first))
+ {
+ Property::Array array;
+ ParseProperties(*node, array);
+ c.second(std::move(array), mOnError);
+ }
+ }
+
+ if (auto animations = docRoot->GetChild("animations"))
+ {
+ ParseAnimations(animations, params);
+ }
+
+ if (!output.mAnimationDefinitions.empty())
+ {
+ if (auto animationGroups = docRoot->GetChild("animationGroups"))
+ {
+ ParseAnimationGroups(animationGroups, params);
+ }
+ }
+}
+
+void DliLoader::Impl::ParseSceneInternal(Index iScene, const Toolkit::TreeNode* tnScenes,
+ const Toolkit::TreeNode* tnNodes, LoadParams& params)
+{
+ auto getSceneRootIdx = [&](Index iScene) {
+ auto tn = Tidx(tnScenes, iScene); // now a "scene" object
+ if (!tn)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << iScene << " is out of bounds access into " << SCENES << ".";
+ }
+
+ tn = RequireChild(tn, NODES); // now a "nodes" array
+ if (tn->GetType() != TreeNode::ARRAY)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << SCENES << "[" << iScene << "]." << NODES <<
+ " has an invalid type; array required.";
+ }
+
+ if (tn->Size() < 1)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << SCENES << "[" << iScene << "]." << NODES <<
+ " must define a node id.";
+ }
+
+ tn = Tidx(tn, 0); // now the first element of the array
+ Index iRootNode;
+ if (!ReadIndex(tn, iRootNode))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << SCENES << "[" << iScene << "]." << NODES <<
+ " has an invalid value for root node index: '" << iRootNode << "'.";
+ }
+
+ if (iRootNode >= tnNodes->Size())
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Root node index << " << iRootNode << " of scene " << iScene << " is out of bounds.";
+ }
+
+ tn = Tidx(tnNodes, iRootNode); // now a "node" object
+ if (tn->GetType() != TreeNode::OBJECT)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Root node of scene " << iScene << " is of invalid JSON type; object required";
+ }
+
+ return iRootNode;
+ };
+
+ Index iRootNode = getSceneRootIdx(iScene);
+ ParseNodes(tnNodes, iRootNode, params);
+
+ auto& scene = params.output.mScene;
+ scene.AddRootNode(0);
+
+ for (Index i = 0; i < iScene; ++i)
+ {
+ Index iRootNode = getSceneRootIdx(i);
+ const Index iRoot = scene.GetNodeCount();
+ ParseNodes(tnNodes, iRootNode, params);
+ scene.AddRootNode(iRoot);
+ }
+
+ auto numScenes = tnScenes->Size();
+ for (Index i = iScene + 1; i < numScenes; ++i)
+ {
+ Index iRootNode = getSceneRootIdx(i);
+ const Index iRoot = scene.GetNodeCount();
+ ParseNodes(tnNodes, iRootNode, params);
+ scene.AddRootNode(iRoot);
+ }
+}
+
+void DliLoader::Impl::ParseSkeletons(const TreeNode* skeletons, SceneDefinition& scene, ResourceBundle& resources)
+{
+ if (skeletons)
+ {
+ auto iStart = skeletons->CBegin();
+ for (auto i0 = iStart, i1 = skeletons->CEnd(); i0 != i1; ++i0)
+ {
+ auto& node = (*i0).second;
+ std::string skeletonRootName;
+ if (ReadString(node.GetChild(NODE), skeletonRootName))
+ {
+ SkeletonDefinition skeleton;
+ if (!scene.FindNode(skeletonRootName, &skeleton.mRootNodeIdx))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << FormatString("Skeleton %d: node '%s' not defined.", resources.mSkeletons.size(), skeletonRootName.c_str());
+ }
+
+ uint32_t jointCount = 0;
+ std::function<void(Index)> visitFn;
+ auto& ibms = mInverseBindMatrices;
+ visitFn = [&](Index id) {
+ auto node = scene.GetNode(id);
+ jointCount += ibms.find(id) != ibms.end();
+
+ for (auto i : node->mChildren)
+ {
+ visitFn(i);
+ }
+ };
+ visitFn(skeleton.mRootNodeIdx);
+
+ if (jointCount > Skinning::MAX_JOINTS)
+ {
+ mOnError(FormatString("Skeleton %d: joint count exceeds supported limit.", resources.mSkeletons.size()));
+ jointCount = Skinning::MAX_JOINTS;
+ }
+
+ skeleton.mJoints.reserve(jointCount);
+
+ visitFn = [&](Index id) {
+ auto iFind = ibms.find(id);
+ if (iFind != ibms.end() && skeleton.mJoints.size() < Skinning::MAX_JOINTS)
+ {
+ skeleton.mJoints.push_back({ id, iFind->second });
+ }
+
+ auto node = scene.GetNode(id);
+ for (auto i : node->mChildren)
+ {
+ visitFn(i);
+ }
+ };
+ visitFn(skeleton.mRootNodeIdx);
+
+ resources.mSkeletons.push_back(std::move(skeleton));
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "skeleton " << std::distance(iStart, i0) <<
+ ": Missing required attribute '"<< NODE <<"'.";
+ }
+ }
+ }
+}
+
+void DliLoader::Impl::ParseEnvironments(const TreeNode* environments, ResourceBundle& resources)
+{
+ Matrix cubeOrientation(Matrix::IDENTITY);
+
+ for (auto i0 = environments->CBegin(), i1 = environments->CEnd(); i0 != i1; ++i0)
+ {
+ auto& node = (*i0).second;
+
+ EnvironmentDefinition envDef;
+ ReadString(node.GetChild("cubeSpecular"), envDef.mSpecularMapPath);
+ ReadString(node.GetChild("cubeDiffuse"), envDef.mDiffuseMapPath);
+ ToUnixFileSeparators(envDef.mSpecularMapPath);
+ ToUnixFileSeparators(envDef.mDiffuseMapPath);
+ envDef.mIblIntensity = 1.0f;
+ ReadFloat(node.GetChild("iblIntensity"), envDef.mIblIntensity);
+ if (ReadVector(node.GetChild("cubeInitialOrientation"), cubeOrientation.AsFloat(), 16u))
+ {
+ envDef.mCubeOrientation = Quaternion(cubeOrientation);
+ }
+
+ resources.mEnvironmentMaps.emplace_back(std::move(envDef), EnvironmentDefinition::Textures());
+ }
+
+ // NOTE: guarantees environmentMaps to have an empty environment.
+ if (resources.mEnvironmentMaps.empty())
+ {
+ resources.mEnvironmentMaps.emplace_back(EnvironmentDefinition(), EnvironmentDefinition::Textures());
+ }
+}
+
+void DliLoader::Impl::ParseShaders(const TreeNode* shaders, ResourceBundle& resources)
+{
+ uint32_t iShader = 0;
+ for (auto i0 = shaders->CBegin(), i1 = shaders->CEnd(); i0 != i1; ++i0, ++iShader)
+ {
+ auto& node = (*i0).second;
+ ShaderDefinition shaderDef;
+ ReadStringVector(node.GetChild("defines"), shaderDef.mDefines);
+
+ // Read shader hints. Possible values are:
+ // Don't define for No hints.
+ // "OUTPUT_IS_TRANSPARENT" Might generate transparent alpha from opaque inputs.
+ // "MODIFIES_GEOMETRY" Might change position of vertices, this option disables any culling optimizations.
+
+ ReadStringVector(node.GetChild( HINTS ), shaderDef.mHints);
+
+ if (ReadString(node.GetChild("vertex"), shaderDef.mVertexShaderPath) &&
+ ReadString(node.GetChild("fragment"), shaderDef.mFragmentShaderPath))
+ {
+ ToUnixFileSeparators(shaderDef.mVertexShaderPath);
+ ToUnixFileSeparators(shaderDef.mFragmentShaderPath);
+
+ for (TreeNode::ConstIterator j0 = node.CBegin(), j1 = node.CEnd(); j0 != j1; ++j0)
+ {
+ const TreeNode::KeyNodePair& keyValue = *j0;
+ const std::string& key = keyValue.first;
+ const TreeNode& value = keyValue.second;
+
+ Property::Value uniformValue;
+ if (key.compare("vertex") == 0 || key.compare("fragment") == 0 || key.compare("defines") == 0 || key.compare(HINTS) == 0)
+ {
+ continue;
+ }
+ else if (key.compare("rendererState") == 0)
+ {
+ shaderDef.mRendererState = ReadRendererState(keyValue.second);
+ }
+ else if (value.GetType() == TreeNode::INTEGER || value.GetType() == TreeNode::FLOAT)
+ {
+ float f = 0.f;
+ ReadFloat(&value, f);
+ uniformValue = f;
+ }
+ else if (value.GetType() == TreeNode::BOOLEAN)
+ {
+ DALI_LOG_WARNING("\"bool\" uniforms are handled as floats in shader");
+ bool value = false;
+ if (ReadBool(&keyValue.second, value))
+ {
+ uniformValue = value ? 1.0f : 0.0f;
+ }
+ }
+ else switch (auto size = GetNumericalArraySize(&value))
+ {
+ case 16:
+ {
+ Matrix m;
+ ReadVector(&value, m.AsFloat(), size);
+ uniformValue = m;
+ break;
+ }
+
+ case 9:
+ {
+ Matrix3 m;
+ ReadVector(&value, m.AsFloat(), size);
+ uniformValue = m;
+ break;
+ }
+
+ case 4:
+ {
+ Vector4 v;
+ ReadVector(&value, v.AsFloat(), size);
+ uniformValue = v;
+ break;
+ }
+
+ case 3:
+ {
+ Vector3 v;
+ ReadVector(&value, v.AsFloat(), size);
+ uniformValue = v;
+ break;
+ }
+
+ case 2:
+ {
+ Vector2 v;
+ ReadVector(&value, v.AsFloat(), size);
+ uniformValue = v;
+ break;
+ }
+
+ default:
+ mOnError(FormatString(
+ "shader %d: Ignoring uniform '%s': failed to infer type from %d elements.",
+ iShader, key.c_str()));
+ break;
+ }
+
+ if (Property::NONE != uniformValue.GetType())
+ {
+ shaderDef.mUniforms.Insert(key, uniformValue);
+ }
+ }
+
+ resources.mShaders.emplace_back(std::move(shaderDef), Shader());
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "shader " << iShader <<
+ ": Missing vertex / fragment shader definition.";
+ }
+ }
+}
+
+void DliLoader::Impl::ParseMeshes(const TreeNode* meshes, ResourceBundle& resources)
+{
+ for (auto i0 = meshes->CBegin(), i1 = meshes->CEnd(); i0 != i1; ++i0)
+ {
+ auto& node = (*i0).second;
+
+ MeshDefinition meshDef;
+ if (!ReadString(node.GetChild(URI), meshDef.mUri))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "mesh " << resources.mMeshes.size() <<
+ ": Missing required attribute '" << URI << "'.";
+ }
+
+ ToUnixFileSeparators(meshDef.mUri);
+
+ std::string primitive;
+ if (ReadString(node.GetChild("primitive"), primitive))
+ {
+ if (primitive == "LINES")
+ {
+ meshDef.mPrimitiveType = Geometry::LINES;
+ }
+ else if (primitive == "POINTS")
+ {
+ meshDef.mPrimitiveType = Geometry::POINTS;
+ }
+ else if (primitive != "TRIANGLES")
+ {
+ mOnError(FormatString(
+ "mesh %d: Using TRIANGLES instead of unsupported primitive type '%s'.",
+ resources.mMeshes.size(), primitive.c_str()));
+ }
+ }
+
+ int attributes;
+ if (ReadInt(node.GetChild("attributes"), attributes))
+ {
+ if (MaskMatch(attributes, MeshDefinition::INDICES) &&
+ !ReadAttribAccessor(node.GetChild("indices"), meshDef.mIndices))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << FormatString("mesh %d: Failed to read %s.",
+ resources.mMeshes.size(), "indices");
+ }
+
+ if (MaskMatch(attributes, MeshDefinition::POSITIONS) &&
+ !ReadAttribAccessor(node.GetChild("positions"), meshDef.mPositions))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << FormatString("mesh %d: Failed to read %s.",
+ resources.mMeshes.size(), "positions");
+ }
+
+ if (MaskMatch(attributes, MeshDefinition::NORMALS) &&
+ !ReadAttribAccessor(node.GetChild("normals"), meshDef.mNormals))
+ {
+ mOnError(FormatString("mesh %d: Failed to read %s.", resources.mMeshes.size(),
+ "normals"));
+ }
+
+ if (MaskMatch(attributes, MeshDefinition::TEX_COORDS) &&
+ !ReadAttribAccessor(node.GetChild("textures"), meshDef.mTexCoords))
+ {
+ mOnError(FormatString("mesh %d: Failed to read %s.", resources.mMeshes.size(),
+ "textures"));
+ }
+
+ if (MaskMatch(attributes, MeshDefinition::TANGENTS) &&
+ !ReadAttribAccessor(node.GetChild("tangents"), meshDef.mTangents))
+ {
+ mOnError(FormatString("mesh %d: Failed to read %s.", resources.mMeshes.size(),
+ "tangents"));
+ }
+
+ // NOTE: we're no longer reading bitangents as these are calculated in the shaders.
+ if (ReadIndex(node.GetChild("skeleton"), meshDef.mSkeletonIdx))
+ {
+ if (!MaskMatch(attributes, MeshDefinition::JOINTS_0) &&
+ !MaskMatch(attributes, MeshDefinition::WEIGHTS_0))
+ {
+ mOnError(FormatString("mesh %d: Expected joints0 / weights0 attribute(s) missing.",
+ resources.mMeshes.size()));
+ }
+ else if (!ReadAttribAccessor(node.GetChild("joints0"), meshDef.mJoints0) ||
+ !ReadAttribAccessor(node.GetChild("weights0"), meshDef.mWeights0))
+ {
+ mOnError(FormatString("mesh %d: Failed to read skinning information.",
+ resources.mMeshes.size()));
+ }
+ }
+
+ if (auto blendshapeHeader = node.GetChild(BLEND_SHAPE_HEADER))
+ {
+ std::string blendShapeVersion;
+ ReadString(blendshapeHeader->GetChild(VERSION), blendShapeVersion);
+
+ if (0u == blendShapeVersion.compare(BLEND_SHAPE_VERSION_1_0))
+ {
+ meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_1_0;
+ }
+ else if (0u == blendShapeVersion.compare(BLEND_SHAPE_VERSION_2_0))
+ {
+ meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
+ }
+
+ switch (meshDef.mBlendShapeVersion)
+ {
+ case BlendShapes::Version::VERSION_1_0:
+ case BlendShapes::Version::VERSION_2_0: // FALL THROUGH
+ {
+ ReadAttribBlob(blendshapeHeader, meshDef.mBlendShapeHeader);
+ break;
+ }
+ default:
+ {
+ // nothing to do
+ break;
+ }
+ }
+ }
+
+ if (auto blendShapes = node.GetChild(BLEND_SHAPES) )
+ {
+ meshDef.mBlendShapes.resize(blendShapes->Size());
+
+ auto index = 0u;
+ for (auto it = blendShapes->CBegin(), endIt = blendShapes->CEnd(); it != endIt; ++it, ++index)
+ {
+ // Each blend shape is stored as the difference with the original mesh.
+
+ auto& blendShapeNode = (*it).second;
+
+ auto& blendShape = meshDef.mBlendShapes[index];
+ ReadString(blendShapeNode.GetChild("name"), blendShape.name);
+ if (auto position = blendShapeNode.GetChild("positions"))
+ {
+ ReadAttribAccessor(position, blendShape.deltas);
+ }
+ if (auto normals = blendShapeNode.GetChild("normals"))
+ {
+ ReadAttribAccessor(normals, blendShape.normals);
+ }
+ if (auto tangents = blendShapeNode.GetChild("tangents"))
+ {
+ ReadAttribAccessor(tangents, blendShape.tangents);
+ }
+ ReadFloat(blendShapeNode.GetChild("weight"), blendShape.weight);
+ }
+ }
+
+ bool flipV;
+ if (ReadBool(node.GetChild("flipV"), flipV))
+ {
+ meshDef.mFlags |= flipV * MeshDefinition::FLIP_UVS_VERTICAL;
+ }
+
+ resources.mMeshes.emplace_back(std::move(meshDef), MeshGeometry());
+ }
+ }
+}
+
+void DliLoader::Impl::ParseMaterials(const TreeNode* materials, ConvertColorCode convertColorCode,
+ ResourceBundle& resources)
+{
+ for (auto i0 = materials->CBegin(), i1 = materials->CEnd(); i0 != i1; ++i0)
+ {
+ auto& node = (*i0).second;
+
+ MaterialDefinition materialDef;
+ if (auto eEnvironment = node.GetChild("environment"))
+ {
+ ReadIndex(eEnvironment, materialDef.mEnvironmentIdx);
+ if (static_cast<unsigned int>(materialDef.mEnvironmentIdx) >= resources.mEnvironmentMaps.size())
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "material " << resources.mMaterials.size() <<
+ ": Environment index " << materialDef.mEnvironmentIdx << " out of bounds (" <<
+ resources.mEnvironmentMaps.size() << ").";
+ }
+ }
+
+ //TODO : need to consider AGIF
+ std::vector<std::string> texturePaths;
+ std::string texturePath;
+ if (ReadString(node.GetChild("albedoMap"), texturePath))
+ {
+ ToUnixFileSeparators(texturePath);
+ const auto semantic = MaterialDefinition::ALBEDO;
+ materialDef.mTextureStages.push_back({ semantic, TextureDefinition{ std::move(texturePath) } });
+ materialDef.mFlags |= semantic | MaterialDefinition::TRANSPARENCY; // NOTE: only in dli does single / separate ALBEDO texture mean TRANSPARENCY.
+ }
+ if (ReadString(node.GetChild("albedoMetallicMap"), texturePath))
+ {
+ ToUnixFileSeparators(texturePath);
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO))
+ {
+ mOnError(FormatString("material %d: conflicting semantics; already set %s.", resources.mMaterials.size(), "albedo"));
+ }
+
+ const auto semantic = MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC;
+ materialDef.mTextureStages.push_back({ semantic, TextureDefinition{ std::move(texturePath) } });
+ materialDef.mFlags |= semantic;
+ }
+
+ if (ReadString(node.GetChild("metallicRoughnessMap"), texturePath))
+ {
+ ToUnixFileSeparators(texturePath);
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::METALLIC))
+ {
+ mOnError(FormatString("material %d: conflicting semantics; already set %s.", resources.mMaterials.size(), "metallic"));
+ }
+
+ const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS;
+ materialDef.mTextureStages.push_back({ semantic, TextureDefinition{ std::move(texturePath) } });
+ materialDef.mFlags |= semantic |
+ // We have a metallic-roughhness map and the first texture did not have albedo semantics - we're in the transparency workflow.
+ (MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO) * MaterialDefinition::TRANSPARENCY);
+ }
+
+ if (ReadString(node.GetChild("normalMap"), texturePath))
+ {
+ ToUnixFileSeparators(texturePath);
+
+ const auto semantic = MaterialDefinition::NORMAL;
+ materialDef.mTextureStages.push_back({ semantic, TextureDefinition{ std::move(texturePath) } });
+ materialDef.mFlags |= semantic |
+ // We have a standalone normal map and the first texture did not have albedo semantics - we're in the transparency workflow.
+ (MaskMatch(materialDef.mFlags, MaterialDefinition::ALBEDO) * MaterialDefinition::TRANSPARENCY);
+ }
+
+ if (ReadString(node.GetChild("normalRoughnessMap"), texturePath))
+ {
+ ToUnixFileSeparators(texturePath);
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::NORMAL))
+ {
+ mOnError(FormatString("material %d: conflicting semantics; already set %s.", resources.mMaterials.size(), "normal"));
+ }
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::ROUGHNESS))
+ {
+ mOnError(FormatString("material %d: conflicting semantics; already set %s.", resources.mMaterials.size(), "roughness"));
+ }
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY))
+ {
+ mOnError(FormatString("material %d: conflicting semantics; already set %s.", resources.mMaterials.size(), "transparency"));
+ }
+
+ const auto semantic = MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS;
+ materialDef.mTextureStages.push_back({ semantic, TextureDefinition{ std::move(texturePath) } });
+ materialDef.mFlags |= semantic;
+ }
+
+ if (ReadString(node.GetChild("subsurfaceMap"), texturePath))
+ {
+ ToUnixFileSeparators(texturePath);
+
+ const auto semantic = MaterialDefinition::SUBSURFACE;
+ materialDef.mTextureStages.push_back({ semantic, TextureDefinition{ std::move(texturePath) } });
+ materialDef.mFlags |= semantic;
+ }
+
+ if (ReadColorCodeOrColor(&node, materialDef.mColor, convertColorCode) &&
+ materialDef.mColor.a < 1.0f)
+ {
+ materialDef.mFlags |= MaterialDefinition::TRANSPARENCY;
+ }
+
+ ReadFloat(node.GetChild("metallic"), materialDef.mMetallic);
+ ReadFloat(node.GetChild("roughness"), materialDef.mRoughness);
+
+ bool mipmaps;
+ if (ReadBool(node.GetChild("mipmap"), mipmaps) && mipmaps)
+ {
+ for (auto& ts : materialDef.mTextureStages)
+ {
+ ts.mTexture.mSamplerFlags |= SamplerFlags::FILTER_MIPMAP_LINEAR;
+ }
+ }
+
+ resources.mMaterials.emplace_back(std::move(materialDef), TextureSet());
+ }
+}
+
+void DliLoader::Impl::ParseNodes(const TreeNode* const nodes, Index index, LoadParams& params)
+{
+ std::vector<Index> parents;
+ parents.reserve(8);
+
+ struct IndexMapper : IIndexMapper
+ {
+ IndexMapper(size_t numNodes)
+ {
+ mIndices.reserve(numNodes);
+ }
+
+ virtual bool Map(Index iDli, Index iScene) override
+ {
+ Entry idx{ iDli, iScene };
+ auto iInsert = std::lower_bound(mIndices.begin(), mIndices.end(), idx);
+ if (iInsert == mIndices.end() || iInsert->iDli != iDli)
+ {
+ mIndices.insert(iInsert, idx);
+ }
+ else if (iInsert->iScene != iScene)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ virtual unsigned int Resolve(Index iDli) override
+ {
+ auto iFind = std::lower_bound(mIndices.begin(), mIndices.end(), iDli,
+ [](const Entry& idx, Index iDli) {
+ return idx.iDli < iDli;
+ });
+ DALI_ASSERT_ALWAYS(iFind != mIndices.end());
+ return iFind->iScene;
+ }
+
+ private:
+ struct Entry
+ {
+ unsigned int iDli;
+ unsigned int iScene;
+
+ bool operator<(const Entry& other) const
+ {
+ return iDli < other.iDli;
+ }
+ };
+ std::vector<Entry> mIndices;
+ } mapper(nodes->Size());
+ ParseNodesInternal(nodes, index, parents, params, mapper);
+
+ auto& scene = params.output.mScene;
+ for (size_t i0 = 0, i1 = scene.GetNodeCount(); i0 < i1; ++i0)
+ {
+ for (auto& c : scene.GetNode(i0)->mConstraints)
+ {
+ c.mSourceIdx = mapper.Resolve(c.mSourceIdx);
+ }
+ }
+}
+
+void DliLoader::Impl::ParseNodesInternal(const TreeNode* const nodes, Index index,
+ std::vector<Index>& inOutParentStack, LoadParams& params, IIndexMapper& mapper)
+{
+ // Properties that may be resolved from a JSON value with ReadInt() -- or default to 0.
+ struct IndexProperty { ResourceType::Value type; const TreeNode* source; Index& target; };
+ std::vector<IndexProperty> resourceIds;
+ resourceIds.reserve(4);
+
+ if (auto node = Tidx(nodes, index))
+ {
+ NodeDefinition nodeDef;
+ nodeDef.mParentIdx = inOutParentStack.empty() ? INVALID_INDEX : inOutParentStack.back();
+
+ // name
+ ReadString(node->GetChild(NAME), nodeDef.mName);
+
+ // transform
+ ReadModelTransform(node, nodeDef.mOrientation, nodeDef.mPosition, nodeDef.mScale);
+
+ // Reads the size of the node.
+ //
+ // * It can be given as 'size' or 'bounds'.
+ // * The sdk saves the 'size' as a vector2 in some cases.
+ // * To avoid size related issues the following code attemps
+ // to read the 'size/bounds' as a vector3 first, if it's
+ // not successful then reads it as a vector2.
+ ReadVector(node->GetChild("size"), nodeDef.mSize.AsFloat(), 3) ||
+ ReadVector(node->GetChild("size"), nodeDef.mSize.AsFloat(), 2) ||
+ ReadVector(node->GetChild("bounds"), nodeDef.mSize.AsFloat(), 3) ||
+ ReadVector(node->GetChild("bounds"), nodeDef.mSize.AsFloat(), 2);
+
+ // visibility
+ ReadBool(node->GetChild("visible"), nodeDef.mIsVisible);
+
+ // type classification
+ if (auto eCustomization = node->GetChild("customization")) // customization
+ {
+ std::string tag;
+ if (ReadString(eCustomization->GetChild("tag"), tag))
+ {
+ nodeDef.mCustomization.reset(new NodeDefinition::CustomizationDefinition{ tag });
+ }
+ }
+ else // something renderable maybe
+ {
+ std::unique_ptr<NodeDefinition::Renderable> renderable;
+ ModelNode* modelNode = nullptr; // no ownership, aliasing renderable for the right type.
+
+ const TreeNode* eRenderable = nullptr;
+ if ((eRenderable = node->GetChild("model")))
+ {
+ // check for mesh before allocating - this can't be missing.
+ auto eMesh = eRenderable->GetChild("mesh");
+ if (!eMesh)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "node " << nodeDef.mName << ": Missing mesh definition.";
+ }
+
+ modelNode = new ModelNode();
+ renderable.reset(modelNode);
+
+ resourceIds.push_back({ ResourceType::Mesh, eMesh, modelNode->mMeshIdx });
+ }
+ else if ((eRenderable = node->GetChild("arc")))
+ {
+ // check for mesh before allocating - this can't be missing.
+ auto eMesh = eRenderable->GetChild("mesh");
+ if (!eMesh)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "node " << nodeDef.mName << ": Missing mesh definition.";
+ }
+
+ auto arcNode = new ArcNode;
+ renderable.reset(arcNode);
+ modelNode = arcNode;
+
+ resourceIds.push_back({ ResourceType::Mesh, eMesh, arcNode->mMeshIdx });
+
+ ReadArcField(eRenderable, *arcNode);
+ }
+
+ if (renderable) // process common properties of all renderables + register payload
+ {
+ // shader
+ renderable->mShaderIdx = 0;
+ auto eShader = eRenderable->GetChild("shader");
+ resourceIds.push_back({ ResourceType::Shader, eShader, renderable->mShaderIdx });
+
+ // color
+ if (modelNode)
+ {
+ modelNode->mMaterialIdx = 0; // must offer default of 0
+ auto eMaterial = eRenderable->GetChild("material");
+ resourceIds.push_back({ ResourceType::Material, eMaterial, modelNode->mMaterialIdx });
+
+ if (!ReadColorCodeOrColor(eRenderable, modelNode->mColor, params.input.mConvertColorCode))
+ {
+ ReadColorCodeOrColor(node, modelNode->mColor, params.input.mConvertColorCode);
+ }
+ }
+
+ nodeDef.mRenderable = std::move(renderable);
+ }
+ }
+
+ // Resolve ints - default to 0 if undefined
+ auto& output = params.output;
+ for (auto& idRes : resourceIds)
+ {
+ Index iCheck = 0;
+ switch (idRes.type)
+ {
+ case ResourceType::Shader:
+ iCheck = output.mResources.mShaders.size();
+ break;
+
+ case ResourceType::Mesh:
+ iCheck = output.mResources.mMeshes.size();
+ break;
+
+ case ResourceType::Material:
+ iCheck = output.mResources.mMaterials.size();
+ break;
+
+ default:
+ ExceptionFlinger(ASSERT_LOCATION) << "node " << index << ": Invalid resource type: " <<
+ idRes.type << " (Programmer error)";
+ }
+
+ if (!idRes.source)
+ {
+ idRes.target = 0;
+ }
+ else if (idRes.source->GetType() != TreeNode::INTEGER)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "node " << index << ": Invalid " <<
+ GetResourceTypeName(idRes.type) << " index type.";
+ }
+ else
+ {
+ idRes.target = idRes.source->GetInteger();
+ }
+
+ if (idRes.target >= iCheck)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "node " << index << ": " <<
+ GetResourceTypeName(idRes.type) << " index " << idRes.target << " out of bounds (" <<
+ iCheck << ").";
+ }
+ }
+ resourceIds.clear();
+
+ // Extra properties
+ if (auto eExtras = node->GetChild("extras"))
+ {
+ auto& extras = nodeDef.mExtras;
+ extras.reserve(eExtras->Size());
+
+ NodeDefinition::Extra e;
+ for (auto i0 = eExtras->CBegin(), i1 = eExtras->CEnd(); i0 != i1; ++i0)
+ {
+ auto eExtra = *i0;
+ e.mKey = eExtra.first;
+ if (e.mKey.empty())
+ {
+ mOnError(FormatString("node %d: empty string is invalid for name of extra %d; ignored.",
+ index, extras.size()));
+ continue;
+ }
+
+ e.mValue = ReadPropertyValue(eExtra.second);
+ if (e.mValue.GetType() == Property::Type::NONE)
+ {
+ mOnError(FormatString("node %d: failed to interpret value of extra '%s' : %s; ignored.",
+ index, e.mKey.c_str(), eExtra.second.GetString()));
+ }
+ else
+ {
+ auto iInsert = std::lower_bound(extras.begin(), extras.end(), e);
+ if (iInsert != extras.end() && iInsert->mKey == e.mKey)
+ {
+ mOnError(FormatString("node %d: extra '%s' already defined; overriding with %s.",
+ index, e.mKey.c_str(), eExtra.second.GetString()));
+ *iInsert = std::move(e);
+ }
+ else
+ {
+ extras.insert(iInsert, e);
+ }
+ }
+ }
+ }
+
+ // Constraints
+ if (auto eConstraints = node->GetChild("constraints"))
+ {
+ auto& constraints = nodeDef.mConstraints;
+ constraints.reserve(eConstraints->Size());
+
+ ConstraintDefinition cDef;
+ for (auto i0 = eConstraints->CBegin(), i1 = eConstraints->CEnd(); i0 != i1; ++i0)
+ {
+ auto eConstraint = *i0;
+ if (!ReadIndex(&eConstraint.second, cDef.mSourceIdx))
+ {
+ mOnError(FormatString("node %d: node ID %s for constraint %d is invalid; ignored.",
+ index, eConstraint.second.GetString(), constraints.size()));
+ }
+ else
+ {
+ cDef.mProperty = eConstraint.first;
+
+ auto iInsert = std::lower_bound(constraints.begin(), constraints.end(), cDef);
+ if (iInsert != constraints.end() && *iInsert == cDef)
+ {
+ mOnError(FormatString("node %d: constraint %s@%d already defined; ignoring.",
+ index, cDef.mProperty.c_str(), cDef.mSourceIdx));
+ }
+ else
+ {
+ constraints.insert(iInsert, cDef);
+ }
+ }
+ }
+ }
+
+ // Determine index for mapping
+ const unsigned int myIndex = output.mScene.GetNodeCount();
+ if (!mapper.Map(index, myIndex))
+ {
+ mOnError(FormatString("node %d: error mapping dli index %d: node has multiple parents. Ignoring subtree."));
+ return;
+ }
+
+ // if the node is a bone in a skeletal animation, it will have the inverse bind pose matrix.
+ Matrix invBindMatrix{ false };
+ if (ReadVector(node->GetChild("inverseBindPoseMatrix"), invBindMatrix.AsFloat(), 16u)) // TODO: more robust error checking?
+ {
+ mInverseBindMatrices[myIndex] = invBindMatrix;
+ }
+
+ // Register nodeDef
+ auto rawDef = output.mScene.AddNode(std::make_unique<NodeDefinition>(std::move(nodeDef)));
+ if (rawDef) // NOTE: no ownership. Guaranteed to stay in scope.
+ {
+ // ...And only then parse children.
+ if (auto children = node->GetChild("children"))
+ {
+ inOutParentStack.push_back(myIndex);
+
+ rawDef->mChildren.reserve(children->Size());
+
+ uint32_t iChild = 0;
+ for (auto j0 = children->CBegin(), j1 = children->CEnd(); j0 != j1; ++j0, ++iChild)
+ {
+ auto& child = (*j0).second;
+ if (child.GetType() == TreeNode::INTEGER)
+ {
+ ParseNodesInternal(nodes, child.GetInteger(), inOutParentStack, params, mapper); // child object is created in scene definition.
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "node " << index << ", child " << iChild <<
+ ": invalid index type.";
+ }
+ }
+
+ inOutParentStack.pop_back();
+ }
+ else if (rawDef->mCustomization)
+ {
+ mOnError(FormatString("node %d: not an actual customization without children.", index));
+ }
+
+ if (auto proc = params.input.mNodePropertyProcessor) // optional processing
+ {
+ // WARNING: constraint IDs are not resolved at this point.
+ Property::Map nodeData;
+ ParseProperties(*node, nodeData);
+ proc(*rawDef, std::move(nodeData), mOnError);
+ }
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Node " << index << ": name already used.";
+ }
+ }
+}
+
+void DliLoader::Impl::ParseAnimations(const TreeNode* tnAnimations, LoadParams& params)
+{
+ auto& definitions = params.output.mAnimationDefinitions;
+ definitions.reserve(definitions.size() + tnAnimations->Size());
+
+ for (TreeNode::ConstIterator iAnim = tnAnimations->CBegin(), iAnimEnd = tnAnimations->CEnd();
+ iAnim != iAnimEnd; ++iAnim)
+ {
+ const TreeNode& tnAnim = (*iAnim).second;
+ AnimationDefinition animDef;
+ ReadString(tnAnim.GetChild(NAME), animDef.mName);
+
+ auto iFind = std::lower_bound(definitions.begin(), definitions.end(), animDef,
+ [](const AnimationDefinition& ad0, const AnimationDefinition& ad1) {
+ return ad0.mName < ad1.mName;
+ });
+ const bool overwrite = iFind != definitions.end() && iFind->mName == animDef.mName;
+ if (overwrite)
+ {
+ mOnError(FormatString("Pre-existing animation with name '%s' is being overwritten.", animDef.mName.c_str()));
+ }
+
+ // Duration -- We need something that animated properties' delay / duration can
+ // be expressed as a multiple of; 0 won't work. This is small enough (i.e. shorter
+ // than our frame delay) to not be restrictive WRT replaying. If anything needs
+ // to occur more frequently, then Animations are likely not your solution anyway.
+ animDef.mDuration = AnimationDefinition::MIN_DURATION_SECONDS;
+ if (!ReadFloat(tnAnim.GetChild("duration"), animDef.mDuration))
+ {
+ mOnError(FormatString("Animation '%s' fails to define '%s', defaulting to %f.",
+ animDef.mName.c_str(), "duration", animDef.mDuration));
+ }
+
+ // Get loop count - # of playbacks. Default is once. 0 means repeat indefinitely.
+ animDef.mLoopCount = 1;
+ if (ReadInt(tnAnim.GetChild("loopCount"), animDef.mLoopCount) &&
+ animDef.mLoopCount < 0)
+ {
+ animDef.mLoopCount = 0;
+ }
+
+ std::string endAction;
+ if (ReadString(tnAnim.GetChild("endAction"), endAction))
+ {
+ if ("BAKE" == endAction)
+ {
+ animDef.mEndAction = Animation::BAKE;
+ }
+ else if ("DISCARD" == endAction)
+ {
+ animDef.mEndAction = Animation::DISCARD;
+ }
+ else if ("BAKE_FINAL" == endAction)
+ {
+ animDef.mEndAction = Animation::BAKE_FINAL;
+ }
+ }
+
+ if (ReadString(tnAnim.GetChild("disconnectAction"), endAction))
+ {
+ if ("BAKE" == endAction)
+ {
+ animDef.mDisconnectAction = Animation::BAKE;
+ }
+ else if ("DISCARD" == endAction)
+ {
+ animDef.mDisconnectAction = Animation::DISCARD;
+ }
+ else if ("BAKE_FINAL" == endAction)
+ {
+ animDef.mDisconnectAction = Animation::BAKE_FINAL;
+ }
+ }
+
+ if (const TreeNode* tnProperties = tnAnim.GetChild("properties"))
+ {
+ animDef.mProperties.reserve(tnProperties->Size());
+ for (TreeNode::ConstIterator iProperty = tnProperties->CBegin(), iPropertyEnd = tnProperties->CEnd();
+ iProperty != iPropertyEnd; ++iProperty)
+ {
+ const TreeNode &tnProperty = (*iProperty).second;
+
+ AnimatedProperty animProp;
+ if (!ReadString(tnProperty.GetChild("node"), animProp.mNodeName))
+ {
+ mOnError(FormatString("Animation '%s': Failed to read the 'node' tag.", animDef.mName.c_str()));
+ continue;
+ }
+
+ if (!ReadString(tnProperty.GetChild("property"), animProp.mPropertyName))
+ {
+ mOnError(FormatString("Animation '%s': Failed to read the 'property' tag", animDef.mName.c_str()));
+ continue;
+ }
+
+ // these are the defaults
+ animProp.mTimePeriod.delaySeconds = 0.f;
+ animProp.mTimePeriod.durationSeconds = animDef.mDuration;
+ if (!ReadTimePeriod(tnProperty.GetChild("timePeriod"), animProp.mTimePeriod))
+ {
+ mOnError(FormatString("Animation '%s': timePeriod missing in Property #%d: defaulting to %f.",
+ animDef.mName.c_str(), animDef.mProperties.size(), animProp.mTimePeriod.durationSeconds));
+ }
+
+ std::string alphaFunctionValue;
+ if (ReadString(tnProperty.GetChild("alphaFunction"), alphaFunctionValue))
+ {
+ animProp.mAlphaFunction = GetAlphaFunction(alphaFunctionValue);
+ }
+
+ if (const TreeNode* tnKeyFramesBin = tnProperty.GetChild("keyFramesBin"))
+ {
+ DALI_ASSERT_ALWAYS(!animProp.mPropertyName.empty() && "Animation must specify a property name");
+
+ std::ifstream binAniFile;
+ std::string animationFilename;
+ if (ReadString(tnKeyFramesBin->GetChild(URL), animationFilename))
+ {
+ std::string animationFullPath = params.input.mAnimationsPath + animationFilename;
+ binAniFile.open(animationFullPath, std::ios::binary);
+ if (binAniFile.fail())
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to open animation data '" <<
+ animationFullPath << "'";
+ }
+ }
+
+ int byteOffset = 0;
+ ReadInt(tnKeyFramesBin->GetChild("byteOffset"), byteOffset);
+ DALI_ASSERT_ALWAYS(byteOffset >= 0);
+
+ binAniFile.seekg(byteOffset, std::ios::beg);
+
+ int numKeys = 0;
+ ReadInt(tnKeyFramesBin->GetChild("numKeys"), numKeys);
+ DALI_ASSERT_ALWAYS(numKeys >= 0);
+
+ animProp.mKeyFrames = KeyFrames::New();
+
+ //In binary animation file only is saved the position, rotation, scale and blend shape weight keys.
+ //so, if it is vector3 we assume is position or scale keys, if it is vector4 we assume is rotation,
+ // otherwise are blend shape weight keys.
+ // TODO support for binary header with size information
+ Property::Type propType = Property::FLOAT; // assume blend shape weights
+ if (animProp.mPropertyName == "orientation")
+ {
+ propType = Property::VECTOR4;
+ }
+ else if ((animProp.mPropertyName == "position") || (animProp.mPropertyName == "scale"))
+ {
+ propType = Property::VECTOR3;
+ }
+
+ //alphafunction is reserved for future implementation
+ // NOTE: right now we're just using AlphaFunction::LINEAR.
+ unsigned char dummyAlphaFunction;
+
+ float progress;
+ Property::Value propValue;
+ for (int key = 0; key < numKeys; key++)
+ {
+ binAniFile.read(reinterpret_cast<char*>(&progress), sizeof(float));
+ if (propType == Property::VECTOR3)
+ {
+ Vector3 value;
+ binAniFile.read(reinterpret_cast<char*>(value.AsFloat()), sizeof(float) * 3);
+ propValue = Property::Value(value);
+ }
+ else if (propType == Property::VECTOR4)
+ {
+ Vector4 value;
+ binAniFile.read(reinterpret_cast<char*>(value.AsFloat()), sizeof(float) * 4);
+ propValue = Property::Value(Quaternion(value));
+ }
+ else
+ {
+ float value;
+ binAniFile.read(reinterpret_cast<char*>(&value), sizeof(float));
+ propValue = Property::Value(value);
+ }
+
+ binAniFile.read(reinterpret_cast<char*>(&dummyAlphaFunction), sizeof(unsigned char));
+
+ animProp.mKeyFrames.Add(progress, propValue, AlphaFunction::LINEAR);
+ }
+ }
+ else if (const TreeNode* tnKeyFrames = tnProperty.GetChild("keyFrames"))
+ {
+ DALI_ASSERT_ALWAYS(!animProp.mPropertyName.empty() && "Animation must specify a property name");
+ animProp.mKeyFrames = KeyFrames::New();
+
+ float progress = 0.0f;
+ for (auto i0 = tnKeyFrames->CBegin(), i1 = tnKeyFrames->CEnd(); i1 != i0; ++i0)
+ {
+ const TreeNode::KeyNodePair& kfKeyChild = *i0;
+ bool readResult = ReadFloat(kfKeyChild.second.GetChild("progress"), progress);
+ DALI_ASSERT_ALWAYS(readResult && "Key frame entry must have 'progress'");
+
+ const TreeNode* tnValue = kfKeyChild.second.GetChild("value");
+ DALI_ASSERT_ALWAYS(tnValue && "Key frame entry must have 'value'");
+
+ // For the "orientation" property, convert from Vector4 -> Rotation value
+ // This work-around is preferable to a null-pointer exception in the DALi update thread
+ Property::Value propValue(ReadPropertyValue(*tnValue));
+ if (propValue.GetType() == Property::VECTOR4 &&
+ animProp.mPropertyName == "orientation")
+ {
+ Vector4 v;
+ propValue.Get(v);
+ propValue = Property::Value(Quaternion(v.w, v.x, v.y, v.z));
+ }
+
+ AlphaFunction kfAlphaFunction(AlphaFunction::DEFAULT);
+ std::string alphaFuncStr;
+ if (ReadString(kfKeyChild.second.GetChild("alphaFunction"), alphaFuncStr))
+ {
+ kfAlphaFunction = GetAlphaFunction(alphaFuncStr);
+ }
+
+ animProp.mKeyFrames.Add(progress, propValue, kfAlphaFunction);
+ }
+ }
+ else
+ {
+ const TreeNode* tnValue = tnProperty.GetChild("value");
+ if (tnValue)
+ {
+ animProp.mValue.reset(new AnimatedProperty::Value{ ReadPropertyValue(*tnValue) });
+ }
+ else
+ {
+ mOnError(FormatString("Property '%s' fails to define target value.",
+ animProp.mPropertyName.c_str()));
+ }
+
+ ReadBool(tnProperty.GetChild("relative"), animProp.mValue->mIsRelative);
+ }
+
+ animDef.mProperties.push_back(std::move(animProp));
+ }
+ }
+
+ if (overwrite)
+ {
+ *iFind = std::move(animDef);
+ }
+ else
+ {
+ iFind = definitions.insert(iFind, std::move(animDef));
+ }
+
+ if (auto proc = params.input.mAnimationPropertyProcessor) // optional processing
+ {
+ Property::Map map;
+ ParseProperties(tnAnim, map);
+ proc(animDef, std::move(map), mOnError);
+ }
+ }
+}
+
+void DliLoader::Impl::ParseAnimationGroups(const Toolkit::TreeNode* tnAnimationGroups, LoadParams& params)
+{
+ auto& animGroups = params.output.mAnimationGroupDefinitions;
+
+ int numGroups = 0;
+ for (auto iGroups = tnAnimationGroups->CBegin(), iGroupsEnd = tnAnimationGroups->CEnd();
+ iGroups != iGroupsEnd; ++iGroups, ++numGroups)
+ {
+ const auto& tnGroup = *iGroups;
+ auto tnName = tnGroup.second.GetChild(NAME);
+ std::string groupName;
+ if (!tnName || !ReadString(tnName, groupName))
+ {
+ mOnError(FormatString("Failed to get the name for the Animation group %d; ignoring.", numGroups));
+ continue;
+ }
+
+ auto iFind = std::lower_bound(animGroups.begin(), animGroups.end(), groupName,
+ [](const AnimationGroupDefinition& group, const std::string& name) {
+ return group.mName < name;
+ });
+ if (iFind != animGroups.end() && iFind->mName == groupName)
+ {
+ mOnError(FormatString("Animation group with name '%s' already exists; new entries will be merged.", groupName.c_str()));
+ }
+ else
+ {
+ iFind = animGroups.insert(iFind, AnimationGroupDefinition{});
+ }
+
+ iFind->mName = groupName;
+
+ auto tnAnims = tnGroup.second.GetChild("animations");
+ if (tnAnims && tnAnims->Size() > 0)
+ {
+ auto& anims = iFind->mAnimations;
+ anims.reserve(anims.size() + tnAnims->Size());
+ for (auto iAnims = tnAnims->CBegin(), iAnimsEnd = tnAnims->CEnd(); iAnims != iAnimsEnd; ++iAnims)
+ {
+ anims.push_back((*iAnims).second.GetString());
+ }
+ }
+ }
+}
+
+void DliLoader::Impl::GetCameraParameters(std::vector<CameraParameters>& cameras) const
+{
+ if (const TreeNode* jsonCameras = mParser.GetRoot()->GetChild("cameras"))
+ {
+ cameras.resize(jsonCameras->Size());
+ auto iCamera = cameras.begin();
+ for (auto i0 = jsonCameras->CBegin(), i1 = jsonCameras->CEnd(); i0 != i1; ++i0)
+ {
+ auto& jsonCamera = (*i0).second;
+
+ ReadFloat(jsonCamera.GetChild("fov"), iCamera->yFov);
+ ReadFloat(jsonCamera.GetChild("near"), iCamera->zNear);
+ ReadFloat(jsonCamera.GetChild("far"), iCamera->zFar);
+ if (ReadVector(jsonCamera.GetChild("orthographic"), iCamera->orthographicSize.AsFloat(), 4u))
+ {
+ iCamera->isPerspective = false;
+ }
+
+ if (auto jsonMatrix = jsonCamera.GetChild("matrix"))
+ {
+ ReadVector(jsonMatrix, iCamera->matrix.AsFloat(), 16u);
+ }
+
+ ++iCamera;
+ }
+ }
+}
+
+void DliLoader::Impl::GetLightParameters(std::vector<LightParameters>& lights) const
+{
+ if (const TreeNode* jsonLights = mParser.GetRoot()->GetChild("lights"))
+ {
+ lights.resize(jsonLights->Size());
+ auto iLight = lights.begin();
+ for (auto i0 = jsonLights->CBegin(), i1 = jsonLights->CEnd(); i0 != i1; ++i0)
+ {
+ auto& jsonLight = (*i0).second;
+ if (!ReadVector(jsonLight.GetChild("matrix"), iLight->transform.AsFloat(), 16))
+ {
+ mOnError(
+ FormatString("Failed to parse light %d - \"matrix\" child with 16 floats expected.\n",
+ std::distance(jsonLights->CBegin(), i0)));
+ continue;
+ }
+
+ int shadowMapSize = 0;
+ if (ReadInt(jsonLight.GetChild(SHADOW_MAP_SIZE), shadowMapSize) && shadowMapSize < 0)
+ {
+ mOnError(
+ FormatString("Failed to parse light %d - %s has an invalid value.",
+ std::distance(jsonLights->CBegin(), i0), SHADOW_MAP_SIZE));
+ continue;
+ }
+ iLight->shadowMapSize = shadowMapSize;
+
+ float orthoSize = 0.f;
+ if (ReadFloat(jsonLight.GetChild(ORTHOGRAPHIC_SIZE), orthoSize) &&
+ (orthoSize < .0f || std::isnan(orthoSize) || std::isinf(orthoSize)))
+ {
+ mOnError(
+ FormatString("Failed to parse light %d - %s has an invalid value.",
+ std::distance(jsonLights->CBegin(), i0), ORTHOGRAPHIC_SIZE));
+ continue;
+ }
+ iLight->orthographicSize = orthoSize;
+
+ if ((iLight->shadowMapSize > 0) != (iLight->orthographicSize > .0f))
+ {
+ mOnError(FormatString(
+ "Light %d: Both shadow map size and orthographic size must be set for shadows to work.",
+ std::distance(jsonLights->CBegin(), i0)));
+ }
+
+ if (!ReadVector(jsonLight.GetChild("color"), iLight->color.AsFloat(), 3)) // color is optional
+ {
+ iLight->color = Vector3::ONE; // default to white
+ }
+
+ if (!ReadFloat(jsonLight.GetChild("intensity"), iLight->intensity)) // intensity is optional
+ {
+ iLight->intensity = 1.0f; // default to 1.0
+ }
+
+ if (!ReadFloat(jsonLight.GetChild("shadowIntensity"), iLight->shadowIntensity)) // intensity is optional
+ {
+ iLight->shadowIntensity = 1.0f; // default to 1.0
+ }
+
+ ++iLight;
+ }
+ }
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_DLI_LOADER_H
+#define DALI_SCENE_LOADER_DLI_LOADER_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ // INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/animation-definition.h"
+#include "dali-scene-loader/public-api/customization.h"
+#include "dali-scene-loader/public-api/string-callback.h"
+#include "dali-scene-loader/public-api/index.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+typedef std::pair<std::string, std::string> Metadata;
+
+// Forward declarations
+struct LoadResult;
+struct CameraParameters;
+struct LightParameters;
+struct TextParameters;
+
+class ResourceBundle;
+struct NodeDefinition;
+class SceneDefinition;
+
+class DALI_SCENE_LOADER_API DliLoader
+{
+public:
+ using ConvertFontCode = void(*)(const std::string& code, std::string& fontFamily, std::string& slant, std::string& weight, float& size);
+ using ConvertColorCode = Vector4(*)(const std::string& code);
+
+ using CategoryProcessor = std::function<void(Property::Array&& categoryData, StringCallback onError)>;
+ using CategoryProcessorVector = std::vector<std::pair<std::string /*name*/, CategoryProcessor>>;
+
+ using NodeProcessor = std::function<void(const NodeDefinition& nodeDef,
+ Property::Map&& nodeData, StringCallback onError)>;
+
+ using AnimationProcessor = std::function<void(const AnimationDefinition& animDef,
+ Property::Map&& animData, StringCallback onError)>;
+
+ struct InputParams
+ {
+ /**
+ * @brief The absolute path of animation binaries referenced in the .dli.
+ */
+ std::string mAnimationsPath;
+
+ /**
+ * @brief Provides a facility to determine a color from a code instead of RGB(A) values.
+ */
+ ConvertColorCode mConvertColorCode;
+
+ /**
+ * @brief A collection of handlers, mapped to the names of the top level (i.e. below
+ * root) element, whom they will attempt to process. This will take place before
+ * the parsing of scene Nodes and Animations, but after skeletons, environment, mesh,
+ * shader and material resources.
+ */
+ CategoryProcessorVector mPreNodeCategoryProcessors;
+
+ /**
+ * @brief A collection of handlers, mapped to the names of the top level (i.e. below
+ * root) element, whom they will attempt to process. This will take place after
+ * the parsing of the scene Nodes and Animations.
+ */
+ CategoryProcessorVector mPostNodeCategoryProcessors;
+
+ /**
+ * @brief Provides an extension point to nodes. If provided, this function will be
+ * called with each JSON element and definition, of a scene node.
+ * @note Constraints rely on ID resolution (from .dli to scene definition), which
+ * takes place after the parsing of the nodes; therefore AT THIS POINT the node
+ * IDs seen in constraints will still be the .dli IDs - NOT to be relied on for
+ * indexing into mScene.
+ */
+ NodeProcessor mNodePropertyProcessor;
+
+ /**
+ * @brief Provides an extension point to animations. If provided, this function will be
+ * called with each JSON element and fully processed definition, of an animation.
+ */
+ AnimationProcessor mAnimationPropertyProcessor;
+ };
+
+ struct LoadParams
+ {
+ InputParams const& input;
+ LoadResult& output;
+ };
+
+ DliLoader();
+ ~DliLoader();
+
+ /**
+ * @brief Sets the callback that messages from non-fatal errors get posted to.
+ * Uses DefaultErrorCallback by default.
+ */
+ void SetErrorCallback(StringCallback onError);
+
+ /**
+ * @brief Attempts to load and parse a .dli document into a DOM tree.
+ * @return Whether the operation was successful.
+ */
+ bool LoadScene(const std::string& uri, LoadParams& params);
+
+ /**
+ * @return The error string describing how the parse has failed, if any.
+ */
+ std::string GetParseError() const;
+
+private:
+ struct Impl;
+ const std::unique_ptr<Impl> mImpl;
+};
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_DLI_LOADER_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/environment-definition.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+EnvironmentDefinition::RawData
+ EnvironmentDefinition::LoadRaw(const std::string& environmentsPath) const
+{
+ RawData raw;
+ auto loadFn = [&environmentsPath](const std::string& path, CubeData& cd) {
+ if (path.empty())
+ {
+ cd.data.resize(6);
+ for (auto& face : cd.data)
+ {
+ face.push_back(PixelData::New(new uint8_t[3]{ 0xff, 0xff, 0xff }, 3, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY));
+ }
+ }
+ else if(!LoadCubeMapData(environmentsPath + path, cd))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to load cubemap texture from '" <<
+ path << "'.";
+ }
+ };
+
+ loadFn(mDiffuseMapPath, raw.mDiffuse);
+ loadFn(mSpecularMapPath, raw.mSpecular);
+ return raw;
+}
+
+EnvironmentDefinition::Textures EnvironmentDefinition::Load(RawData&& raw) const
+{
+ Textures textures;
+
+ // This texture should have 6 faces and only one mipmap
+ if (!raw.mDiffuse.data.empty())
+ {
+ textures.mDiffuse = raw.mDiffuse.CreateTexture();
+ }
+
+ // This texture should have 6 faces and 6 mipmaps
+ if (!raw.mSpecular.data.empty())
+ {
+ textures.mSpecular = raw.mSpecular.CreateTexture();
+ }
+ return textures;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_ENVIRONMENT_DEFINITION_H
+#define DALI_SCENE_LOADER_ENVIRONMENT_DEFINITION_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ // INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/ktx-loader.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/rendering/texture.h"
+#include "dali/public-api/math/quaternion.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Defines an environment map with either or both of radiance
+ * and irradiance maps.
+ */
+struct DALI_SCENE_LOADER_API EnvironmentDefinition
+{
+ struct Textures
+ {
+ Texture mDiffuse; // irradiance
+ Texture mSpecular; // radiance
+
+ bool IsLoaded() const
+ {
+ return mDiffuse || mSpecular;
+ }
+ };
+
+ struct RawData
+ {
+ CubeData mDiffuse;
+ CubeData mSpecular;
+ };
+
+ using EnvironmentData = std::pair<EnvironmentDefinition, Textures>;
+ using Vector = std::vector<EnvironmentData>;
+
+ EnvironmentDefinition() = default;
+
+ EnvironmentDefinition(const EnvironmentDefinition&) = delete;
+ EnvironmentDefinition& operator=(const EnvironmentDefinition&) = delete;
+
+ EnvironmentDefinition(EnvironmentDefinition&&) = default;
+ EnvironmentDefinition& operator=(EnvironmentDefinition&&) = default;
+
+ /**
+ * @brief Loads raw pixel data for the given diffuse and specular maps.
+ * @note This can be done on any thread.
+ */
+ RawData LoadRaw(const std::string& environmentsPath) const;
+
+ /**
+ * @brief Creates DALi cubemap Textures from the pixel data in @a raw, then
+ * returns them in a Textures object.
+ * @note This must only be called from the event thread.
+ */
+ Textures Load(RawData&& raw) const;
+
+public: // DATA
+ std::string mDiffuseMapPath;
+ std::string mSpecularMapPath;
+ Quaternion mCubeOrientation = Quaternion::IDENTITY;
+ float mIblIntensity = 1.0f;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_ENVIRONMENT_DEFINITION_H
--- /dev/null
+set(scene_loader_public_api_dir "${scene_loader_dir}/public-api")
+
+set(scene_loader_src_files ${scene_loader_src_files}
+ ${scene_loader_public_api_dir}/alpha-function-helper.cpp
+ ${scene_loader_public_api_dir}/animated-property.cpp
+ ${scene_loader_public_api_dir}/animation-definition.cpp
+ ${scene_loader_public_api_dir}/blend-shape-details.cpp
+ ${scene_loader_public_api_dir}/camera-parameters.cpp
+ ${scene_loader_public_api_dir}/customization.cpp
+ ${scene_loader_public_api_dir}/dli-loader.cpp
+ ${scene_loader_public_api_dir}/environment-definition.cpp
+ ${scene_loader_public_api_dir}/gltf2-loader.cpp
+ ${scene_loader_public_api_dir}/ktx-loader.cpp
+ ${scene_loader_public_api_dir}/material-definition.cpp
+ ${scene_loader_public_api_dir}/matrix-stack.cpp
+ ${scene_loader_public_api_dir}/mesh-definition.cpp
+ ${scene_loader_public_api_dir}/node-definition.cpp
+ ${scene_loader_public_api_dir}/parse-renderer-state.cpp
+ ${scene_loader_public_api_dir}/renderer-state.cpp
+ ${scene_loader_public_api_dir}/resource-bundle.cpp
+ ${scene_loader_public_api_dir}/scene-definition.cpp
+ ${scene_loader_public_api_dir}/shader-definition.cpp
+ ${scene_loader_public_api_dir}/shader-definition-factory.cpp
+ ${scene_loader_public_api_dir}/skinning-details.cpp
+ ${scene_loader_public_api_dir}/string-callback.cpp
+ ${scene_loader_public_api_dir}/utils.cpp
+ ${scene_loader_public_api_dir}/view-projection.cpp
+)
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/load-result.h"
+#include "dali-scene-loader/public-api/scene-definition.h"
+#include "dali-scene-loader/public-api/resource-bundle.h"
+#include "dali-scene-loader/public-api/gltf2-loader.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include "dali-scene-loader/public-api/shader-definition-factory.h"
+#include "dali-scene-loader/internal/gltf2-asset.h"
+#include "dali/public-api/math/quaternion.h"
+#include <fstream>
+
+#define ENUM_STRING_MAPPING(t, x) { #x, t::x }
+
+namespace gt = gltf2;
+namespace js = json;
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+const std::string POSITION_PROPERTY("position");
+const std::string ORIENTATION_PROPERTY("orientation");
+const std::string SCALE_PROPERTY("scale");
+const std::string BLEND_SHAPE_WEIGHTS_UNIFORM("uBlendShapeWeight");
+
+const Geometry::Type GLTF2_TO_DALI_PRIMITIVES[]{
+ Geometry::POINTS,
+ Geometry::LINES,
+ Geometry::LINE_LOOP,
+ Geometry::LINE_STRIP,
+ Geometry::TRIANGLES,
+ Geometry::TRIANGLE_STRIP,
+ Geometry::TRIANGLE_FAN
+}; //...because Dali swaps the last two.
+
+struct AttributeMapping
+{
+ gt::Attribute::Type mType;
+ MeshDefinition::Accessor MeshDefinition::* mAccessor;
+ uint16_t mElementSizeRequired;
+} ATTRIBUTE_MAPPINGS[]{
+ { gt::Attribute::NORMAL, &MeshDefinition::mNormals, sizeof(Vector3) },
+ { gt::Attribute::TANGENT, &MeshDefinition::mTangents, sizeof(Vector3) },
+ { gt::Attribute::TEXCOORD_0, &MeshDefinition::mTexCoords, sizeof(Vector2) },
+ { gt::Attribute::JOINTS_0, &MeshDefinition::mJoints0, sizeof(Vector4) },
+ { gt::Attribute::WEIGHTS_0, &MeshDefinition::mWeights0, sizeof(Vector4) },
+};
+
+std::vector<gt::Animation> ReadAnimationArray(const json_value_s& j)
+{
+ gt::Animation proxy;
+ SetRefReaderObject(proxy);
+
+ auto results = js::Read::Array<gt::Animation, js::ObjectReader<gt::Animation>::Read>(j);
+
+ for (auto& animation : results)
+ {
+ for (auto& channel : animation.mChannels)
+ {
+ channel.mSampler.UpdateVector(animation.mSamplers);
+ }
+ }
+
+ return results;
+}
+
+void ApplyAccessorMinMax(const gt::Accessor& acc, float* values)
+{
+ DALI_ASSERT_ALWAYS(acc.mMax.empty() || gt::AccessorType::ElementCount(acc.mType) == acc.mMax.size());
+ DALI_ASSERT_ALWAYS(acc.mMin.empty() || gt::AccessorType::ElementCount(acc.mType) == acc.mMin.size());
+ MeshDefinition::Blob::ApplyMinMax(acc.mMin, acc.mMax, acc.mCount, values);
+}
+
+const auto BUFFER_READER = std::move(js::Reader<gt::Buffer>()
+ .Register(*js::MakeProperty("byteLength", js::Read::Number<uint32_t>, >::Buffer::mByteLength))
+ .Register(*js::MakeProperty("uri", js::Read::StringView, >::Buffer::mUri))
+);
+
+const auto BUFFER_VIEW_READER = std::move(js::Reader<gt::BufferView>()
+ .Register(*js::MakeProperty("buffer", gt::RefReader<gt::Document>::Read<gt::Buffer, >::Document::mBuffers>, >::BufferView::mBuffer))
+ .Register(*js::MakeProperty("byteOffset", js::Read::Number<uint32_t>, >::BufferView::mByteOffset))
+ .Register(*js::MakeProperty("byteLength", js::Read::Number<uint32_t>, >::BufferView::mByteLength))
+ .Register(*js::MakeProperty("byteStride", js::Read::Number<uint32_t>, >::BufferView::mByteStride))
+ .Register(*js::MakeProperty("target", js::Read::Number<uint32_t>, >::BufferView::mTarget))
+);
+
+const auto BUFFER_VIEW_CLIENT_READER = std::move(js::Reader<gt::BufferViewClient>()
+ .Register(*js::MakeProperty("bufferView", gt::RefReader<gt::Document>::Read<gt::BufferView, >::Document::mBufferViews>, >::BufferViewClient::mBufferView))
+ .Register(*js::MakeProperty("byteOffset", js::Read::Number<uint32_t>, >::BufferViewClient::mByteOffset))
+);
+
+const auto COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER = std::move(js::Reader<gt::ComponentTypedBufferViewClient>()
+ .Register(*new js::Property<gt::ComponentTypedBufferViewClient, gt::Ref<gt::BufferView>>("bufferView", gt::RefReader<gt::Document>::Read<gt::BufferView, >::Document::mBufferViews>, >::ComponentTypedBufferViewClient::mBufferView))
+ .Register(*new js::Property<gt::ComponentTypedBufferViewClient, uint32_t>("byteOffset", js::Read::Number<uint32_t>, >::ComponentTypedBufferViewClient::mByteOffset))
+ .Register(*js::MakeProperty("componentType", js::Read::Enum<gt::Component::Type>, >::ComponentTypedBufferViewClient::mComponentType))
+);
+
+const auto ACCESSOR_SPARSE_READER = std::move(js::Reader<gt::Accessor::Sparse>()
+ .Register(*js::MakeProperty("count", js::Read::Number<uint32_t>, >::Accessor::Sparse::mCount))
+ .Register(*js::MakeProperty("indices", js::ObjectReader<gt::ComponentTypedBufferViewClient>::Read,
+ >::Accessor::Sparse::mIndices))
+ .Register(*js::MakeProperty("values", js::ObjectReader<gt::BufferViewClient>::Read,
+ >::Accessor::Sparse::mValues))
+);
+
+const auto ACCESSOR_READER = std::move(js::Reader<gt::Accessor>()
+ .Register(*new js::Property<gt::Accessor, gt::Ref<gt::BufferView>>("bufferView",
+ gt::RefReader<gt::Document>::Read<gt::BufferView, >::Document::mBufferViews>, >::Accessor::mBufferView))
+ .Register(*new js::Property<gt::Accessor, uint32_t>("byteOffset",
+ js::Read::Number<uint32_t>, >::Accessor::mByteOffset))
+ .Register(*new js::Property<gt::Accessor, gt::Component::Type>("componentType",
+ js::Read::Enum<gt::Component::Type>, >::Accessor::mComponentType))
+ .Register(*new js::Property<gt::Accessor, std::string_view>("name", js::Read::StringView, >::Accessor::mName))
+ .Register(*js::MakeProperty("count", js::Read::Number<uint32_t>, >::Accessor::mCount))
+ .Register(*js::MakeProperty("normalized", js::Read::Boolean, >::Accessor::mNormalized))
+ .Register(*js::MakeProperty("type", gt::ReadStringEnum<gt::AccessorType>, >::Accessor::mType))
+ .Register(*js::MakeProperty("min", js::Read::Array<float, js::Read::Number>, >::Accessor::mMin))
+ .Register(*js::MakeProperty("max", js::Read::Array<float, js::Read::Number>, >::Accessor::mMax))
+ .Register(*new js::Property<gt::Accessor, gt::Accessor::Sparse>("sparse", js::ObjectReader<gt::Accessor::Sparse>::Read,
+ >::Accessor::SetSparse))
+);
+
+const auto IMAGE_READER = std::move(js::Reader<gt::Image>()
+ .Register(*new js::Property<gt::Image, std::string_view>("name", js::Read::StringView, >::Material::mName))
+ .Register(*js::MakeProperty("uri", js::Read::StringView, >::Image::mUri))
+ .Register(*js::MakeProperty("mimeType", js::Read::StringView, >::Image::mMimeType))
+ .Register(*js::MakeProperty("bufferView", gt::RefReader<gt::Document>::Read<gt::BufferView, >::Document::mBufferViews>, >::Image::mBufferView))
+);
+
+const auto SAMPLER_READER = std::move(js::Reader<gt::Sampler>()
+ .Register(*js::MakeProperty("minFilter", js::Read::Enum<gt::Filter::Type>, >::Sampler::mMinFilter))
+ .Register(*js::MakeProperty("magFilter", js::Read::Enum<gt::Filter::Type>, >::Sampler::mMagFilter))
+ .Register(*js::MakeProperty("wrapS", js::Read::Enum<gt::Wrap::Type>, >::Sampler::mWrapS))
+ .Register(*js::MakeProperty("wrapT", js::Read::Enum<gt::Wrap::Type>, >::Sampler::mWrapT))
+);
+
+const auto TEXURE_READER = std::move(js::Reader<gt::Texture>()
+ .Register(*js::MakeProperty("source", gt::RefReader<gt::Document>::Read<gt::Image, >::Document::mImages>, >::Texture::mSource))
+ .Register(*js::MakeProperty("sampler", gt::RefReader<gt::Document>::Read<gt::Sampler, >::Document::mSamplers>, >::Texture::mSampler))
+);
+
+const auto TEXURE_INFO_READER = std::move(js::Reader<gt::TextureInfo>()
+ .Register(*js::MakeProperty("index", gt::RefReader<gt::Document>::Read<gt::Texture, >::Document::mTextures>, >::TextureInfo::mTexture))
+ .Register(*js::MakeProperty("texCoord", js::Read::Number<uint32_t>, >::TextureInfo::mTexCoord))
+ .Register(*js::MakeProperty("scale", js::Read::Number<float>, >::TextureInfo::mScale))
+);
+
+const auto MATERIAL_PBR_READER = std::move(js::Reader<gt::Material::Pbr>()
+ .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector<Vector4>, >::Material::Pbr::mBaseColorFactor))
+ .Register(*js::MakeProperty("baseColorTexture", js::ObjectReader<gt::TextureInfo>::Read,
+ >::Material::Pbr::mBaseColorTexture))
+ .Register(*js::MakeProperty("metallicFactor", js::Read::Number<float>, >::Material::Pbr::mMetallicFactor))
+ .Register(*js::MakeProperty("roughnessFactor", js::Read::Number<float>, >::Material::Pbr::mRoughnessFactor))
+ .Register(*js::MakeProperty("metallicRoughnessTexture", js::ObjectReader<gt::TextureInfo>::Read,
+ >::Material::Pbr::mMetallicRoughnessTexture))
+);
+
+const auto MATERIAL_READER = std::move(js::Reader<gt::Material>()
+ .Register(*new js::Property<gt::Material, std::string_view>("name", js::Read::StringView, >::Material::mName))
+ .Register(*js::MakeProperty("pbrMetallicRoughness", js::ObjectReader<gt::Material::Pbr>::Read, >::Material::mPbrMetallicRoughness))
+ .Register(*js::MakeProperty("normalTexture", js::ObjectReader<gt::TextureInfo>::Read, >::Material::mNormalTexture))
+ .Register(*js::MakeProperty("occlusionTexture", js::ObjectReader<gt::TextureInfo>::Read, >::Material::mOcclusionTexture))
+ .Register(*js::MakeProperty("emissiveTexture", js::ObjectReader<gt::TextureInfo>::Read, >::Material::mEmissiveTexture))
+ .Register(*js::MakeProperty("emissiveFactor", gt::ReadDaliVector<Vector3>, >::Material::mEmissiveFactor))
+ .Register(*js::MakeProperty("alphaMode", gt::ReadStringEnum<gt::AlphaMode>, >::Material::mAlphaMode))
+ .Register(*js::MakeProperty("alphaCutoff", js::Read::Number<float>, >::Material::mAlphaCutoff))
+);
+
+std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>> ReadMeshPrimitiveAttributes(const json_value_s& j)
+{
+ auto& jo = js::Cast<json_object_s>(j);
+ std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>> result;
+
+ auto i = jo.start;
+ while (i)
+ {
+ auto jstr = *i->name;
+ result[gt::Attribute::FromString(jstr.string, jstr.string_size)] = gt::RefReader<gt::Document>::Read<gt::Accessor, >::Document::mAccessors>(*i->value);
+ i = i->next;
+ }
+ return result;
+}
+
+std::vector<std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>>> ReadMeshPrimitiveTargets(const json_value_s& j)
+{
+ auto& jo = js::Cast<json_array_s>(j);
+ std::vector<std::map<gt::Attribute::Type, gt::Ref<gt::Accessor>>> result;
+
+ result.reserve(jo.length);
+
+ auto i = jo.start;
+ while (i)
+ {
+ result.push_back(std::move(ReadMeshPrimitiveAttributes(*i->value)));
+ i = i->next;
+ }
+
+ return result;
+}
+
+const auto MESH_PRIMITIVE_READER = std::move(js::Reader<gt::Mesh::Primitive>()
+ .Register(*js::MakeProperty("attributes", ReadMeshPrimitiveAttributes, >::Mesh::Primitive::mAttributes))
+ .Register(*js::MakeProperty("indices", gt::RefReader<gt::Document>::Read<gt::Accessor, >::Document::mAccessors>, >::Mesh::Primitive::mIndices))
+ .Register(*js::MakeProperty("material", gt::RefReader<gt::Document>::Read<gt::Material, >::Document::mMaterials>, >::Mesh::Primitive::mMaterial))
+ .Register(*js::MakeProperty("mode", js::Read::Enum<gt::Mesh::Primitive::Mode>, >::Mesh::Primitive::mMode))
+ .Register(*js::MakeProperty("targets", ReadMeshPrimitiveTargets, >::Mesh::Primitive::mTargets))
+);
+
+const auto MESH_READER = std::move(js::Reader<gt::Mesh>()
+ .Register(*new js::Property<gt::Mesh, std::string_view>("name", js::Read::StringView, >::Mesh::mName))
+ .Register(*js::MakeProperty("primitives",
+ js::Read::Array<gt::Mesh::Primitive, js::ObjectReader<gt::Mesh::Primitive>::Read>, >::Mesh::mPrimitives))
+ .Register(*js::MakeProperty("weights", js::Read::Array<float, js::Read::Number>, >::Mesh::mWeights))
+);
+
+const auto SKIN_READER = std::move(js::Reader<gt::Skin>()
+ .Register(*new js::Property<gt::Skin, std::string_view>("name", js::Read::StringView, >::Skin::mName))
+ .Register(*js::MakeProperty("inverseBindMatrices",
+ gt::RefReader<gt::Document>::Read<gt::Accessor, >::Document::mAccessors>, >::Skin::mInverseBindMatrices))
+ .Register(*js::MakeProperty("skeleton",
+ gt::RefReader<gt::Document>::Read<gt::Node, >::Document::mNodes>, >::Skin::mSkeleton))
+ .Register(*js::MakeProperty("joints",
+ js::Read::Array<gt::Ref<gt::Node>, gt::RefReader<gt::Document>::Read<gt::Node, >::Document::mNodes>>, >::Skin::mJoints))
+);
+
+const auto CAMERA_PERSPECTIVE_READER = std::move(js::Reader<gt::Camera::Perspective>()
+ .Register(*js::MakeProperty("aspectRatio", js::Read::Number<float>, >::Camera::Perspective::mAspectRatio))
+ .Register(*js::MakeProperty("yfov", js::Read::Number<float>, >::Camera::Perspective::mYFov))
+ .Register(*js::MakeProperty("zfar", js::Read::Number<float>, >::Camera::Perspective::mZFar))
+ .Register(*js::MakeProperty("znear", js::Read::Number<float>, >::Camera::Perspective::mZNear))
+); // TODO: infinite perspective projection, where znear is omitted
+
+const auto CAMERA_ORTHOGRAPHIC_READER = std::move(js::Reader<gt::Camera::Orthographic>()
+ .Register(*js::MakeProperty("xmag", js::Read::Number<float>, >::Camera::Orthographic::mXMag))
+ .Register(*js::MakeProperty("ymag", js::Read::Number<float>, >::Camera::Orthographic::mXMag))
+ .Register(*js::MakeProperty("zfar", js::Read::Number<float>, >::Camera::Orthographic::mZFar))
+ .Register(*js::MakeProperty("znear", js::Read::Number<float>, >::Camera::Orthographic::mZNear))
+);
+
+const auto CAMERA_READER = std::move(js::Reader<gt::Camera>()
+ .Register(*new js::Property<gt::Camera, std::string_view>("name", js::Read::StringView, >::Camera::mName))
+ .Register(*js::MakeProperty("type", js::Read::StringView, >::Camera::mType))
+ .Register(*js::MakeProperty("perspective", js::ObjectReader<gt::Camera::Perspective>::Read, >::Camera::mPerspective))
+ .Register(*js::MakeProperty("orthographic", js::ObjectReader<gt::Camera::Orthographic>::Read, >::Camera::mOrthographic))
+);
+
+const auto NODE_READER = std::move(js::Reader<gt::Node>()
+ .Register(*new js::Property<gt::Node, std::string_view>("name", js::Read::StringView, >::Node::mName))
+ .Register(*js::MakeProperty("translation", gt::ReadDaliVector<Vector3>, >::Node::mTranslation))
+ .Register(*js::MakeProperty("rotation", gt::ReadQuaternion, >::Node::mRotation))
+ .Register(*js::MakeProperty("scale", gt::ReadDaliVector<Vector3>, >::Node::mScale))
+ .Register(*new js::Property<gt::Node, Matrix>("matrix", gt::ReadDaliVector<Matrix>, >::Node::SetMatrix))
+ .Register(*js::MakeProperty("camera", gt::RefReader<gt::Document>::Read<gt::Camera, >::Document::mCameras>,
+ >::Node::mCamera))
+ .Register(*js::MakeProperty("children", js::Read::Array<gt::Ref<gt::Node>, gt::RefReader<gt::Document>::Read<gt::Node, >::Document::mNodes>>,
+ >::Node::mChildren))
+ .Register(*js::MakeProperty("mesh", gt::RefReader<gt::Document>::Read<gt::Mesh, >::Document::mMeshes>, >::Node::mMesh))
+ .Register(*js::MakeProperty("skin", gt::RefReader<gt::Document>::Read<gt::Skin, >::Document::mSkins>, >::Node::mSkin))
+);
+
+const auto ANIMATION_SAMPLER_READER = std::move(js::Reader<gt::Animation::Sampler>()
+ .Register(*js::MakeProperty("input", gt::RefReader<gt::Document>::Read<gt::Accessor, >::Document::mAccessors>,
+ >::Animation::Sampler::mInput))
+ .Register(*js::MakeProperty("output", gt::RefReader<gt::Document>::Read<gt::Accessor, >::Document::mAccessors>,
+ >::Animation::Sampler::mOutput))
+ .Register(*js::MakeProperty("interpolation", gt::ReadStringEnum<gt::Animation::Sampler::Interpolation>, >::Animation::Sampler::mInterpolation))
+);
+
+const auto ANIMATION_TARGET_READER = std::move(js::Reader<gt::Animation::Channel::Target>()
+ .Register(*js::MakeProperty("node", gt::RefReader<gt::Document>::Read<gt::Node, >::Document::mNodes>,
+ >::Animation::Channel::Target::mNode))
+ .Register(*js::MakeProperty("path", gt::ReadStringEnum<gt::Animation::Channel::Target>,
+ >::Animation::Channel::Target::mPath))
+);
+
+const auto ANIMATION_CHANNEL_READER = std::move(js::Reader<gt::Animation::Channel>()
+ .Register(*js::MakeProperty("target", js::ObjectReader<gt::Animation::Channel::Target>::Read, >::Animation::Channel::mTarget))
+ .Register(*js::MakeProperty("sampler", gt::RefReader<gt::Animation>::Read<gt::Animation::Sampler, >::Animation::mSamplers>, >::Animation::Channel::mSampler))
+);
+
+const auto ANIMATION_READER = std::move(js::Reader<gt::Animation>()
+ .Register(*new js::Property<gt::Animation, std::string_view>("name", js::Read::StringView, >::Animation::mName))
+ .Register(*js::MakeProperty("samplers",
+ js::Read::Array<gt::Animation::Sampler, js::ObjectReader<gt::Animation::Sampler>::Read>, >::Animation::mSamplers))
+ .Register(*js::MakeProperty("channels",
+ js::Read::Array<gt::Animation::Channel, js::ObjectReader<gt::Animation::Channel>::Read>, >::Animation::mChannels))
+);
+
+const auto SCENE_READER = std::move(js::Reader<gt::Scene>()
+ .Register(*new js::Property<gt::Scene, std::string_view>("name", js::Read::StringView, >::Scene::mName))
+ .Register(*js::MakeProperty("nodes",
+ js::Read::Array<gt::Ref<gt::Node>, gt::RefReader<gt::Document>::Read<gt::Node, >::Document::mNodes>>, >::Scene::mNodes))
+);
+
+const auto DOCUMENT_READER = std::move(js::Reader<gt::Document>()
+ .Register(*js::MakeProperty("buffers",
+ js::Read::Array<gt::Buffer, js::ObjectReader<gt::Buffer>::Read>, >::Document::mBuffers))
+ .Register(*js::MakeProperty("bufferViews",
+ js::Read::Array<gt::BufferView, js::ObjectReader<gt::BufferView>::Read>, >::Document::mBufferViews))
+ .Register(*js::MakeProperty("accessors",
+ js::Read::Array<gt::Accessor, js::ObjectReader<gt::Accessor>::Read>, >::Document::mAccessors))
+ .Register(*js::MakeProperty("images",
+ js::Read::Array<gt::Image, js::ObjectReader<gt::Image>::Read>, >::Document::mImages))
+ .Register(*js::MakeProperty("samplers",
+ js::Read::Array<gt::Sampler, js::ObjectReader<gt::Sampler>::Read>, >::Document::mSamplers))
+ .Register(*js::MakeProperty("textures",
+ js::Read::Array<gt::Texture, js::ObjectReader<gt::Texture>::Read>, >::Document::mTextures))
+ .Register(*js::MakeProperty("materials",
+ js::Read::Array<gt::Material, js::ObjectReader<gt::Material>::Read>, >::Document::mMaterials))
+ .Register(*js::MakeProperty("meshes",
+ js::Read::Array<gt::Mesh, js::ObjectReader<gt::Mesh>::Read>, >::Document::mMeshes))
+ .Register(*js::MakeProperty("skins",
+ js::Read::Array<gt::Skin, js::ObjectReader<gt::Skin>::Read>, >::Document::mSkins))
+ .Register(*js::MakeProperty("cameras",
+ js::Read::Array<gt::Camera, js::ObjectReader<gt::Camera>::Read>, >::Document::mCameras))
+ .Register(*js::MakeProperty("nodes",
+ js::Read::Array<gt::Node, js::ObjectReader<gt::Node>::Read>, >::Document::mNodes))
+ .Register(*js::MakeProperty("animations",
+ ReadAnimationArray, >::Document::mAnimations))
+ .Register(*js::MakeProperty("scenes",
+ js::Read::Array<gt::Scene, js::ObjectReader<gt::Scene>::Read>, >::Document::mScenes))
+ .Register(*js::MakeProperty("scene", gt::RefReader<gt::Document>::Read<gt::Scene, >::Document::mScenes>, >::Document::mScene))
+);
+
+struct NodeMapping
+{
+ Index gltfIdx;
+ Index runtimeIdx;
+};
+
+bool operator<(const NodeMapping& mapping, Index gltfIdx)
+{
+ return mapping.gltfIdx < gltfIdx;
+}
+
+class NodeIndexMapper
+{
+public:
+ NodeIndexMapper() = default;
+ NodeIndexMapper(const NodeIndexMapper&) = delete;
+ NodeIndexMapper& operator=(const NodeIndexMapper&) = delete;
+
+ ///@brief Registers a mapping of the @a gltfIdx of a node to its @a runtimeIdx .
+ ///@note If the indices are the same, the registration is omitted, in order to
+ /// save growing a vector.
+ void RegisterMapping(Index gltfIdx, Index runtimeIdx)
+ {
+ if (gltfIdx != runtimeIdx)
+ {
+ auto iInsert = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx);
+ DALI_ASSERT_DEBUG(iInsert == mNodes.end() || iInsert->gltfIdx != gltfIdx);
+ mNodes.insert(iInsert, NodeMapping{ gltfIdx, runtimeIdx });
+ }
+ }
+
+ ///@brief Retrieves the runtime index of a Node, mapped to the given @a gltfIdx.
+ Index GetRuntimeId(Index gltfIdx) const
+ {
+ auto iFind = std::lower_bound(mNodes.begin(), mNodes.end(), gltfIdx); // using custom operator<
+ return (iFind != mNodes.end() && iFind->gltfIdx == gltfIdx) ? iFind->runtimeIdx : gltfIdx;
+ }
+
+private:
+ std::vector<NodeMapping> mNodes;
+};
+
+struct ConversionContext
+{
+ LoadResult& mOutput;
+
+ std::string mPath;
+ Index mDefaultMaterial;
+
+ std::vector<Index> mMeshIds;
+ NodeIndexMapper mNodeIndices;
+};
+
+SamplerFlags::Type ConvertWrapMode(gt::Wrap::Type w)
+{
+ switch (w)
+ {
+ case gt::Wrap::REPEAT:
+ return SamplerFlags::WRAP_REPEAT;
+ case gt::Wrap::CLAMP_TO_EDGE:
+ return SamplerFlags::WRAP_CLAMP;
+ case gt::Wrap::MIRRORED_REPEAT:
+ return SamplerFlags::WRAP_MIRROR;
+ default:
+ throw std::runtime_error("Invalid wrap type.");
+ }
+}
+
+SamplerFlags::Type ConvertSampler(const gt::Ref<gt::Sampler>& s)
+{
+ if (s)
+ {
+ return (s->mMinFilter < gt::Filter::NEAREST_MIPMAP_NEAREST) ? (s->mMinFilter - gt::Filter::NEAREST) :
+ ((s->mMinFilter - gt::Filter::NEAREST_MIPMAP_NEAREST) + 2) |
+ ((s->mMagFilter - gt::Filter::NEAREST) << SamplerFlags::FILTER_MAG_SHIFT) |
+ (ConvertWrapMode(s->mWrapS) << SamplerFlags::WRAP_S_SHIFT) |
+ (ConvertWrapMode(s->mWrapT) << SamplerFlags::WRAP_T_SHIFT);
+ }
+ else
+ {
+ // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#texturesampler
+ // "The index of the sampler used by this texture. When undefined, a sampler with repeat wrapping and auto filtering should be used."
+ // "What is an auto filtering", I hear you ask. Since there's nothing else to determine mipmapping from - including glTF image
+ // properties, if not in some extension -, we will simply assume linear filtering.
+ return SamplerFlags::FILTER_LINEAR | (SamplerFlags::FILTER_LINEAR << SamplerFlags::FILTER_MAG_SHIFT) |
+ (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_S_SHIFT) | (SamplerFlags::WRAP_REPEAT << SamplerFlags::WRAP_T_SHIFT);
+ }
+}
+
+TextureDefinition ConvertTextureInfo(const gt::TextureInfo& mm)
+{
+ return TextureDefinition{ std::string(mm.mTexture->mSource->mUri), ConvertSampler(mm.mTexture->mSampler) };
+}
+
+void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials)& outMaterials)
+{
+ MaterialDefinition matDef;
+
+ auto& pbr = m.mPbrMetallicRoughness;
+ if (m.mAlphaMode != gt::AlphaMode::OPAQUE || pbr.mBaseColorFactor.a < 1.f)
+ {
+ matDef.mFlags |= MaterialDefinition::TRANSPARENCY;
+ }
+
+ if (m.mAlphaMode == gt::AlphaMode::MASK)
+ {
+ matDef.SetAlphaCutoff(std::min(1.f, std::max(0.f, m.mAlphaCutoff)));
+ }
+
+ matDef.mColor = pbr.mBaseColorFactor;
+
+ matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!m.mNormalTexture);
+ if (pbr.mBaseColorTexture)
+ {
+ const auto semantic = MaterialDefinition::ALBEDO;
+ matDef.mTextureStages.push_back({ semantic, ConvertTextureInfo(pbr.mBaseColorTexture) });
+ // TODO: and there had better be one
+ matDef.mFlags |= semantic;
+ }
+
+ matDef.mMetallic = pbr.mMetallicFactor;
+ matDef.mRoughness = pbr.mRoughnessFactor;
+
+ if (pbr.mMetallicRoughnessTexture)
+ {
+ const auto semantic = MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS |
+ MaterialDefinition::GLTF_CHANNELS;
+ matDef.mTextureStages.push_back({ semantic, ConvertTextureInfo(pbr.mMetallicRoughnessTexture) });
+ // TODO: and there had better be one
+ matDef.mFlags |= semantic;
+ }
+
+ if (m.mNormalTexture)
+ {
+ const auto semantic = MaterialDefinition::NORMAL;
+ matDef.mTextureStages.push_back({ semantic, ConvertTextureInfo(m.mNormalTexture) });
+ // TODO: and there had better be one
+ matDef.mFlags |= semantic;
+ }
+
+ // TODO: handle doubleSided
+
+ outMaterials.emplace_back(std::move(matDef), TextureSet());
+}
+
+void ConvertMaterials(const gt::Document& doc, ConversionContext& cctx)
+{
+ auto& outMaterials = cctx.mOutput.mResources.mMaterials;
+ outMaterials.reserve(doc.mMaterials.size());
+
+ for (auto& m : doc.mMaterials)
+ {
+ ConvertMaterial(m, outMaterials);
+ }
+}
+
+MeshDefinition::Accessor ConvertMeshPrimitiveAccessor(const gt::Accessor& acc)
+{
+ DALI_ASSERT_ALWAYS((acc.mBufferView &&
+ (acc.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max())) ||
+ (acc.mSparse && !acc.mBufferView));
+
+ DALI_ASSERT_ALWAYS(!acc.mSparse ||
+ ((acc.mSparse->mIndices.mBufferView && (acc.mSparse->mIndices.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max())) &&
+ (acc.mSparse->mValues.mBufferView && (acc.mSparse->mValues.mBufferView->mByteStride < std::numeric_limits<uint16_t>::max()))));
+
+
+ MeshDefinition::SparseBlob sparseBlob;
+ if (acc.mSparse)
+ {
+ const gt::Accessor::Sparse& sparse = *acc.mSparse;
+ const gt::ComponentTypedBufferViewClient& indices = sparse.mIndices;
+ const gt::BufferViewClient& values = sparse.mValues;
+
+ MeshDefinition::Blob indicesBlob(
+ indices.mBufferView->mByteOffset + indices.mByteOffset,
+ sparse.mCount * indices.GetBytesPerComponent(),
+ static_cast<uint16_t>(indices.mBufferView->mByteStride),
+ static_cast<uint16_t>(indices.GetBytesPerComponent()),
+ {}, {}
+ );
+ MeshDefinition::Blob valuesBlob(
+ values.mBufferView->mByteOffset + values.mByteOffset,
+ sparse.mCount * acc.GetElementSizeBytes(),
+ static_cast<uint16_t>(values.mBufferView->mByteStride),
+ static_cast<uint16_t>(acc.GetElementSizeBytes()),
+ {}, {}
+ );
+
+ sparseBlob = std::move(MeshDefinition::SparseBlob(std::move(indicesBlob), std::move(valuesBlob), acc.mSparse->mCount));
+ }
+
+ uint32_t bufferViewOffset = 0u;
+ uint32_t bufferViewStride = 0u;
+ if (acc.mBufferView)
+ {
+ bufferViewOffset = acc.mBufferView->mByteOffset;
+ bufferViewStride = acc.mBufferView->mByteStride;
+ }
+
+ return MeshDefinition::Accessor{
+ std::move(MeshDefinition::Blob{bufferViewOffset + acc.mByteOffset,
+ acc.GetBytesLength(),
+ static_cast<uint16_t>(bufferViewStride),
+ static_cast<uint16_t>(acc.GetElementSizeBytes()),
+ acc.mMin,
+ acc.mMax}),
+ std::move(sparseBlob) };
+}
+
+void ConvertMeshes(const gt::Document& doc, ConversionContext& cctx)
+{
+ uint32_t meshCount = 0;
+ cctx.mMeshIds.reserve(doc.mMeshes.size());
+ for (auto& m : doc.mMeshes)
+ {
+ cctx.mMeshIds.push_back(meshCount);
+ meshCount += m.mPrimitives.size();
+ }
+
+ auto& outMeshes = cctx.mOutput.mResources.mMeshes;
+ outMeshes.reserve(meshCount);
+ for (auto& m : doc.mMeshes)
+ {
+ for (auto& p : m.mPrimitives)
+ {
+ MeshDefinition meshDef;
+
+ auto& attribs = p.mAttributes;
+ meshDef.mUri = attribs.begin()->second->mBufferView->mBuffer->mUri;
+ meshDef.mPrimitiveType = GLTF2_TO_DALI_PRIMITIVES[p.mMode];
+
+ auto& accPositions = *attribs.find(gt::Attribute::POSITION)->second;
+ meshDef.mPositions = ConvertMeshPrimitiveAccessor(accPositions);
+
+ const bool needNormalsTangents = accPositions.mType == gt::AccessorType::VEC3;
+ for (auto& am : ATTRIBUTE_MAPPINGS)
+ {
+ auto iFind = attribs.find(am.mType);
+ if (iFind != attribs.end())
+ {
+ DALI_ASSERT_DEBUG(iFind->second->mBufferView->mBuffer->mUri.compare(meshDef.mUri) == 0);
+ auto& accessor = meshDef.*(am.mAccessor);
+ accessor = ConvertMeshPrimitiveAccessor(*iFind->second);
+
+ // Fixing up -- a few of glTF2 sample models have VEC4 tangents; we need VEC3s.
+ if (iFind->first == gt::Attribute::TANGENT && (accessor.mBlob.mElementSizeHint > am.mElementSizeRequired))
+ {
+ accessor.mBlob.mStride = std::max(static_cast<uint16_t>(accessor.mBlob.mStride + accessor.mBlob.mElementSizeHint - am.mElementSizeRequired),
+ accessor.mBlob.mElementSizeHint);
+ accessor.mBlob.mElementSizeHint = am.mElementSizeRequired;
+ }
+
+ if (iFind->first == gt::Attribute::JOINTS_0)
+ {
+ meshDef.mFlags |= (iFind->second->mComponentType == gt::Component::UNSIGNED_SHORT) * MeshDefinition::U16_JOINT_IDS;
+ DALI_ASSERT_DEBUG(MaskMatch(meshDef.mFlags, MeshDefinition::U16_JOINT_IDS) || iFind->second->mComponentType == gt::Component::FLOAT);
+ }
+ }
+ else if (needNormalsTangents)
+ {
+ switch (am.mType)
+ {
+ case gt::Attribute::NORMAL:
+ meshDef.RequestNormals();
+ break;
+
+ case gt::Attribute::TANGENT:
+ meshDef.RequestTangents();
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ if (p.mIndices)
+ {
+ meshDef.mIndices = ConvertMeshPrimitiveAccessor(*p.mIndices);
+ meshDef.mFlags |= (p.mIndices->mComponentType == gt::Component::UNSIGNED_INT) * MeshDefinition::U32_INDICES;
+ DALI_ASSERT_DEBUG(MaskMatch(meshDef.mFlags, MeshDefinition::U32_INDICES) || p.mIndices->mComponentType == gt::Component::UNSIGNED_SHORT);
+ }
+
+ if (!p.mTargets.empty())
+ {
+ meshDef.mBlendShapes.reserve(p.mTargets.size());
+ meshDef.mBlendShapeVersion = BlendShapes::Version::VERSION_2_0;
+ for (const auto& target : p.mTargets)
+ {
+ MeshDefinition::BlendShape blendShape;
+
+ auto endIt = target.end();
+ auto it = target.find(gt::Attribute::POSITION);
+ if (it != endIt)
+ {
+ blendShape.deltas = ConvertMeshPrimitiveAccessor(*it->second);
+ }
+ it = target.find(gt::Attribute::NORMAL);
+ if (it != endIt)
+ {
+ blendShape.normals = ConvertMeshPrimitiveAccessor(*it->second);
+ }
+ it = target.find(gt::Attribute::TANGENT);
+ if (it != endIt)
+ {
+ blendShape.tangents = ConvertMeshPrimitiveAccessor(*it->second);
+ }
+
+ if (!m.mWeights.empty())
+ {
+ blendShape.weight = m.mWeights[meshDef.mBlendShapes.size()];
+ }
+
+ meshDef.mBlendShapes.push_back(std::move(blendShape));
+ }
+ }
+
+ outMeshes.push_back({ std::move(meshDef), MeshGeometry{} });
+ }
+ }
+}
+
+ModelNode* MakeModelNode(const gt::Mesh::Primitive& prim, ConversionContext& cctx)
+{
+ auto modelNode = new ModelNode();
+
+ modelNode->mShaderIdx = 0; // TODO: further thought
+
+ auto materialIdx = prim.mMaterial.GetIndex();
+ if (INVALID_INDEX == materialIdx)
+ {
+ // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#default-material
+ if (INVALID_INDEX == cctx.mDefaultMaterial)
+ {
+ auto& outMaterials = cctx.mOutput.mResources.mMaterials;
+ cctx.mDefaultMaterial = outMaterials.size();
+
+ ConvertMaterial(gt::Material{}, outMaterials);
+ }
+
+ materialIdx = cctx.mDefaultMaterial;
+ }
+
+ modelNode->mMaterialIdx = materialIdx;
+
+ return modelNode;
+}
+
+void ConvertCamera(const gt::Camera& camera, CameraParameters& camParams)
+{
+ camParams.isPerspective = camera.mType.compare("perspective") == 0;
+ if (camParams.isPerspective)
+ {
+ auto& perspective = camera.mPerspective;
+ camParams.yFov = Degree(Radian(perspective.mYFov)).degree;
+ camParams.zNear = perspective.mZNear;
+ camParams.zFar = perspective.mZFar;
+ // TODO: yes, we seem to ignore aspectRatio in CameraParameters.
+ }
+ else
+ {
+ auto& ortho = camera.mOrthographic;
+ camParams.orthographicSize = Vector4(-ortho.mXMag, ortho.mXMag, ortho.mYMag, -ortho.mYMag) * .5f;
+ camParams.zNear = ortho.mZNear;
+ camParams.zFar = ortho.mZFar;
+ }
+}
+
+void ConvertNode(gt::Node const& node, const Index gltfIdx, Index parentIdx, ConversionContext& cctx)
+{
+ auto& output = cctx.mOutput;
+ auto& scene = output.mScene;
+ auto& resources = output.mResources;
+
+ const auto idx = scene.GetNodeCount();
+ auto weakNode = scene.AddNode([&]() {
+ std::unique_ptr<NodeDefinition> nodeDef{ new NodeDefinition() };
+
+ nodeDef->mParentIdx = parentIdx;
+ nodeDef->mName = node.mName;
+ if (nodeDef->mName.empty())
+ {
+ // TODO: Production quality generation of unique names.
+ nodeDef->mName = std::to_string(reinterpret_cast<uintptr_t>(nodeDef.get()));
+ }
+
+ if (!node.mSkin) // Nodes with skinned meshes are not supposed to have local transforms.
+ {
+ nodeDef->mPosition = node.mTranslation;
+ nodeDef->mOrientation = node.mRotation;
+ nodeDef->mScale = node.mScale;
+ }
+
+ return nodeDef;
+ }());
+ if (!weakNode)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Node name '" << node.mName << "' is not unique; scene is invalid.";
+ }
+
+ cctx.mNodeIndices.RegisterMapping(gltfIdx, idx);
+
+ Index skeletonIdx = node.mSkin ? node.mSkin.GetIndex() : INVALID_INDEX;
+ if (node.mMesh && !node.mMesh->mPrimitives.empty())
+ {
+ auto& mesh = *node.mMesh;
+
+ auto iPrim = mesh.mPrimitives.begin();
+ auto modelNode = MakeModelNode(*iPrim, cctx);
+ auto meshIdx = cctx.mMeshIds[node.mMesh.GetIndex()];
+ modelNode->mMeshIdx = meshIdx;
+
+ weakNode->mRenderable.reset(modelNode);
+
+ DALI_ASSERT_DEBUG(resources.mMeshes[meshIdx].first.mSkeletonIdx == INVALID_INDEX ||
+ resources.mMeshes[meshIdx].first.mSkeletonIdx == skeletonIdx);
+ resources.mMeshes[meshIdx].first.mSkeletonIdx = skeletonIdx;
+
+ // As does model-exporter, we'll create anonymous child nodes for additional mesh( primitiv)es.
+ while (++iPrim != mesh.mPrimitives.end())
+ {
+ std::unique_ptr<NodeDefinition> child{ new NodeDefinition };
+ child->mParentIdx = idx;
+
+ auto childModel = MakeModelNode(*iPrim, cctx);
+
+ ++meshIdx;
+ childModel->mMeshIdx = meshIdx;
+
+ child->mRenderable.reset(childModel);
+
+ scene.AddNode(std::move(child));
+
+ DALI_ASSERT_DEBUG(resources.mMeshes[meshIdx].first.mSkeletonIdx == INVALID_INDEX ||
+ resources.mMeshes[meshIdx].first.mSkeletonIdx == skeletonIdx);
+ resources.mMeshes[meshIdx].first.mSkeletonIdx = skeletonIdx;
+ }
+ }
+
+ if (node.mCamera)
+ {
+ CameraParameters camParams;
+ ConvertCamera(*node.mCamera, camParams);
+
+ camParams.matrix.SetTransformComponents(node.mScale, node.mRotation, node.mTranslation);
+ output.mCameraParameters.push_back(camParams);
+ }
+
+ for (auto& n : node.mChildren)
+ {
+ ConvertNode(*n, n.GetIndex(), idx, cctx);
+ }
+}
+
+void ConvertSceneNodes(const gt::Scene& scene, ConversionContext& cctx)
+{
+ auto& outScene = cctx.mOutput.mScene;
+ Index rootIdx = outScene.GetNodeCount();
+ switch (scene.mNodes.size())
+ {
+ case 0:
+ break;
+
+ case 1:
+ ConvertNode(*scene.mNodes[0], scene.mNodes[0].GetIndex(), INVALID_INDEX, cctx);
+ outScene.AddRootNode(rootIdx);
+ break;
+
+ default:
+ {
+ std::unique_ptr<NodeDefinition> sceneRoot{ new NodeDefinition() };
+ sceneRoot->mName = "GLTF_LOADER_SCENE_ROOT_" + std::to_string(outScene.GetRoots().size());
+
+ outScene.AddNode(std::move(sceneRoot));
+ outScene.AddRootNode(rootIdx);
+
+ for (auto& n : scene.mNodes)
+ {
+ ConvertNode(*n, n.GetIndex(), rootIdx, cctx);
+ }
+ break;
+ }
+ }
+}
+
+void ConvertNodes(const gt::Document& doc, ConversionContext& cctx)
+{
+ ConvertSceneNodes(*doc.mScene, cctx);
+
+ for (uint32_t i = 0, i1 = doc.mScene.GetIndex(); i < i1; ++i)
+ {
+ ConvertSceneNodes(doc.mScenes[i], cctx);
+ }
+
+ for (uint32_t i = doc.mScene.GetIndex() + 1; i < doc.mScenes.size(); ++i)
+ {
+ ConvertSceneNodes(doc.mScenes[i], cctx);
+ }
+}
+
+template <typename T>
+void LoadDataFromAccessor(const std::string& path, Vector<T>& dataBuffer, uint32_t offset, uint32_t size)
+{
+ std::ifstream animationBinaryFile(path, std::ifstream::binary);
+
+ if (!animationBinaryFile.is_open())
+ {
+ throw std::runtime_error("Failed to load " + path);
+ }
+
+ animationBinaryFile.seekg(offset);
+ animationBinaryFile.read(reinterpret_cast<char*>(dataBuffer.Begin()), size);
+ animationBinaryFile.close();
+}
+
+template <typename T>
+float LoadDataFromAccessors(const std::string& path, const gltf2::Accessor& input, const gltf2::Accessor& output, Vector<float>& inputDataBuffer, Vector<T>& outputDataBuffer)
+{
+ inputDataBuffer.Resize(input.mCount);
+ outputDataBuffer.Resize(output.mCount);
+
+ const uint32_t inputDataBufferSize = input.GetBytesLength();
+ const uint32_t outputDataBufferSize = output.GetBytesLength();
+
+ LoadDataFromAccessor<float>(path + std::string(input.mBufferView->mBuffer->mUri), inputDataBuffer,
+ input.mBufferView->mByteOffset + input.mByteOffset, inputDataBufferSize);
+ LoadDataFromAccessor<T>(path + std::string(output.mBufferView->mBuffer->mUri), outputDataBuffer,
+ output.mBufferView->mByteOffset + output.mByteOffset, outputDataBufferSize);
+ ApplyAccessorMinMax(output, reinterpret_cast<float*>(outputDataBuffer.begin()));
+
+ return inputDataBuffer[input.mCount - 1u];
+}
+
+template<typename T>
+float LoadKeyFrames(const std::string& path, const gt::Animation::Channel& channel, KeyFrames& keyFrames, gt::Animation::Channel::Target::Type type)
+{
+ const gltf2::Accessor& input = *channel.mSampler->mInput;
+ const gltf2::Accessor& output = *channel.mSampler->mOutput;
+
+ Vector<float> inputDataBuffer;
+ Vector<T> outputDataBuffer;
+
+ const float duration = LoadDataFromAccessors<T>(path, input, output, inputDataBuffer, outputDataBuffer);
+
+ for (uint32_t i = 0; i < input.mCount; ++i)
+ {
+ keyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i]);
+ }
+
+ return duration;
+}
+
+float LoadBlendShapeKeyFrames(const std::string& path, const gt::Animation::Channel& channel, const std::string& nodeName, uint32_t& propertyIndex, std::vector<SceneLoader::AnimatedProperty>& properties)
+{
+ const gltf2::Accessor& input = *channel.mSampler->mInput;
+ const gltf2::Accessor& output = *channel.mSampler->mOutput;
+
+ Vector<float> inputDataBuffer;
+ Vector<float> outputDataBuffer;
+
+ const float duration = LoadDataFromAccessors<float>(path, input, output, inputDataBuffer, outputDataBuffer);
+
+ char weightNameBuffer[32];
+ char* const pWeightName = weightNameBuffer + sprintf(weightNameBuffer, "%s[", BLEND_SHAPE_WEIGHTS_UNIFORM.c_str());
+ for (uint32_t weightIndex = 0u, endWeightIndex = channel.mSampler->mOutput->mCount / channel.mSampler->mInput->mCount; weightIndex < endWeightIndex; ++weightIndex)
+ {
+ AnimatedProperty& animatedProperty = properties[propertyIndex++];
+
+ animatedProperty.mNodeName = nodeName;
+ sprintf(pWeightName, "%d]", weightIndex);
+ animatedProperty.mPropertyName = std::string(weightNameBuffer);
+
+ animatedProperty.mKeyFrames = KeyFrames::New();
+ for (uint32_t i = 0; i < input.mCount; ++i)
+ {
+ animatedProperty.mKeyFrames.Add(inputDataBuffer[i] / duration, outputDataBuffer[i*endWeightIndex + weightIndex]);
+ }
+
+ animatedProperty.mTimePeriod = { 0.f, duration };
+ }
+
+ return duration;
+}
+
+void ConvertAnimations(const gt::Document& doc, ConversionContext& cctx)
+{
+ auto& output = cctx.mOutput;
+
+ output.mAnimationDefinitions.reserve(output.mAnimationDefinitions.size() + doc.mAnimations.size());
+
+ for (const auto& animation : doc.mAnimations)
+ {
+ AnimationDefinition animationDef;
+
+ if (!animation.mName.empty())
+ {
+ animationDef.mName = animation.mName;
+ }
+
+ uint32_t numberOfProperties = 0u;
+
+ for (const auto& channel : animation.mChannels)
+ {
+ numberOfProperties += channel.mSampler->mOutput->mCount;
+ }
+ animationDef.mProperties.resize(numberOfProperties);
+
+ Index propertyIndex = 0u;
+ for (const auto& channel : animation.mChannels)
+ {
+ std::string nodeName;
+ if (!channel.mTarget.mNode->mName.empty())
+ {
+ nodeName = channel.mTarget.mNode->mName;
+ }
+ else
+ {
+ Index index = cctx.mNodeIndices.GetRuntimeId(channel.mTarget.mNode.GetIndex());
+ nodeName = cctx.mOutput.mScene.GetNode(index)->mName;
+ }
+
+ float duration = 0.f;
+
+ switch (channel.mTarget.mPath)
+ {
+ case gt::Animation::Channel::Target::TRANSLATION:
+ {
+ AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
+
+ animatedProperty.mNodeName = nodeName;
+ animatedProperty.mPropertyName = POSITION_PROPERTY;
+
+ animatedProperty.mKeyFrames = KeyFrames::New();
+ duration = LoadKeyFrames<Vector3>(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
+
+ animatedProperty.mTimePeriod = { 0.f, duration };
+ break;
+ }
+ case gt::Animation::Channel::Target::ROTATION:
+ {
+ AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
+
+ animatedProperty.mNodeName = nodeName;
+ animatedProperty.mPropertyName = ORIENTATION_PROPERTY;
+
+ animatedProperty.mKeyFrames = KeyFrames::New();
+ duration = LoadKeyFrames<Quaternion>(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
+
+ animatedProperty.mTimePeriod = { 0.f, duration };
+ break;
+ }
+ case gt::Animation::Channel::Target::SCALE:
+ {
+ AnimatedProperty& animatedProperty = animationDef.mProperties[propertyIndex];
+
+ animatedProperty.mNodeName = nodeName;
+ animatedProperty.mPropertyName = SCALE_PROPERTY;
+
+ animatedProperty.mKeyFrames = KeyFrames::New();
+ duration = LoadKeyFrames<Vector3>(cctx.mPath, channel, animatedProperty.mKeyFrames, channel.mTarget.mPath);
+
+ animatedProperty.mTimePeriod = { 0.f, duration };
+ break;
+ }
+ case gt::Animation::Channel::Target::WEIGHTS:
+ {
+ duration = LoadBlendShapeKeyFrames(cctx.mPath, channel, nodeName, propertyIndex, animationDef.mProperties);
+
+ break;
+ }
+ default:
+ {
+ // nothing to animate.
+ break;
+ }
+ }
+
+ animationDef.mDuration = std::max(duration, animationDef.mDuration);
+
+ ++propertyIndex;
+ }
+
+ output.mAnimationDefinitions.push_back(std::move(animationDef));
+ }
+}
+
+void ProcessSkins(const gt::Document& doc, ConversionContext& cctx)
+{
+ // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skininversebindmatrices
+ // If an inverseBindMatrices accessor was provided, we'll load the joint data from the buffer,
+ // otherwise we'll set identity matrices for inverse bind pose.
+ struct IInverseBindMatrixProvider
+ {
+ virtual ~IInverseBindMatrixProvider() {}
+ virtual void Provide(Matrix& ibm) = 0;
+ };
+
+ struct InverseBindMatrixAccessor : public IInverseBindMatrixProvider
+ {
+ std::ifstream mStream;
+ const uint32_t mElementSizeBytes;
+
+ InverseBindMatrixAccessor(const gt::Accessor& accessor, const std::string& path)
+ : mStream(path + std::string(accessor.mBufferView->mBuffer->mUri), std::ios::binary),
+ mElementSizeBytes(accessor.GetElementSizeBytes())
+ {
+ DALI_ASSERT_ALWAYS(mStream);
+ DALI_ASSERT_DEBUG(accessor.mType == gt::AccessorType::MAT4 && accessor.mComponentType == gt::Component::FLOAT);
+
+ mStream.seekg(accessor.mBufferView->mByteOffset + accessor.mByteOffset);
+ }
+
+ virtual void Provide(Matrix& ibm) override
+ {
+ DALI_ASSERT_ALWAYS(mStream.read(reinterpret_cast<char*>(ibm.AsFloat()), mElementSizeBytes));
+ }
+ };
+
+ struct DefaultInverseBindMatrixProvider : public IInverseBindMatrixProvider
+ {
+ virtual void Provide(Matrix& ibm) override
+ {
+ ibm = Matrix::IDENTITY;
+ }
+ };
+
+ auto& resources = cctx.mOutput.mResources;
+ resources.mSkeletons.reserve(doc.mSkins.size());
+
+ for (auto& s : doc.mSkins)
+ {
+ std::unique_ptr<IInverseBindMatrixProvider> ibmProvider;
+ if (s.mInverseBindMatrices)
+ {
+ ibmProvider.reset(new InverseBindMatrixAccessor(*s.mInverseBindMatrices, cctx.mPath));
+ }
+ else
+ {
+ ibmProvider.reset(new DefaultInverseBindMatrixProvider());
+ }
+
+ SkeletonDefinition skeleton;
+ if (s.mSkeleton.GetIndex() != INVALID_INDEX)
+ {
+ skeleton.mRootNodeIdx = cctx.mNodeIndices.GetRuntimeId(s.mSkeleton.GetIndex());
+ }
+
+ skeleton.mJoints.resize(s.mJoints.size());
+ auto iJoint = skeleton.mJoints.begin();
+ for (auto& j : s.mJoints)
+ {
+ iJoint->mNodeIdx = cctx.mNodeIndices.GetRuntimeId(j.GetIndex());
+
+ ibmProvider->Provide(iJoint->mInverseBindMatrix);
+
+ ++iJoint;
+ }
+
+ resources.mSkeletons.push_back(std::move(skeleton));
+ }
+}
+
+void ProduceShaders(ShaderDefinitionFactory& shaderFactory, SceneDefinition& scene)
+{
+ for (size_t i0 = 0, i1 = scene.GetNodeCount(); i0 != i1; ++i0)
+ {
+ auto nodeDef = scene.GetNode(i0);
+ if (auto renderable = nodeDef->mRenderable.get())
+ {
+ renderable->mShaderIdx = shaderFactory.ProduceShader(*nodeDef);
+ }
+ }
+}
+
+void SetObjectReaders()
+{
+ js::SetObjectReader(BUFFER_READER);
+ js::SetObjectReader(BUFFER_VIEW_READER);
+ js::SetObjectReader(BUFFER_VIEW_CLIENT_READER);
+ js::SetObjectReader(COMPONENT_TYPED_BUFFER_VIEW_CLIENT_READER);
+ js::SetObjectReader(ACCESSOR_SPARSE_READER);
+ js::SetObjectReader(ACCESSOR_READER);
+ js::SetObjectReader(IMAGE_READER);
+ js::SetObjectReader(SAMPLER_READER);
+ js::SetObjectReader(TEXURE_READER);
+ js::SetObjectReader(TEXURE_INFO_READER);
+ js::SetObjectReader(MATERIAL_PBR_READER);
+ js::SetObjectReader(MATERIAL_READER);
+ js::SetObjectReader(MESH_PRIMITIVE_READER);
+ js::SetObjectReader(MESH_READER);
+ js::SetObjectReader(SKIN_READER);
+ js::SetObjectReader(CAMERA_PERSPECTIVE_READER);
+ js::SetObjectReader(CAMERA_ORTHOGRAPHIC_READER);
+ js::SetObjectReader(CAMERA_READER);
+ js::SetObjectReader(NODE_READER);
+ js::SetObjectReader(ANIMATION_SAMPLER_READER);
+ js::SetObjectReader(ANIMATION_TARGET_READER);
+ js::SetObjectReader(ANIMATION_CHANNEL_READER);
+ js::SetObjectReader(ANIMATION_READER);
+ js::SetObjectReader(SCENE_READER);
+}
+
+} // nonamespace
+
+void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params)
+{
+ bool failed = false;
+ auto js = LoadTextFile(url.c_str(), &failed);
+ if (failed)
+ {
+ throw std::runtime_error("Failed to load " + url);
+ }
+
+ json::unique_ptr root(json_parse(js.c_str(), js.size()));
+ if (!root)
+ {
+ throw std::runtime_error("Failed to parse " + url);
+ }
+
+ static bool setObjectReaders = true;
+ if (setObjectReaders)
+ {
+ // NOTE: only referencing own, anonymous namespace, const objects; the pointers will never need to change.
+ SetObjectReaders();
+ setObjectReaders = false;
+ }
+
+ gt::Document doc;
+
+ auto& rootObj = js::Cast<json_object_s>(*root);
+ auto jsAsset = js::FindObjectChild("asset", rootObj);
+ auto jsAssetVersion = js::FindObjectChild("version", js::Cast<json_object_s>(*jsAsset));
+ doc.mAsset.mVersion = js::Read::StringView(*jsAssetVersion);
+
+ gt::SetRefReaderObject(doc);
+ DOCUMENT_READER.Read(rootObj, doc);
+
+ auto path = url.substr(0, url.rfind('/') + 1);
+ ConversionContext cctx{ params, path, INVALID_INDEX };
+
+ ConvertMaterials(doc, cctx);
+ ConvertMeshes(doc, cctx);
+ ConvertNodes(doc, cctx);
+ ConvertAnimations(doc, cctx);
+
+ ProcessSkins(doc, cctx);
+
+ ProduceShaders(shaderFactory, params.mScene);
+ params.mScene.EnsureUniqueSkinningShaderInstances(params.mResources);
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_GLTF2_LOADER_H
+#define DALI_SCENE_LOADER_GLTF2_LOADER_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ // INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include <string>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+struct CameraParameters;
+struct LoadResult;
+class ShaderDefinitionFactory;
+
+/**
+ * @brief Loads the scene from the glTF file located at @a url, storing the results in @a params.
+ * @note Will throw std::runtime_error for JSON entities with types mismatching expectations, carrying
+ * invalid values, or I/O errors.
+ */
+DALI_SCENE_LOADER_API void LoadGltfScene(const std::string& url, ShaderDefinitionFactory& shaderFactory, LoadResult& params);
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_GLTF2_LOADER_H
--- /dev/null
+#ifndef DALI_SCENE_LOADER_INDEX_H_
+#define DALI_SCENE_LOADER_INDEX_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include <cstdint>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+using Index = uint32_t;
+
+constexpr Index INVALID_INDEX = static_cast<Index>(-1);
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_INDEX_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ // FILE HEADER
+#include "dali-scene-loader/public-api/ktx-loader.h"
+
+ // EXTERNAL INCLUDES
+#include "dali/public-api/rendering/texture.h"
+#include <fstream>
+#include <memory>
+
+namespace Dali
+{
+
+namespace
+{
+
+// http://github.khronos.org/KTX-Specification/
+const uint8_t KTX_ID_HEAD[] = { 0xAB, 0x4B, 0x54, 0x58, 0x20 };
+const uint8_t KTX_ID_TAIL[] = { 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
+
+const uint8_t KTX_VERSION_1_1[] = { 0x31, 0x31 };
+const uint8_t KTX_VERSION_2_0[] = { 0x32, 0x30 };
+
+static_assert(sizeof(KTX_ID_HEAD) + sizeof(KTX_ID_TAIL) == 10);
+static_assert(sizeof(KTX_VERSION_1_1) == 2);
+static_assert(sizeof(KTX_VERSION_2_0) == sizeof(KTX_VERSION_1_1));
+
+void FreeBuffer(uint8_t* buffer)
+{
+ delete[] buffer;
+}
+} // namespace
+
+namespace SceneLoader
+{
+struct KtxFileHeader
+{
+ uint8_t identifier[12];
+ uint32_t endianness;
+ uint32_t glType; //(UNSIGNED_BYTE, UNSIGNED_SHORT_5_6_5, etc.)
+ uint32_t glTypeSize;
+ uint32_t glFormat; //(RGB, RGBA, BGRA, etc.)
+ uint32_t glInternalFormat; //For uncompressed textures, specifies the internalformat parameter passed to glTexStorage*D or glTexImage*D
+ uint32_t glBaseInternalFormat;
+ uint32_t pixelWidth;
+ uint32_t pixelHeight;
+ uint32_t pixelDepth;
+ uint32_t numberOfArrayElements;
+ uint32_t numberOfFaces; //Cube map faces are stored in the order: +X, -X, +Y, -Y, +Z, -Z.
+ uint32_t numberOfMipmapLevels;
+ uint32_t bytesOfKeyValueData;
+
+ bool IsIdentifierValid() const
+ {
+ return std::equal(KTX_ID_HEAD, std::end(KTX_ID_HEAD), identifier) &&
+ (std::equal(KTX_VERSION_1_1, std::end(KTX_VERSION_1_1), identifier + sizeof(KTX_ID_HEAD)) ||
+ std::equal(KTX_VERSION_2_0, std::end(KTX_VERSION_2_0), identifier + sizeof(KTX_ID_HEAD))) &&
+ std::equal(KTX_ID_TAIL, std::end(KTX_ID_TAIL), identifier + (sizeof(KTX_ID_HEAD) + sizeof(KTX_VERSION_1_1)));
+ }
+};
+
+/**
+ * Convert KTX format to Pixel::Format
+ */
+bool ConvertPixelFormat(const uint32_t ktxPixelFormat, Pixel::Format& format)
+{
+ switch (ktxPixelFormat)
+ {
+ case 0x93B0: // GL_COMPRESSED_RGBA_ASTC_4x4
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_4x4_KHR;
+ break;
+ }
+ case 0x93B1: // GL_COMPRESSED_RGBA_ASTC_5x4
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_5x4_KHR;
+ break;
+ }
+ case 0x93B2: // GL_COMPRESSED_RGBA_ASTC_5x5
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_5x5_KHR;
+ break;
+ }
+ case 0x93B3: // GL_COMPRESSED_RGBA_ASTC_6x5
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_6x5_KHR;
+ break;
+ }
+ case 0x93B4: // GL_COMPRESSED_RGBA_ASTC_6x6
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_6x6_KHR;
+ break;
+ }
+ case 0x93B5: // GL_COMPRESSED_RGBA_ASTC_8x5
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_8x5_KHR;
+ break;
+ }
+ case 0x93B6: // GL_COMPRESSED_RGBA_ASTC_8x6
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_8x6_KHR;
+ break;
+ }
+ case 0x93B7: // GL_COMPRESSED_RGBA_ASTC_8x8
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_8x8_KHR;
+ break;
+ }
+ case 0x93B8: // GL_COMPRESSED_RGBA_ASTC_10x5
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_10x5_KHR;
+ break;
+ }
+ case 0x93B9: // GL_COMPRESSED_RGBA_ASTC_10x6
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_10x6_KHR;
+ break;
+ }
+ case 0x93BA: // GL_COMPRESSED_RGBA_ASTC_10x8
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_10x8_KHR;
+ break;
+ }
+ case 0x93BB: // GL_COMPRESSED_RGBA_ASTC_10x10
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_10x10_KHR;
+ break;
+ }
+ case 0x93BC: // GL_COMPRESSED_RGBA_ASTC_12x10
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_12x10_KHR;
+ break;
+ }
+ case 0x93BD: // GL_COMPRESSED_RGBA_ASTC_12x12
+ {
+ format = Pixel::COMPRESSED_RGBA_ASTC_12x12_KHR;
+ break;
+ }
+ case 0x881B: // GL_RGB16F
+ {
+ format = Pixel::RGB16F;
+ break;
+ }
+ case 0x8815: // GL_RGB32F
+ {
+ format = Pixel::RGB32F;
+ break;
+ }
+ case 0x8C3A: // GL_R11F_G11F_B10F
+ {
+ format = Pixel::RGB32F;
+ break;
+ }
+ case 0x8D7C: // GL_RGBA8UI
+ {
+ format = Pixel::RGBA8888;
+ break;
+ }
+ case 0x8D7D: // GL_RGB8UI
+ {
+ format = Pixel::RGB888;
+ break;
+ }
+ default:
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+Texture CubeData::CreateTexture() const
+{
+ Texture texture = Texture::New(TextureType::TEXTURE_CUBE, data[0][0].GetPixelFormat(),
+ data[0][0].GetWidth(), data[0][0].GetHeight());
+ for (size_t iSide = 0u, iEndSize = data.size(); iSide < iEndSize; ++iSide)
+ {
+ auto& side = data[iSide];
+ for (size_t iMipLevel = 0u, iEndMipLevel = data[0].size(); iMipLevel < iEndMipLevel; ++iMipLevel)
+ {
+ texture.Upload(side[iMipLevel], CubeMapLayer::POSITIVE_X + iSide, iMipLevel,
+ 0u, 0u, side[iMipLevel].GetWidth(), side[iMipLevel].GetHeight());
+ }
+ }
+
+ return texture;
+}
+
+bool LoadCubeMapData(const std::string& path, CubeData& cubedata)
+{
+ std::fstream fp(path, std::ios::in | std::ios::binary);
+ if (fp.is_open() == false)
+ {
+ return false;
+ }
+
+ KtxFileHeader header;
+ if (fp.read(reinterpret_cast<char*>(&header), sizeof(KtxFileHeader)).good() == false)
+ {
+ return false;
+ }
+
+ if (!header.IsIdentifierValid())
+ {
+ return false;
+ }
+
+ // Skip the key-values:
+ if (fp.seekg(header.bytesOfKeyValueData, fp.cur).good() == false)
+ {
+ return false;
+ }
+
+ header.numberOfMipmapLevels = std::max(header.numberOfMipmapLevels, 1u);
+ header.numberOfArrayElements = std::max(header.numberOfArrayElements, 1u);
+ header.pixelDepth = std::max(header.pixelDepth, 1u);
+ header.pixelHeight = std::max(header.pixelHeight, 1u);
+
+ cubedata.data.resize(header.numberOfFaces);
+ for (uint32_t face = 0u; face < header.numberOfFaces; ++face)
+ {
+ cubedata.data[face].resize(header.numberOfMipmapLevels);
+ }
+
+ Pixel::Format daliformat = Pixel::RGB888;
+
+ ConvertPixelFormat(header.glInternalFormat, daliformat);
+
+ for (uint32_t mipmapLevel = 0u; mipmapLevel < header.numberOfMipmapLevels; ++mipmapLevel)
+ {
+ uint32_t byteSize = 0u;
+ if (fp.read(reinterpret_cast<char*>(&byteSize), sizeof(byteSize)).good() == false)
+ {
+ return false;
+ }
+
+ if (0u != byteSize % 4u)
+ {
+ byteSize += 4u - byteSize % 4u;
+ }
+
+ for (uint32_t arrayElement = 0u; arrayElement < header.numberOfArrayElements; ++arrayElement) //arrayElement must be 0 or 1
+ {
+ for (uint32_t face = 0u; face < header.numberOfFaces; ++face)
+ {
+ std::unique_ptr<uint8_t, void(*)(uint8_t*)>img(new uint8_t[byteSize], FreeBuffer);
+ if (fp.read(reinterpret_cast<char*>(img.get()), byteSize).good() == false)
+ {
+ return false;
+ }
+ cubedata.data[face][mipmapLevel] = PixelData::New(img.release(), byteSize, header.pixelWidth, header.pixelHeight, daliformat, PixelData::DELETE_ARRAY);
+ }
+ }
+
+ header.pixelHeight /= 2u;
+ header.pixelWidth /= 2u;
+ }
+
+ return true;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_KTX_LOADER_H
+#define DALI_SCENE_LOADER_KTX_LOADER_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/images/pixel-data.h"
+#include "dali/public-api/rendering/texture.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Stores the pixel data objects for each face of the cube texture and their mipmaps.
+ */
+struct DALI_SCENE_LOADER_API CubeData
+{
+ std::vector< std::vector<PixelData> > data;
+
+ Texture CreateTexture() const;
+};
+
+/**
+ * @brief Loads cube map data texture from a ktx file.
+ *
+ * @param[in] path The file path.
+ * @param[out] cubedata The data structure with all pixel data objects.
+ */
+DALI_SCENE_LOADER_API bool LoadCubeMapData(const std::string& path, CubeData& cubedata);
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_KTX_LOADER_H
--- /dev/null
+#ifndef DALI_SCENE_LOADER_LIGHT_PARAMETERS_H
+#define DALI_SCENE_LOADER_LIGHT_PARAMETERS_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/matrix.h"
+#include "dali/public-api/math/vector3.h"
+#include <stdint.h>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+struct DALI_SCENE_LOADER_API LightParameters
+{
+ Matrix transform;
+
+ Vector3 color;
+ float intensity;
+ float shadowIntensity;
+ uint32_t shadowMapSize;
+ float orthographicSize;
+};
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_LIGHT_PARAMETERS_H
--- /dev/null
+#ifndef DALI_SCENE_LOADER_OUTPUT_H
+#define DALI_SCENE_LOADER_OUTPUT_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/animation-definition.h"
+#include "dali-scene-loader/public-api/light-parameters.h"
+#include "dali-scene-loader/public-api/camera-parameters.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+class ResourceBundle;
+class SceneDefinition;
+
+/**
+ * @brief The outputs from loading and processing a scene.
+ */
+struct DALI_SCENE_LOADER_API LoadResult
+{
+ /**
+ * @brief The bundle to store resources in.
+ */
+ ResourceBundle& mResources;
+
+ /**
+ * @brief The scene definition to populate.
+ */
+ SceneDefinition& mScene;
+
+ /**
+ * @brief The list of animation definitions, in lexicographical order of their names.
+ */
+ std::vector<AnimationDefinition>& mAnimationDefinitions;
+
+ /**
+ * @brief The list of animation group definitions, in lexicographical order of their names.
+ */
+ std::vector<AnimationGroupDefinition>& mAnimationGroupDefinitions;
+
+ /**
+ * @brief The camera parameters that were loaded from the scene.
+ */
+ std::vector<CameraParameters>& mCameraParameters;
+
+ /**
+ * @brief The light parameters that were loaded from the scene.
+ */
+ std::vector<LightParameters>& mLightParameters;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_OUTPUT_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/material-definition.h"
+
+// EXTERNAL INCLUDES
+#include "dali-toolkit/public-api/image-loader/sync-image-loader.h"
+
+namespace Dali
+{
+using namespace Toolkit;
+
+namespace SceneLoader
+{
+namespace
+{
+
+constexpr SamplerFlags::Type FILTER_MODES_FROM_DALI[]{
+ SamplerFlags::FILTER_LINEAR | SamplerFlags::FILTER_MIPMAP_NEAREST,
+ SamplerFlags::FILTER_LINEAR,
+ SamplerFlags::FILTER_NEAREST,
+ SamplerFlags::FILTER_LINEAR,
+ SamplerFlags::FILTER_NEAREST | SamplerFlags::FILTER_MIPMAP_NEAREST,
+ SamplerFlags::FILTER_LINEAR | SamplerFlags::FILTER_MIPMAP_NEAREST,
+ SamplerFlags::FILTER_NEAREST | SamplerFlags::FILTER_MIPMAP_LINEAR,
+ SamplerFlags::FILTER_LINEAR | SamplerFlags::FILTER_MIPMAP_LINEAR,
+};
+
+constexpr SamplerFlags::Type WRAP_MODES_FROM_DALI[]{
+ SamplerFlags::WRAP_CLAMP,
+ SamplerFlags::WRAP_CLAMP,
+ SamplerFlags::WRAP_REPEAT,
+ SamplerFlags::WRAP_MIRROR,
+};
+
+constexpr FilterMode::Type FILTER_MODES_TO_DALI[]{
+ FilterMode::NEAREST,
+ FilterMode::LINEAR,
+ FilterMode::NEAREST_MIPMAP_NEAREST,
+ FilterMode::LINEAR_MIPMAP_NEAREST,
+ FilterMode::NEAREST_MIPMAP_LINEAR,
+ FilterMode::LINEAR_MIPMAP_LINEAR,
+};
+
+constexpr WrapMode::Type WRAP_MODES_TO_DALI[]{
+ WrapMode::REPEAT,
+ WrapMode::CLAMP_TO_EDGE,
+ WrapMode::MIRRORED_REPEAT
+};
+
+const SamplerFlags::Type SINGLE_VALUE_SAMPLER = SamplerFlags::Encode(FilterMode::NEAREST, FilterMode::NEAREST, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
+}
+
+SamplerFlags::Type SamplerFlags::Encode(FilterMode::Type minFilter, FilterMode::Type magFilter, WrapMode::Type wrapS, WrapMode::Type wrapT)
+{
+ return FILTER_MODES_FROM_DALI[minFilter] | ((FILTER_MODES_FROM_DALI[magFilter] & FILTER_MAG_BITS) << FILTER_MAG_SHIFT) |
+ (WRAP_MODES_FROM_DALI[wrapS] << WRAP_S_SHIFT) | (WRAP_MODES_FROM_DALI[wrapT] << WRAP_T_SHIFT);
+}
+
+FilterMode::Type SamplerFlags::GetMinFilter(Type flags)
+{
+ return FILTER_MODES_TO_DALI[flags & FILTER_MIN_MASK];
+}
+
+FilterMode::Type SamplerFlags::GetMagFilter(Type flags)
+{
+ return FILTER_MODES_TO_DALI[(flags >> FILTER_MAG_SHIFT) & FILTER_MAG_MASK];
+}
+
+WrapMode::Type SamplerFlags::GetWrapS(Type flags)
+{
+ return WRAP_MODES_TO_DALI[(flags >> WRAP_S_SHIFT) & WRAP_S_MASK];
+}
+
+WrapMode::Type SamplerFlags::GetWrapT(Type flags)
+{
+ return WRAP_MODES_TO_DALI[(flags >> WRAP_T_SHIFT) & WRAP_T_MASK];
+}
+
+Sampler SamplerFlags::MakeSampler(Type flags)
+{
+ auto sampler = Sampler::New();
+ sampler.SetFilterMode(GetMinFilter(flags), GetMagFilter(flags));
+ sampler.SetWrapMode(GetWrapS(flags), GetWrapT(flags));
+ return sampler;
+}
+
+MaterialDefinition::RawData
+ MaterialDefinition::LoadRaw(const std::string& imagesPath) const
+{
+ RawData raw;
+
+ const bool hasTransparency = MaskMatch(mFlags, TRANSPARENCY);
+ uint32_t numBuffers = mTextureStages.size() + (hasTransparency ?
+ !CheckTextures(ALBEDO) + !CheckTextures(METALLIC | ROUGHNESS) + !CheckTextures(NORMAL) :
+ !CheckTextures(ALBEDO | METALLIC) + !CheckTextures(NORMAL | ROUGHNESS));
+ if (numBuffers == 0)
+ {
+ return raw;
+ }
+ raw.mTextures.reserve(numBuffers);
+
+ // Load textures
+ auto iTexture = mTextureStages.cbegin();
+ auto checkStage = [&](uint32_t flags) {
+ return iTexture != mTextureStages.end() && MaskMatch(iTexture->mSemantic, flags);
+ };
+
+ // Check for compulsory textures: Albedo, Metallic, Roughness, Normal
+ if (checkStage(ALBEDO | METALLIC))
+ {
+ raw.mTextures.push_back({ SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags });
+ ++iTexture;
+
+ if (checkStage(NORMAL | ROUGHNESS))
+ {
+ raw.mTextures.push_back({ SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags });
+ ++iTexture;
+ }
+ else // single value normal-roughness
+ {
+ const auto bufferSize = 4;
+ uint8_t* buffer = new uint8_t[bufferSize]{ 0x7f, 0x7f, 0xff, 0xff }; // normal of (0, 0, 1), roughness of 1
+ raw.mTextures.push_back({ PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER });
+ }
+ }
+ else
+ {
+ if (checkStage(ALBEDO))
+ {
+ raw.mTextures.push_back({ SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags });
+ ++iTexture;
+ }
+ else // single value albedo, albedo-alpha or albedo-metallic
+ {
+ uint32_t bufferSize = 4;
+ uint8_t* buffer = nullptr;
+ auto format = Pixel::Format::RGBA8888;
+ if (hasTransparency) // albedo-alpha
+ {
+ buffer = new uint8_t[bufferSize];
+ buffer[3] = static_cast<uint8_t>(mColor.a * 255.f);
+ }
+ else if (!checkStage(METALLIC | ROUGHNESS)) // albedo-metallic
+ {
+ buffer = new uint8_t[bufferSize];
+ buffer[3] = 0xff; // metallic of 1.0
+ }
+ else // albedo
+ {
+ bufferSize = 3;
+ buffer = new uint8_t[bufferSize];
+ format = Pixel::Format::RGB888;
+ }
+ buffer[0] = static_cast<uint8_t>(mColor.r * 255.f);
+ buffer[1] = static_cast<uint8_t>(mColor.g * 255.f);
+ buffer[2] = static_cast<uint8_t>(mColor.b * 255.f);
+ raw.mTextures.push_back({ PixelData::New(buffer, bufferSize, 1, 1, format, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER });
+ }
+
+ // If we have transparency, or an image based albedo map, we will have to continue with separate metallicRoughness + normal.
+ const bool createMetallicRoughnessAndNormal = hasTransparency || std::distance(mTextureStages.begin(), iTexture) > 0;
+ if (checkStage(METALLIC | ROUGHNESS))
+ {
+ raw.mTextures.push_back({ SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags });
+ ++iTexture;
+ }
+ else if (createMetallicRoughnessAndNormal)
+ {
+ // NOTE: we want to set both metallic and roughness to 1.0; dli uses the R & A channels,
+ // glTF2 uses B & G, so we might as well just set all components to 1.0.
+ const auto bufferSize = 4;
+ uint8_t* buffer = new uint8_t[bufferSize]{ 0xff, 0xff, 0xff, 0xff };
+ raw.mTextures.push_back({ PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER });
+ }
+
+ if (checkStage(NORMAL))
+ {
+ raw.mTextures.push_back({ SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags });
+ ++iTexture;
+ }
+ else if (createMetallicRoughnessAndNormal)
+ {
+ const auto bufferSize = 3;
+ uint8_t* buffer = new uint8_t[bufferSize]{ 0x7f, 0x7f, 0xff }; // normal of (0, 0, 1)
+ raw.mTextures.push_back({ PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGB888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER });
+ }
+ else // single-value normal-roughness
+ {
+ const auto bufferSize = 4;
+ uint8_t* buffer = new uint8_t[bufferSize]{ 0x7f, 0x7f, 0xff, 0xff }; // normal of (0, 0, 1), roughness of 1.0
+ raw.mTextures.push_back({ PixelData::New(buffer, bufferSize, 1, 1, Pixel::RGBA8888, PixelData::DELETE_ARRAY), SINGLE_VALUE_SAMPLER });
+ }
+ }
+
+ // Extra textures. TODO: emissive, occlusion etc.
+ if (checkStage(SUBSURFACE))
+ {
+ raw.mTextures.push_back({ SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags });
+ ++iTexture;
+ }
+
+ return raw;
+}
+
+TextureSet MaterialDefinition::Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const
+{
+ auto textureSet = TextureSet::New();
+
+ uint32_t n = 0;
+ for (auto& tData : raw.mTextures)
+ {
+ auto& pixels = tData.mPixels;
+ auto texture = Texture::New(TextureType::TEXTURE_2D, pixels.GetPixelFormat(), pixels.GetWidth(), pixels.GetHeight());
+ texture.Upload(tData.mPixels, 0, 0, 0, 0, pixels.GetWidth(), pixels.GetHeight());
+ if (tData.mSamplerFlags & SamplerFlags::MIPMAP_MASK)
+ {
+ texture.GenerateMipmaps();
+ }
+
+ textureSet.SetTexture(n, texture);
+ textureSet.SetSampler(n, SamplerFlags::MakeSampler(tData.mSamplerFlags));
+
+ ++n;
+ }
+
+ // Assign textures to slots -- starting with 2D ones, then cubemaps, if any.
+ if (mEnvironmentIdx < environments.size())
+ {
+ auto& envTextures = environments[mEnvironmentIdx].second;
+ if (envTextures.mDiffuse)
+ {
+ textureSet.SetTexture(n, envTextures.mDiffuse);
+ ++n;
+ }
+
+ if (envTextures.mSpecular)
+ {
+ auto specularSampler = Sampler::New();
+ specularSampler.SetWrapMode(WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE, WrapMode::CLAMP_TO_EDGE);
+ specularSampler.SetFilterMode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR);
+
+ textureSet.SetTexture(n, envTextures.mSpecular);
+ textureSet.SetSampler(n, specularSampler);
+ }
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Environment index (" << mEnvironmentIdx << ") out of bounds (" <<
+ environments.size() << ").";
+ }
+
+ return textureSet;
+}
+
+bool MaterialDefinition::CheckTextures(uint32_t flags) const
+{
+ return std::find_if(mTextureStages.begin(), mTextureStages.end(), [flags](const TextureStage& ts) {
+ return MaskMatch(ts.mSemantic, flags);
+ }) != mTextureStages.end();
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_MATERIAL_DEFINITION_H
+#define DALI_SCENE_LOADER_MATERIAL_DEFINITION_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/environment-definition.h"
+#include "dali-scene-loader/public-api/index.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/vector4.h"
+#include "dali/public-api/common/vector-wrapper.h"
+#include <cmath>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Helper enum for encoding and decoding sampler states.
+ */
+struct DALI_SCENE_LOADER_API SamplerFlags
+{
+ using Type = uint8_t;
+
+ enum Values : Type
+ {
+ // Filter - 3 bits
+ FILTER_NEAREST = 0,
+ FILTER_LINEAR = NthBit(0),
+ FILTER_MIPMAP_NEAREST = NthBit(1),
+ FILTER_MIPMAP_LINEAR = NthBit(2),
+
+ // Wrap - 2 bits
+ WRAP_REPEAT = 0,
+ WRAP_CLAMP = NthBit(0),
+ WRAP_MIRROR = NthBit(1),
+
+ // Layout - apply shift, then mask
+ FILTER_MIN_BITS = 3,
+ FILTER_MIN_MASK = NthBit(FILTER_MIN_BITS) - 1,
+
+ FILTER_MAG_BITS = 1,
+ FILTER_MAG_SHIFT = FILTER_MIN_BITS,
+ FILTER_MAG_MASK = NthBit(FILTER_MAG_BITS) - 1,
+
+ WRAP_S_BITS = 2,
+ WRAP_S_SHIFT = FILTER_MAG_SHIFT + FILTER_MAG_BITS,
+ WRAP_S_MASK = NthBit(WRAP_S_BITS) - 1,
+
+ WRAP_T_BITS = 2,
+ WRAP_T_SHIFT = WRAP_S_SHIFT + WRAP_S_BITS,
+ WRAP_T_MASK = NthBit(WRAP_T_BITS) - 1,
+
+ // Diagnostics
+ MIPMAP_MASK = FILTER_MIPMAP_LINEAR | FILTER_MIPMAP_NEAREST,
+
+ // Default
+ DEFAULT = FILTER_LINEAR | (FILTER_LINEAR << FILTER_MAG_SHIFT) | (WRAP_REPEAT << WRAP_S_SHIFT) | (WRAP_REPEAT << WRAP_T_SHIFT), // LINEAR filters, REPEAT wraps
+ };
+
+ /**
+ * @return SamplerFlags bit pattern calculated from the given Dali Sampler settings.
+ */
+ static Type Encode(FilterMode::Type minFilter, FilterMode::Type magFilter,
+ WrapMode::Type wrapS, WrapMode::Type wrapT);
+
+ /**
+ * @brief Decodes the minification filter patter of @a flags into the corresponding FilterMode.
+ */
+ static FilterMode::Type GetMinFilter(Type flags);
+
+ /**
+ * @brief Decodes the magnification filter patter of @a flags into the corresponding FilterMode.
+ */
+ static FilterMode::Type GetMagFilter(Type flags);
+
+ /**
+ * @brief Decodes the horizontal wrap pattern of @a flags into the corresponding WrapMode.
+ */
+ static WrapMode::Type GetWrapS(Type flags);
+
+ /**
+ * @brief Decodes the vertical wrap pattern of @a flags into the corresponding WrapMode.
+ */
+ static WrapMode::Type GetWrapT(Type flags);
+
+ /**
+ * @brief Creates a Sampler with the settings encoded in @a flags.
+ */
+ static Sampler MakeSampler(Type flags);
+};
+
+/**
+ * @brief Defines a texture from a combination of an image URI and its sampler definition.
+ */
+struct DALI_SCENE_LOADER_API TextureDefinition
+{
+ std::string mImageUri;
+ SamplerFlags::Type mSamplerFlags;
+
+ TextureDefinition(const std::string& imageUri = "", SamplerFlags::Type samplerFlags = SamplerFlags::DEFAULT)
+ : mImageUri(imageUri),
+ mSamplerFlags(samplerFlags)
+ {}
+};
+
+/**
+ * @brief Defines a material with a number of texture stages, whether mipmappping
+ * is enabled, and an index of an environment (usually of all environments in a
+ * scene). Textures from the environment are added last when the DALi TextureSet
+ * is being created.
+ */
+struct DALI_SCENE_LOADER_API MaterialDefinition
+{
+ enum Flags : uint32_t
+ {
+ // Texture semantics
+ ALBEDO = NthBit(0),
+ METALLIC = NthBit(1),
+ ROUGHNESS = NthBit(2),
+ NORMAL = NthBit(3),
+ EMISSIVE = NthBit(4), // TODO: support
+ OCCLUSION = NthBit(5), // TODO: support
+ SUBSURFACE = NthBit(6), // Note: dli-only
+
+ // Other binary options
+ TRANSPARENCY = NthBit(20),
+ GLTF_CHANNELS = NthBit(21), // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture
+
+ // Alpha cutoff - reserved from the 24th bit
+ ALPHA_CUTOFF_BITS = 8,
+ ALPHA_CUTOFF_SHIFT = sizeof(uint32_t) * 8 - ALPHA_CUTOFF_BITS,
+ ALPHA_CUTOFF_MASK = (1 << ALPHA_CUTOFF_BITS) - 1,
+ };
+
+ /**
+ * @brief A(n image based) texture that's used in a material.
+ */
+ struct TextureStage
+ {
+ uint32_t mSemantic;
+ TextureDefinition mTexture;
+ };
+
+ using Vector = std::vector<std::pair<MaterialDefinition, TextureSet>>;
+
+ struct RawData
+ {
+ struct TextureData
+ {
+ PixelData mPixels;
+ SamplerFlags::Type mSamplerFlags;
+ };
+
+ std::vector<TextureData> mTextures;
+ };
+
+ MaterialDefinition() = default;
+
+ MaterialDefinition(const MaterialDefinition&) = delete;
+ MaterialDefinition& operator=(const MaterialDefinition&) = delete;
+
+ MaterialDefinition(MaterialDefinition&&) = default;
+ MaterialDefinition& operator=(MaterialDefinition&&) = default;
+
+ /**
+ * @brief Loads (or, in the case of solid color materials, creates) raw pixel data,
+ * which is then returned.
+ * @note This may be called from any thread.
+ */
+ RawData LoadRaw(const std::string& imagesPath) const;
+
+ /**
+ * @brief Creates Textures from the pixel data in @a raw, gets the
+ * the cube maps from the iEnvironment'th element of @a environments,
+ * then creates a DALi TextureSet and returns it.
+ * @note This must be called from the event thread.
+ * @note The textures are added in the following order: 2D, cube maps.
+ */
+ TextureSet Load(const EnvironmentDefinition::Vector& environments, RawData&& raw) const;
+
+ /**
+ * @brief Checks if the given mask matches any of the textures defined.
+ */
+ bool CheckTextures(uint32_t flags) const;
+
+ /**
+ * @return The alpha test reference value.
+ * @note A value of 0.f means no alpha testing.
+ */
+ float GetAlphaCutoff() const
+ {
+ return ((mFlags >> ALPHA_CUTOFF_SHIFT) & ALPHA_CUTOFF_MASK) / 255.f;
+ }
+
+ /**
+ * @brief Encodes the alpha test reference @a value in flags.
+ * @note A value of 0.f means no alpha testing.
+ */
+ void SetAlphaCutoff(float value)
+ {
+ DALI_ASSERT_DEBUG(value >= 0.f && value <= 1.f);
+ mFlags |= static_cast<uint8_t>(std::round(value * 255.f)) << ALPHA_CUTOFF_SHIFT;
+ }
+
+public: // DATA
+ uint32_t mFlags = 0x0;
+
+ Index mEnvironmentIdx = 0;
+ Vector4 mColor = Color::WHITE;
+ float mMetallic = 1.f;
+ float mRoughness = 1.f;
+ std::vector<TextureStage> mTextureStages;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_MATERIAL_DEFINITION_H
--- /dev/null
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*/
+#include "dali-scene-loader/public-api/matrix-stack.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+MatrixStack::MatrixStack()
+{
+ mStack.reserve(16);
+}
+
+bool MatrixStack::IsEmpty() const
+{
+ return mStack.empty();
+}
+
+void MatrixStack::Push(const Matrix& model)
+{
+ if (mStack.empty())
+ {
+ mStack.push_back(model);
+ }
+ else
+ {
+ Matrix m{ false };
+ Matrix::Multiply(m, model, mStack.back());
+ mStack.push_back(m);
+ }
+}
+
+const Matrix& MatrixStack::Top() const
+{
+ return mStack.back();
+}
+
+void MatrixStack::Pop()
+{
+ DALI_ASSERT_ALWAYS(mStack.size() > 0);
+ mStack.pop_back();
+}
+
+void MatrixStack::PopAll()
+{
+ mStack.clear();
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_MATRIX_STACK_H_
+#define DALI_SCENE_LOADER_MATRIX_STACK_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/matrix.h"
+#include "dali/public-api/common/vector-wrapper.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief A stack of matrices whereby each newly pushed matrix is stored
+ * after being multiplied by the previous one (if any).
+ * @note Current implementation reserves space for 16 matrices.
+ */
+class DALI_SCENE_LOADER_API MatrixStack
+{
+public:
+ MatrixStack();
+
+ bool IsEmpty() const;
+ void Push(const Matrix& model);
+ const Matrix& Top() const;
+ void Pop();
+ void PopAll(); // clears the stack, but retains the storage.
+
+private:
+ std::vector<Matrix> mStack;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_MATRIX_STACK_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/mesh-definition.h"
+
+// EXTERNAL INCLUDES
+#include "dali/devel-api/adaptor-framework/pixel-buffer.h"
+#include <fstream>
+#include <cstring>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+
+using Uint16Vector4 = uint16_t[4];
+
+class IndexProvider
+{
+public:
+ IndexProvider(const uint16_t* indices)
+ : mData(reinterpret_cast<uintptr_t>(indices)),
+ mFunc(indices ? IncrementPointer : Increment)
+ {}
+
+ uint16_t operator()()
+ {
+ return mFunc(mData);
+ }
+
+private:
+ static uint16_t Increment(uintptr_t& data)
+ {
+ return static_cast<uint16_t>(data++);
+ }
+
+ static uint16_t IncrementPointer(uintptr_t& data)
+ {
+ auto iPtr = reinterpret_cast<const uint16_t*>(data);
+ auto result = *iPtr;
+ data = reinterpret_cast<uintptr_t>(++iPtr);
+ return result;
+ }
+
+ uintptr_t mData;
+ uint16_t(*mFunc)(uintptr_t&);
+};
+
+
+const std::string QUAD_STRING("quad");
+
+///@brief Reads a blob from the given stream @a source into @a target, which must have
+/// at least @a descriptor.length bytes.
+bool ReadBlob(const MeshDefinition::Blob& descriptor, std::istream& source, uint8_t* target)
+{
+ if (!source.seekg(descriptor.mOffset, std::istream::beg))
+ {
+ return false;
+ }
+
+ if (descriptor.IsConsecutive())
+ {
+ return !!source.read(reinterpret_cast<char*>(target), descriptor.mLength);
+ }
+ else
+ {
+ DALI_ASSERT_DEBUG(descriptor.mStride > descriptor.mElementSizeHint);
+ const uint32_t diff = descriptor.mStride - descriptor.mElementSizeHint;
+ uint32_t readSize = 0;
+ while (readSize < descriptor.mLength &&
+ source.read(reinterpret_cast<char*>(target), descriptor.mElementSizeHint) &&
+ source.seekg(diff, std::istream::cur))
+ {
+ readSize += descriptor.mStride;
+ target += descriptor.mElementSizeHint;
+ }
+ return readSize == descriptor.mLength;
+ }
+}
+
+template <typename T>
+void ReadValues(const std::vector<uint8_t>& valuesBuffer, const std::vector<uint8_t>& indicesBuffer, uint8_t* target, uint32_t count, uint32_t elementSizeHint)
+{
+ const T* const indicesPtr = reinterpret_cast<const T* const>(indicesBuffer.data());
+ for (uint32_t index = 0u; index < count; ++index)
+ {
+ uint32_t valuesIndex = indicesPtr[index] * elementSizeHint;
+ memcpy(target + valuesIndex, &valuesBuffer[index * elementSizeHint], elementSizeHint);
+ }
+}
+
+bool ReadAccessor(const MeshDefinition::Accessor& accessor, std::istream& source, uint8_t* target)
+{
+ bool success = false;
+
+ if (accessor.mBlob.IsDefined())
+ {
+ success = ReadBlob(accessor.mBlob, source, target);
+ if (!success)
+ {
+ return false;
+ }
+ }
+
+ if (accessor.mSparse)
+ {
+ const MeshDefinition::Blob& indices = accessor.mSparse->mIndices;
+ const MeshDefinition::Blob& values = accessor.mSparse->mValues;
+
+ if (!indices.IsDefined() || !values.IsDefined())
+ {
+ return false;
+ }
+
+ const auto indicesBufferSize = indices.GetBufferSize();
+ std::vector<uint8_t> indicesBuffer(indicesBufferSize);
+ success = ReadBlob(indices, source, indicesBuffer.data());
+ if (!success)
+ {
+ return false;
+ }
+
+ const auto valuesBufferSize = values.GetBufferSize();
+ std::vector<uint8_t> valuesBuffer(valuesBufferSize);
+ success = ReadBlob(values, source, valuesBuffer.data());
+ if (!success)
+ {
+ return false;
+ }
+
+ switch (indices.mElementSizeHint)
+ {
+ case 1u:
+ {
+ ReadValues<uint8_t>(valuesBuffer, indicesBuffer, target, accessor.mSparse->mCount, values.mElementSizeHint);
+ break;
+ }
+ case 2u:
+ {
+ ReadValues<uint16_t>(valuesBuffer, indicesBuffer, target, accessor.mSparse->mCount, values.mElementSizeHint);
+ break;
+ }
+ case 4u:
+ {
+ ReadValues<uint32_t>(valuesBuffer, indicesBuffer, target, accessor.mSparse->mCount, values.mElementSizeHint);
+ break;
+ }
+ default:
+ DALI_ASSERT_DEBUG(!"Unsupported type for an index");
+ }
+ }
+
+ return success;
+}
+
+void GenerateNormals(MeshDefinition::RawData& raw)
+{
+ auto& attribs = raw.mAttribs;
+ DALI_ASSERT_DEBUG(attribs.size() > 0); // positions
+ IndexProvider getIndex(raw.mIndices.data());
+
+ const uint32_t numIndices = raw.mIndices.empty() ? attribs[0].mNumElements : raw.mIndices.size();
+
+ auto* positions = reinterpret_cast<const Vector3*>(attribs[0].mData.data());
+
+ std::vector<uint8_t> buffer(attribs[0].mNumElements * sizeof(Vector3));
+ auto normals = reinterpret_cast<Vector3*>(buffer.data());
+
+ for (uint32_t i = 0; i < numIndices; i += 3)
+ {
+ uint16_t indices[]{ getIndex(), getIndex(), getIndex() };
+ Vector3 pos[]{ positions[indices[0]], positions[indices[1]], positions[indices[2]] };
+
+ Vector3 a = pos[1] - pos[0];
+ Vector3 b = pos[2] - pos[0];
+
+ Vector3 normal(a.Cross(b));
+ normals[indices[0]] += normal;
+ normals[indices[1]] += normal;
+ normals[indices[2]] += normal;
+ }
+
+ auto iEnd = normals + attribs[0].mNumElements;
+ while (normals != iEnd)
+ {
+ normals->Normalize();
+ ++normals;
+ }
+
+ attribs.push_back({ "aNormal", Property::VECTOR3, attribs[0].mNumElements, std::move(buffer) });
+}
+
+void GenerateTangentsWithUvs(MeshDefinition::RawData& raw)
+{
+ auto& attribs = raw.mAttribs;
+ DALI_ASSERT_DEBUG(attribs.size() > 2); // positions, normals, uvs
+ IndexProvider getIndex(raw.mIndices.data());
+
+ const uint32_t numIndices = raw.mIndices.empty() ? attribs[0].mNumElements : raw.mIndices.size();
+
+ auto* positions = reinterpret_cast<const Vector3*>(attribs[0].mData.data());
+ auto* uvs = reinterpret_cast<const Vector2*>(attribs[2].mData.data());
+
+ std::vector<uint8_t> buffer(attribs[0].mNumElements * sizeof(Vector3));
+ auto tangents = reinterpret_cast<Vector3*>(buffer.data());
+
+ for (uint32_t i = 0; i < numIndices; i += 3)
+ {
+ uint16_t indices[]{ getIndex(), getIndex(), getIndex() };
+ Vector3 pos[]{ positions[indices[0]], positions[indices[1]], positions[indices[2]] };
+ Vector2 uv[]{ uvs[indices[0]], uvs[indices[1]], uvs[indices[2]] };
+
+ float x0 = pos[1].x - pos[0].x;
+ float y0 = pos[1].y - pos[0].y;
+ float z0 = pos[1].z - pos[0].z;
+
+ float x1 = pos[2].x - pos[0].x;
+ float y1 = pos[2].y - pos[0].y;
+ float z1 = pos[2].z - pos[0].z;
+
+ float s0 = uv[1].x - uv[0].x;
+ float t0 = uv[1].y - uv[0].y;
+
+ float s1 = uv[2].x - uv[0].x;
+ float t1 = uv[2].y - uv[0].y;
+
+ float r = 1.f / (s0 * t1 - t0 * s1);
+ Vector3 tangent((x0 * t1 - t0 * x1) * r, (y0 * t1 - t0 * y1) * r, (z0 * t1 - t0 * z1) * r);
+ tangents[indices[0]] += tangent;
+ tangents[indices[1]] += tangent;
+ tangents[indices[2]] += tangent;
+ }
+
+ auto* normals = reinterpret_cast<const Vector3*>(attribs[1].mData.data());
+ auto iEnd = normals + attribs[1].mNumElements;
+ while (normals != iEnd)
+ {
+ *tangents -= *normals * normals->Dot(*tangents);
+ tangents->Normalize();
+
+ ++tangents;
+ ++normals;
+ }
+ attribs.push_back({ "aTangent", Property::VECTOR3, attribs[0].mNumElements, std::move(buffer) });
+}
+
+void GenerateTangents(MeshDefinition::RawData& raw)
+{
+ auto& attribs = raw.mAttribs;
+ DALI_ASSERT_DEBUG(attribs.size() > 1); // positions, normals
+
+ auto* normals = reinterpret_cast<const Vector3*>(attribs[1].mData.data());
+
+ std::vector<uint8_t> buffer(attribs[0].mNumElements * sizeof(Vector3));
+ auto tangents = reinterpret_cast<Vector3*>(buffer.data());
+
+ auto iEnd = normals + attribs[1].mNumElements;
+ while (normals != iEnd)
+ {
+ Vector3 t[]{ normals->Cross(Vector3::XAXIS), normals->Cross(Vector3::YAXIS) };
+
+ *tangents = t[t[1].LengthSquared() > t[0].LengthSquared()];
+ *tangents -= *normals * normals->Dot(*tangents);
+ tangents->Normalize();
+
+ ++tangents;
+ ++normals;
+ }
+ attribs.push_back({ "aTangent", Property::VECTOR3, attribs[0].mNumElements, std::move(buffer) });
+}
+
+void CalculateTextureSize(uint32_t totalTextureSize, uint32_t& textureWidth, uint32_t& textureHeight)
+{
+ DALI_ASSERT_DEBUG(0u != totalTextureSize && "totalTextureSize is zero.")
+
+ // Calculate the dimensions of the texture.
+ // The total size of the texture is the length of the blend shapes blob.
+
+ textureWidth = 0u;
+ textureHeight = 0u;
+
+ if (0u == totalTextureSize)
+ {
+ // nothing to do.
+ return;
+ }
+
+ const uint32_t pow2 = static_cast<uint32_t>(ceil(log2(totalTextureSize)));
+ const uint32_t powWidth = pow2 >> 1u;
+ const uint32_t powHeight = pow2 - powWidth;
+
+ textureWidth = 1u << powWidth;
+ textureHeight = 1u << powHeight;
+}
+
+void CalculateGltf2BlendShapes(uint8_t* geometryBuffer, std::ifstream& binFile, const std::vector<MeshDefinition::BlendShape>& blendShapes, uint32_t numberOfVertices, float& blendShapeUnnormalizeFactor)
+{
+ uint32_t geometryBufferIndex = 0u;
+ float maxDistance = 0.f;
+ Vector3* geometryBufferV3 = reinterpret_cast<Vector3*>(geometryBuffer);
+ for (const auto& blendShape : blendShapes)
+ {
+ if (blendShape.deltas.IsDefined())
+ {
+ DALI_ASSERT_ALWAYS(((blendShape.deltas.mBlob.mLength % sizeof(Vector3) == 0u) ||
+ blendShape.deltas.mBlob.mStride >= sizeof(Vector3)) &&
+ "Blend Shape position buffer length not a multiple of element size");
+
+ const auto bufferSize = blendShape.deltas.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (ReadAccessor(blendShape.deltas, binFile, buffer.data()))
+ {
+ blendShape.deltas.mBlob.ApplyMinMax(bufferSize / sizeof(Vector3), reinterpret_cast<float*>(buffer.data()));
+ // Calculate the difference with the original mesh.
+ // Find the max distance to normalize the deltas.
+ const Vector3* const deltasBuffer = reinterpret_cast<const Vector3* const>(buffer.data());
+
+ for (uint32_t index = 0u; index < numberOfVertices; ++index)
+ {
+ Vector3& delta = geometryBufferV3[geometryBufferIndex++];
+ delta = deltasBuffer[index];
+
+ maxDistance = std::max(maxDistance, delta.LengthSquared());
+ }
+ }
+ }
+
+ if (blendShape.normals.IsDefined())
+ {
+ DALI_ASSERT_ALWAYS(((blendShape.normals.mBlob.mLength % sizeof(Vector3) == 0u) ||
+ blendShape.normals.mBlob.mStride >= sizeof(Vector3)) &&
+ "Blend Shape normals buffer length not a multiple of element size");
+
+ const auto bufferSize = blendShape.normals.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (ReadAccessor(blendShape.normals, binFile, buffer.data()))
+ {
+ blendShape.normals.mBlob.ApplyMinMax(bufferSize / sizeof(Vector3), reinterpret_cast<float*>(buffer.data()));
+
+ // Calculate the difference with the original mesh, and translate to make all values positive.
+ const Vector3* const deltasBuffer = reinterpret_cast<const Vector3* const>(buffer.data());
+
+ for (uint32_t index = 0u; index < numberOfVertices; ++index)
+ {
+ Vector3& delta = geometryBufferV3[geometryBufferIndex++];
+ delta = deltasBuffer[index];
+
+ delta.x *= 0.5f;
+ delta.y *= 0.5f;
+ delta.z *= 0.5f;
+
+ delta.x += 0.5f;
+ delta.y += 0.5f;
+ delta.z += 0.5f;
+ }
+ }
+ }
+
+ if (blendShape.tangents.IsDefined())
+ {
+ DALI_ASSERT_ALWAYS(((blendShape.tangents.mBlob.mLength % sizeof(Vector3) == 0u) ||
+ blendShape.tangents.mBlob.mStride >= sizeof(Vector3)) &&
+ "Blend Shape tangents buffer length not a multiple of element size");
+
+ const auto bufferSize = blendShape.tangents.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (ReadAccessor(blendShape.tangents, binFile, buffer.data()))
+ {
+ blendShape.tangents.mBlob.ApplyMinMax(bufferSize / sizeof(Vector3), reinterpret_cast<float*>(buffer.data()));
+
+ // Calculate the difference with the original mesh, and translate to make all values positive.
+ const Vector3* const deltasBuffer = reinterpret_cast<const Vector3* const>(buffer.data());
+
+ for (uint32_t index = 0u; index < numberOfVertices; ++index)
+ {
+ Vector3& delta = geometryBufferV3[geometryBufferIndex++];
+ delta = deltasBuffer[index];
+
+ delta.x *= 0.5f;
+ delta.y *= 0.5f;
+ delta.z *= 0.5f;
+
+ delta.x += 0.5f;
+ delta.y += 0.5f;
+ delta.z += 0.5f;
+ }
+ }
+ }
+ }
+
+ geometryBufferIndex = 0u;
+ for (const auto& blendShape : blendShapes)
+ {
+ // Normalize all the deltas and translate to a possitive value.
+ // Deltas are going to be passed to the shader in a color texture
+ // whose values that are less than zero are clamped.
+ if (blendShape.deltas.IsDefined())
+ {
+
+ const float normalizeFactor = (fabsf(maxDistance) < Math::MACHINE_EPSILON_1000) ? 1.f : (0.5f / sqrtf(maxDistance));
+
+ for (uint32_t index = 0u; index < numberOfVertices; ++index)
+ {
+ Vector3& delta = geometryBufferV3[geometryBufferIndex++];
+ delta.x = Clamp(((delta.x * normalizeFactor) + 0.5f), 0.f, 1.f);
+ delta.y = Clamp(((delta.y * normalizeFactor) + 0.5f), 0.f, 1.f);
+ delta.z = Clamp(((delta.z * normalizeFactor) + 0.5f), 0.f, 1.f);
+ }
+
+ // Calculate and store the unnormalize factor.
+ blendShapeUnnormalizeFactor = 1.f / normalizeFactor;
+ }
+
+ if (blendShape.normals.IsDefined())
+ {
+ geometryBufferIndex += numberOfVertices;
+ }
+
+ if (blendShape.tangents.IsDefined())
+ {
+ geometryBufferIndex += numberOfVertices;
+ }
+ }
+}
+
+}
+
+MeshDefinition::SparseBlob::SparseBlob(const Blob& indices, const Blob& values, uint32_t count)
+: mIndices{indices},
+ mValues{values},
+ mCount{count}
+{}
+
+MeshDefinition::Accessor::Accessor(const MeshDefinition::Blob& blob,
+ const MeshDefinition::SparseBlob& sparse)
+: mBlob{blob},
+ mSparse{(sparse.mIndices.IsDefined() && sparse.mValues.IsDefined()) ? new SparseBlob{sparse} : nullptr}
+{}
+
+void MeshDefinition::Blob::ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max,
+ uint32_t count, float* values)
+{
+ DALI_ASSERT_DEBUG(max.empty() || max.size() == min.size());
+ const auto numComponents = std::max(min.size(), max.size());
+
+ using ClampFn = void(*)(const float*, const float*, uint32_t, float&);
+ ClampFn clampFn = min.empty() ?
+ (max.empty() ?
+ static_cast<ClampFn>(nullptr) :
+ [](const float* min, const float* max, uint32_t i, float& value) {
+ value = std::min(max[i], value);
+ }) :
+ (max.empty() ?
+ [](const float* min, const float* max, uint32_t i, float& value) {
+ value = std::max(min[i], value);
+ } :
+ [](const float* min, const float* max, uint32_t i, float& value) {
+ value = std::min(std::max(min[i], value), max[i]);
+ });
+
+ auto end = values + count * numComponents;
+ while (values != end)
+ {
+ auto nextElement = values + numComponents;
+ uint32_t i = 0;
+ while (values != nextElement)
+ {
+ clampFn(min.data(), max.data(), i, *values);
+ ++values;
+ ++i;
+ }
+ }
+}
+
+uint32_t MeshDefinition::Blob::GetBufferSize() const
+{
+ return IsConsecutive() ? mLength : (mLength * mElementSizeHint / mStride);
+}
+
+void MeshDefinition::Blob::ApplyMinMax(uint32_t count, float* values) const
+{
+ ApplyMinMax(mMin, mMax, count, values);
+}
+
+void MeshDefinition::RawData::Attrib::AttachBuffer(Geometry& g) const
+{
+ Property::Map attribMap;
+ attribMap[mName] = mType;
+ VertexBuffer attribBuffer = VertexBuffer::New(attribMap);
+ attribBuffer.SetData(mData.data(), mNumElements);
+
+ g.AddVertexBuffer(attribBuffer);
+}
+
+bool MeshDefinition::IsQuad() const
+{
+ return CaseInsensitiveStringCompare("quad", mUri);
+}
+
+bool MeshDefinition::IsSkinned() const
+{
+ return mJoints0.IsDefined() && mWeights0.IsDefined();
+}
+
+bool MeshDefinition::HasBlendShapes() const
+{
+ return !mBlendShapes.empty();
+}
+
+void MeshDefinition::RequestNormals()
+{
+ mNormals.mBlob.mLength = mPositions.mBlob.GetBufferSize();
+}
+
+void MeshDefinition::RequestTangents()
+{
+ mTangents.mBlob.mLength = mNormals.mBlob.GetBufferSize();
+}
+
+MeshDefinition::RawData
+ MeshDefinition::LoadRaw(const std::string& modelsPath) const
+{
+ RawData raw;
+ if (IsQuad())
+ {
+ return raw;
+ }
+
+ const std::string meshPath = modelsPath + mUri;
+ std::ifstream binFile(meshPath, std::ios::binary);
+ if (!binFile)
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read geometry data from '" << meshPath << "'";
+ }
+
+ if (mIndices.IsDefined())
+ {
+ if (MaskMatch(mFlags, U32_INDICES))
+ {
+ DALI_ASSERT_ALWAYS(((mIndices.mBlob.mLength % sizeof(uint32_t) == 0) ||
+ mIndices.mBlob.mStride >= sizeof(uint32_t)) &&
+ "Index buffer length not a multiple of element size");
+ const auto indexCount = mIndices.mBlob.GetBufferSize() / sizeof(uint32_t);
+ raw.mIndices.resize(indexCount * 2); // NOTE: we need space for uint32_ts initially.
+ if (!ReadAccessor(mIndices, binFile, reinterpret_cast<uint8_t*>(raw.mIndices.data())))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read indices from '" << meshPath << "'.";
+ }
+
+ auto u16s = raw.mIndices.data();
+ auto u32s = reinterpret_cast<uint32_t*>(raw.mIndices.data());
+ auto end = u32s + indexCount;
+ while (u32s != end)
+ {
+ *u16s = static_cast<uint16_t>(*u32s);
+ ++u16s;
+ ++u32s;
+ }
+
+ raw.mIndices.resize(indexCount);
+ }
+ else
+ {
+ DALI_ASSERT_ALWAYS(((mIndices.mBlob.mLength % sizeof(unsigned short) == 0) ||
+ mIndices.mBlob.mStride >= sizeof(unsigned short)) &&
+ "Index buffer length not a multiple of element size");
+ raw.mIndices.resize(mIndices.mBlob.mLength / sizeof(unsigned short));
+ if (!ReadAccessor(mIndices, binFile, reinterpret_cast<uint8_t*>(raw.mIndices.data())))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read indices from '" << meshPath << "'.";
+ }
+ }
+ }
+
+ std::vector<Vector3> positions;
+ if (mPositions.IsDefined())
+ {
+ DALI_ASSERT_ALWAYS(((mPositions.mBlob.mLength % sizeof(Vector3) == 0) ||
+ mPositions.mBlob.mStride >= sizeof(Vector3)) &&
+ "Position buffer length not a multiple of element size");
+ const auto bufferSize = mPositions.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (!ReadAccessor(mPositions, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read positions from '" << meshPath << "'.";
+ }
+
+ uint32_t numVector3 = bufferSize / sizeof(Vector3);
+ mPositions.mBlob.ApplyMinMax(numVector3, reinterpret_cast<float*>(buffer.data()));
+
+ if (HasBlendShapes())
+ {
+ positions.resize(numVector3);
+ std::copy(buffer.data(), buffer.data() + buffer.size(), reinterpret_cast<uint8_t*>(positions.data()));
+ }
+
+ raw.mAttribs.push_back({ "aPosition", Property::VECTOR3, numVector3, std::move(buffer) });
+ }
+
+ const auto isTriangles = mPrimitiveType == Geometry::TRIANGLES;
+ auto hasNormals = mNormals.IsDefined();
+ if (hasNormals)
+ {
+ DALI_ASSERT_ALWAYS(((mNormals.mBlob.mLength % sizeof(Vector3) == 0) ||
+ mNormals.mBlob.mStride >= sizeof(Vector3)) &&
+ "Normal buffer length not a multiple of element size");
+ const auto bufferSize = mNormals.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (!ReadAccessor(mNormals, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read normals from '" << meshPath << "'.";
+ }
+
+ mNormals.mBlob.ApplyMinMax(bufferSize / sizeof(Vector3), reinterpret_cast<float*>(buffer.data()));
+
+ raw.mAttribs.push_back({ "aNormal", Property::VECTOR3,
+ static_cast<uint32_t>(bufferSize / sizeof(Vector3)), std::move(buffer) });
+ }
+ else if (mNormals.mBlob.mLength != 0 && isTriangles)
+ {
+ DALI_ASSERT_DEBUG(mNormals.mBlob.mLength == mPositions.mBlob.GetBufferSize());
+ GenerateNormals(raw);
+ hasNormals = true;
+ }
+
+ const auto hasUvs = mTexCoords.IsDefined();
+ if (hasUvs)
+ {
+ DALI_ASSERT_ALWAYS(((mTexCoords.mBlob.mLength % sizeof(Vector2) == 0) ||
+ mTexCoords.mBlob.mStride >= sizeof(Vector2)) &&
+ "Normal buffer length not a multiple of element size");
+ const auto bufferSize = mTexCoords.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (!ReadAccessor(mTexCoords, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read uv-s from '" << meshPath << "'.";
+ }
+
+ const auto uvCount = bufferSize / sizeof(Vector2);
+ if (MaskMatch(mFlags, FLIP_UVS_VERTICAL))
+ {
+ auto uv = reinterpret_cast<Vector2*>(buffer.data());
+ auto uvEnd = uv + uvCount;
+ while (uv != uvEnd)
+ {
+ uv->y = 1.0f - uv->y;
+ ++uv;
+ }
+ }
+
+ mTexCoords.mBlob.ApplyMinMax(bufferSize / sizeof(Vector2), reinterpret_cast<float*>(buffer.data()));
+
+ raw.mAttribs.push_back({ "aTexCoord", Property::VECTOR2, static_cast<uint32_t>(uvCount),
+ std::move(buffer) });
+ }
+
+ if (mTangents.IsDefined())
+ {
+ DALI_ASSERT_ALWAYS(((mTangents.mBlob.mLength % sizeof(Vector3) == 0) ||
+ mTangents.mBlob.mStride >= sizeof(Vector3)) &&
+ "Tangents buffer length not a multiple of element size");
+ const auto bufferSize = mTangents.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (!ReadAccessor(mTangents, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read tangents from '" << meshPath << "'.";
+ }
+
+ mTangents.mBlob.ApplyMinMax(bufferSize / sizeof(Vector3), reinterpret_cast<float*>(buffer.data()));
+
+ raw.mAttribs.push_back({ "aTangent", Property::VECTOR3,
+ static_cast<uint32_t>(bufferSize / sizeof(Vector3)), std::move(buffer) });
+ }
+ else if (mTangents.mBlob.mLength != 0 && hasNormals && isTriangles)
+ {
+ DALI_ASSERT_DEBUG(mTangents.mBlob.mLength == mNormals.mBlob.GetBufferSize());
+ hasUvs ? GenerateTangentsWithUvs(raw) : GenerateTangents(raw);
+ }
+
+ if (IsSkinned())
+ {
+ if (MaskMatch(mFlags, U16_JOINT_IDS))
+ {
+ DALI_ASSERT_ALWAYS(((mJoints0.mBlob.mLength % sizeof(Uint16Vector4) == 0) ||
+ mJoints0.mBlob.mStride >= sizeof(Uint16Vector4)) &&
+ "Joints buffer length not a multiple of element size");
+ const auto inBufferSize = mJoints0.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(inBufferSize * 2);
+ auto u16s = buffer.data() + inBufferSize;
+ if (!ReadAccessor(mJoints0, binFile, u16s))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read joints from '" << meshPath << "'.";
+ }
+
+ auto floats = reinterpret_cast<float*>(buffer.data());
+ auto end = u16s + inBufferSize;
+ while (u16s != end)
+ {
+ auto value = *reinterpret_cast<uint16_t*>(u16s);
+ *floats = static_cast<float>(value);
+
+ u16s += sizeof(uint16_t);
+ ++floats;
+ }
+ raw.mAttribs.push_back({ "aJoints", Property::VECTOR4,
+ static_cast<uint32_t>(buffer.size() / sizeof(Vector4)), std::move(buffer) });
+ }
+ else
+ {
+ DALI_ASSERT_ALWAYS(((mJoints0.mBlob.mLength % sizeof(Vector4) == 0) ||
+ mJoints0.mBlob.mStride >= sizeof(Vector4)) &&
+ "Joints buffer length not a multiple of element size");
+ const auto bufferSize = mJoints0.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (!ReadAccessor(mJoints0, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read joints from '" << meshPath << "'.";
+ }
+
+ raw.mAttribs.push_back({ "aJoints", Property::VECTOR4,
+ static_cast<uint32_t>(bufferSize / sizeof(Vector4)), std::move(buffer) });
+ }
+
+ DALI_ASSERT_ALWAYS(((mWeights0.mBlob.mLength % sizeof(Vector4) == 0) ||
+ mWeights0.mBlob.mStride >= sizeof(Vector4)) &&
+ "Weights buffer length not a multiple of element size");
+ const auto bufferSize = mWeights0.mBlob.GetBufferSize();
+ std::vector<uint8_t> buffer(bufferSize);
+ if (!ReadAccessor(mWeights0, binFile, buffer.data()))
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to read weights from '" << meshPath << "'.";
+ }
+
+ raw.mAttribs.push_back({ "aWeights", Property::VECTOR4,
+ static_cast<uint32_t>(bufferSize / sizeof(Vector4)), std::move(buffer) });
+ }
+
+ // Calculate the Blob for the blend shapes.
+ Blob blendShapesBlob;
+ blendShapesBlob.mOffset = std::numeric_limits<unsigned int>::max();
+ blendShapesBlob.mLength = 0u;
+
+ for (const auto& blendShape : mBlendShapes)
+ {
+ for (auto i : { &blendShape.deltas, &blendShape.normals, &blendShape.tangents })
+ {
+ if (i->IsDefined())
+ {
+ blendShapesBlob.mOffset = std::min(blendShapesBlob.mOffset, i->mBlob.mOffset);
+ blendShapesBlob.mLength += i->mBlob.mLength;
+ }
+ }
+ }
+
+ if (HasBlendShapes())
+ {
+ const uint32_t numberOfVertices = mPositions.mBlob.mLength / sizeof(Vector3);
+
+ // Calculate the size of one buffer inside the texture.
+ raw.mBlendShapeBufferOffset = numberOfVertices;
+
+ bool calculateGltf2BlendShapes = false;
+ uint32_t textureWidth = 0u;
+ uint32_t textureHeight = 0u;
+
+ if (!mBlendShapeHeader.IsDefined())
+ {
+ CalculateTextureSize(blendShapesBlob.mLength / sizeof(Vector3), textureWidth, textureHeight);
+ calculateGltf2BlendShapes = true;
+ }
+ else
+ {
+ uint16_t header[2u];
+ ReadBlob(mBlendShapeHeader, binFile, reinterpret_cast<uint8_t*>(header));
+ textureWidth = header[0u];
+ textureHeight = header[1u];
+ }
+
+ const uint32_t numberOfBlendShapes = mBlendShapes.size();
+ raw.mBlendShapeUnnormalizeFactor.Resize(numberOfBlendShapes);
+
+ Devel::PixelBuffer geometryPixelBuffer = Devel::PixelBuffer::New(textureWidth, textureHeight, Pixel::RGB32F);
+ uint8_t* geometryBuffer = geometryPixelBuffer.GetBuffer();
+
+ if (calculateGltf2BlendShapes)
+ {
+ CalculateGltf2BlendShapes(geometryBuffer, binFile, mBlendShapes, numberOfVertices, raw.mBlendShapeUnnormalizeFactor[0u]);
+ }
+ else
+ {
+ Blob unnormalizeFactorBlob;
+ unnormalizeFactorBlob.mLength = sizeof(float) * ((BlendShapes::Version::VERSION_2_0 == mBlendShapeVersion) ? 1u : numberOfBlendShapes);
+
+ if (blendShapesBlob.IsDefined())
+ {
+ if (ReadBlob(blendShapesBlob, binFile, geometryBuffer))
+ {
+ unnormalizeFactorBlob.mOffset = blendShapesBlob.mOffset + blendShapesBlob.mLength;
+ }
+ }
+
+ // Read the unnormalize factors.
+ if (unnormalizeFactorBlob.IsDefined())
+ {
+ ReadBlob(unnormalizeFactorBlob, binFile, reinterpret_cast<uint8_t*>(&raw.mBlendShapeUnnormalizeFactor[0u]));
+ }
+ }
+ raw.mBlendShapeData = Devel::PixelBuffer::Convert(geometryPixelBuffer);
+ }
+
+ return raw;
+}
+
+MeshGeometry MeshDefinition::Load(RawData&& raw) const
+{
+ MeshGeometry meshGeometry;
+ meshGeometry.geometry = Geometry::New();
+ meshGeometry.geometry.SetType(mPrimitiveType);
+
+ if (IsQuad()) // TODO: do this in raw data; provide MakeTexturedQuadGeometry() that only creates buffers.
+ {
+ auto options = MaskMatch(mFlags, FLIP_UVS_VERTICAL) ? TexturedQuadOptions::FLIP_VERTICAL : 0;
+ meshGeometry.geometry = MakeTexturedQuadGeometry(options);
+ }
+ else
+ {
+ if (!raw.mIndices.empty())
+ {
+ meshGeometry.geometry.SetIndexBuffer(raw.mIndices.data(), raw.mIndices.size());
+ }
+
+ for (auto& a : raw.mAttribs)
+ {
+ a.AttachBuffer(meshGeometry.geometry);
+ }
+
+ if (HasBlendShapes())
+ {
+ meshGeometry.blendShapeBufferOffset = raw.mBlendShapeBufferOffset;
+ meshGeometry.blendShapeUnnormalizeFactor = std::move(raw.mBlendShapeUnnormalizeFactor);
+
+ meshGeometry.blendShapeGeometry = Texture::New( TextureType::TEXTURE_2D,
+ raw.mBlendShapeData.GetPixelFormat(),
+ raw.mBlendShapeData.GetWidth(),
+ raw.mBlendShapeData.GetHeight());
+ meshGeometry.blendShapeGeometry.Upload(raw.mBlendShapeData);
+ }
+ }
+
+ return meshGeometry;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_MESH_DEFINITION_H
+#define DALI_SCENE_LOADER_MESH_DEFINITION_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+#include "dali-scene-loader/public-api/mesh-geometry.h"
+#include "dali-scene-loader/public-api/blend-shape-details.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include "dali-scene-loader/public-api/index.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include <memory>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Defines a mesh with its attributes, the primitive type to render it as,
+ * and the file to load it from with the offset and length information for the
+ * individual attribute buffers.
+ */
+struct DALI_SCENE_LOADER_API MeshDefinition
+{
+ using Vector = std::vector<std::pair<MeshDefinition, MeshGeometry>>;
+
+ enum : uint32_t { INVALID = std::numeric_limits<uint32_t>::max() };
+
+ enum Flags : uint16_t
+ {
+ FLIP_UVS_VERTICAL = NthBit(0),
+ U32_INDICES = NthBit(1), // default is unsigned short
+ U16_JOINT_IDS = NthBit(2), // default is floats
+ };
+
+ enum Attributes
+ {
+ INDICES = NthBit(0),
+ POSITIONS = NthBit(1),
+ NORMALS = NthBit(2),
+ TEX_COORDS = NthBit(3),
+ TANGENTS = NthBit(4),
+ LEGACY_BITANGENTS = NthBit(5), // these are ignored; we're calculating them in the (PBR) shader.
+ JOINTS_0 = NthBit(6),
+ WEIGHTS_0 = NthBit(7),
+ };
+
+ /**
+ * @brief Describes raw data in terms of its position and size in a buffer.
+ * All units in bytes.
+ */
+ struct Blob
+ {
+ uint32_t mOffset = INVALID; // the default means that the blob is undefined.
+ uint32_t mLength = 0; // if the blob is undefined, its data may still be generated. This is enabled by setting length to some non-0 value. Refer to MeshDefinition for details.
+ uint16_t mStride = 0; // ignore if 0
+ uint16_t mElementSizeHint = 0; // ignore if 0 or stride == 0
+ std::vector<float> mMin;
+ std::vector<float> mMax;
+
+ static void ApplyMinMax(const std::vector<float>& min, const std::vector<float>& max, uint32_t count, float* values);
+
+ Blob() = default;
+
+ Blob(uint32_t offset, uint32_t length, uint16_t stride = 0, uint16_t elementSizeHint = 0,
+ const std::vector<float>& min = {}, const std::vector<float>& max = {})
+ : mOffset(offset),
+ mLength(length),
+ mStride(stride),
+ mElementSizeHint(elementSizeHint),
+ mMin(min),
+ mMax(max)
+ {}
+
+ /**
+ * @brief Calculates the size of a tightly-packed buffer for the elements from the blob.
+ */
+ uint32_t GetBufferSize() const;
+
+ /**
+ * @brief Convenience method to tell whether a Blob has meaningful data.
+ */
+ bool IsDefined() const
+ {
+ return mOffset != INVALID;
+ }
+
+ /**
+ * @brief Convenience method to tell whether the elements stored in the blob follow each
+ * other tightly. The opposite would be interleaving.
+ */
+ bool IsConsecutive() const
+ {
+ return mStride == 0 || mStride == mElementSizeHint;
+ }
+
+ /**
+ * @brief Applies the min / max values, if they're defined.
+ */
+ void ApplyMinMax(uint32_t count, float* values) const;
+ };
+
+ /**
+ * @brief A sparse blob describes a change in a reference Blob.
+ * @p indices describe what positions of the reference Blob change and
+ * @p values describe the new values.
+ */
+ struct SparseBlob
+ {
+ SparseBlob() = default;
+
+ SparseBlob(const Blob& indices, const Blob& values, uint32_t count);
+
+ Blob mIndices;
+ Blob mValues;
+ uint32_t mCount = 0u;
+ };
+
+ struct Accessor
+ {
+ Blob mBlob;
+ std::unique_ptr<SparseBlob> mSparse;
+
+ Accessor() = default;
+
+ Accessor(const Accessor&) = delete;
+ Accessor& operator=(const Accessor&) = delete;
+
+ Accessor(Accessor&&) = default;
+ Accessor& operator=(Accessor&&) = default;
+
+ Accessor(const MeshDefinition::Blob& blob,
+ const MeshDefinition::SparseBlob& sparse);
+
+ bool IsDefined() const
+ {
+ return mBlob.IsDefined() || (mSparse && (mSparse->mIndices.IsDefined() && mSparse->mValues.IsDefined()));
+ }
+ };
+
+ /**
+ * @brief Stores a blend shape.
+ */
+ struct BlendShape
+ {
+ std::string name;
+ Accessor deltas;
+ Accessor normals;
+ Accessor tangents;
+ float weight = 0.f;
+ };
+
+ struct RawData
+ {
+ struct Attrib
+ {
+ std::string mName;
+ Property::Type mType;
+ uint32_t mNumElements;
+ std::vector<uint8_t> mData;
+
+ void AttachBuffer(Geometry& g) const;
+ };
+
+ std::vector<uint16_t> mIndices;
+ std::vector<Attrib> mAttribs;
+
+ unsigned int mBlendShapeBufferOffset;
+ Dali::Vector<float> mBlendShapeUnnormalizeFactor;
+ PixelData mBlendShapeData;
+ };
+
+ MeshDefinition() = default;
+
+ MeshDefinition(const MeshDefinition&) = delete;
+ MeshDefinition& operator=(const MeshDefinition&) = delete;
+
+ MeshDefinition(MeshDefinition&&) = default;
+ MeshDefinition& operator=(MeshDefinition&&) = default;
+
+ /**
+ * @brief Determines whether the mesh definition is that of a quad.
+ */
+ bool IsQuad() const;
+
+ /**
+ * @brief Determines whether the mesh is used for skeletal animation.
+ */
+ bool IsSkinned() const;
+
+ /**
+ * @brief Whether the mesh has blend shapes.
+ */
+ bool HasBlendShapes() const;
+
+ /**
+ * @brief Requests normals to be generated.
+ * @note Generation happens in LoadRaw().
+ * @note Must have Vector3 positions defined.
+ */
+ void RequestNormals();
+
+ /**
+ * @brief Requests tangents to be generated.
+ * @note Generation happens in LoadRaw().
+ * @note Must have Vector3 normals defined.
+ */
+ void RequestTangents();
+
+ /**
+ * @brief Loads raw geometry data, which includes index (optional) and
+ * attribute buffers, as well as blend shape data. This is then returned.
+ * @note This can be done on any thread.
+ */
+ RawData LoadRaw(const std::string& modelsPath) const;
+
+ /**
+ * @brief Creates a MeshGeometry based firstly on the value of the uri member:
+ * if it is "quad", a textured quad is created; otherwise it uses the
+ * attribute (and index) buffers and blend shape information (if available)
+ * from @a raw.
+ * If mFlipVertical was set, the UVs are flipped in Y, i.e. v = 1.0 - v.
+ */
+ MeshGeometry Load(RawData&& raw) const;
+
+public: // DATA
+ uint32_t mFlags = 0x0;
+ Geometry::Type mPrimitiveType = Geometry::TRIANGLES;
+ std::string mUri;
+ Accessor mIndices;
+ Accessor mPositions;
+ Accessor mNormals; // data can be generated based on positions
+ Accessor mTexCoords;
+ Accessor mTangents; // data can be generated based on normals and texCoords (the latter isn't mandatory; the results will be better if available)
+ Accessor mJoints0;
+ Accessor mWeights0;
+
+ Blob mBlendShapeHeader;
+ std::vector<BlendShape> mBlendShapes;
+ BlendShapes::Version mBlendShapeVersion = BlendShapes::Version::INVALID;
+
+ Index mSkeletonIdx = INVALID_INDEX;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_MESH_DEFINITION_H
--- /dev/null
+#ifndef DALI_SCENE_LOADER_MESH_GEOMETRY_H
+#define DALI_SCENE_LOADER_MESH_GEOMETRY_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/rendering/geometry.h"
+#include "dali/public-api/rendering/texture.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+struct DALI_SCENE_LOADER_API MeshGeometry
+{
+ Geometry geometry; ///< The array of vertices.
+ Texture blendShapeGeometry; ///< The array of vertices of the different blend shapes encoded inside a texture with power of two dimensions.
+ Vector<float> blendShapeUnnormalizeFactor; ///< Factor used to unnormalize the geometry of the blend shape.
+ unsigned int blendShapeBufferOffset; ///< Offset used to calculate the start of each blend shape.
+};
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_MESH_GEOMETRY_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL
+#include "dali-scene-loader/public-api/node-definition.h"
+#include "dali-scene-loader/public-api/renderer-state.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+void NodeDefinition::Renderable::RegisterResources(IResourceReceiver& receiver) const
+{
+ receiver.Register(ResourceType::Shader, mShaderIdx);
+}
+
+void NodeDefinition::Renderable::ReflectResources(IResourceReflector& reflector)
+{
+ reflector.Reflect(ResourceType::Shader, mShaderIdx);
+}
+
+void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreateParams& params,
+ Actor& actor) const
+{
+ DALI_ASSERT_DEBUG(mShaderIdx != INVALID_INDEX);
+ auto& resources = params.mResources;
+ Shader shader = resources.mShaders[mShaderIdx].second;
+
+ static Geometry defaultGeometry = Geometry::New();
+ Renderer renderer = Renderer::New(defaultGeometry, shader);
+
+ RendererState::Apply(resources.mShaders[mShaderIdx].first.mRendererState, renderer);
+
+ actor.AddRenderer(renderer);
+}
+
+const std::string NodeDefinition::ORIGINAL_MATRIX_PROPERTY_NAME = "originalMatrix";
+
+Actor NodeDefinition::CreateActor(CreateParams& params) const
+{
+ Actor actor = Actor::New();
+ SetActorCentered(actor);
+
+ actor.SetProperty(Actor::Property::NAME, mName);
+ actor.SetProperty(Actor::Property::POSITION, mPosition);
+ actor.SetProperty(Actor::Property::ORIENTATION, mOrientation);
+ actor.SetProperty(Actor::Property::SCALE, mScale);
+ actor.SetProperty(Actor::Property::SIZE, mSize);
+ actor.SetProperty(Actor::Property::VISIBLE, mIsVisible);
+
+ actor.RegisterProperty(ORIGINAL_MATRIX_PROPERTY_NAME, GetLocalSpace(), Property::AccessMode::READ_ONLY);
+
+ if (mRenderable)
+ {
+ mRenderable->OnCreate(*this, params, actor);
+ }
+
+ for (auto& e : mExtras)
+ {
+ actor.RegisterProperty(e.mKey, e.mValue);
+ }
+
+ for (auto& c : mConstraints)
+ {
+ params.mConstrainables.push_back(ConstraintRequest{ &c, actor });
+ }
+
+ return actor;
+}
+
+Matrix NodeDefinition::GetLocalSpace() const
+{
+ Matrix localSpace{ false };
+ localSpace.SetTransformComponents(mScale, mOrientation, mPosition);
+ return localSpace;
+}
+
+void ModelNode::RegisterResources(IResourceReceiver& receiver) const
+{
+ Renderable::RegisterResources(receiver);
+ receiver.Register(ResourceType::Mesh, mMeshIdx);
+ receiver.Register(ResourceType::Material, mMaterialIdx);
+}
+
+void ModelNode::ReflectResources(IResourceReflector& reflector)
+{
+ Renderable::ReflectResources(reflector);
+ reflector.Reflect(ResourceType::Mesh, mMeshIdx);
+ reflector.Reflect(ResourceType::Material, mMaterialIdx);
+}
+
+void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
+{
+ DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX);
+ Renderable::OnCreate(node, params, actor);
+
+ auto& resources = params.mResources;
+ auto& mesh = resources.mMeshes[mMeshIdx];
+
+ auto renderer = actor.GetRendererAt(0);
+ Geometry geometry = mesh.second.geometry;
+ renderer.SetGeometry(geometry);
+
+ auto shader = renderer.GetShader();
+
+ if (mesh.first.IsSkinned())
+ {
+ params.mSkinnables.push_back(SkinningShaderConfigurationRequest{ mesh.first.mSkeletonIdx, shader });
+ }
+
+ if (mesh.first.HasBlendShapes())
+ {
+ params.mBlendshapeRequests.push_back(BlendshapeShaderConfigurationRequest{ node.mName, mMeshIdx, shader });
+ }
+
+ TextureSet textures = resources.mMaterials[mMaterialIdx].second;
+
+ // Set the blend shape texture.
+ if (mesh.second.blendShapeGeometry)
+ {
+ TextureSet newTextureSet = TextureSet::New();
+ newTextureSet.SetTexture(0u, mesh.second.blendShapeGeometry);
+
+ const unsigned int numberOfTextures = textures.GetTextureCount();
+ for (unsigned int index = 0u; index < numberOfTextures; ++index)
+ {
+ const unsigned int newIndex = index + 1u;
+ newTextureSet.SetTexture(newIndex, textures.GetTexture(index));
+ newTextureSet.SetSampler(newIndex, textures.GetSampler(index));
+ }
+
+ textures = newTextureSet;
+ }
+
+ renderer.SetTextures(textures);
+
+ actor.SetProperty(Actor::Property::COLOR, mColor);
+
+ auto& matDef = resources.mMaterials[mMaterialIdx].first;
+ actor.RegisterProperty("uMetallicFactor", matDef.mMetallic);
+ actor.RegisterProperty("uRoughnessFactor", matDef.mRoughness);
+
+ Index envIdx = matDef.mEnvironmentIdx;
+ actor.RegisterProperty("uIblIntensity", resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
+
+ const auto alphaCutoff = matDef.GetAlphaCutoff();
+ if (alphaCutoff > 0.f)
+ {
+ actor.RegisterProperty("uAlphaThreshold", alphaCutoff);
+ }
+}
+
+void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params,
+ Actor& actor) const
+{
+ ModelNode::OnCreate(node, params, actor);
+
+ actor.RegisterProperty("antiAliasing", mAntiAliasing ? 1 : 0);
+ actor.RegisterProperty("arcCaps", mArcCaps);
+ actor.RegisterProperty("radius", mRadius);
+
+ const float startAngleRadians = mStartAngleDegrees * Math::PI_OVER_180;
+ Vector2 startPolar{ std::cos(startAngleRadians), std::sin(startAngleRadians) };
+ actor.RegisterProperty("startAngle", startPolar);
+
+ const float endAngleRadians = mEndAngleDegrees * Math::PI_OVER_180;
+ Vector2 endPolar{ std::cos(endAngleRadians), std::sin(endAngleRadians) };
+ actor.RegisterProperty("endAngle", endPolar);
+}
+
+void ArcNode::GetEndVectorWithDiffAngle(float startAngle, float diffAngle, Vector2& endVector)
+{
+ float endAngle = 0.f;
+
+ if (diffAngle <= 0.001f)
+ {
+ //0.001 is used to ensure is empty arc when startAngle = endAngle + 360 * N
+ endAngle = startAngle + 0.001f;
+ }
+ else if (diffAngle >= 360.f)
+ {
+ endAngle = diffAngle + 359.99f;
+ }
+ else
+ {
+ endAngle = startAngle + 360.0f + diffAngle;
+ }
+ endVector.x = cosf(endAngle * Math::PI_OVER_180);
+ endVector.y = sinf(endAngle * Math::PI_OVER_180);
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_NODE_DEFINITION_H_
+#define DALI_SCENE_LOADER_NODE_DEFINITION_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/customization.h"
+#include "dali-scene-loader/public-api/matrix-stack.h"
+#include "dali-scene-loader/public-api/resource-bundle.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/quaternion.h"
+#include "dali/public-api/math/matrix.h"
+#include "dali/public-api/math/vector4.h"
+#include "dali/public-api/actors/actor.h"
+#include <string>
+#include <memory>
+#include <functional>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+class ViewProjection;
+
+/**
+ * @brief Interface to report (const) resource ids to.
+ */
+class DALI_SCENE_LOADER_API IResourceReceiver
+{
+public:
+ virtual ~IResourceReceiver()
+ {}
+
+ virtual void Register(ResourceType::Value type, Index id) = 0;
+};
+
+/**
+ * @brief Interface to report modifiable resource ids to.
+ * @note These are supposed to be transient. Obviously, the references collected
+ * this way must not outlive the objects that they came from.
+ */
+class DALI_SCENE_LOADER_API IResourceReflector
+{
+public:
+ virtual ~IResourceReflector()
+ {}
+
+ virtual void Reflect(ResourceType::Value type, Index& id) = 0;
+};
+
+/**
+ * @brief Intermediate representation for a constraint that shall be
+ * set up after the Actors were created. The target of the constraint
+ * is the node definition that carries it.
+ */
+struct DALI_SCENE_LOADER_API ConstraintDefinition
+{
+ std::string mProperty; ///< name of the property to constrain.
+ Index mSourceIdx; ///< index of the node to serve as the source of the constraint.
+
+ bool operator<(const ConstraintDefinition& other) const
+ {
+ return mProperty < other.mProperty;
+ }
+
+ bool operator==(const ConstraintDefinition& other) const
+ {
+ return mSourceIdx == other.mSourceIdx && mProperty == other.mProperty;
+ }
+
+ bool operator!=(const ConstraintDefinition& other) const
+ {
+ return !operator==(other);
+ }
+};
+
+struct DALI_SCENE_LOADER_API Transforms
+{
+ MatrixStack modelStack;
+ const ViewProjection& viewProjection;
+};
+
+/**
+ * @brief Information about a skeleton and the shader that needs to be configured with it.
+ * @note Multiple skeletons shalt not share the same shader.
+ */
+struct DALI_SCENE_LOADER_API SkinningShaderConfigurationRequest
+{
+ Index mSkeletonIdx;
+ Shader mShader;
+
+ bool operator<(const SkinningShaderConfigurationRequest& other) const
+ {
+ return mShader < other.mShader;
+ }
+};
+
+/**
+ * @brief Needed to configure blend shape properties.
+ */
+struct DALI_SCENE_LOADER_API BlendshapeShaderConfigurationRequest
+{
+ std::string mNodeName;
+ Index mMeshIdx;
+ Shader mShader;
+
+ bool operator<(const BlendshapeShaderConfigurationRequest& other) const
+ {
+ return mShader < other.mShader;
+ }
+};
+
+/**
+ * @brief Request for creating a constraint, output from NodeDefinition::OnCreate.
+ */
+struct DALI_SCENE_LOADER_API ConstraintRequest
+{
+ const ConstraintDefinition* const mConstraint; ///< Definition of the constraint to create.
+ Actor mTarget; ///< Target of the constraint.
+};
+
+/**
+ * @brief Defines a node, consisting of a name, a transform, a size, a list of child nodes,
+ * and slots for customization and rendering logic, which are mutually exclusive in the
+ * current implementation.
+ */
+struct DALI_SCENE_LOADER_API NodeDefinition
+{
+public: // TYPES
+ using Vector = std::vector<NodeDefinition>;
+
+ struct CreateParams
+ {
+ public: // input
+ const ResourceBundle& mResources;
+ Transforms& mXforms;
+
+ public: // output
+ std::vector<ConstraintRequest> mConstrainables;
+ std::vector<SkinningShaderConfigurationRequest> mSkinnables;
+ std::vector<BlendshapeShaderConfigurationRequest> mBlendshapeRequests;
+ };
+
+ class DALI_SCENE_LOADER_API Renderable
+ {
+ public: // DATA
+ Index mShaderIdx = INVALID_INDEX;
+
+ public: // METHODS
+ virtual ~Renderable() {}
+
+ virtual void RegisterResources(IResourceReceiver& receiver) const;
+ virtual void ReflectResources(IResourceReflector& reflector);
+ virtual void OnCreate(const NodeDefinition& node, CreateParams& params, Actor& actor) const;
+ };
+
+ struct CustomizationDefinition
+ {
+ std::string mTag;
+
+ Index GetChildId(const Customization::Choices& choices, const NodeDefinition& node)
+ {
+ auto choice = choices.Get(mTag);
+ return std::min(choice != Customization::NONE ? choice : 0,
+ static_cast<Index>(node.mChildren.size() - 1));
+ }
+ };
+
+ class IVisitor
+ {
+ public:
+ virtual void Start(NodeDefinition& n) = 0;
+ virtual void Finish(NodeDefinition& n) = 0;
+
+ protected:
+ ~IVisitor() {}
+ };
+
+ class IConstVisitor
+ {
+ public:
+ virtual void Start(const NodeDefinition& n) = 0;
+ virtual void Finish(const NodeDefinition& n) = 0;
+
+ protected:
+ ~IConstVisitor() {}
+ };
+
+ struct Extra
+ {
+ std::string mKey;
+ Property::Value mValue;
+
+ bool operator<(const Extra& other) const
+ {
+ return mKey < other.mKey;
+ }
+ };
+
+public: // METHODS
+ /**
+ * @brief Creates a DALi Actor from this definition only.
+ * @note Not recursive.
+ */
+ Actor CreateActor(CreateParams& params) const;
+
+ Matrix GetLocalSpace() const;
+
+public: // DATA
+ static const std::string ORIGINAL_MATRIX_PROPERTY_NAME;
+
+ std::string mName;
+
+ Vector3 mPosition = Vector3::ZERO;
+ Quaternion mOrientation = Quaternion::IDENTITY;
+ Vector3 mScale = Vector3::ONE;
+ Vector3 mSize = Vector3::ONE;
+
+ bool mIsVisible = true;
+
+ std::unique_ptr<Renderable> mRenderable;
+ std::unique_ptr<CustomizationDefinition> mCustomization;
+ std::vector<Extra> mExtras;
+ std::vector<ConstraintDefinition> mConstraints;
+
+ std::vector<Index> mChildren;
+ Index mParentIdx = INVALID_INDEX;
+};
+
+class DALI_SCENE_LOADER_API ModelNode : public NodeDefinition::Renderable
+{
+public: // DATA
+ Vector4 mColor = Color::WHITE;
+ Index mMeshIdx = INVALID_INDEX;
+ Index mMaterialIdx = INVALID_INDEX;
+
+public: // METHODS
+ void RegisterResources(IResourceReceiver& receiver) const override;
+ void ReflectResources(IResourceReflector& reflector) override;
+ void OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const override;
+};
+
+/**
+ * @brief Parameters for an Arc node.
+ */
+class DALI_SCENE_LOADER_API ArcNode : public ModelNode
+{
+public: // DATA
+ bool mAntiAliasing = true;
+ int mArcCaps = 0;
+ float mStartAngleDegrees = .0f;
+ float mEndAngleDegrees = .0f;
+ float mRadius = .0f;
+
+public: // METHODS
+ static void GetEndVectorWithDiffAngle(float startAngle, float endAngle, Vector2& endVector);
+
+ void OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const override;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_NODE_DEFINITION_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "dali-scene-loader/public-api/parse-renderer-state.h"
+#include "dali/devel-api/common/map-wrapper.h"
+#include <cstring>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace RendererState
+{
+namespace
+{
+
+std::map<std::string_view, Type> COMPARISONS{
+#define DECL_COMPARISON(x) { #x, Comparison::x }
+ DECL_COMPARISON(NEVER),
+ DECL_COMPARISON(ALWAYS),
+ DECL_COMPARISON(LESS),
+ DECL_COMPARISON(GREATER),
+ DECL_COMPARISON(EQUAL),
+ DECL_COMPARISON(NOT_EQUAL),
+ DECL_COMPARISON(LESS_EQUAL),
+ DECL_COMPARISON(GREATER_EQUAL),
+#undef DECL_COMPARISON
+};
+
+Type InterpretComparison(const std::string_view& str)
+{
+ Type value = 0x0;
+ auto iFind = COMPARISONS.find(str);
+ if (iFind != COMPARISONS.end())
+ {
+ value = iFind->second;
+ }
+ return value;
+}
+
+std::map<std::string_view, Type> BLEND_FACTORS{
+#define DECL_BLEND_FACTOR(x) { #x, SceneLoader::BlendFactor::x }
+ DECL_BLEND_FACTOR(ZERO),
+ DECL_BLEND_FACTOR(ONE),
+ DECL_BLEND_FACTOR(SRC_COLOR),
+ DECL_BLEND_FACTOR(ONE_MINUS_SRC_COLOR),
+ DECL_BLEND_FACTOR(SRC_ALPHA),
+ DECL_BLEND_FACTOR(ONE_MINUS_SRC_ALPHA),
+ DECL_BLEND_FACTOR(DST_ALPHA),
+ DECL_BLEND_FACTOR(ONE_MINUS_DST_ALPHA),
+ DECL_BLEND_FACTOR(DST_COLOR),
+ DECL_BLEND_FACTOR(ONE_MINUS_DST_COLOR),
+ DECL_BLEND_FACTOR(SRC_ALPHA_SATURATE),
+ DECL_BLEND_FACTOR(CONSTANT_COLOR),
+ DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_COLOR),
+ DECL_BLEND_FACTOR(CONSTANT_ALPHA),
+ DECL_BLEND_FACTOR(ONE_MINUS_CONSTANT_ALPHA),
+#undef DECL_BLEND_FACTOR
+};
+
+Type InterpretBlendFactor(const std::string_view& str, uint8_t item)
+{
+ Type value = 0x0;
+ auto iFind = BLEND_FACTORS.find(str);
+ if (iFind != BLEND_FACTORS.end())
+ {
+ value = iFind->second << (BLEND_FACTOR_BASE_SHIFT + BLEND_FACTOR_ITEM_BITS * item);
+ }
+ return value;
+}
+
+std::map<std::string_view, Type> BUFFER_MODES{
+#define DECL_BUFFER_MODE(x) { #x, BufferMode::x }
+ DECL_BUFFER_MODE(NONE),
+ DECL_BUFFER_MODE(AUTO),
+ DECL_BUFFER_MODE(COLOR),
+ DECL_BUFFER_MODE(STENCIL),
+ DECL_BUFFER_MODE(COLOR_STENCIL),
+};
+
+Type InterpretBufferMode(const std::string_view& str)
+{
+ Type value = 0x0;
+ auto iFind = BUFFER_MODES.find(str);
+ if (iFind != BUFFER_MODES.end())
+ {
+ value = iFind->second << BUFFER_MODE_SHIFT;
+ }
+ return value;
+}
+
+std::map<std::string_view, Type(*)(const std::string_view&)> RENDERER_STATE_PROCESSORS{
+ { "DEPTH_WRITE", [](const std::string_view&) -> Type { return DEPTH_WRITE; } },
+ { "DEPTH_TEST", [](const std::string_view&) -> Type { return DEPTH_TEST; } },
+ { "CULL_FRONT", [](const std::string_view&) -> Type { return CULL_FRONT; } },
+ { "CULL_BACK", [](const std::string_view&) -> Type { return CULL_BACK; } },
+ { "ALPHA_BLEND", [](const std::string_view&) -> Type { return ALPHA_BLEND; } },
+ { "DEPTH_FUNC", [](const std::string_view& arg) -> Type {
+ Type value = (arg[0] == ':') ?
+ (InterpretComparison(std::string_view(arg.data() + 1, arg.size() - 1)) << DEPTH_FUNCTION_SHIFT) : 0x0;
+ return value;
+ } },
+ { "BLEND_SRC_RGB", [](const std::string_view& arg) -> Type {
+ Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 0) : 0x0;
+ return value;
+ }},
+ { "BLEND_DST_RGB", [](const std::string_view& arg) -> Type {
+ Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 1) : 0x0;
+ return value;
+ }},
+ { "BLEND_SRC_ALPHA", [](const std::string_view& arg) -> Type {
+ Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 2) : 0x0;
+ return value;
+ }},
+ { "BLEND_DST_ALPHA", [](const std::string_view& arg) -> Type {
+ Type value = (arg[0] == ':') ? InterpretBlendFactor(std::string_view(arg.data() + 1, arg.size() - 1), 3) : 0x0;
+ return value;
+ }},
+ { "BUFFER_MODE", [](const std::string_view& arg) -> Type {
+ Type value = (arg[0] == ':') ? InterpretBufferMode(std::string_view(arg.data() + 1, arg.size() - 1)) : 0x0;
+ return value;
+ }},
+};
+
+}
+
+Type Parse(const char* string, size_t length, StringCallback onError)
+{
+ if (length == 0)
+ {
+ length = strlen(string);
+ }
+
+ Type value = 0x0;
+ auto iEnd = string + length;
+ while (string != iEnd)
+ {
+ auto iNextToken = std::find(string, iEnd, '|');
+ auto iColon = std::find(string, iNextToken, ':');
+ auto i = RENDERER_STATE_PROCESSORS.find(std::string_view(string, iColon - string));
+ if (i != RENDERER_STATE_PROCESSORS.end() && size_t(std::distance(string, iNextToken)) >= i->first.size())
+ {
+ value |= i->second(std::string_view(string + i->first.size(), iNextToken - iColon));
+ }
+ else
+ {
+ onError("Not a valid RendererState: " + std::string(string, iNextToken));
+ }
+
+ string = iNextToken + (iNextToken != iEnd);
+ }
+
+ return value;
+}
+
+} // RendererState
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_INTERPRET_RENDERER_STATE_H
+#define DALI_SCENE_LOADER_INTERPRET_RENDERER_STATE_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "dali-scene-loader/public-api/renderer-state.h"
+#include "dali-scene-loader/public-api/string-callback.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace RendererState
+{
+
+/*
+ * @brief Attempts to interpret a string for renderer states, which can be a combination of the following
+ * (using '|' as a delimiter, if multiple specified):<br/>
+ * - one of Value, exc. for NONE or those with the _BITS, _SHIFT, _MASK or _ITEMS suffix;<br/>
+ * - DEPTH_FUNC:${one of Comparison::Type, exc. OMIT};<br/>
+ * - BLEND_(SRC_DST)_(RGB|ALPHA):${one of BlendFactor::Type, exc. OMIT};<br/>
+ * - BUFFER_MODE:${one of BufferMode::Type, exc. OMIT};
+ * @param string The string to parse;
+ * @param length The length of the string; If left at 0, strlen() will be called, which of
+ * course is only suitable i the string is null-terminated.
+ * @param onError The callback to call when an error occurred.
+ * @note No other characters are allowed.
+ */
+DALI_SCENE_LOADER_API Type Parse(const char* string, size_t length = 0, StringCallback onError = DefaultErrorCallback);
+
+}
+}
+}
+
+#endif //DALI_SCENE_LOADER_INTERPRET_RENDERER_STATE_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/renderer-state.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+// NOTE: values for BlendFactor aren't contiguous, hence we need a mapping.
+const Dali::BlendFactor::Type kBlendFactors[] = {
+ Dali::BlendFactor::ZERO,
+ Dali::BlendFactor::ONE,
+ Dali::BlendFactor::SRC_COLOR,
+ Dali::BlendFactor::ONE_MINUS_SRC_COLOR,
+ Dali::BlendFactor::SRC_ALPHA,
+ Dali::BlendFactor::ONE_MINUS_SRC_ALPHA,
+ Dali::BlendFactor::DST_ALPHA,
+ Dali::BlendFactor::ONE_MINUS_DST_ALPHA,
+ Dali::BlendFactor::DST_COLOR,
+ Dali::BlendFactor::ONE_MINUS_DST_COLOR,
+ Dali::BlendFactor::SRC_ALPHA_SATURATE,
+ Dali::BlendFactor::CONSTANT_COLOR,
+ Dali::BlendFactor::ONE_MINUS_CONSTANT_COLOR,
+ Dali::BlendFactor::CONSTANT_ALPHA,
+ Dali::BlendFactor::ONE_MINUS_CONSTANT_ALPHA,
+};
+}
+
+namespace RendererState
+{
+#define RENDERER_SET_PROPERTY(name, value) renderer.SetProperty(Renderer::Property::name, (value))
+
+void Apply(Type rendererState, Renderer& renderer)
+{
+ RENDERER_SET_PROPERTY(DEPTH_WRITE_MODE, MaskMatch(rendererState, DEPTH_WRITE) ? DepthWriteMode::ON : DepthWriteMode::OFF);
+ RENDERER_SET_PROPERTY(DEPTH_TEST_MODE, MaskMatch(rendererState, DEPTH_TEST) ? DepthTestMode::ON : DepthTestMode::OFF);
+
+ RENDERER_SET_PROPERTY(BLEND_MODE, MaskMatch(rendererState, ALPHA_BLEND) ? BlendMode::ON : BlendMode::OFF);
+
+ const bool cullBack = MaskMatch(rendererState, CULL_BACK);
+ RENDERER_SET_PROPERTY(FACE_CULLING_MODE, MaskMatch(rendererState, CULL_FRONT) ?
+ (cullBack ? FaceCullingMode::FRONT_AND_BACK : FaceCullingMode::FRONT) :
+ (cullBack ? FaceCullingMode::BACK : FaceCullingMode::NONE));
+
+ if (auto depthFunc = (rendererState & DEPTH_FUNCTION_MASK) >> DEPTH_FUNCTION_SHIFT)
+ {
+ RENDERER_SET_PROPERTY(DEPTH_FUNCTION, static_cast<DepthFunction::Type>(depthFunc - 1));
+ }
+
+ if (auto blendFactors = (rendererState & BLEND_FACTOR_MASK) >> BLEND_FACTOR_BASE_SHIFT)
+ {
+ if (auto srcRgb = (blendFactors & BLEND_FACTOR_ITEM_MASK))
+ {
+ RENDERER_SET_PROPERTY(BLEND_FACTOR_SRC_RGB, kBlendFactors[static_cast<BlendFactor::Type>(srcRgb - 1)]);
+ }
+
+ blendFactors >>= BLEND_FACTOR_ITEM_BITS;
+ if (auto dstRgb = (blendFactors & BLEND_FACTOR_ITEM_MASK))
+ {
+ RENDERER_SET_PROPERTY(BLEND_FACTOR_DEST_RGB, kBlendFactors[static_cast<BlendFactor::Type>(dstRgb - 1)]);
+ }
+
+ blendFactors >>= BLEND_FACTOR_ITEM_BITS;
+ if (auto srcAlpha = (blendFactors & BLEND_FACTOR_ITEM_MASK))
+ {
+ RENDERER_SET_PROPERTY(BLEND_FACTOR_SRC_ALPHA, kBlendFactors[static_cast<BlendFactor::Type>(srcAlpha - 1)]);
+ }
+
+ blendFactors >>= BLEND_FACTOR_ITEM_BITS;
+ if (auto dstAlpha = (blendFactors & BLEND_FACTOR_ITEM_MASK))
+ {
+ RENDERER_SET_PROPERTY(BLEND_FACTOR_DEST_ALPHA, kBlendFactors[static_cast<BlendFactor::Type>(dstAlpha - 1)]);
+ }
+ }
+
+ if (auto bufferMode = (rendererState & BUFFER_MODE_MASK) >> BUFFER_MODE_SHIFT)
+ {
+ RENDERER_SET_PROPERTY(RENDER_MODE, static_cast<RenderMode::Type>(bufferMode - 1));
+ }
+}
+
+} // RendererState
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_RENDERER_STATE_H
+#define DALI_SCENE_LOADER_RENDERER_STATE_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/rendering/renderer.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/*
+ * @brief Contains values for comparison functions used in depth and stencil testing.
+ * @note Relative order of members must match DepthFunction::Type and StencilFunction::Type.
+ */
+struct DALI_SCENE_LOADER_API Comparison
+{
+ enum Type
+ {
+ OMIT, // not specified; will not be set.
+ NEVER,
+ ALWAYS,
+ LESS,
+ GREATER,
+ EQUAL,
+ NOT_EQUAL,
+ LESS_EQUAL,
+ GREATER_EQUAL
+ };
+
+ Comparison() = delete;
+};
+
+/*
+ * @brief Determines the blend factor used.
+ * @note Relative order of members must match BlendFactor::Type.
+ */
+struct DALI_SCENE_LOADER_API BlendFactor
+{
+ enum Type
+ {
+ OMIT, // not specified - will not be updated
+ ZERO,
+ ONE, // default for source alpha
+ SRC_COLOR,
+ ONE_MINUS_SRC_COLOR,
+ SRC_ALPHA, // default for source RGB
+ ONE_MINUS_SRC_ALPHA, // default for destination RGB and destination alpha
+ DST_ALPHA,
+ ONE_MINUS_DST_ALPHA,
+ DST_COLOR,
+ ONE_MINUS_DST_COLOR,
+ SRC_ALPHA_SATURATE,
+ CONSTANT_COLOR,
+ ONE_MINUS_CONSTANT_COLOR,
+ CONSTANT_ALPHA,
+ ONE_MINUS_CONSTANT_ALPHA,
+ };
+
+ BlendFactor() = delete;
+};
+
+/*
+ * @brief Determines which buffers shall the Renderer write into.
+ * @note Relative order of members must match RenderMode::Type.
+ */
+struct DALI_SCENE_LOADER_API BufferMode
+{
+ enum Type
+ {
+ OMIT, ///< not specified - will not be updated
+ NONE, ///< Don’t write to either color or stencil buffer (But will potentially render to depth buffer).
+ AUTO, ///< Writes are managed by the Actor Clipping API. This is DALi's default.
+ COLOR, ///< Ignore stencil properties. Write to the color buffer.
+ STENCIL, ///< Use the stencil properties. Do not write to the color buffer.
+ COLOR_STENCIL ///< Use the stencil properties AND Write to the color buffer.
+ };
+
+ BufferMode() = delete;
+};
+
+/*
+ * @brief Contains values and functionality for configuring Renderers.
+ */
+namespace RendererState
+{
+
+using Type = uint32_t; // 8 bits reserved for flags, 4 * 4 bit for blend factors, 4 bits for depth function
+
+enum DALI_SCENE_LOADER_API Value : Type
+{
+ NONE = 0x0,
+
+ DEPTH_WRITE = 0x01,
+ DEPTH_TEST = 0x02,
+
+ CULL_FRONT = 0x04,
+ CULL_BACK = 0x08,
+
+ ALPHA_BLEND = 0x10,
+
+ DEPTH_FUNCTION_SHIFT = 6,
+ DEPTH_FUNCTION_BITS = 4,
+ DEPTH_FUNCTION_MASK = ((1 << DEPTH_FUNCTION_BITS) - 1) << DEPTH_FUNCTION_SHIFT,
+
+ BLEND_FACTOR_BASE_SHIFT = DEPTH_FUNCTION_SHIFT + DEPTH_FUNCTION_BITS,
+ BLEND_FACTOR_ITEM_BITS = 4,
+ BLEND_FACTOR_ITEMS = 4,
+ BLEND_FACTOR_BITS = BLEND_FACTOR_ITEM_BITS * BLEND_FACTOR_ITEMS,
+ BLEND_FACTOR_MASK = ((1 << BLEND_FACTOR_BITS) - 1) << BLEND_FACTOR_BASE_SHIFT,
+ BLEND_FACTOR_ITEM_MASK = (1 << BLEND_FACTOR_ITEM_BITS) - 1, // after rshifting by BLEND_FACTOR_BASE_SHIFT
+
+ // Buffer mode is DALi's RenderMode, just to avoid too much conflation.
+ BUFFER_MODE_BITS = 3u,
+ BUFFER_MODE_SHIFT = 32u - BUFFER_MODE_BITS, // from end
+ BUFFER_MODE_MASK = ((1u << BUFFER_MODE_BITS) - 1u) << BUFFER_MODE_SHIFT,
+
+ DEFAULT = DEPTH_WRITE | DEPTH_TEST | CULL_BACK | (Comparison::LESS_EQUAL << DEPTH_FUNCTION_SHIFT),
+};
+
+/*
+ * @brief Encodes the given blend factors into a RenderMode value, maskable into other options,
+ * passable into ApplyRenderMode().
+ */
+inline
+DALI_SCENE_LOADER_API constexpr uint32_t FromBlendFactors(BlendFactor::Type srcRgb, BlendFactor::Type destRgb,
+ BlendFactor::Type srcAlpha, BlendFactor::Type destAlpha)
+{
+ return (srcRgb | (destRgb << BLEND_FACTOR_ITEM_BITS) | (srcAlpha << (BLEND_FACTOR_ITEM_BITS * 2)) |
+ (destAlpha << (BLEND_FACTOR_ITEM_BITS * 3))) << BLEND_FACTOR_BASE_SHIFT;
+}
+
+/*
+ * @brief Applies the settings encoded in @a rendererState, to a @a renderer.
+ * @note Depth function is only set if not Comparison::OMIT.
+ * @note Blend factors are only set if not BlendFactor::OMIT.
+ * @note Buffer mode is only set is not BufferMode::OMIT.
+ */
+DALI_SCENE_LOADER_API void Apply(Type rendererState, Renderer& renderer);
+
+} // RendererState
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_RENDERER_STATE_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// FILE HEADER
+#include "dali-scene-loader/public-api/resource-bundle.h"
+
+// EXTERNAL
+#include "dali/public-api/rendering/sampler.h"
+#include "dali-toolkit/public-api/image-loader/sync-image-loader.h"
+#include <fstream>
+#include <istream>
+#include <cstring>
+#include <fstream>
+
+namespace Dali
+{
+using namespace Toolkit;
+
+namespace SceneLoader
+{
+namespace
+{
+
+const char* const RESOURCE_TYPE_NAMES[] = {
+ "Environment",
+ "Shader",
+ "Mesh",
+ "Material",
+};
+
+} // nonamespace
+
+const char* GetResourceTypeName(ResourceType::Value type)
+{
+ return RESOURCE_TYPE_NAMES[static_cast<int>(type)];
+}
+
+ResourceRefCounts ResourceBundle::CreateRefCounter() const
+{
+ ResourceRefCounts refCounts(4);
+ refCounts[ResourceType::Environment].Resize(mEnvironmentMaps.size(), 0u);
+ refCounts[ResourceType::Shader].Resize(mShaders.size(), 0u);
+ refCounts[ResourceType::Mesh].Resize(mMeshes.size(), 0u);
+ refCounts[ResourceType::Material].Resize(mMaterials.size(), 0u);
+ return refCounts;
+}
+
+void ResourceBundle::CountEnvironmentReferences(ResourceRefCounts& refCounts) const
+{
+ auto& environmentRefCounts = refCounts[ResourceType::Environment];
+
+ const auto& materialRefs = refCounts[ResourceType::Material];
+ for (uint32_t i = 0, iEnd = materialRefs.Size(); i != iEnd; ++i)
+ {
+ if (materialRefs[i] > 0)
+ {
+ ++environmentRefCounts[mMaterials[i].first.mEnvironmentIdx];
+ }
+ }
+}
+
+void ResourceBundle::LoadResources(const ResourceRefCounts& refCounts, PathProvider pathProvider, Options::Type options)
+{
+ const auto kForceLoad = MaskMatch(options, Options::ForceReload);
+ const auto kKeepUnused = MaskMatch(options, Options::KeepUnused);
+
+ const auto& refCountEnvMaps = refCounts[ResourceType::Environment];
+ auto environmentsPath = pathProvider(ResourceType::Environment);
+ for (uint32_t i = 0, iEnd = refCountEnvMaps.Size(); i != iEnd; ++i)
+ {
+ auto refCount = refCountEnvMaps[i];
+ auto& iEnvMap = mEnvironmentMaps[i];
+ if (refCount > 0 && (kForceLoad || !iEnvMap.second.IsLoaded()))
+ {
+ auto raw = iEnvMap.first.LoadRaw(environmentsPath);
+ iEnvMap.second = iEnvMap.first.Load(std::move(raw));
+ }
+ else if (!kKeepUnused && refCount == 0 && iEnvMap.second.IsLoaded())
+ {
+ iEnvMap.second.mDiffuse = Texture();
+ iEnvMap.second.mSpecular = Texture();
+ }
+ }
+
+ const auto& refCountShaders = refCounts[ResourceType::Shader];
+ auto shadersPath = pathProvider(ResourceType::Shader);
+ for (uint32_t i = 0, iEnd = refCountShaders.Size(); i != iEnd; ++i)
+ {
+ auto refCount = refCountShaders[i];
+ auto& iShader = mShaders[i];
+ if (refCount > 0 && (kForceLoad || !iShader.second))
+ {
+ auto raw = iShader.first.LoadRaw(shadersPath);
+ iShader.second = iShader.first.Load(std::move(raw));
+ }
+ else if(!kKeepUnused && refCount == 0 && iShader.second)
+ {
+ iShader.second = Shader();
+ }
+ }
+
+ const auto& refCountMeshes = refCounts[ResourceType::Mesh];
+ auto modelsPath = pathProvider(ResourceType::Mesh);
+ for (uint32_t i = 0, iEnd = refCountMeshes.Size(); i != iEnd; ++i)
+ {
+ auto refCount = refCountMeshes[i];
+ auto& iMesh = mMeshes[i];
+ if (refCount > 0 && (kForceLoad || !iMesh.second.geometry))
+ {
+ auto raw = iMesh.first.LoadRaw(modelsPath);
+ iMesh.second = iMesh.first.Load(std::move(raw));
+ }
+ else if (!kKeepUnused && refCount == 0 && iMesh.second.geometry)
+ {
+ iMesh.second.geometry = Geometry();
+ }
+ }
+
+ const auto& refCountMaterials = refCounts[ResourceType::Material];
+ auto imagesPath = pathProvider(ResourceType::Material);
+ for (uint32_t i = 0, iEnd = refCountMaterials.Size(); i != iEnd; ++i)
+ {
+ auto refCount = refCountMaterials[i];
+ auto& iMaterial = mMaterials[i];
+ if (refCount > 0 && (kForceLoad || !iMaterial.second))
+ {
+ auto raw = iMaterial.first.LoadRaw(imagesPath);
+ iMaterial.second = iMaterial.first.Load(mEnvironmentMaps, std::move(raw));
+ }
+ else if (!kKeepUnused && refCount == 0 && iMaterial.second)
+ {
+ iMaterial.second = TextureSet();
+ }
+ }
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_RESOURCE_BUNDLE_H_
+#define DALI_SCENE_LOADER_RESOURCE_BUNDLE_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL
+#include "dali-scene-loader/public-api/mesh-definition.h"
+#include "dali-scene-loader/public-api/material-definition.h"
+#include "dali-scene-loader/public-api/environment-definition.h"
+#include "dali-scene-loader/public-api/shader-definition.h"
+#include "dali-scene-loader/public-api/skeleton-definition.h"
+
+// EXTERNAL
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/rendering/shader.h"
+#include "dali/public-api/rendering/texture-set.h"
+#include <memory>
+#include <functional>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/*
+ * @brief The types of resources that .dli may define.
+ */
+struct DALI_SCENE_LOADER_API ResourceType
+{
+ enum Value
+ {
+ Environment,
+ Shader,
+ Mesh,
+ Material,
+ };
+
+ ResourceType() = delete;
+};
+
+/*
+ * @return The string value corresponding to the given resource @a type.
+ */
+DALI_SCENE_LOADER_API const char* GetResourceTypeName(ResourceType::Value type);
+
+using ResourceRefCounts = std::vector<Vector<uint32_t>>;
+
+/*
+ * @brief Stores all resource definitions along with the DALi resources that
+ * could be created from them, directly indexible into with values from a dli
+ * document.
+ */
+class DALI_SCENE_LOADER_API ResourceBundle
+{
+public:
+ struct Options
+ {
+ using Type = uint8_t;
+
+ enum Value : Type
+ {
+ None = 0,
+ ForceReload = NthBit(0), ///< Load resources [again] even if they were already loaded.
+ KeepUnused = NthBit(1) ///<s Don't reset handles to resources that had a 0 reference count.
+ };
+ };
+
+ using PathProvider = std::function<std::string(ResourceType::Value)>;
+
+ ResourceBundle() = default;
+
+ ResourceBundle(const ResourceBundle&) = delete;
+ ResourceBundle& operator=(const ResourceBundle&) = delete;
+
+ ResourceBundle(ResourceBundle&&) = default;
+ ResourceBundle& operator=(ResourceBundle&&) = default;
+
+ /*
+ * @return A ResourceRefCounts object with the correct number of entries for
+ * all resource types (based on the various resource definition vectors),
+ * with all reference counts set to 0.
+ */
+ ResourceRefCounts CreateRefCounter() const;
+
+ /*
+ * @brief Based on a ResourceRefCounts, and more specifically the reference
+ * count of materials therein, it will calculate the reference count of
+ * environment maps.
+ */
+ void CountEnvironmentReferences(ResourceRefCounts& refCounts) const;
+
+ /*
+ * @brief Performs the loading of all resources based on their respective
+ * reference count in @a refCounts. Resources that had a non-zero ref count will be
+ * loaded unless we already have a handle to them (OR the ForceReload option was specified).
+ * Any handles we have to resources that come in with a zero ref count will be reset,
+ * UNLESS the KeepUnused option was specified.
+ */
+ void LoadResources(const ResourceRefCounts& refCounts,
+ PathProvider pathProvider,
+ Options::Type options = Options::None);
+
+public: // DATA
+ EnvironmentDefinition::Vector mEnvironmentMaps;
+ ShaderDefinition::Vector mShaders;
+ MeshDefinition::Vector mMeshes;
+ MaterialDefinition::Vector mMaterials;
+
+ SkeletonDefinition::Vector mSkeletons;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_RESOURCE_BUNDLE_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// EXTERNAL
+#include "dali/public-api/animation/constraints.h"
+#include "dali/devel-api/common/map-wrapper.h"
+
+// INTERNAL
+#include "dali-scene-loader/public-api/scene-definition.h"
+#include "dali-scene-loader/public-api/blend-shape-details.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include "dali-scene-loader/public-api/skinning-details.h"
+
+//#define DEBUG_SCENE_DEFINITION
+//#define DEBUG_JOINTS
+
+#if defined(DEBUG_SCENE_DEFINITION) || defined(DEBUG_JOINTS)
+#define DEBUG_ONLY(x) x
+#else
+#define DEBUG_ONLY(x)
+#endif
+
+#define LOGD(x) DEBUG_ONLY(printf x ; printf("\n"); fflush(stdout))
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+
+const std::string JOINT_MATRIX{ "jointMatrix" };
+
+const std::map<Property::Type, Constraint(*)(Actor&, Property::Index)> sConstraintFactory = {
+ {
+ Property::Type::BOOLEAN,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<bool>(a, i, [](bool& current, const PropertyInputContainer& inputs) {
+ current = inputs[0]->GetBoolean();
+ });
+ }
+ },
+ {
+ Property::Type::INTEGER,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<int>(a, i, [](int& current, const PropertyInputContainer& inputs) {
+ current = inputs[0]->GetInteger();
+ });
+ }
+ },
+ {
+ Property::Type::FLOAT,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<float>(a, i, EqualToConstraint());
+ }
+ },
+ {
+ Property::Type::VECTOR2,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Vector2>(a, i, EqualToConstraint());
+ }
+ },
+ {
+ Property::Type::VECTOR3,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Vector3>(a, i, EqualToConstraint());
+ }
+ },
+ {
+ Property::Type::VECTOR4,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Vector4>(a, i, EqualToConstraint());
+ }
+ },
+ {
+ Property::Type::MATRIX,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Matrix>(a, i, EqualToConstraint());
+ }
+ },
+ {
+ Property::Type::MATRIX3,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Matrix3>(a, i, EqualToConstraint());
+ }
+ },
+ {
+ Property::Type::ROTATION,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Quaternion>(a, i, EqualToConstraint());
+ }
+ },
+};
+
+struct ResourceReflector : IResourceReflector
+{
+ Index* iMesh = nullptr;
+ Index* iShader = nullptr;
+
+ void Reflect(ResourceType::Value type, Index& id)
+ {
+ switch (type)
+ {
+ case ResourceType::Shader:
+ DALI_ASSERT_ALWAYS(!iShader && "Shader index already assigned!");
+ iShader = &id;
+ break;
+
+ case ResourceType::Mesh:
+ DALI_ASSERT_ALWAYS(!iMesh && "Mesh index already assigned!");
+ iMesh = &id;
+ break;
+
+ default: // Other resource types are not relevant to the problem at hand.
+ break;
+ }
+ }
+};
+
+
+#ifdef DEBUG_JOINTS
+const char* JOINT_DEBUG_VSH = "#version 300 es\n"
+DALI_COMPOSE_SHADER(
+ precision mediump float;
+ uniform mat4 uMvpMatrix;
+ in vec3 aPosition;
+ in float aColor;
+ flat out float vColor;
+ void main() {
+ vColor = aColor;
+ gl_Position = uMvpMatrix * vec4(aPosition, 1.0);
+ });
+
+const char* JOINT_DEBUG_FSH = "#version 300 es\n"
+DALI_COMPOSE_SHADER(
+ precision mediump float;
+ flat in float vColor;
+ out vec4 FragColor;
+ void main() {
+ vec3 rgb = vec3(fract(vColor), fract(vColor * 0.00390625), fract(vColor * 0.00390625 * 0.00390625));
+ FragColor = vec4(rgb, 1.);
+ });
+
+Shader sJointDebugShader;
+int sNumScenes = 0;
+
+void EnsureJointDebugShaderCreated()
+{
+ if (0 == sNumScenes)
+ {
+ sJointDebugShader = Shader::New(JOINT_DEBUG_VSH, JOINT_DEBUG_FSH);
+ }
+ ++sNumScenes;
+}
+
+void AddJointDebugVisual(Actor aJoint)
+{
+ Property::Map attribs;
+ attribs["aPosition"] = Property::Type::VECTOR3;
+ attribs["aColor"] = Property::Type::FLOAT;
+
+ PropertyBuffer vbo = PropertyBuffer::New(attribs);
+
+ struct Vertex
+ {
+ Vector3 pos;
+ float color;
+ } vertices[] = {
+ { Vector3::ZERO, .999f + .999f * 256.f + .999f * 256.f * 256.f },
+ { Vector3::XAXIS, .999f },
+ { Vector3::YAXIS, .999f * 256.f },
+ { Vector3::ZAXIS, .999f * 256.f * 256.f },
+ };
+
+ vbo.SetData(&vertices, std::extent<decltype(vertices)>::value);
+
+ uint16_t indices[] = { 0, 1, 0, 2, 0, 3 };
+
+ Geometry geo = Geometry::New();
+ geo.AddVertexBuffer(vbo);
+ geo.SetIndexBuffer(indices, std::extent<decltype(indices)>::value);
+ geo.SetType(Geometry::LINES);
+
+ Renderer r = Renderer::New(geo, sJointDebugShader);
+ aJoint.AddRenderer(r);
+
+ aJoint.SetVisible(true);
+}
+#endif //DEBUG_JOINTS
+
+class ActorCreatorVisitor : public NodeDefinition::IConstVisitor
+{
+public:
+ ActorCreatorVisitor(NodeDefinition::CreateParams& params)
+ : mCreationContext(params)
+ {}
+
+ void Start(const NodeDefinition& n)
+ {
+ mCreationContext.mXforms.modelStack.Push(n.GetLocalSpace());
+
+ Actor a = n.CreateActor(mCreationContext);
+ if (!mActorStack.empty())
+ {
+ mActorStack.back().Add(a);
+ }
+ else
+ {
+ mRoot = a;
+ }
+ mActorStack.push_back(a);
+ }
+
+ void Finish(const NodeDefinition& n)
+ {
+ mActorStack.pop_back();
+ mCreationContext.mXforms.modelStack.Pop();
+ }
+
+ Actor GetRoot() const
+ {
+ return mRoot;
+ }
+
+private:
+ NodeDefinition::CreateParams& mCreationContext;
+ std::vector<Actor> mActorStack;
+ Actor mRoot;
+};
+
+bool IsAncestor(const SceneDefinition& scene, Index ancestor, Index node, Index rootHint = INVALID_INDEX)
+{
+ bool isAncestor = false;
+ while (node != rootHint && !isAncestor)
+ {
+ node = scene.GetNode(node)->mParentIdx;
+ isAncestor = ancestor == node;
+ }
+ return isAncestor;
+}
+
+void InsertUniqueSorted(std::vector<Index>& data, Index value)
+{
+ auto iInsert = std::lower_bound(data.begin(), data.end(), value);
+ if (iInsert == data.end() || *iInsert != value)
+ {
+ data.insert(iInsert, value);
+ }
+}
+
+void RemoveFromSorted(std::vector<Index>& data, Index value)
+{
+ auto iRemove = std::lower_bound(data.begin(), data.end(), value);
+ if (iRemove != data.end() && *iRemove == value)
+ {
+ data.erase(iRemove);
+ }
+}
+
+Property::Index ConfigureJointMatrix(Actor actor, Actor ancestor, Property::Index propJointMatrix)
+{
+ Actor parent = actor.GetParent();
+ if (parent != ancestor)
+ {
+ propJointMatrix = ConfigureJointMatrix(parent, ancestor, propJointMatrix);
+ }
+
+ auto myPropJointMatrix = actor.GetPropertyIndex(JOINT_MATRIX);
+ if (myPropJointMatrix == Property::INVALID_INDEX)
+ {
+ myPropJointMatrix = actor.RegisterProperty(JOINT_MATRIX, Matrix{ false });
+ Constraint constraint = Constraint::New<Matrix>(actor, propJointMatrix,
+ [](Matrix& output, const PropertyInputContainer& inputs)
+ {
+ Matrix jointMatrix{ false };
+ jointMatrix.SetTransformComponents(Vector3::ONE, inputs[0]->GetQuaternion(), inputs[1]->GetVector3());
+
+ Matrix::Multiply(output, jointMatrix, inputs[2]->GetMatrix());
+ });
+ constraint.AddSource(Source{ actor, Actor::Property::ORIENTATION });
+ constraint.AddSource(Source{ actor, Actor::Property::POSITION });
+ constraint.AddSource(Source{ parent, propJointMatrix });
+ constraint.Apply();
+ }
+
+ return myPropJointMatrix;
+}
+
+void SortAndDeduplicateSkinningRequests(std::vector<SkinningShaderConfigurationRequest>& requests)
+{
+ // Sort requests by shaders.
+ std::sort(requests.begin(), requests.end());
+
+ // Remove duplicates.
+ auto i = requests.begin();
+ auto iEnd = requests.end();
+ Shader s = i->mShader;
+ Index skeletonIdx = i->mSkeletonIdx;
+ ++i;
+ do
+ {
+ // Multiple identical shader instances are removed.
+ while (i != iEnd && i->mShader == s)
+ {
+ // Cannot have multiple skeletons input to the same shader.
+ // NOTE: DliModel now makes sure this doesn't happen.
+ DALI_ASSERT_ALWAYS(i->mSkeletonIdx == skeletonIdx &&
+ "Skinning shader must not be shared between different skeletons.");
+
+ i->mShader = Shader();
+ ++i;
+ }
+
+ if (i == iEnd)
+ {
+ break;
+ }
+ s = i->mShader;
+ skeletonIdx = i->mSkeletonIdx;
+ ++i;
+ } while (true);
+
+ requests.erase(std::remove_if(requests.begin(), requests.end(), [](const SkinningShaderConfigurationRequest& sscr)
+ {
+ return !sscr.mShader;
+ }), requests.end());
+}
+
+void ConfigureBoneMatrix(const Matrix& ibm, Actor joint, Shader& shader, Index& boneIdx)
+{
+ // Register bone transform on shader.
+ char propertyNameBuffer[32];
+ snprintf(propertyNameBuffer, sizeof(propertyNameBuffer), "%s[%d]", Skinning::BONE_UNIFORM_NAME.c_str(), boneIdx);
+ DALI_ASSERT_DEBUG(shader.GetPropertyIndex(propertyNameBuffer) == Property::INVALID_INDEX);
+ auto propBoneXform = shader.RegisterProperty(propertyNameBuffer, Matrix{ false });
+
+ // Constrain bone matrix to joint transform.
+ Constraint constraint = Constraint::New<Matrix>(shader, propBoneXform,
+ [ibm](Matrix& output, const PropertyInputContainer& inputs)
+ {
+ Matrix::Multiply(output, ibm, inputs[0]->GetMatrix());
+ });
+
+ auto propJointMatrix = joint.GetPropertyIndex(JOINT_MATRIX);
+ constraint.AddSource(Source{ joint, propJointMatrix });
+ constraint.Apply();
+
+ ++boneIdx;
+}
+
+template <class Visitor, class SceneDefinition>
+void VisitInternal(Index iNode, const Customization::Choices& choices, Visitor& v, SceneDefinition& sd)
+{
+ auto& node = *sd.GetNode(iNode);
+ v.Start(node);
+
+ if (node.mCustomization)
+ {
+ if (!node.mChildren.empty())
+ {
+ auto choice = choices.Get(node.mCustomization->mTag);
+ Index i = std::min(choice != Customization::NONE ? choice : 0, static_cast<Index>(node.mChildren.size() - 1));
+ sd.Visit(node.mChildren[i], choices, v);
+ }
+ }
+ else
+ {
+ for (auto i : node.mChildren)
+ {
+ sd.Visit(i, choices, v);
+ }
+ }
+
+ v.Finish(node);
+}
+
+} // nonamespace
+
+SceneDefinition::SceneDefinition()
+{
+ mNodes.reserve(128);
+
+#ifdef DEBUG_JOINTS
+ EnsureJointDebugShaderCreated();
+#endif
+}
+
+SceneDefinition::SceneDefinition(SceneDefinition&& other)
+: mNodes(std::move(other.mNodes)),
+ mRootNodeIds(std::move(other.mRootNodeIds))
+{
+#ifdef DEBUG_JOINTS
+ EnsureJointDebugShaderCreated();
+#endif
+}
+
+SceneDefinition::~SceneDefinition()
+{
+#ifdef DEBUG_JOINTS
+ --sNumScenes;
+ if (sNumScenes == 0)
+ {
+ sJointDebugShader = Shader();
+ }
+#endif
+}
+
+uint32_t SceneLoader::SceneDefinition::AddRootNode(Index iNode)
+{
+ if (iNode < mNodes.size())
+ {
+ uint32_t result = mRootNodeIds.size();
+ mRootNodeIds.push_back(iNode);
+ return result;
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to add new root with node " << iNode << " -- index out of bounds.";
+ return -1;
+ }
+}
+
+const std::vector<Index>& SceneDefinition::GetRoots() const
+{
+ return mRootNodeIds;
+}
+
+void SceneDefinition::RemoveRootNode(Index iRoot)
+{
+ if (iRoot < mRootNodeIds.size())
+ {
+ mRootNodeIds.erase(mRootNodeIds.begin() + iRoot);
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to remove root " << iRoot << " -- index out of bounds.";
+ }
+}
+
+uint32_t SceneDefinition::GetNodeCount() const
+{
+ return mNodes.size();
+}
+
+const NodeDefinition* SceneDefinition::GetNode(Index iNode) const
+{
+ return mNodes[iNode].get();
+}
+
+NodeDefinition* SceneDefinition::GetNode(Index iNode)
+{
+ return mNodes[iNode].get();
+}
+
+void SceneDefinition::Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IVisitor& v)
+{
+ VisitInternal(iNode, choices, v, *this);
+}
+
+void SceneDefinition::Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IConstVisitor& v) const
+{
+ VisitInternal(iNode, choices, v, *this);
+}
+
+void SceneDefinition::CountResourceRefs(Index iNode, const Customization::Choices& choices, ResourceRefCounts& refCounts) const
+{
+ struct RefCounter : IResourceReceiver
+ {
+ ResourceRefCounts* refCounts;
+
+ void Register(ResourceType::Value type, Index id)
+ {
+ ++(*refCounts)[type][id];
+ }
+ };
+
+ struct : NodeDefinition::IConstVisitor
+ {
+ RefCounter counter;
+
+ void Start(const NodeDefinition& n)
+ {
+ if (n.mRenderable)
+ {
+ n.mRenderable->RegisterResources(counter);
+ }
+ }
+
+ void Finish(const NodeDefinition& n)
+ {}
+
+ } refCounterVisitor;
+ refCounterVisitor.counter.refCounts = &refCounts;
+
+ Visit(iNode, choices, refCounterVisitor);
+}
+
+Actor SceneDefinition::CreateNodes(Index iNode, const Customization::Choices & choices,
+ NodeDefinition::CreateParams& params) const
+{
+ ActorCreatorVisitor actorCreatorVisitor(params);
+
+ Visit(iNode, choices, actorCreatorVisitor);
+
+ return actorCreatorVisitor.GetRoot();
+}
+
+void SceneDefinition::GetCustomizationOptions(const Customization::Choices& choices,
+ Customization::Map& outCustomizationOptions, Customization::Choices* outMissingChoices) const
+{
+ struct : NodeDefinition::IConstVisitor
+ {
+ const Customization::Choices* choices; // choices that we know about.
+ Customization::Map* options; // tags are registered here. NO OWNERSHIP.
+ Customization::Choices* missingChoices; // tags will be registered with the default 0. NO OWNERSHIP.
+
+ void Start(const NodeDefinition& n)
+ {
+ if (n.mCustomization)
+ {
+ const std::string& tag = n.mCustomization->mTag;
+ if (missingChoices != nullptr && choices->Get(tag) == Customization::NONE)
+ {
+ missingChoices->Set(tag, 0);
+ }
+
+ auto customization = options->Get(tag);
+ if (!customization)
+ {
+ customization = options->Set(tag, {});
+ }
+ customization->nodes.push_back(n.mName);
+ customization->numOptions = std::max(customization->numOptions,
+ static_cast<uint32_t>(n.mChildren.size()));
+ }
+ }
+
+ void Finish(const NodeDefinition& n)
+ {}
+
+ } customizationRegistrationVisitor;
+ customizationRegistrationVisitor.choices = &choices;
+ customizationRegistrationVisitor.options = &outCustomizationOptions;
+ customizationRegistrationVisitor.missingChoices = outMissingChoices;
+
+ for (auto i : mRootNodeIds)
+ {
+ Visit(i, choices, customizationRegistrationVisitor);
+ }
+}
+
+NodeDefinition* SceneDefinition::AddNode(std::unique_ptr<NodeDefinition>&& nodeDef)
+{
+ if (FindNode(nodeDef->mName))
+ {
+ return nullptr;
+ }
+
+ // add next index (to which we're about to push) as a child to the designated parent, if any.
+ if (nodeDef->mParentIdx != INVALID_INDEX)
+ {
+ mNodes[nodeDef->mParentIdx]->mChildren.push_back(mNodes.size());
+ }
+
+ mNodes.push_back(std::move(nodeDef));
+
+ return mNodes.back().get();
+}
+
+bool SceneDefinition::ReparentNode(const std::string& name, const std::string& newParentName, Index siblingOrder)
+{
+ LOGD(("reparenting %s to %s @ %d", name.c_str(), newParentName.c_str(), siblingOrder));
+
+ std::unique_ptr<NodeDefinition>* nodePtr = nullptr;
+ std::unique_ptr<NodeDefinition>* newParentPtr = nullptr;
+ if (!FindNode(name, &nodePtr) || !FindNode(newParentName, &newParentPtr))
+ {
+ return false;
+ }
+
+ auto& node = *nodePtr;
+ auto iNode = std::distance(mNodes.data(), nodePtr);
+
+ DEBUG_ONLY(auto dumpNode = [](NodeDefinition const& n) {
+ std::ostringstream stream;
+ stream << n.mName << " (" << n.mParentIdx << "):";
+ for (auto i : n.mChildren)
+ {
+ stream << i << ", ";
+ }
+ LOGD(("%s", stream.str().c_str()));
+ };)
+
+ // Remove node from children of previous parent (if any).
+ if (node->mParentIdx != INVALID_INDEX)
+ {
+ LOGD(("old parent:"));
+ DEBUG_ONLY(dumpNode(*mNodes[node->mParentIdx]);)
+
+ auto& children = mNodes[node->mParentIdx]->mChildren;
+ children.erase(std::remove(children.begin(), children.end(), iNode), children.end());
+
+ DEBUG_ONLY(dumpNode(*mNodes[node->mParentIdx]);)
+ }
+
+ // Register node to new parent.
+ LOGD(("new parent:"));
+ DEBUG_ONLY(dumpNode(**newParentPtr);)
+ auto& children = (*newParentPtr)->mChildren;
+ if (siblingOrder > children.size())
+ {
+ siblingOrder = children.size();
+ }
+ children.insert(children.begin() + siblingOrder, 1, iNode);
+ DEBUG_ONLY(dumpNode(**newParentPtr);)
+
+ // Update parent index.
+ LOGD(("node:"));
+ DEBUG_ONLY(dumpNode(*node);)
+ auto iParent = std::distance(mNodes.data(), newParentPtr);
+ node->mParentIdx = iParent;
+ DEBUG_ONLY(dumpNode(*node);)
+ return true;
+}
+
+bool SceneDefinition::RemoveNode(const std::string& name)
+{
+ std::unique_ptr<NodeDefinition>* node = nullptr;
+ if (!FindNode(name, &node))
+ {
+ return false;
+ }
+
+ // Reset node def pointers recursively.
+ auto& thisNodes = mNodes;
+ unsigned int numReset = 0;
+ std::function<void(std::unique_ptr<NodeDefinition>&)> resetFn =
+ [&thisNodes, &resetFn, &numReset](std::unique_ptr<NodeDefinition>& nd) {
+ LOGD(("resetting %d", &nd - thisNodes.data()));
+ for (auto i : nd->mChildren)
+ {
+ resetFn(thisNodes[i]);
+ }
+ nd.reset();
+ ++numReset;
+ };
+
+ resetFn(*node);
+
+ // Gather indices of dead nodes into a vector which we sort on insertion.
+ std::vector<Index> offsets;
+ offsets.reserve(numReset);
+ for (auto& n : mNodes)
+ {
+ if (!n)
+ {
+ offsets.push_back(std::distance(mNodes.data(), &n));
+ }
+ }
+
+ // Erase dead nodes as they don't have to be processed anymore.
+ mNodes.erase(std::remove(mNodes.begin(), mNodes.end(), decltype(mNodes)::value_type()), mNodes.end());
+
+ // Offset all indices (parent and child) by the index they'd sort into in offsets.
+ enum { INDEX_FOR_REMOVAL = INVALID_INDEX };
+ auto offsetter = [&offsets](Index& i) {
+ auto iFind = std::lower_bound(offsets.begin(), offsets.end(), i);
+ if (iFind != offsets.end() && *iFind == i)
+ {
+ LOGD(("marking %d for removal.", i));
+ i = INDEX_FOR_REMOVAL;
+ return false;
+ }
+ else
+ {
+ auto distance = std::distance(offsets.begin(), iFind);
+ if (distance > 0)
+ {
+ LOGD(("offsetting %d by %d.", i, distance));
+ i -= distance;
+ }
+ return true;
+ }
+ };
+
+ for (auto& nd : mNodes)
+ {
+ bool parentOffsetResult = offsetter(nd->mParentIdx);
+ DALI_ASSERT_ALWAYS(parentOffsetResult); // since nodes were recursively removed, we should not be finding invalid parents at this point.
+
+ auto& children = nd->mChildren;
+ for (auto i0 = children.begin(), i1 = children.end(); i0 != i1; ++i0)
+ {
+ offsetter(*i0);
+ }
+
+ children.erase(std::remove(children.begin(), children.end(), INDEX_FOR_REMOVAL), children.end());
+ }
+
+ return true;
+}
+
+void SceneDefinition::GetNodeModelStack(Index index, MatrixStack& model) const
+{
+ auto& thisNodes = mNodes;
+ std::function<void(int)> buildStack = [&model, &thisNodes, &buildStack](int i) {
+ auto node = thisNodes[i].get();
+ if (node->mParentIdx != INVALID_INDEX)
+ {
+ buildStack(node->mParentIdx);
+ }
+ model.Push(node->GetLocalSpace());
+ };
+ buildStack(index);
+}
+
+NodeDefinition* SceneDefinition::FindNode(const std::string &name, Index* outIndex)
+{
+ auto iBegin = mNodes.begin();
+ auto iEnd = mNodes.end();
+ auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr<NodeDefinition>& nd) {
+ return nd->mName == name;
+ });
+
+ auto result = iFind != iEnd ? iFind->get() : nullptr;
+ if (result && outIndex)
+ {
+ *outIndex = std::distance(iBegin, iFind);
+ }
+ return result;
+}
+
+const NodeDefinition* SceneDefinition::FindNode(const std::string &name, Index* outIndex) const
+{
+ auto iBegin = mNodes.begin();
+ auto iEnd = mNodes.end();
+ auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr<NodeDefinition>& nd) {
+ return nd->mName == name;
+ });
+
+ auto result = iFind != iEnd ? iFind->get() : nullptr;
+ if (result && outIndex)
+ {
+ *outIndex = std::distance(iBegin, iFind);
+ }
+ return result;
+}
+
+Index SceneDefinition::FindNodeIndex(const NodeDefinition& node) const
+{
+ auto iBegin = mNodes.begin();
+ auto iEnd = mNodes.end();
+ auto iFind = std::find_if(iBegin, iEnd, [&node](const std::unique_ptr<NodeDefinition>& n) {
+ return n.get() == &node;
+ });
+ return iFind != iEnd ? std::distance(iBegin, iFind) : INVALID_INDEX;
+}
+
+void SceneDefinition::FindNodes(NodePredicate predicate, NodeConsumer consumer,
+ unsigned int limit)
+{
+ unsigned int n = 0;
+ for (auto& defp : mNodes)
+ {
+ if (predicate(*defp))
+ {
+ consumer(*defp);
+ ++n;
+ if (n == limit)
+ {
+ break;
+ }
+ }
+ }
+}
+
+void SceneDefinition::FindNodes(NodePredicate predicate, ConstNodeConsumer consumer,
+ unsigned int limit) const
+{
+ unsigned int n = 0;
+ for (auto& defp : mNodes)
+ {
+ if (predicate(*defp))
+ {
+ consumer(*defp);
+ ++n;
+ if (n == limit)
+ {
+ break;
+ }
+ }
+ }
+}
+
+void SceneDefinition::ApplyConstraints(Actor& root,
+ std::vector<ConstraintRequest>&& constrainables, StringCallback onError) const
+{
+ for (auto& cr : constrainables)
+ {
+ auto& nodeDef = mNodes[cr.mConstraint->mSourceIdx];
+ auto sourceName = nodeDef->mName.c_str();
+ Property::Index iTarget = cr.mTarget.GetPropertyIndex(cr.mConstraint->mProperty);
+ if (iTarget != Property::INVALID_INDEX)
+ {
+ auto propertyType = cr.mTarget.GetPropertyType(iTarget);
+ auto iFind = sConstraintFactory.find(propertyType);
+ if (iFind == sConstraintFactory.end())
+ {
+ onError(FormatString("node '%s': Property '%s' has unsupported type '%s'; ignored.",
+ sourceName, cr.mConstraint->mProperty.c_str(), PropertyTypes::GetName(propertyType)));
+ continue;
+ }
+
+ Constraint constraint = iFind->second(cr.mTarget, iTarget);
+
+ Actor source = root.FindChildByName(nodeDef->mName);
+ if (!source)
+ {
+ auto targetName = cr.mTarget.GetProperty(Actor::Property::NAME).Get<std::string>();
+ onError(FormatString("node '%s': Failed to locate constraint source %s@%s; ignored.",
+ sourceName, cr.mConstraint->mProperty.c_str(), targetName.c_str()));
+ continue;
+ }
+ else if (source == cr.mTarget)
+ {
+ onError(FormatString("node '%s': Cyclic constraint definition for property '%s'; ignored.",
+ sourceName, cr.mConstraint->mProperty.c_str()));
+ continue;
+ }
+
+ Property::Index iSource = source.GetPropertyIndex(cr.mConstraint->mProperty);
+ constraint.AddSource(Source{ source, iSource });
+ constraint.Apply();
+ }
+ else
+ {
+ auto targetName = cr.mTarget.GetProperty(Actor::Property::NAME).Get<std::string>();
+ onError(FormatString("node '%s': Failed to create constraint for property %s@%s; ignored.",
+ sourceName, cr.mConstraint->mProperty.c_str(), targetName.c_str()));
+ }
+ }
+}
+
+void SceneDefinition::ConfigureSkeletonJoints(uint32_t iRoot, const SkeletonDefinition::Vector& skeletons, Actor root) const
+{
+ // 1, For each skeleton, for each joint, walk upwards until we reach mNodes[iRoot]. If we do, record +1
+ // to the refcount of each node we have visited, in our temporary registry. Those with refcount 1
+ // are the leaves, while the most descendant node with the highest refcount is the root of the skeleton.
+ std::map<Index, std::vector<Index>> rootsJoints;
+ std::vector<Index> path;
+ path.reserve(16);
+ for (auto& s : skeletons)
+ {
+ std::map<uint32_t, uint32_t> jointRefs;
+ for (auto& j : s.mJoints)
+ {
+ auto nodeIdx = j.mNodeIdx;
+ do // Traverse upwards and record each node we have visited until we reach the scene root.
+ {
+ path.push_back(nodeIdx);
+ if (nodeIdx == iRoot)
+ {
+ break;
+ }
+ auto node = GetNode(nodeIdx);
+ nodeIdx = node->mParentIdx;
+ }
+ while (nodeIdx != INVALID_INDEX);
+
+ if (nodeIdx == iRoot) // If the joint is in the correct scene, increment the reference count for all visited nodes.
+ {
+ for (auto i : path)
+ {
+ ++jointRefs[i];
+ }
+ }
+
+ path.clear();
+ }
+
+ // Only record the skeleton if we have encountered the root of the current scene.
+ if (jointRefs.empty())
+ {
+ continue;
+ }
+
+ Index root = s.mRootNodeIdx;
+ uint32_t maxRef = 0;
+ auto iFind = jointRefs.find(root);
+ if (iFind != jointRefs.end())
+ {
+ maxRef = iFind->second;
+ }
+
+ std::vector<Index> joints;
+ for (auto& j : jointRefs) // NOTE: jointRefs are sorted, so joints will also be.
+ {
+ // The most descendant node with the highest ref count is the root of the skeleton.
+ if (j.second > maxRef || (j.second == maxRef && IsAncestor(*this, root, j.first, iRoot)))
+ {
+ maxRef = j.second;
+
+ RemoveFromSorted(joints, root);
+ root = j.first;
+ }
+ else if (j.second == 1) // This one's a leaf.
+ {
+ InsertUniqueSorted(joints, j.first);
+ }
+ }
+
+ // Merge skeletons that share the same root.
+ auto& finalJoints = rootsJoints[root];
+ for (auto j : joints)
+ {
+ if (std::find_if(finalJoints.begin(), finalJoints.end(), [this, j, root](Index jj) {
+ return IsAncestor(*this, j, jj, root);
+ }) != finalJoints.end())
+ {
+ continue; // if the joint is found to be an ancestor of another joint already registered, move on.
+ }
+
+ auto i = j;
+ while (i != root) // See if the current joint is a better leaf, i.e. descended from another leaf - which we'll then remove.
+ {
+ auto node = GetNode(i);
+ i = node->mParentIdx;
+
+ RemoveFromSorted(finalJoints, i);
+ }
+
+ InsertUniqueSorted(finalJoints, j);
+ }
+ }
+
+ // 2, Merge records where one root joint is descendant of another. Handle leaf node changes - remove previous
+ // leaf nodes that now have descendants, and add new ones.
+ auto iRoots = rootsJoints.begin();
+ auto iRootsEnd = rootsJoints.end();
+ while (iRoots != iRootsEnd)
+ {
+ auto i = iRoots->first;
+ bool merged = false;
+ while (i != iRoot) // Starting with the root joint of the skeleton, traverse upwards.
+ {
+ auto node = GetNode(i);
+ i = node->mParentIdx;
+
+ auto iFind = rootsJoints.find(i);
+ if (iFind != rootsJoints.end()) // Check if we've reached the root of another skeleton.
+ {
+ // Now find out which leaf of iFind is an ancestor, if any.
+ auto iFindLeaf = std::find_if(iFind->second.begin(), iFind->second.end(), [this, iRoots, iFind](Index j) {
+ return IsAncestor(*this, j, iRoots->first, iFind->first);
+ });
+ if (iFindLeaf != iFind->second.end())
+ {
+ iFind->second.erase(iFindLeaf); // Will no longer be a leaf -- remove it.
+ }
+
+ // Merge iRoots with iFind
+ auto& targetJoints = iFind->second;
+ if (iRoots->second.empty()) // The root is a leaf.
+ {
+ InsertUniqueSorted(targetJoints, iRoots->first);
+ }
+ else for (auto j : iRoots->second)
+ {
+ InsertUniqueSorted(targetJoints, j);
+ }
+
+ merged = true;
+ break; // Traverse no more
+ }
+ }
+
+ iRoots = merged ? rootsJoints.erase(iRoots) : std::next(iRoots);
+ }
+
+ // 3, For each root, register joint matrices and constraints
+ for (auto r : rootsJoints)
+ {
+ auto node = GetNode(r.first);
+ auto rootJoint = root.FindChildByName(node->mName);
+ DALI_ASSERT_ALWAYS(!!rootJoint);
+
+ DALI_ASSERT_DEBUG(rootJoint.GetPropertyIndex(JOINT_MATRIX) == Property::INVALID_INDEX);
+ auto propJointMatrix = rootJoint.RegisterProperty(JOINT_MATRIX, Matrix{ false });
+ Constraint constraint = Constraint::New<Matrix>(rootJoint, propJointMatrix,
+ [](Matrix& output, const PropertyInputContainer& inputs)
+ {
+ output.SetTransformComponents(Vector3::ONE, inputs[0]->GetQuaternion(), inputs[1]->GetVector3());
+ });
+ constraint.AddSource(Source(rootJoint, Actor::Property::ORIENTATION));
+ constraint.AddSource(Source(rootJoint, Actor::Property::POSITION));
+ constraint.Apply();
+
+ for (auto j : r.second)
+ {
+ node = GetNode(j);
+ auto joint = rootJoint.FindChildByName(node->mName);
+ ConfigureJointMatrix(joint, rootJoint, propJointMatrix);
+ }
+ }
+}
+
+void SceneDefinition::EnsureUniqueSkinningShaderInstances(ResourceBundle& resources) const
+{
+ std::map<Index, std::map<Index, std::vector<Index*>>> skinningShaderUsers;
+ for (auto& node : mNodes)
+ {
+ if (node->mRenderable)
+ {
+ ResourceReflector reflector;
+ node->mRenderable->ReflectResources(reflector);
+
+ if (reflector.iMesh)
+ {
+ const auto& mesh = resources.mMeshes[*reflector.iMesh].first;
+ if (mesh.IsSkinned())
+ {
+ skinningShaderUsers[*reflector.iShader][mesh.mSkeletonIdx].push_back(reflector.iShader);
+ }
+ }
+ }
+ }
+
+ // For each shader, and each skeleton using the same shader as the first skeleton,
+ // update the shader references (from nodes with skinned meshes) with a new copy of
+ // the shader definition from the node using the first skeleton.
+ for (auto& users : skinningShaderUsers)
+ {
+ auto& skeletons = users.second;
+ auto iterSkeleton = skeletons.begin();
+ // skipping the first skeleton.
+ ++iterSkeleton;
+
+ resources.mShaders.reserve(resources.mShaders.size() + std::distance(iterSkeleton, skeletons.end()));
+ const ShaderDefinition& shaderDef = resources.mShaders[users.first].first;
+
+ while (iterSkeleton != skeletons.end())
+ {
+ Index iShader = resources.mShaders.size();
+ resources.mShaders.push_back({ shaderDef, Shader() });
+
+ for (auto& i : iterSkeleton->second)
+ {
+ *i = iShader;
+ }
+ ++iterSkeleton;
+ }
+ }
+}
+
+void SceneDefinition::ConfigureSkinningShaders(const ResourceBundle& resources,
+ Actor rootActor, std::vector<SkinningShaderConfigurationRequest>&& requests) const
+{
+ if (requests.empty())
+ {
+ return;
+ }
+
+ SortAndDeduplicateSkinningRequests(requests);
+
+ for (auto& i : requests)
+ {
+ auto& skeleton = resources.mSkeletons[i.mSkeletonIdx];
+ if (skeleton.mJoints.empty())
+ {
+ LOGD(("Skeleton %d has no joints.", i.mSkeletonIdx));
+ continue;
+ }
+
+ Index boneIdx = 0;
+ for (auto& j : skeleton.mJoints)
+ {
+ auto node = GetNode(j.mNodeIdx);
+ Actor actor = rootActor.FindChildByName(node->mName);
+ ConfigureBoneMatrix(j.mInverseBindMatrix, actor, i.mShader, boneIdx);
+ }
+ }
+}
+
+bool SceneDefinition::ConfigureBlendshapeShaders(const ResourceBundle& resources,
+ Actor rootActor, std::vector<BlendshapeShaderConfigurationRequest>&& requests,
+ StringCallback onError ) const
+{
+ if (requests.empty())
+ {
+ return true;
+ }
+
+ // Sort requests by shaders.
+ std::sort(requests.begin(), requests.end());
+
+ // Remove duplicates.
+ auto i = requests.begin();
+ auto iEnd = requests.end();
+ Shader s = i->mShader;
+ ++i;
+ do
+ {
+ // Multiple identical shader instances are removed.
+ while (i != iEnd && i->mShader == s)
+ {
+ i->mShader = Shader();
+ ++i;
+ }
+
+ if (i == iEnd)
+ {
+ break;
+ }
+ s = i->mShader;
+ ++i;
+ } while (true);
+
+ requests.erase(std::remove_if(requests.begin(), requests.end(), [](const BlendshapeShaderConfigurationRequest& bscr)
+ {
+ return !bscr.mShader;
+ }), requests.end());
+
+ // Configure the rest.
+ bool ok = true;
+
+ for (auto& i : requests)
+ {
+ Index iNode;
+ if (FindNode(i.mNodeName, &iNode))
+ {
+ const auto& node = GetNode(iNode);
+
+ const auto& mesh = resources.mMeshes[i.mMeshIdx];
+
+ if (mesh.first.HasBlendShapes())
+ {
+ Actor actor = rootActor.FindChildByName(node->mName);
+
+ // Sets the property to be animated.
+ BlendShapes::ConfigureProperties(mesh, i.mShader, actor);
+ }
+ }
+ }
+
+ return ok;
+}
+
+void SceneDefinition::EnsureUniqueBlendShapeShaderInstances(ResourceBundle& resources) const
+{
+ std::map<Index, std::map<std::string, std::vector<Index*>>> blendShapeShaderUsers;
+ for (auto& node : mNodes)
+ {
+ if (node->mRenderable)
+ {
+ ResourceReflector reflector;
+ node->mRenderable->ReflectResources(reflector);
+
+ if (reflector.iMesh)
+ {
+ const auto& mesh = resources.mMeshes[*reflector.iMesh].first;
+ if (mesh.HasBlendShapes())
+ {
+ blendShapeShaderUsers[*reflector.iShader][node->mName].push_back(reflector.iShader);
+ }
+ }
+ }
+ }
+
+ for (auto& users : blendShapeShaderUsers)
+ {
+ resources.mShaders.reserve(resources.mShaders.size() + users.second.size() - 1u);
+ const ShaderDefinition& shaderDef = resources.mShaders[users.first].first;
+
+ auto nodesIt = users.second.begin();
+ auto nodesEndIt = users.second.end();
+ // skipping the first node.
+ ++nodesIt;
+ while(nodesIt != nodesEndIt)
+ {
+ Index iShader = resources.mShaders.size();
+ resources.mShaders.push_back({ shaderDef, Shader() });
+
+ auto& nodes = *nodesIt;
+ for (auto& shader : nodes.second)
+ {
+ *shader = iShader;
+ }
+ ++nodesIt;
+ }
+ }
+}
+
+SceneDefinition& SceneDefinition::operator=(SceneDefinition&& other)
+{
+ SceneDefinition temp(std::move(other));
+ std::swap(mNodes, temp.mNodes);
+ std::swap(mRootNodeIds, temp.mRootNodeIds);
+ return *this;
+}
+
+bool SceneDefinition::FindNode(const std::string& name, std::unique_ptr<NodeDefinition>** result)
+{
+ // We're searching from the end assuming a higher probability of operations targeting
+ // recently added nodes. (conf.: root, which is immovable, cannot be removed, and was
+ // the first to be added, is index 0.)
+ auto iFind = std::find_if(mNodes.rbegin(), mNodes.rend(),
+ [&name](const std::unique_ptr<NodeDefinition>& nd) {
+ return nd->mName == name;
+ }).base();
+
+ const bool success = iFind != mNodes.begin();
+ if (success && result)
+ {
+ --iFind;
+ *result = &*iFind;
+ }
+
+ return success;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_SCENE_DEFINITION_H_
+#define DALI_SCENE_LOADER_SCENE_DEFINITION_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/customization.h"
+#include "dali-scene-loader/public-api/utils.h"
+#include "dali-scene-loader/public-api/node-definition.h"
+#include "dali-scene-loader/public-api/string-callback.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/quaternion.h"
+#include "dali/public-api/math/matrix.h"
+#include "dali/public-api/math/vector4.h"
+#include "dali/public-api/actors/actor.h"
+#include <string>
+#include <memory>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+class MatrixStack;
+
+/*
+ * @brief Intermediate representation of a scene with functionality required to
+ * create DALi objects (Actors, Renderers) from it.
+ */
+class DALI_SCENE_LOADER_API SceneDefinition
+{
+public: // TYPES
+ using NodePredicate = std::function<bool(const NodeDefinition&)>;
+ using NodeConsumer = std::function<void(NodeDefinition&)>;
+ using ConstNodeConsumer = std::function<void(const NodeDefinition&)>;
+
+public: // METHODS
+ SceneDefinition();
+ SceneDefinition(SceneDefinition&& other);
+ ~SceneDefinition();
+
+ /*
+ * @brief Registers a scene root node.
+ * @return The index of the scene root node *registration*.
+ */
+ Index AddRootNode(Index iNode);
+
+ /*
+ * @return the list of scene root node IDs in the order of their loading.
+ */
+ const std::vector<Index>& GetRoots() const;
+
+ /*
+ * @brief Removes scene root registration at the given index @a iRoot.
+ * @note @a iRoot is the index of the registration (i.e. into the vector returned by GetRoots()),
+ * not of the node.
+ */
+ void RemoveRootNode(Index iRoot);
+
+ /*
+ * @return The number of node( definition)s in the scene.
+ */
+ uint32_t GetNodeCount() const;
+
+ /*
+ * @return Const pointer to the node (definition) at the given index.
+ */
+ const NodeDefinition* GetNode(Index iNode) const;
+
+ /*
+ * @return Pointer to the node (definition) at the given index.
+ */
+ NodeDefinition* GetNode(Index iNode);
+
+ /*
+ * @brief Traverses the scene starting from the node at the given index into
+ * nodes, using the given customization @a choices and the visitor @a v.
+ */
+ void Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IVisitor& v);
+
+ /*
+ * @brief Traverses the scene starting from the node at the given index into
+ * nodes, using the given customization @a choices and the visitor @a v.
+ */
+ void Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IConstVisitor& v) const;
+
+ /*
+ * @brief Counts the references to meshes, shaders, materials that nodes in
+ * the scene are holding, writing the results into @a refCounts.
+ * @note @a refCounts' entries must have the correct size. Use ResourceBundle::GetRefCounter().
+ */
+ void CountResourceRefs(Index iNode, const Customization::Choices& choices, ResourceRefCounts& refCounts) const;
+
+ /*
+ * @brief Given a bundle of @a resources that are loaded, and customization
+ * @a choices, this method traverses the scene, creating the actors and renderers
+ * from node definitions.
+ * @return Handle to the root actor.
+ */
+ Actor CreateNodes(Index iNode, const Customization::Choices& choices,
+ NodeDefinition::CreateParams& params) const;
+
+ /*
+ * @brief Creates / update a registry of mappings from customization tags to
+ * a lists of names of customizable nodes under each tag, and the number of
+ * options. If @a outMissingChoices was specified, each tag that it encounters
+ * in the scene but not in @a choices, will be registered on it with the default
+ * choice of 0.
+ */
+ void GetCustomizationOptions(const Customization::Choices& choices,
+ Customization::Map& outCustomizationOptions,
+ Customization::Choices* outMissingChoices) const;
+
+ /*
+ * @brief Attempts to add @a nodeDef to the end of nodes, and its index to the end of
+ * its parent's list of children (if iParent != NodeDefinition::INVALID_PARENT).
+ * @return If the operation was successful - which requires nodeDef->name to be unique -
+ * a pointer to the stored node definition; nullptr otherwise.
+ */
+ NodeDefinition* AddNode(std::unique_ptr<NodeDefinition>&& nodeDef);
+
+ /*
+ * @brief Moves the node to some other parent and / or to a different index.
+ * @return Whether the operation was successful.
+ * @note This is currently breaking an assumption of never having a child of a node at a lower
+ * index as that of the node itself, due to the fact that we're only changing parent ids (and
+ * entries into the vector of children of node definitions), to save the complication of having
+ * to move about, and offset indices to, everything past the reparented node. This should be
+ * sufficient AT LEAST AS LONG AS we recreate the SceneDefinition when loading the scene; if
+ * we ever needed to serialize it, we should ensure correct ordering of nodes.
+ */
+ bool ReparentNode(const std::string& name, const std::string& newParentName, Index siblingOrder);
+
+ /*
+ * @brief Removes a node with the given name, including all of its children, and updating
+ * the indices on all remaining node definitions.
+ * @return Whether the operation was successful.
+ */
+ bool RemoveNode(const std::string& name);
+
+ /*
+ * @brief Builds the model matrix stack for the node at the given @a index.
+ * @note It only pushes new matrices; does not require the stack to be empty (or cares if it was not).
+ */
+ void GetNodeModelStack(Index index, MatrixStack& model) const;
+
+ /*
+ * @brief Attempts to find the definition of a node with the given @a name. Only upon
+ * success, and if @a outIndex is non-null, the index of the node is written to it.
+ * @return Pointer to the node definition; nullptr if not found.
+ * @note No ownership transfer.
+ */
+ NodeDefinition* FindNode(const std::string& name, Index* outIndex = nullptr);
+
+ /*
+ * @brief Attempts to find the definition of a node with the given @a name. Only upon
+ * success, and if @a outIndex is non-null, the index of the node is written to it.
+ * @return Pointer to the node definition; nullptr if not found.
+ * @note No ownership transfer.
+ */
+ const NodeDefinition* FindNode(const std::string& name, Index* outIndex = nullptr) const;
+
+ /*
+ * @return The index of the given NodeDefinition@ a node, or -1 if the node definition
+ * was not found.
+ */
+ Index FindNodeIndex(const NodeDefinition& node) const;
+
+ /*
+ * @brief Calls @a consumer with up to @a limit NodeDefinitions that evaluate to true
+ * with @a predicate.
+ * @note A @a limit value of 0 means no limit.
+ */
+ void FindNodes(NodePredicate predicate, NodeConsumer consumer, unsigned int limit = 0);
+
+ /*
+ * @brief Calls @a consumer with up to @a limit NodeDefinitions that evaluate to true
+ * with @a predicate.
+ * @note A @a limit value of 0 means no limit.
+ */
+ void FindNodes(NodePredicate predicate, ConstNodeConsumer consumer, unsigned int limit = 0) const;
+
+ /*
+ * @brief Applies constraints from the given requests.
+ */
+ void ApplyConstraints(Actor& root,
+ std::vector<ConstraintRequest>&& constrainables,
+ StringCallback onError = DefaultErrorCallback) const;
+
+ /*
+ * @brief Sets up joint matrix properties and constraints on actors that are involved in skeletal
+ * animation (i.e. those that are between (inclusive) the lower and upper bounds of any skeleton),
+ * to ensure the correct update of meshes skinned to these skeletons.
+ * @param iRoot The index of the scene root node. Skeletons that aren't descendants of this node
+ * will be ignored.
+ * @param skeletons The list of skeletons that require setting up.
+ * @param rootActor The Actor corresponding to the root node, which will be used to locate
+ * other actors.
+ */
+ void ConfigureSkeletonJoints(uint32_t iRoot, const SkeletonDefinition::Vector& skeletons, Actor rootActor) const;
+
+ /*
+ * @brief Ensures that there is no overlap between shaders used by nodes that have
+ * meshes skinned to different skeletons.
+ */
+ void EnsureUniqueSkinningShaderInstances(ResourceBundle& resources) const;
+
+ /*
+ * @brief Performs the configuration of the given skinning shaders with the given skeleton
+ * This means that the absolute transforms of the joints are calculated and set as one of
+ * the uniforms in the mat4 @b uBone array (in depth first traversal). Further, the following
+ * are created:<br />
+ * - a @b jointMatrix property on each joint Actor;<br />
+ * - constraint from the Actor's local position and rotation (and if it has a @e joint
+ * parent, the jointMatrix of the parent) to its @b jointMatrix property;<br />
+ * - a constraint from the the Actor's @b jointMatrix property to the related entry in
+ * the shader's @b uBone property;<br />
+ * This ensures the automatic update of the skeletal animation, should any of the joints'
+ * transform changes, by whatever means.
+ * @return The success of the operations. Error messages will be posted to the optional
+ * @a onError callback.
+ * @note A maximum of SkinningDetails::MAX_JOINTS joints per skeleton are supported at the moment.
+ * @note Even if multiple skinned meshes use the same skinning shader, the correct number
+ * of separate instances need to be declared in the .dli to avoid clashing uniform
+ * definitions and constraints.
+ */
+ void ConfigureSkinningShaders(const ResourceBundle& resources,
+ Actor root, std::vector<SkinningShaderConfigurationRequest>&& requests) const;
+
+ /*
+ * @brief Ensures there is no two meshes with blend shapes sharing the same shader.
+ */
+ void EnsureUniqueBlendShapeShaderInstances(ResourceBundle& resources) const;
+
+ /**
+ * @brief Performs the configuration of the given blend shapes.
+ *
+ * For each node with blend shapes it registers into the actor the weights properties for each morph target
+ * and some needed uniforms into the shader.
+ *
+ * @param[in] root The root actor.
+ * @param[in] requests The requests to configure blend shapes.
+ * @param[in] resources The resources bundle. Meshes need to be accessed to configure the blend shapes.
+ * @param[in] onError The error callback.
+ */
+ bool ConfigureBlendshapeShaders(const ResourceBundle& resources,
+ Actor root, std::vector<BlendshapeShaderConfigurationRequest>&& requests,
+ StringCallback onError = DefaultErrorCallback) const;
+
+ SceneDefinition& operator=(SceneDefinition&& other);
+
+private: // METHODS
+ bool FindNode(const std::string& name, std::unique_ptr<NodeDefinition>** result);
+
+private: // DATA
+ std::vector<std::unique_ptr<NodeDefinition>> mNodes; // size unknown up front (may discard nodes).
+ std::vector<Index> mRootNodeIds;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_SCENE_DEFINITION_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/internal/hash.h"
+#include "dali-scene-loader/public-api/shader-definition-factory.h"
+#include "dali-scene-loader/public-api/node-definition.h"
+#include "dali-scene-loader/public-api/blend-shape-details.h"
+#include "dali/devel-api/common/map-wrapper.h"
+#include <cstring>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+struct ResourceReceiver : IResourceReceiver
+{
+ const ResourceBundle& mResources;
+ const MeshDefinition* mMeshDef = nullptr;
+ const MaterialDefinition* mMaterialDef = nullptr;
+
+ ResourceReceiver(const ResourceBundle& resources)
+ : mResources(resources)
+ {}
+
+ void Register(ResourceType::Value type, Index id) override
+ {
+ switch (type)
+ {
+ case ResourceType::Mesh:
+ mMeshDef = &mResources.mMeshes[id].first;
+ break;
+
+ case ResourceType::Material:
+ mMaterialDef = &mResources.mMaterials[id].first;
+ break;
+
+ default:
+ break;
+ }
+ }
+};
+
+const std::string PBR_SHADER_NAME = "dli_pbr";
+
+void RetrieveBlendShapeComponents(const std::vector<MeshDefinition::BlendShape>& blendShapes, bool& hasPositions, bool& hasNormals, bool& hasTangents)
+{
+ for (const auto& blendShape : blendShapes)
+ {
+ hasPositions = hasPositions || blendShape.deltas.IsDefined();
+ hasNormals = hasNormals || blendShape.normals.IsDefined();
+ hasTangents = hasTangents || blendShape.tangents.IsDefined();
+ }
+}
+
+uint64_t HashNode(const NodeDefinition& nodeDef, const MaterialDefinition& materialDef, const MeshDefinition& meshDef)
+{
+ Hash hash;
+
+ // note: could be per vertex / fragment component - in WatchViewer, these have the same name.
+ hash.Add(PBR_SHADER_NAME);
+
+ const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY);
+ hash.Add(hasTransparency);
+
+ if (hasTransparency ||
+ materialDef.CheckTextures(MaterialDefinition::ALBEDO) ||
+ materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS) ||
+ materialDef.CheckTextures(MaterialDefinition::NORMAL))
+ {
+ hash.Add("3TEX");
+ }
+
+ if (materialDef.GetAlphaCutoff() > 0.f)
+ {
+ hash.Add("ALPH"/*A_TEST*/);
+ }
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::SUBSURFACE))
+ {
+ hash.Add("SSS");
+ }
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS))
+ {
+ hash.Add("GLTF"/*_CHANNELS*/);
+ }
+
+ if (meshDef.IsSkinned())
+ {
+ hash.Add("SKIN"/*NING*/);
+ }
+
+ if (MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL))
+ {
+ hash.Add("FLIP"/*_V*/);
+ }
+
+ if (meshDef.HasBlendShapes())
+ {
+ bool hasPositions = false;
+ bool hasNormals = false;
+ bool hasTangents = false;
+ RetrieveBlendShapeComponents(meshDef.mBlendShapes, hasPositions, hasNormals, hasTangents);
+ if (hasPositions)
+ {
+ hash.Add("MORPHPOS");
+ }
+
+ if (hasNormals)
+ {
+ hash.Add("MORPHNOR");
+ }
+
+ if (hasTangents)
+ {
+ hash.Add("MORPHTAN");
+ }
+
+ if (hasPositions || hasNormals || hasTangents)
+ {
+ hash.Add("MORPH");
+
+ if (BlendShapes::Version::VERSION_2_0 == meshDef.mBlendShapeVersion)
+ {
+ hash.Add("MORPHV2");
+ }
+ }
+ }
+
+ return hash;
+}
+}
+
+struct ShaderDefinitionFactory::Impl
+{
+ ResourceBundle* mResources; // no ownership
+ std::map<uint64_t, Index> mShaderMap;
+};
+
+ShaderDefinitionFactory::ShaderDefinitionFactory()
+: mImpl{ new Impl() }
+{}
+
+ShaderDefinitionFactory::~ShaderDefinitionFactory() = default;
+
+void ShaderDefinitionFactory::SetResources(ResourceBundle& resources)
+{
+ mImpl->mResources = &resources;
+ mImpl->mShaderMap.clear();
+}
+
+Index ShaderDefinitionFactory::ProduceShader(const NodeDefinition& nodeDef)
+{
+ DALI_ASSERT_DEBUG(nodeDef.mRenderable);
+
+ auto& resources = *mImpl->mResources;
+ ResourceReceiver receiver{ resources };
+ nodeDef.mRenderable->RegisterResources(receiver);
+ if (!(receiver.mMeshDef && receiver.mMaterialDef))
+ {
+ return INVALID_INDEX;
+ }
+
+ auto& shaderMap = mImpl->mShaderMap;
+ uint64_t hash = HashNode(nodeDef, *receiver.mMaterialDef, *receiver.mMeshDef);
+ auto iFind = shaderMap.find(hash);
+ if (iFind != shaderMap.end())
+ {
+ return iFind->second;
+ }
+
+ ShaderDefinition shaderDef;
+ shaderDef.mVertexShaderPath = PBR_SHADER_NAME + ".vsh";
+ shaderDef.mFragmentShaderPath = PBR_SHADER_NAME + ".fsh";
+ shaderDef.mRendererState = RendererState::DEPTH_TEST | RendererState::DEPTH_WRITE | RendererState::CULL_BACK;
+
+ auto& materialDef = *receiver.mMaterialDef;
+ const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY);
+ if (hasTransparency)
+ {
+ // TODO: this requires more granularity
+ shaderDef.mRendererState = (shaderDef.mRendererState | RendererState::ALPHA_BLEND) & ~RendererState::DEPTH_WRITE;
+ }
+
+ if (hasTransparency ||
+ materialDef.CheckTextures(MaterialDefinition::ALBEDO) ||
+ materialDef.CheckTextures(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS) ||
+ materialDef.CheckTextures(MaterialDefinition::NORMAL))
+ {
+ shaderDef.mDefines.push_back("THREE_TEX");
+ }
+
+ if (materialDef.GetAlphaCutoff() > 0.f)
+ {
+ shaderDef.mDefines.push_back("ALPHA_TEST");
+ }
+
+ if (MaskMatch(materialDef.mFlags, MaterialDefinition::SUBSURFACE))
+ {
+ shaderDef.mDefines.push_back("SSS");
+ }
+
+ if (MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::GLTF_CHANNELS))
+ {
+ shaderDef.mDefines.push_back("GLTF_CHANNELS");
+ }
+
+ const auto& meshDef = *receiver.mMeshDef;
+ if (meshDef.IsSkinned())
+ {
+ shaderDef.mDefines.push_back("SKINNING");
+ }
+
+ if (MaskMatch(meshDef.mFlags, MeshDefinition::FLIP_UVS_VERTICAL))
+ {
+ shaderDef.mDefines.push_back("FLIP_V");
+ }
+
+ if (meshDef.HasBlendShapes())
+ {
+ bool hasPositions = false;
+ bool hasNormals = false;
+ bool hasTangents = false;
+ RetrieveBlendShapeComponents(meshDef.mBlendShapes, hasPositions, hasNormals, hasTangents);
+
+ if (hasPositions)
+ {
+ shaderDef.mDefines.push_back("MORPH_POSITION");
+ }
+
+ if (hasNormals)
+ {
+ shaderDef.mDefines.push_back("MORPH_NORMAL");
+ }
+
+ if (hasTangents)
+ {
+ shaderDef.mDefines.push_back("MORPH_TANGENT");
+ }
+
+ if (hasPositions || hasNormals || hasTangents)
+ {
+ shaderDef.mDefines.push_back("MORPH");
+
+ if (BlendShapes::Version::VERSION_2_0 == meshDef.mBlendShapeVersion)
+ {
+ shaderDef.mDefines.push_back("MORPH_VERSION_2_0");
+ }
+ }
+ }
+
+ shaderDef.mUniforms["uMaxLOD"] = 6.f;
+ shaderDef.mUniforms["uCubeMatrix"] = Matrix::IDENTITY;
+
+ Index result = resources.mShaders.size();
+ shaderMap[hash] = result;
+
+ resources.mShaders.emplace_back(std::move(shaderDef), Shader());
+
+ return result;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_SHADER_DEFINITION_FACTORY_H_
+#define DALI_SCENE_LOADER_SHADER_DEFINITION_FACTORY_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/index.h"
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDER
+#include <memory>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+struct NodeDefinition;
+class ResourceBundle;
+
+class DALI_SCENE_LOADER_API ShaderDefinitionFactory
+{
+public:
+ ShaderDefinitionFactory();
+ ~ShaderDefinitionFactory();
+
+ /*
+ * @brief Input for meshes and materials, output for shaders.
+ */
+ void SetResources(ResourceBundle& resources);
+
+ /*
+ * @brief Produces the index of a shader, which should be used to index into the shaders
+ * vector of the ResourceBundle which was provided for the factory. This shader will be
+ * created if one with the given settings hasn't been created by the factory yet (shaders
+ * already existing in the ResourceBundle are ignored), otherwise the index of the previously
+ * created shader will be returned.
+ */
+ Index ProduceShader(const NodeDefinition& nodeDef);
+
+private:
+ struct Impl;
+ const std::unique_ptr<Impl> mImpl;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_SHADER_DEFINITION_FACTORY_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/shader-definition.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+
+const std::string SHADER_HINT_OUTPUT_IS_TRANSPARENT("OUTPUT_IS_TRANSPARENT"); ///< Might generate transparent alpha from opaque inputs.
+const std::string SHADER_HINT_MODIFIES_GEOMETRY("MODIFIES_GEOMETRY"); ///< Might change position of vertices, this option disables any culling optimizations.
+
+}
+
+ShaderDefinition::ShaderDefinition(const ShaderDefinition& other)
+: mRendererState(other.mRendererState),
+ mVertexShaderPath(other.mVertexShaderPath),
+ mFragmentShaderPath(other.mFragmentShaderPath),
+ mDefines(other.mDefines),
+ mHints(other.mHints),
+ mUniforms(other.mUniforms)
+{}
+
+void ShaderDefinition::ApplyDefine(std::string& shaderCode, const std::string& definevar)
+{
+ const std::string IF_1 = "#if 1";
+
+ std::size_t found = shaderCode.find(definevar);
+ while (found != std::string::npos)
+ {
+ // Greater then "@" character means is a letter,
+ // therefore is not has the definevar we looking for.
+ if ((found + definevar.length()) < shaderCode.length() && shaderCode.at(found + definevar.length()) > '@')
+ {
+ found = shaderCode.find(definevar, found + definevar.length());
+ continue;
+ }
+ if (found > 0u && shaderCode.at(found - 1) > '@')
+ {
+ found = shaderCode.find(definevar, found + definevar.length());
+ continue;
+ }
+
+ std::size_t defidx = shaderCode.rfind("#ifdef", found);
+ std::size_t newlineidx = shaderCode.rfind("\n", found);
+ if (newlineidx < defidx && defidx != std::string::npos)
+ {
+ shaderCode.replace(defidx, found - defidx + definevar.length(), IF_1);
+ found = defidx + IF_1.length();
+ }
+ else
+ {
+ found += definevar.length();
+ }
+ found = shaderCode.find(definevar, found);
+ }
+}
+
+ShaderDefinition::RawData
+ ShaderDefinition::LoadRaw(const std::string& shadersPath) const
+{
+ RawData raw;
+
+ bool fail = false;
+ raw.mVertexShaderSource = LoadTextFile((shadersPath + mVertexShaderPath).c_str(), &fail);
+ if (!fail)
+ {
+ raw.mFragmentShaderSource = LoadTextFile((shadersPath + mFragmentShaderPath).c_str(), &fail);
+ if (!fail)
+ {
+ for (auto definevar : mDefines)
+ {
+ ApplyDefine(raw.mVertexShaderSource, definevar);
+ ApplyDefine(raw.mFragmentShaderSource, definevar);
+ }
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" <<
+ shadersPath + mFragmentShaderPath << "'.";
+ }
+ }
+ else
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" <<
+ shadersPath + mVertexShaderPath << "'.";
+ }
+ return raw;
+}
+
+Shader ShaderDefinition::Load(RawData&& raw) const
+{
+ uint32_t hints = Shader::Hint::NONE;
+ for (const auto& hint : mHints)
+ {
+ if (hint == SHADER_HINT_OUTPUT_IS_TRANSPARENT)
+ {
+ hints |= Shader::Hint::OUTPUT_IS_TRANSPARENT;
+ }
+ else if (hint == SHADER_HINT_MODIFIES_GEOMETRY)
+ {
+ hints |= Shader::Hint::MODIFIES_GEOMETRY;
+ }
+ }
+
+ Shader shader = Shader::New(raw.mVertexShaderSource, raw.mFragmentShaderSource,
+ static_cast<Shader::Hint::Value>(hints));
+ for (Property::Map::SizeType i0 = 0, i1 = mUniforms.Count(); i0 != i1; ++i0)
+ {
+ auto pair = mUniforms.GetKeyValue(i0);
+ DALI_ASSERT_ALWAYS(pair.first.type == Property::Key::STRING);
+ shader.RegisterProperty(pair.first.stringKey, pair.second);
+ }
+
+ return shader;
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_SHADER_DEFINITION_H
+#define DALI_SCENE_LOADER_SHADER_DEFINITION_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/renderer-state.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/rendering/shader.h"
+#include <memory>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/*
+ * @brief Defines a shader with paths to the files which define its
+ * vertex and fragment components, and a mapping of uniform names (which are
+ * used to refer to them in GLSL) to data.
+ */
+struct DALI_SCENE_LOADER_API ShaderDefinition
+{
+ using Vector = std::vector<std::pair<ShaderDefinition, Shader>>;
+
+ struct RawData
+ {
+ std::string mVertexShaderSource;
+ std::string mFragmentShaderSource;
+ };
+
+ /*
+ * @brief Apply the defines values to shader.
+ */
+ static void ApplyDefine(std::string& shaderCode, const std::string& definevar);
+
+ ShaderDefinition() = default;
+
+ ShaderDefinition(const ShaderDefinition& other);
+ ShaderDefinition& operator=(const ShaderDefinition& other);
+
+ ShaderDefinition(ShaderDefinition&&) = default;
+ ShaderDefinition& operator=(ShaderDefinition&&) = default;
+
+ /*
+ * @brief Attempts to load the source of the vertex and fragment shaders,
+ * then performs pre-processing of defines.
+ * @note This may be called from any thread.
+ */
+ RawData LoadRaw(const std::string& shadersPath) const;
+
+ /*
+ * @brief Creates a DALi Shader from the sources in @a raw, traverses
+ * uniforms to get them to register their data against their name,
+ * then returns the Shader.
+ * @note This must be called from the event thread.
+ */
+ Shader Load(RawData&& raw) const;
+
+public: // DATA
+ RendererState::Type mRendererState = RendererState::NONE;
+
+ std::string mVertexShaderPath;
+ std::string mFragmentShaderPath;
+ std::vector<std::string> mDefines;
+ std::vector<std::string> mHints;
+
+ Property::Map mUniforms;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_SHADER_DEFINITION_H
--- /dev/null
+#ifndef DALI_SCENE_LOADER_SKELETON_H
+#define DALI_SCENE_LOADER_SKELETON_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/index.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/math/matrix.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/*
+ * @brief A set of joints (stored as node indices), and an optional root node index.
+ * @note The list of joints must not be empty and must not contain INVALID_INDEX.
+ * @note Client code should not change the order of joints, as they are indexed by mesh vertex data.
+ * @note Client code should make no assumption about the relation of the joint IDs.
+ */
+struct DALI_SCENE_LOADER_API SkeletonDefinition
+{
+ struct Joint
+ {
+ Index mNodeIdx;
+ Matrix mInverseBindMatrix;
+ };
+
+ using Vector = std::vector<SkeletonDefinition>;
+
+ Index mRootNodeIdx = INVALID_INDEX;
+ std::vector<Joint> mJoints;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_SKELETON_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/skinning-details.h"
+#include "dali/public-api/rendering/shader.h"
+#include "dali/public-api/object/property.h"
+#include "dali/public-api/animation/constraints.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+const unsigned int Skinning::MAX_JOINTS = 64;
+
+const std::string Skinning::BONE_UNIFORM_NAME = "uBone";
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_SKINNING_DETAILS_H_
+#define DALI_SCENE_LOADER_SKINNING_DETAILS_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/rendering/shader.h"
+#include <string>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+struct DALI_SCENE_LOADER_API Skinning
+{
+ /*
+ * @brief Upper limit on the number of joints supported.
+ */
+ static const uint32_t MAX_JOINTS;
+
+ /*
+ * @brief Name of bone matrix uniform (array).
+ */
+ static const std::string BONE_UNIFORM_NAME;
+};
+
+}
+}
+
+#endif // DALI_SCENE_LOADER_SKINNING_DETAILS_H_
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/string-callback.h"
+#include "dali/integration-api/debug.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+void DefaultErrorCallback(const std::string& message)
+{
+ DALI_LOG_ERROR("%s", message.c_str());
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_STRING_CALLBACK_H
+#define DALI_SCENE_LOADER_STRING_CALLBACK_H
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include <functional>
+#include <string>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/*
+ * @brief A callback to post strings to.
+ */
+using StringCallback = std::function<void(const std::string&)>;
+
+/*
+ * @brief Simply passes the formatted message to LOGE().
+ */
+DALI_SCENE_LOADER_API void DefaultErrorCallback(const std::string& message);
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_STRING_CALLBACK_H
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL
+#include "dali-scene-loader/public-api/utils.h"
+
+// EXTERNAL
+#include "dali/public-api/common/vector-wrapper.h"
+#include "dali/public-api/animation/constraints.h"
+#include <iostream>
+#include <fstream>
+#include <cstring>
+#include <stdarg.h>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+namespace
+{
+thread_local char sExceptionFlingerMessageBuffer[ExceptionFlinger::MESSAGE_BUFFER_SIZE]{};
+}
+
+char* ExceptionFlinger::GetMessageBuffer()
+{
+ return sExceptionFlingerMessageBuffer;
+}
+
+std::string FormatString(const char* format, ...)
+{
+ va_list vl;
+ va_start(vl, format);
+ va_list vl2;
+ va_copy(vl2, vl);
+
+ size_t sizeRequired = vsnprintf(nullptr, 0, format, vl);
+ va_end(vl);
+
+ ++sizeRequired;
+ std::string result(sizeRequired, '\0');
+ vsnprintf(&result[0], sizeRequired, format, vl2);
+ va_end(vl2);
+
+ return result;
+}
+
+std::string LoadTextFile(const char * path, bool* fail)
+{
+ std::ifstream inFile(path);
+ if (inFile)
+ {
+ std::istreambuf_iterator<char> eos;
+ std::istreambuf_iterator<char> i(inFile.rdbuf());
+ return std::string(i, eos);
+ }
+ else if (fail)
+ {
+ *fail = true;
+ }
+ return std::string();
+}
+
+Geometry MakeTexturedQuadGeometry(TexturedQuadOptions::Type options)
+{
+ Property::Map properties;
+ properties.Insert("aPosition", Property::VECTOR3);
+ properties.Insert("aTexCoord", Property::VECTOR2);
+
+ std::vector<uint8_t> bytes;
+ size_t stride = 0;
+ size_t uvOffset = 0;
+ struct
+ {
+ Vector3 aPosition;
+ Vector2 aTexCoord;
+ } vertices[] = {
+ { Vector3(-0.5f, 0.5f, 0.0f), Vector2(0.0f, .0f) },
+ { Vector3(0.5f, 0.5f, 0.0f), Vector2(1.0f, .0f) },
+ { Vector3(-0.5f, -0.5f, 0.0f), Vector2(0.0f, 1.0f) },
+ { Vector3(0.5f, -0.5f, 0.0f), Vector2(1.0f, 1.0f) }
+ };
+
+ bytes.resize(sizeof(vertices));
+ stride = sizeof(vertices[0]);
+ uvOffset = reinterpret_cast<const uint8_t*>(&vertices[0].aTexCoord) - reinterpret_cast<const uint8_t*>(&vertices[0]);
+
+ std::memcpy(bytes.data(), vertices, sizeof(vertices));
+
+ if (MaskMatch(options, TexturedQuadOptions::FLIP_VERTICAL))
+ {
+ Vector2* uv = reinterpret_cast<Vector2*>(reinterpret_cast<uint8_t*>(bytes.data()) + uvOffset);
+ for (int i = 0; i < 4; ++i)
+ {
+ uv->y = 1.0f - uv->y;
+ uv = reinterpret_cast<Vector2*>(reinterpret_cast<uint8_t*>(uv) + stride);
+ }
+ }
+
+ VertexBuffer vertexBuffer = VertexBuffer::New(properties);
+ vertexBuffer.SetData(bytes.data(), bytes.size() / stride);
+
+ Geometry geometry = Geometry::New();
+ geometry.AddVertexBuffer(vertexBuffer);
+ geometry.SetType(Geometry::TRIANGLE_STRIP);
+ return geometry;
+}
+
+void ToUnixFileSeparators(std::string& path)
+{
+ std::replace(path.begin(), path.end(), '\\', '/');
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_UTILS_H_
+#define DALI_SCENE_LOADER_UTILS_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/actors/actor.h"
+#include "dali/public-api/rendering/renderer.h"
+#include "dali/public-api/common/dali-common.h"
+#include <sstream>
+#include <cctype>
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/*
+ * @brief Fixed size backing buffer to use with std::ostreams where control over
+ * allocations (which this does not make), is required.
+ * @note All stream insertions that would overflow the buffer that StreamBuffer
+ * was created with, will fail.
+ */
+class DALI_SCENE_LOADER_API StreamBuffer : public std::basic_streambuf<char>
+{
+public:
+ StreamBuffer(char* buffer, size_t size)
+ {
+ setp(buffer, buffer + size);
+ }
+};
+
+/*
+ * @brief Wraps an ostream with a pre-allocated, fixed size backing buffer
+ * which a message can be formatted into. Upon destruction, it throws a
+ * DaliException with the message.
+ */
+class DALI_SCENE_LOADER_API ExceptionFlinger
+{
+public:
+ enum { MESSAGE_BUFFER_SIZE = 512 };
+
+ ExceptionFlinger(const char* location)
+ : mLocation(location),
+ mStreamBuffer(GetMessageBuffer(), MESSAGE_BUFFER_SIZE - 1),
+ mStream(&mStreamBuffer)
+ {}
+
+ ~ExceptionFlinger() noexcept(false)
+ {
+ operator<<('\0');
+ throw DaliException(mLocation, GetMessageBuffer());
+ }
+
+ template <typename T>
+ ExceptionFlinger& operator<<(const T& rhs)
+ {
+ mStream << rhs;
+ return *this;
+ }
+
+private:
+ static char* GetMessageBuffer();
+
+ const char* mLocation;
+ StreamBuffer mStreamBuffer;
+ std::ostream mStream;
+};
+
+/*
+ * @brief Formats the given printf-style varargs into a std::string.
+ */
+DALI_SCENE_LOADER_API std::string FormatString(const char* format, ...);
+
+/*
+ * @return The @n th bit in a bitmask.
+ */
+DALI_SCENE_LOADER_API constexpr size_t NthBit(size_t n) { return 1 << n; }
+
+/*
+ * @return Whether all of @a mask 's bits are set on @a value.
+ */
+inline
+DALI_SCENE_LOADER_API bool MaskMatch(uint32_t value, uint32_t mask)
+{
+ return (value & mask) == mask;
+}
+
+/*
+ * @brief Convert a four-letter(, null-terminated) string literal into a uint32_t.
+ */
+inline
+DALI_SCENE_LOADER_API constexpr uint32_t FourCC(const char(&fourCC)[5])
+{
+ return (fourCC[3] << 24) | (fourCC[2] << 16) | (fourCC[1] << 8) | fourCC[0];
+}
+
+/*
+ * @brief Insensitive case compare function.
+ * @param[in] a, compare string
+ * @param[in] b, compare string
+ * @return true if strings are equal
+ */
+inline
+DALI_SCENE_LOADER_API bool CaseInsensitiveCharacterCompare( unsigned char a, unsigned char b )
+{
+ // Converts to lower case in the current locale.
+ return std::tolower( a ) == std::tolower( b );
+}
+
+/*
+ * @return true if the lower cased ASCII strings are equal.
+ * @param[in] a, compare string
+ * @param[in] b, compare string
+ */
+inline
+DALI_SCENE_LOADER_API bool CaseInsensitiveStringCompare( const std::string& a, const std::string& b )
+{
+ bool result = false;
+ if( a.length() == b.length() )
+ {
+ result = std::equal( a.begin(), a.end(), b.begin(), &CaseInsensitiveCharacterCompare );
+ }
+ return result;
+}
+
+/*
+ * @brief Attempts to load the contents of a text file; returns empty string on
+ * failure. A pointer to a boolean may be passed in @a fail; this will be set
+ * to true in case of failure (should only be checked if the returned string
+ * was empty()).
+ */
+DALI_SCENE_LOADER_API std::string LoadTextFile(const char* path, bool* fail = nullptr);
+
+/*
+ * @brief Makes a number of calls to @a fn, passing to each one the given
+ * @a actor then each of its children, in depth-first traversal.
+ * @note @a fn must not change the actor hierarchy during traversal.
+ * @note Use of a @a fn that is itself recursing in @a is also discouraged
+ * for performance and stability reasons.
+ */
+template <typename Func>
+inline
+DALI_SCENE_LOADER_API void VisitActor(Actor a, Func fn)
+{
+ fn(a);
+
+ unsigned int numChildren = a.GetChildCount();
+ for(unsigned int i = 0; i < numChildren; ++i)
+ {
+ VisitActor(a.GetChildAt(i), fn);
+ }
+}
+
+/*
+ * @brief Convenience function to set the given actor @a 's anchor point
+ * and parent origin to center.
+ */
+inline
+DALI_SCENE_LOADER_API void SetActorCentered(Actor a)
+{
+ a.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
+ a.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+}
+
+namespace TexturedQuadOptions
+{
+using Type = uint32_t;
+
+enum DALI_SCENE_LOADER_API Values : Type
+{
+ NONE = 0x00,
+ FLIP_VERTICAL = 0x01,
+};
+}
+
+/*
+ * @brief Makes... geometry for a textured quad.
+ */
+DALI_SCENE_LOADER_API Geometry MakeTexturedQuadGeometry(TexturedQuadOptions::Type options = TexturedQuadOptions::NONE);
+
+/*
+ * @brief Fixes the path of a file. Replaces the '\\' separator by the '/' one.
+ * @param[in,out] path The path to be fixed.
+ */
+DALI_SCENE_LOADER_API void ToUnixFileSeparators( std::string& path );
+
+}
+}
+
+#endif /* DALI_SCENE_LOADER_UTILS_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include "dali-scene-loader/public-api/view-projection.h"
+#include "dali-scene-loader/public-api/utils.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+void ViewProjection::Update()
+{
+ Matrix::Multiply(mViewProjection, mView, mProjection);
+
+ mInvProjection = mProjection;
+ if (!mInvProjection.Invert())
+ {
+ ExceptionFlinger(ASSERT_LOCATION) << "Failed to find inverse of projection matrix " << mProjection << ".";
+ }
+}
+
+}
+}
--- /dev/null
+#ifndef DALI_SCENE_LOADER_VIEW_PROJECTION_H_
+#define DALI_SCENE_LOADER_VIEW_PROJECTION_H_
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+// INTERNAL INCLUDES
+#include "dali-scene-loader/public-api/api.h"
+
+// EXTERNAL INCLUDES
+#include "dali/public-api/math/matrix.h"
+
+namespace Dali
+{
+namespace SceneLoader
+{
+
+/**
+ * @brief Contains view and projection matrices, also caching the view-projection
+ * and inverse projection matrices.
+ */
+class ViewProjection
+{
+public:
+ Matrix& GetView() { return mView; }
+ Matrix& GetProjection() { return mProjection; }
+
+ /*
+ * @brief Updates the cached view projection and inverse projection matrices.
+ */
+ void Update();
+
+ const Matrix& GetView() const { return mView; }
+ const Matrix& GetProjection() const { return mProjection; }
+ const Matrix& GetInverseProjection() const { return mInvProjection; }
+ const Matrix& GetViewProjection() const { return mViewProjection; }
+
+private:
+ Matrix mView;
+ Matrix mProjection;
+ Matrix mInvProjection;
+ Matrix mViewProjection;
+};
+
+}
+}
+
+#endif //DALI_SCENE_LOADER_VIEW_PROJECTION_H_
--- /dev/null
+/*
+ The latest version of this library is available on GitHub;
+ https://github.com/sheredom/json.h.
+*/
+
+/*
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ 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 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.
+
+ For more information, please refer to <http://unlicense.org/>.
+*/
+
+#ifndef SHEREDOM_JSON_H_INCLUDED
+#define SHEREDOM_JSON_H_INCLUDED
+
+#if defined(_MSC_VER)
+#pragma warning(push)
+
+/* disable 'bytes padding added after construct' warning */
+#pragma warning(disable : 4820)
+#endif
+
+#include <stddef.h>
+
+#if defined(__clang__) || defined(__GNUC__)
+#define json_weak __attribute__((weak))
+#elif defined(_MSC_VER)
+#define json_weak __inline
+#else
+#error Non clang, non gcc, non MSVC compiler found!
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ struct json_value_s;
+ struct json_parse_result_s;
+
+ enum json_parse_flags_e {
+ json_parse_flags_default = 0,
+
+ /* allow trailing commas in objects and arrays. For example, both [true,] and
+ {"a" : null,} would be allowed with this option on. */
+ json_parse_flags_allow_trailing_comma = 0x1,
+
+ /* allow unquoted keys for objects. For example, {a : null} would be allowed
+ with this option on. */
+ json_parse_flags_allow_unquoted_keys = 0x2,
+
+ /* allow a global unbracketed object. For example, a : null, b : true, c : {}
+ would be allowed with this option on. */
+ json_parse_flags_allow_global_object = 0x4,
+
+ /* allow objects to use '=' instead of ':' between key/value pairs. For
+ example, a = null, b : true would be allowed with this option on. */
+ json_parse_flags_allow_equals_in_object = 0x8,
+
+ /* allow that objects don't have to have comma separators between key/value
+ pairs. */
+ json_parse_flags_allow_no_commas = 0x10,
+
+ /* allow c-style comments (either variants) to be ignored in the input JSON
+ file. */
+ json_parse_flags_allow_c_style_comments = 0x20,
+
+ /* deprecated flag, unused. */
+ json_parse_flags_deprecated = 0x40,
+
+ /* record location information for each value. */
+ json_parse_flags_allow_location_information = 0x80,
+
+ /* allow strings to be 'single quoted'. */
+ json_parse_flags_allow_single_quoted_strings = 0x100,
+
+ /* allow numbers to be hexadecimal. */
+ json_parse_flags_allow_hexadecimal_numbers = 0x200,
+
+ /* allow numbers like +123 to be parsed. */
+ json_parse_flags_allow_leading_plus_sign = 0x400,
+
+ /* allow numbers like .0123 or 123. to be parsed. */
+ json_parse_flags_allow_leading_or_trailing_decimal_point = 0x800,
+
+ /* allow Infinity, -Infinity, NaN, -NaN. */
+ json_parse_flags_allow_inf_and_nan = 0x1000,
+
+ /* allow multi line string values. */
+ json_parse_flags_allow_multi_line_strings = 0x2000,
+
+ /* allow simplified JSON to be parsed. Simplified JSON is an enabling of a set
+ of other parsing options. */
+ json_parse_flags_allow_simplified_json =
+ (json_parse_flags_allow_trailing_comma |
+ json_parse_flags_allow_unquoted_keys |
+ json_parse_flags_allow_global_object |
+ json_parse_flags_allow_equals_in_object |
+ json_parse_flags_allow_no_commas),
+
+ /* allow JSON5 to be parsed. JSON5 is an enabling of a set of other parsing
+ options. */
+ json_parse_flags_allow_json5 =
+ (json_parse_flags_allow_trailing_comma |
+ json_parse_flags_allow_unquoted_keys |
+ json_parse_flags_allow_c_style_comments |
+ json_parse_flags_allow_single_quoted_strings |
+ json_parse_flags_allow_hexadecimal_numbers |
+ json_parse_flags_allow_leading_plus_sign |
+ json_parse_flags_allow_leading_or_trailing_decimal_point |
+ json_parse_flags_allow_inf_and_nan |
+ json_parse_flags_allow_multi_line_strings)
+ };
+
+ /* Parse a JSON text file, returning a pointer to the root of the JSON
+ * structure. json_parse performs 1 call to malloc for the entire encoding.
+ * Returns 0 if an error occurred (malformed JSON input, or malloc failed). */
+ json_weak struct json_value_s *json_parse(const void *src, size_t src_size);
+
+ /* Parse a JSON text file, returning a pointer to the root of the JSON
+ * structure. json_parse performs 1 call to malloc for the entire encoding.
+ * Returns 0 if an error occurred (malformed JSON input, or malloc failed). If
+ * an error occurred, the result struct (if not NULL) will explain the type of
+ * error, and the location in the input it occurred. */
+ json_weak struct json_value_s *
+ json_parse_ex(const void *src, size_t src_size, size_t flags_bitset,
+ void *(*alloc_func_ptr)(void *, size_t), void *user_data,
+ struct json_parse_result_s *result);
+
+ /* Write out a minified JSON utf-8 string. This string is an encoding of the
+ * minimal string characters required to still encode the same data.
+ * json_write_minified performs 1 call to malloc for the entire encoding. Return
+ * 0 if an error occurred (malformed JSON input, or malloc failed). The out_size
+ * parameter is optional as the utf-8 string is null terminated. */
+ json_weak void *json_write_minified(const struct json_value_s *value,
+ size_t *out_size);
+
+ /* Write out a pretty JSON utf-8 string. This string is encoded such that the
+ * resultant JSON is pretty in that it is easily human readable. The indent and
+ * newline parameters allow a user to specify what kind of indentation and
+ * newline they want (two spaces / three spaces / tabs? \r, \n, \r\n ?). Both
+ * indent and newline can be NULL, indent defaults to two spaces (" "), and
+ * newline defaults to linux newlines ('\n' as the newline character).
+ * json_write_pretty performs 1 call to malloc for the entire encoding. Return 0
+ * if an error occurred (malformed JSON input, or malloc failed). The out_size
+ * parameter is optional as the utf-8 string is null terminated. */
+ json_weak void *json_write_pretty(const struct json_value_s *value,
+ const char *indent, const char *newline,
+ size_t *out_size);
+
+ /* Reinterpret a JSON value as a string. Returns null is the value was not a
+ * string. */
+ json_weak struct json_string_s *
+ json_value_as_string(struct json_value_s *const value);
+
+ /* Reinterpret a JSON value as a number. Returns null is the value was not a
+ * number. */
+ json_weak struct json_number_s *
+ json_value_as_number(struct json_value_s *const value);
+
+ /* Reinterpret a JSON value as an object. Returns null is the value was not an
+ * object. */
+ json_weak struct json_object_s *
+ json_value_as_object(struct json_value_s *const value);
+
+ /* Reinterpret a JSON value as an array. Returns null is the value was not an
+ * array. */
+ json_weak struct json_array_s *
+ json_value_as_array(struct json_value_s *const value);
+
+ /* Whether the value is true. */
+ json_weak int json_value_is_true(const struct json_value_s *const value);
+
+ /* Whether the value is false. */
+ json_weak int json_value_is_false(const struct json_value_s *const value);
+
+ /* Whether the value is null. */
+ json_weak int json_value_is_null(const struct json_value_s *const value);
+
+ /* The various types JSON values can be. Used to identify what a value is. */
+ enum json_type_e {
+ json_type_string,
+ json_type_number,
+ json_type_object,
+ json_type_array,
+ json_type_true,
+ json_type_false,
+ json_type_null
+ };
+
+ /* A JSON string value. */
+ struct json_string_s {
+ /* utf-8 string */
+ const char *string;
+ /* The size (in bytes) of the string */
+ size_t string_size;
+ };
+
+ /* A JSON string value (extended). */
+ struct json_string_ex_s {
+ /* The JSON string this extends. */
+ struct json_string_s string;
+
+ /* The character offset for the value in the JSON input. */
+ size_t offset;
+
+ /* The line number for the value in the JSON input. */
+ size_t line_no;
+
+ /* The row number for the value in the JSON input, in bytes. */
+ size_t row_no;
+ };
+
+ /* A JSON number value. */
+ struct json_number_s {
+ /* ASCII string containing representation of the number. */
+ const char *number;
+ /* the size (in bytes) of the number. */
+ size_t number_size;
+ };
+
+ /* an element of a JSON object. */
+ struct json_object_element_s {
+ /* the name of this element. */
+ struct json_string_s *name;
+ /* the value of this element. */
+ struct json_value_s *value;
+ /* the next object element (can be NULL if the last element in the object). */
+ struct json_object_element_s *next;
+ };
+
+ /* a JSON object value. */
+ struct json_object_s {
+ /* a linked list of the elements in the object. */
+ struct json_object_element_s *start;
+ /* the number of elements in the object. */
+ size_t length;
+ };
+
+ /* an element of a JSON array. */
+ struct json_array_element_s {
+ /* the value of this element. */
+ struct json_value_s *value;
+ /* the next array element (can be NULL if the last element in the array). */
+ struct json_array_element_s *next;
+ };
+
+ /* a JSON array value. */
+ struct json_array_s {
+ /* a linked list of the elements in the array. */
+ struct json_array_element_s *start;
+ /* the number of elements in the array. */
+ size_t length;
+ };
+
+ /* a JSON value. */
+ struct json_value_s {
+ /* a pointer to either a json_string_s, json_number_s, json_object_s, or. */
+ /* json_array_s. Should be cast to the appropriate struct type based on what.
+ */
+ /* the type of this value is. */
+ void *payload;
+ /* must be one of json_type_e. If type is json_type_true, json_type_false, or.
+ */
+ /* json_type_null, payload will be NULL. */
+ size_t type;
+ };
+
+ /* a JSON value (extended). */
+ struct json_value_ex_s {
+ /* the JSON value this extends. */
+ struct json_value_s value;
+
+ /* the character offset for the value in the JSON input. */
+ size_t offset;
+
+ /* the line number for the value in the JSON input. */
+ size_t line_no;
+
+ /* the row number for the value in the JSON input, in bytes. */
+ size_t row_no;
+ };
+
+ /* a parsing error code. */
+ enum json_parse_error_e {
+ /* no error occurred (huzzah!). */
+ json_parse_error_none = 0,
+
+ /* expected either a comma or a closing '}' or ']' to close an object or. */
+ /* array! */
+ json_parse_error_expected_comma_or_closing_bracket,
+
+ /* colon separating name/value pair was missing! */
+ json_parse_error_expected_colon,
+
+ /* expected string to begin with '"'! */
+ json_parse_error_expected_opening_quote,
+
+ /* invalid escaped sequence in string! */
+ json_parse_error_invalid_string_escape_sequence,
+
+ /* invalid number format! */
+ json_parse_error_invalid_number_format,
+
+ /* invalid value! */
+ json_parse_error_invalid_value,
+
+ /* reached end of buffer before object/array was complete! */
+ json_parse_error_premature_end_of_buffer,
+
+ /* string was malformed! */
+ json_parse_error_invalid_string,
+
+ /* a call to malloc, or a user provider allocator, failed. */
+ json_parse_error_allocator_failed,
+
+ /* the JSON input had unexpected trailing characters that weren't part of the.
+ */
+ /* JSON value. */
+ json_parse_error_unexpected_trailing_characters,
+
+ /* catch-all error for everything else that exploded (real bad chi!). */
+ json_parse_error_unknown
+ };
+
+ /* error report from json_parse_ex(). */
+ struct json_parse_result_s {
+ /* the error code (one of json_parse_error_e). */
+ size_t error;
+
+ /* the character offset for the error in the JSON input. */
+ size_t error_offset;
+
+ /* the line number for the error in the JSON input. */
+ size_t error_line_no;
+
+ /* the row number for the error, in bytes. */
+ size_t error_row_no;
+ };
+
+#ifdef __cplusplus
+} /* extern "C". */
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#include <stdlib.h>
+
+#if defined(_MSC_VER)
+#define json_strtoumax _strtoui64
+#define json_uintmax_t unsigned __int64
+#else
+#include <inttypes.h>
+#define json_strtoumax strtoumax
+#define json_uintmax_t uintmax_t
+#endif
+
+#if defined(__cplusplus) && (__cplusplus >= 201103L)
+#define json_null nullptr
+#else
+#define json_null 0
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+
+/* we do one big allocation via malloc, then cast aligned slices of this for. */
+/* our structures - we don't have a way to tell the compiler we know what we. */
+/* are doing, so disable the warning instead! */
+#pragma clang diagnostic ignored "-Wcast-align"
+
+/* We use C style casts everywhere. */
+#pragma clang diagnostic ignored "-Wold-style-cast"
+
+/* We need long long for strtoull. */
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+
+/* Who cares if nullptr doesn't work with C++98, we don't use it there! */
+#pragma clang diagnostic ignored "-Wc++98-compat"
+#pragma clang diagnostic ignored "-Wc++98-compat-pedantic"
+#elif defined(_MSC_VER)
+#pragma warning(push)
+
+/* disable 'function selected for inline expansion' warning. */
+#pragma warning(disable : 4711)
+
+/* disable '#pragma warning: there is no warning number' warning. */
+#pragma warning(disable : 4619)
+
+/* disable 'warning number not a valid compiler warning' warning. */
+#pragma warning(disable : 4616)
+
+/* disable 'Compiler will insert Spectre mitigation for memory load if
+ * /Qspectre. */
+ /* switch specified' warning. */
+#pragma warning(disable : 5045)
+#endif
+
+struct json_parse_state_s {
+ const char *src;
+ size_t size;
+ size_t offset;
+ size_t flags_bitset;
+ char *data;
+ char *dom;
+ size_t dom_size;
+ size_t data_size;
+ size_t line_no; /* line counter for error reporting. */
+ size_t line_offset; /* (offset-line_offset) is the character number (in
+ bytes). */
+ size_t error;
+};
+
+json_weak int json_hexadecimal_digit(const char c);
+int json_hexadecimal_digit(const char c) {
+ if ('0' <= c && c <= '9') {
+ return c - '0';
+ }
+ if ('a' <= c && c <= 'f') {
+ return c - 'a' + 10;
+ }
+ if ('A' <= c && c <= 'F') {
+ return c - 'A' + 10;
+ }
+ return -1;
+}
+
+json_weak int json_hexadecimal_value(const char * c, const unsigned long size, unsigned long * result);
+int json_hexadecimal_value(const char * c, const unsigned long size, unsigned long * result) {
+ const char * p;
+ int digit;
+
+ if (size > sizeof(unsigned long) * 2) {
+ return 0;
+ }
+
+ *result = 0;
+ for (p = c; (unsigned long)(p - c) < size; ++p) {
+ *result <<= 4;
+ digit = json_hexadecimal_digit(*p);
+ if (digit < 0 || digit > 15) {
+ return 0;
+ }
+ *result |= (unsigned char)digit;
+ }
+ return 1;
+}
+
+json_weak int json_skip_whitespace(struct json_parse_state_s *state);
+int json_skip_whitespace(struct json_parse_state_s *state) {
+ size_t offset = state->offset;
+ const size_t size = state->size;
+ const char *const src = state->src;
+
+ /* the only valid whitespace according to ECMA-404 is ' ', '\n', '\r' and
+ * '\t'. */
+ switch (src[offset]) {
+ default:
+ return 0;
+ case ' ':
+ case '\r':
+ case '\t':
+ case '\n':
+ break;
+ }
+
+ do {
+ switch (src[offset]) {
+ default:
+ /* Update offset. */
+ state->offset = offset;
+ return 1;
+ case ' ':
+ case '\r':
+ case '\t':
+ break;
+ case '\n':
+ state->line_no++;
+ state->line_offset = offset;
+ break;
+ }
+
+ offset++;
+ } while (offset < size);
+
+ /* Update offset. */
+ state->offset = offset;
+ return 1;
+}
+
+json_weak int json_skip_c_style_comments(struct json_parse_state_s *state);
+int json_skip_c_style_comments(struct json_parse_state_s *state) {
+ /* do we have a comment?. */
+ if ('/' == state->src[state->offset]) {
+ /* skip '/'. */
+ state->offset++;
+
+ if ('/' == state->src[state->offset]) {
+ /* we had a comment of the form //. */
+
+ /* skip second '/'. */
+ state->offset++;
+
+ while (state->offset < state->size) {
+ switch (state->src[state->offset]) {
+ default:
+ /* skip the character in the comment. */
+ state->offset++;
+ break;
+ case '\n':
+ /* if we have a newline, our comment has ended! Skip the newline. */
+ state->offset++;
+
+ /* we entered a newline, so move our line info forward. */
+ state->line_no++;
+ state->line_offset = state->offset;
+ return 1;
+ }
+ }
+
+ /* we reached the end of the JSON file! */
+ return 1;
+ }
+ else if ('*' == state->src[state->offset]) {
+ /* we had a comment in the C-style long form. */
+
+ /* skip '*'. */
+ state->offset++;
+
+ while (state->offset + 1 < state->size) {
+ if (('*' == state->src[state->offset]) &&
+ ('/' == state->src[state->offset + 1])) {
+ /* we reached the end of our comment! */
+ state->offset += 2;
+ return 1;
+ }
+ else if ('\n' == state->src[state->offset]) {
+ /* we entered a newline, so move our line info forward. */
+ state->line_no++;
+ state->line_offset = state->offset;
+ }
+
+ /* skip character within comment. */
+ state->offset++;
+ }
+
+ /* Comment wasn't ended correctly which is a failure. */
+ return 1;
+ }
+ }
+
+ /* we didn't have any comment, which is ok too! */
+ return 0;
+}
+
+json_weak int json_skip_all_skippables(struct json_parse_state_s *state);
+int json_skip_all_skippables(struct json_parse_state_s *state) {
+ /* skip all whitespace and other skippables until there are none left. note
+ * that the previous version suffered from read past errors should. the
+ * stream end on json_skip_c_style_comments eg. '{"a" ' with comments flag.
+ */
+
+ int did_consume = 0;
+ const size_t size = state->size;
+
+ if (json_parse_flags_allow_c_style_comments & state->flags_bitset) {
+ do {
+ if (state->offset == size) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ did_consume = json_skip_whitespace(state);
+
+ /* This should really be checked on access, not in front of every call.
+ */
+ if (state->offset == size) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ did_consume |= json_skip_c_style_comments(state);
+ } while (0 != did_consume);
+ }
+ else {
+ do {
+ if (state->offset == size) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ did_consume = json_skip_whitespace(state);
+ } while (0 != did_consume);
+ }
+
+ if (state->offset == size) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ return 0;
+}
+
+json_weak int json_get_value_size(struct json_parse_state_s *state,
+ int is_global_object);
+
+json_weak int json_get_string_size(struct json_parse_state_s *state,
+ size_t is_key);
+int json_get_string_size(struct json_parse_state_s *state,
+ size_t is_key) {
+ size_t offset = state->offset;
+ const size_t size = state->size;
+ size_t data_size = 0;
+ const char *const src = state->src;
+ const int is_single_quote = '\'' == src[offset];
+ const char quote_to_use = is_single_quote ? '\'' : '"';
+ const size_t flags_bitset = state->flags_bitset;
+ unsigned long codepoint;
+ unsigned long high_surrogate = 0;
+
+ if ((json_parse_flags_allow_location_information & flags_bitset) != 0 &&
+ is_key != 0) {
+ state->dom_size += sizeof(struct json_string_ex_s);
+ }
+ else {
+ state->dom_size += sizeof(struct json_string_s);
+ }
+
+ if ('"' != src[offset]) {
+ /* if we are allowed single quoted strings check for that too. */
+ if (!((json_parse_flags_allow_single_quoted_strings & flags_bitset) &&
+ is_single_quote)) {
+ state->error = json_parse_error_expected_opening_quote;
+ state->offset = offset;
+ return 1;
+ }
+ }
+
+ /* skip leading '"' or '\''. */
+ offset++;
+
+ while ((offset < size) && (quote_to_use != src[offset])) {
+ /* add space for the character. */
+ data_size++;
+
+ if ('\\' == src[offset]) {
+ /* skip reverse solidus character. */
+ offset++;
+
+ if (offset == size) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ state->offset = offset;
+ return 1;
+ }
+
+ switch (src[offset]) {
+ default:
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ case '"':
+ case '\\':
+ case '/':
+ case 'b':
+ case 'f':
+ case 'n':
+ case 'r':
+ case 't':
+ /* all valid characters! */
+ offset++;
+ break;
+ case 'u':
+ if (!(offset + 5 < size)) {
+ /* invalid escaped unicode sequence! */
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ }
+
+ codepoint = 0;
+ if (!json_hexadecimal_value(&src[offset + 1], 4, &codepoint)) {
+ /* escaped unicode sequences must contain 4 hexadecimal digits! */
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ }
+
+ /* Valid sequence!
+ * see: https://en.wikipedia.org/wiki/UTF-8#Invalid_code_points.
+ * 1 7 U + 0000 U + 007F 0xxxxxxx.
+ * 2 11 U + 0080 U + 07FF 110xxxxx
+ * 10xxxxxx.
+ * 3 16 U + 0800 U + FFFF 1110xxxx
+ * 10xxxxxx 10xxxxxx.
+ * 4 21 U + 10000 U + 10FFFF 11110xxx
+ * 10xxxxxx 10xxxxxx 10xxxxxx.
+ * Note: the high and low surrogate halves used by UTF-16 (U+D800
+ * through U+DFFF) and code points not encodable by UTF-16 (those after
+ * U+10FFFF) are not legal Unicode values, and their UTF-8 encoding must
+ * be treated as an invalid byte sequence. */
+
+ if (high_surrogate != 0) {
+ /* we previously read the high half of the \uxxxx\uxxxx pair, so now
+ * we expect the low half. */
+ if (codepoint >= 0xdc00 &&
+ codepoint <= 0xdfff) { /* low surrogate range. */
+ data_size += 3;
+ high_surrogate = 0;
+ }
+ else {
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ }
+ }
+ else if (codepoint <= 0x7f) {
+ data_size += 0;
+ }
+ else if (codepoint <= 0x7ff) {
+ data_size += 1;
+ }
+ else if (codepoint >= 0xd800 &&
+ codepoint <= 0xdbff) { /* high surrogate range. */
+ /* The codepoint is the first half of a "utf-16 surrogate pair". so we
+ * need the other half for it to be valid: \uHHHH\uLLLL. */
+ if (offset + 11 > size || '\\' != src[offset + 5] ||
+ 'u' != src[offset + 6]) {
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ }
+ high_surrogate = codepoint;
+ }
+ else if (codepoint >= 0xd800 &&
+ codepoint <= 0xdfff) { /* low surrogate range. */
+ /* we did not read the other half before. */
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ }
+ else {
+ data_size += 2;
+ }
+ /* escaped codepoints after 0xffff are supported in json through utf-16
+ * surrogate pairs: \uD83D\uDD25 for U+1F525. */
+
+ offset += 5;
+ break;
+ }
+ }
+ else if (('\r' == src[offset]) || ('\n' == src[offset])) {
+ if (!(json_parse_flags_allow_multi_line_strings & flags_bitset)) {
+ /* invalid escaped unicode sequence! */
+ state->error = json_parse_error_invalid_string_escape_sequence;
+ state->offset = offset;
+ return 1;
+ }
+
+ offset++;
+ }
+ else {
+ /* skip character (valid part of sequence). */
+ offset++;
+ }
+ }
+
+ /* skip trailing '"' or '\''. */
+ offset++;
+
+ /* add enough space to store the string. */
+ state->data_size += data_size;
+
+ /* one more byte for null terminator ending the string! */
+ state->data_size++;
+
+ /* update offset. */
+ state->offset = offset;
+
+ return 0;
+}
+
+json_weak int is_valid_unquoted_key_char(const char c);
+int is_valid_unquoted_key_char(const char c) {
+ return (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') ||
+ ('A' <= c && c <= 'Z') || ('_' == c));
+}
+
+json_weak int json_get_key_size(struct json_parse_state_s *state);
+int json_get_key_size(struct json_parse_state_s *state) {
+ const size_t flags_bitset = state->flags_bitset;
+
+ if (json_parse_flags_allow_unquoted_keys & flags_bitset) {
+ size_t offset = state->offset;
+ const size_t size = state->size;
+ const char *const src = state->src;
+ size_t data_size = state->data_size;
+
+ /* if we are allowing unquoted keys, first grok for a quote... */
+ if ('"' == src[offset]) {
+ /* ... if we got a comma, just parse the key as a string as normal. */
+ return json_get_string_size(state, 1);
+ }
+ else if ((json_parse_flags_allow_single_quoted_strings & flags_bitset) &&
+ ('\'' == src[offset])) {
+ /* ... if we got a comma, just parse the key as a string as normal. */
+ return json_get_string_size(state, 1);
+ }
+ else {
+ while ((offset < size) && is_valid_unquoted_key_char(src[offset])) {
+ offset++;
+ data_size++;
+ }
+
+ /* one more byte for null terminator ending the string! */
+ data_size++;
+
+ if (json_parse_flags_allow_location_information & flags_bitset) {
+ state->dom_size += sizeof(struct json_string_ex_s);
+ }
+ else {
+ state->dom_size += sizeof(struct json_string_s);
+ }
+
+ /* update offset. */
+ state->offset = offset;
+
+ /* update data_size. */
+ state->data_size = data_size;
+
+ return 0;
+ }
+ }
+ else {
+ /* we are only allowed to have quoted keys, so just parse a string! */
+ return json_get_string_size(state, 1);
+ }
+}
+
+json_weak int json_get_object_size(struct json_parse_state_s *state,
+ int is_global_object);
+int json_get_object_size(struct json_parse_state_s *state,
+ int is_global_object) {
+ const size_t flags_bitset = state->flags_bitset;
+ const char *const src = state->src;
+ const size_t size = state->size;
+ size_t elements = 0;
+ int allow_comma = 0;
+
+ if (is_global_object) {
+ /* if we found an opening '{' of an object, we actually have a normal JSON
+ * object at the root of the DOM... */
+ if (!json_skip_all_skippables(state) && '{' == state->src[state->offset]) {
+ /* . and we don't actually have a global object after all! */
+ is_global_object = 0;
+ }
+ }
+
+ if (!is_global_object) {
+ if ('{' != src[state->offset]) {
+ state->error = json_parse_error_unknown;
+ return 1;
+ }
+
+ /* skip leading '{'. */
+ state->offset++;
+ }
+
+ state->dom_size += sizeof(struct json_object_s);
+
+ while (state->offset < size) {
+ if (!is_global_object) {
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+ if ('}' == src[state->offset]) {
+ /* skip trailing '}'. */
+ state->offset++;
+
+ /* finished the object! */
+ break;
+ }
+ }
+ else {
+ /* we don't require brackets, so that means the object ends when the input
+ * stream ends! */
+ if (json_skip_all_skippables(state)) {
+ break;
+ }
+ }
+
+ /* if we parsed at least once element previously, grok for a comma. */
+ if (allow_comma) {
+ if (',' == src[state->offset]) {
+ /* skip comma. */
+ state->offset++;
+ allow_comma = 0;
+ }
+ else if (json_parse_flags_allow_no_commas & flags_bitset) {
+ /* we don't require a comma, and we didn't find one, which is ok! */
+ allow_comma = 0;
+ }
+ else {
+ /* otherwise we are required to have a comma, and we found none. */
+ state->error = json_parse_error_expected_comma_or_closing_bracket;
+ return 1;
+ }
+
+ if (json_parse_flags_allow_trailing_comma & flags_bitset) {
+ continue;
+ }
+ else {
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+ }
+ }
+
+ if (json_get_key_size(state)) {
+ /* key parsing failed! */
+ state->error = json_parse_error_invalid_string;
+ return 1;
+ }
+
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ if (json_parse_flags_allow_equals_in_object & flags_bitset) {
+ const char current = src[state->offset];
+ if ((':' != current) && ('=' != current)) {
+ state->error = json_parse_error_expected_colon;
+ return 1;
+ }
+ }
+ else {
+ if (':' != src[state->offset]) {
+ state->error = json_parse_error_expected_colon;
+ return 1;
+ }
+ }
+
+ /* skip colon. */
+ state->offset++;
+
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ if (json_get_value_size(state, /* is_global_object = */ 0)) {
+ /* value parsing failed! */
+ return 1;
+ }
+
+ /* successfully parsed a name/value pair! */
+ elements++;
+ allow_comma = 1;
+ }
+
+ state->dom_size += sizeof(struct json_object_element_s) * elements;
+
+ return 0;
+}
+
+json_weak int json_get_array_size(struct json_parse_state_s *state);
+int json_get_array_size(struct json_parse_state_s *state) {
+ const size_t flags_bitset = state->flags_bitset;
+ size_t elements = 0;
+ int allow_comma = 0;
+ const char *const src = state->src;
+ const size_t size = state->size;
+
+ if ('[' != src[state->offset]) {
+ /* expected array to begin with leading '['. */
+ state->error = json_parse_error_unknown;
+ return 1;
+ }
+
+ /* skip leading '['. */
+ state->offset++;
+
+ state->dom_size += sizeof(struct json_array_s);
+
+ while (state->offset < size) {
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ if (']' == src[state->offset]) {
+ /* skip trailing ']'. */
+ state->offset++;
+
+ state->dom_size += sizeof(struct json_array_element_s) * elements;
+
+ /* finished the object! */
+ return 0;
+ }
+
+ /* if we parsed at least once element previously, grok for a comma. */
+ if (allow_comma) {
+ if (',' == src[state->offset]) {
+ /* skip comma. */
+ state->offset++;
+ allow_comma = 0;
+ }
+ else if (!(json_parse_flags_allow_no_commas & flags_bitset)) {
+ state->error = json_parse_error_expected_comma_or_closing_bracket;
+ return 1;
+ }
+
+ if (json_parse_flags_allow_trailing_comma & flags_bitset) {
+ allow_comma = 0;
+ continue;
+ }
+ else {
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+ }
+ }
+
+ if (json_get_value_size(state, /* is_global_object = */ 0)) {
+ /* value parsing failed! */
+ return 1;
+ }
+
+ /* successfully parsed an array element! */
+ elements++;
+ allow_comma = 1;
+ }
+
+ /* we consumed the entire input before finding the closing ']' of the array!
+ */
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+}
+
+json_weak int json_get_number_size(struct json_parse_state_s *state);
+int json_get_number_size(struct json_parse_state_s *state) {
+ const size_t flags_bitset = state->flags_bitset;
+ size_t offset = state->offset;
+ const size_t size = state->size;
+ int had_leading_digits = 0;
+ const char *const src = state->src;
+
+ state->dom_size += sizeof(struct json_number_s);
+
+ if ((json_parse_flags_allow_hexadecimal_numbers & flags_bitset) &&
+ (offset + 1 < size) && ('0' == src[offset]) &&
+ (('x' == src[offset + 1]) || ('X' == src[offset + 1]))) {
+ /* skip the leading 0x that identifies a hexadecimal number. */
+ offset += 2;
+
+ /* consume hexadecimal digits. */
+ while ((offset < size) && (('0' <= src[offset] && src[offset] <= '9') ||
+ ('a' <= src[offset] && src[offset] <= 'f') ||
+ ('A' <= src[offset] && src[offset] <= 'F'))) {
+ offset++;
+ }
+ }
+ else {
+ int found_sign = 0;
+ int inf_or_nan = 0;
+
+ if ((offset < size) &&
+ (('-' == src[offset]) ||
+ ((json_parse_flags_allow_leading_plus_sign & flags_bitset) &&
+ ('+' == src[offset])))) {
+ /* skip valid leading '-' or '+'. */
+ offset++;
+
+ found_sign = 1;
+ }
+
+ if (json_parse_flags_allow_inf_and_nan & flags_bitset) {
+ const char inf[9] = "Infinity";
+ const size_t inf_strlen = sizeof(inf) - 1;
+ const char nan[4] = "NaN";
+ const size_t nan_strlen = sizeof(nan) - 1;
+
+ if (offset + inf_strlen < size) {
+ int found = 1;
+ size_t i;
+ for (i = 0; i < inf_strlen; i++) {
+ if (inf[i] != src[offset + i]) {
+ found = 0;
+ break;
+ }
+ }
+
+ if (found) {
+ /* We found our special 'Infinity' keyword! */
+ offset += inf_strlen;
+
+ inf_or_nan = 1;
+ }
+ }
+
+ if (offset + nan_strlen < size) {
+ int found = 1;
+ size_t i;
+ for (i = 0; i < nan_strlen; i++) {
+ if (nan[i] != src[offset + i]) {
+ found = 0;
+ break;
+ }
+ }
+
+ if (found) {
+ /* We found our special 'NaN' keyword! */
+ offset += nan_strlen;
+
+ inf_or_nan = 1;
+ }
+ }
+ }
+
+ if (found_sign && !inf_or_nan && (offset < size) &&
+ !('0' <= src[offset] && src[offset] <= '9')) {
+ /* check if we are allowing leading '.'. */
+ if (!(json_parse_flags_allow_leading_or_trailing_decimal_point &
+ flags_bitset) ||
+ ('.' != src[offset])) {
+ /* a leading '-' must be immediately followed by any digit! */
+ state->error = json_parse_error_invalid_number_format;
+ state->offset = offset;
+ return 1;
+ }
+ }
+
+ if ((offset < size) && ('0' == src[offset])) {
+ /* skip valid '0'. */
+ offset++;
+
+ /* we need to record whether we had any leading digits for checks later.
+ */
+ had_leading_digits = 1;
+
+ if ((offset < size) && ('0' <= src[offset] && src[offset] <= '9')) {
+ /* a leading '0' must not be immediately followed by any digit! */
+ state->error = json_parse_error_invalid_number_format;
+ state->offset = offset;
+ return 1;
+ }
+ }
+
+ /* the main digits of our number next. */
+ while ((offset < size) && ('0' <= src[offset] && src[offset] <= '9')) {
+ offset++;
+
+ /* we need to record whether we had any leading digits for checks later.
+ */
+ had_leading_digits = 1;
+ }
+
+ if ((offset < size) && ('.' == src[offset])) {
+ offset++;
+
+ if (!('0' <= src[offset] && src[offset] <= '9')) {
+ if (!(json_parse_flags_allow_leading_or_trailing_decimal_point &
+ flags_bitset) ||
+ !had_leading_digits) {
+ /* a decimal point must be followed by at least one digit. */
+ state->error = json_parse_error_invalid_number_format;
+ state->offset = offset;
+ return 1;
+ }
+ }
+
+ /* a decimal point can be followed by more digits of course! */
+ while ((offset < size) && ('0' <= src[offset] && src[offset] <= '9')) {
+ offset++;
+ }
+ }
+
+ if ((offset < size) && ('e' == src[offset] || 'E' == src[offset])) {
+ /* our number has an exponent! Wkip 'e' or 'E'. */
+ offset++;
+
+ if ((offset < size) && ('-' == src[offset] || '+' == src[offset])) {
+ /* skip optional '-' or '+'. */
+ offset++;
+ }
+
+ /* consume exponent digits. */
+ while ((offset < size) && ('0' <= src[offset] && src[offset] <= '9')) {
+ offset++;
+ }
+ }
+ }
+
+ if (offset < size) {
+ switch (src[offset]) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ case '}':
+ case ',':
+ case ']':
+ /* all of the above are ok. */
+ break;
+ case '=':
+ if (json_parse_flags_allow_equals_in_object & flags_bitset) {
+ break;
+ }
+
+ state->error = json_parse_error_invalid_number_format;
+ state->offset = offset;
+ return 1;
+ default:
+ state->error = json_parse_error_invalid_number_format;
+ state->offset = offset;
+ return 1;
+ }
+ }
+
+ state->data_size += offset - state->offset;
+
+ /* one more byte for null terminator ending the number string! */
+ state->data_size++;
+
+ /* update offset. */
+ state->offset = offset;
+
+ return 0;
+}
+
+json_weak int json_get_value_size(struct json_parse_state_s *state,
+ int is_global_object);
+int json_get_value_size(struct json_parse_state_s *state,
+ int is_global_object) {
+ const size_t flags_bitset = state->flags_bitset;
+ const char *const src = state->src;
+ size_t offset;
+ const size_t size = state->size;
+
+ if (json_parse_flags_allow_location_information & flags_bitset) {
+ state->dom_size += sizeof(struct json_value_ex_s);
+ }
+ else {
+ state->dom_size += sizeof(struct json_value_s);
+ }
+
+ if (is_global_object) {
+ return json_get_object_size(state, /* is_global_object = */ 1);
+ }
+ else {
+ if (json_skip_all_skippables(state)) {
+ state->error = json_parse_error_premature_end_of_buffer;
+ return 1;
+ }
+
+ /* can cache offset now. */
+ offset = state->offset;
+
+ switch (src[offset]) {
+ case '"':
+ return json_get_string_size(state, 0);
+ case '\'':
+ if (json_parse_flags_allow_single_quoted_strings & flags_bitset) {
+ return json_get_string_size(state, 0);
+ }
+ else {
+ /* invalid value! */
+ state->error = json_parse_error_invalid_value;
+ return 1;
+ }
+ case '{':
+ return json_get_object_size(state, /* is_global_object = */ 0);
+ case '[':
+ return json_get_array_size(state);
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return json_get_number_size(state);
+ case '+':
+ if (json_parse_flags_allow_leading_plus_sign & flags_bitset) {
+ return json_get_number_size(state);
+ }
+ else {
+ /* invalid value! */
+ state->error = json_parse_error_invalid_number_format;
+ return 1;
+ }
+ case '.':
+ if (json_parse_flags_allow_leading_or_trailing_decimal_point &
+ flags_bitset) {
+ return json_get_number_size(state);
+ }
+ else {
+ /* invalid value! */
+ state->error = json_parse_error_invalid_number_format;
+ return 1;
+ }
+ default:
+ if ((offset + 4) <= size && 't' == src[offset + 0] &&
+ 'r' == src[offset + 1] && 'u' == src[offset + 2] &&
+ 'e' == src[offset + 3]) {
+ state->offset += 4;
+ return 0;
+ }
+ else if ((offset + 5) <= size && 'f' == src[offset + 0] &&
+ 'a' == src[offset + 1] && 'l' == src[offset + 2] &&
+ 's' == src[offset + 3] && 'e' == src[offset + 4]) {
+ state->offset += 5;
+ return 0;
+ }
+ else if ((offset + 4) <= size && 'n' == state->src[offset + 0] &&
+ 'u' == state->src[offset + 1] &&
+ 'l' == state->src[offset + 2] &&
+ 'l' == state->src[offset + 3]) {
+ state->offset += 4;
+ return 0;
+ }
+ else if ((json_parse_flags_allow_inf_and_nan & flags_bitset) &&
+ (offset + 3) <= size && 'N' == src[offset + 0] &&
+ 'a' == src[offset + 1] && 'N' == src[offset + 2]) {
+ return json_get_number_size(state);
+ }
+ else if ((json_parse_flags_allow_inf_and_nan & flags_bitset) &&
+ (offset + 8) <= size && 'I' == src[offset + 0] &&
+ 'n' == src[offset + 1] && 'f' == src[offset + 2] &&
+ 'i' == src[offset + 3] && 'n' == src[offset + 4] &&
+ 'i' == src[offset + 5] && 't' == src[offset + 6] &&
+ 'y' == src[offset + 7]) {
+ return json_get_number_size(state);
+ }
+
+ /* invalid value! */
+ state->error = json_parse_error_invalid_value;
+ return 1;
+ }
+ }
+}
+
+json_weak void json_parse_value(struct json_parse_state_s *state,
+ int is_global_object, struct json_value_s *value);
+
+json_weak void json_parse_string(struct json_parse_state_s *state,
+ struct json_string_s *string);
+void json_parse_string(struct json_parse_state_s *state,
+ struct json_string_s *string) {
+ size_t offset = state->offset;
+ size_t bytes_written = 0;
+ const char *const src = state->src;
+ const char quote_to_use = '\'' == src[offset] ? '\'' : '"';
+ char *data = state->data;
+ unsigned long high_surrogate = 0;
+ unsigned long codepoint;
+
+ string->string = data;
+
+ /* skip leading '"' or '\''. */
+ offset++;
+
+ while (quote_to_use != src[offset]) {
+ if ('\\' == src[offset]) {
+ /* skip the reverse solidus. */
+ offset++;
+
+ switch (src[offset++]) {
+ default:
+ return; /* we cannot ever reach here. */
+ case 'u': {
+ codepoint = 0;
+ if (!json_hexadecimal_value(&src[offset], 4, &codepoint)) {
+ return; /* this shouldn't happen as the value was already validated.
+ */
+ }
+
+ offset += 4;
+
+ if (codepoint <= 0x7fu) {
+ data[bytes_written++] = (char)codepoint; /* 0xxxxxxx. */
+ }
+ else if (codepoint <= 0x7ffu) {
+ data[bytes_written++] =
+ (char)(0xc0u | (codepoint >> 6)); /* 110xxxxx. */
+ data[bytes_written++] =
+ (char)(0x80u | (codepoint & 0x3fu)); /* 10xxxxxx. */
+ }
+ else if (codepoint >= 0xd800 &&
+ codepoint <= 0xdbff) { /* high surrogate. */
+ high_surrogate = codepoint;
+ continue; /* we need the low half to form a complete codepoint. */
+ }
+ else if (codepoint >= 0xdc00 &&
+ codepoint <= 0xdfff) { /* low surrogate. */
+ /* combine with the previously read half to obtain the complete
+ * codepoint. */
+ const unsigned long surrogate_offset = 0x10000u - (0xD800u << 10) - 0xDC00u;
+ codepoint = (high_surrogate << 10) + codepoint + surrogate_offset;
+ high_surrogate = 0;
+ data[bytes_written++] =
+ (char)(0xF0u | (codepoint >> 18)); /* 11110xxx. */
+ data[bytes_written++] =
+ (char)(0x80u | ((codepoint >> 12) & 0x3fu)); /* 10xxxxxx. */
+ data[bytes_written++] =
+ (char)(0x80u | ((codepoint >> 6) & 0x3fu)); /* 10xxxxxx. */
+ data[bytes_written++] =
+ (char)(0x80u | (codepoint & 0x3fu)); /* 10xxxxxx. */
+ }
+ else {
+ /* we assume the value was validated and thus is within the valid
+ * range. */
+ data[bytes_written++] =
+ (char)(0xe0u | (codepoint >> 12)); /* 1110xxxx. */
+ data[bytes_written++] =
+ (char)(0x80u | ((codepoint >> 6) & 0x3fu)); /* 10xxxxxx. */
+ data[bytes_written++] =
+ (char)(0x80u | (codepoint & 0x3fu)); /* 10xxxxxx. */
+ }
+ } break;
+ case '"':
+ data[bytes_written++] = '"';
+ break;
+ case '\\':
+ data[bytes_written++] = '\\';
+ break;
+ case '/':
+ data[bytes_written++] = '/';
+ break;
+ case 'b':
+ data[bytes_written++] = '\b';
+ break;
+ case 'f':
+ data[bytes_written++] = '\f';
+ break;
+ case 'n':
+ data[bytes_written++] = '\n';
+ break;
+ case 'r':
+ data[bytes_written++] = '\r';
+ break;
+ case 't':
+ data[bytes_written++] = '\t';
+ break;
+ case '\r':
+ data[bytes_written++] = '\r';
+
+ /* check if we have a "\r\n" sequence. */
+ if ('\n' == src[offset]) {
+ data[bytes_written++] = '\n';
+ offset++;
+ }
+
+ break;
+ case '\n':
+ data[bytes_written++] = '\n';
+ break;
+ }
+ }
+ else {
+ /* copy the character. */
+ data[bytes_written++] = src[offset++];
+ }
+ }
+
+ /* skip trailing '"' or '\''. */
+ offset++;
+
+ /* record the size of the string. */
+ string->string_size = bytes_written;
+
+ /* add null terminator to string. */
+ data[bytes_written++] = '\0';
+
+ /* move data along. */
+ state->data += bytes_written;
+
+ /* update offset. */
+ state->offset = offset;
+}
+
+json_weak void json_parse_key(struct json_parse_state_s *state,
+ struct json_string_s *string);
+void json_parse_key(struct json_parse_state_s *state,
+ struct json_string_s *string) {
+ if (json_parse_flags_allow_unquoted_keys & state->flags_bitset) {
+ const char *const src = state->src;
+ char *const data = state->data;
+ size_t offset = state->offset;
+
+ /* if we are allowing unquoted keys, check for quoted anyway... */
+ if (('"' == src[offset]) || ('\'' == src[offset])) {
+ /* ... if we got a quote, just parse the key as a string as normal. */
+ json_parse_string(state, string);
+ }
+ else {
+ size_t size = 0;
+
+ string->string = state->data;
+
+ while (is_valid_unquoted_key_char(src[offset])) {
+ data[size++] = src[offset++];
+ }
+
+ /* add null terminator to string. */
+ data[size] = '\0';
+
+ /* record the size of the string. */
+ string->string_size = size++;
+
+ /* move data along. */
+ state->data += size;
+
+ /* update offset. */
+ state->offset = offset;
+ }
+ }
+ else {
+ /* we are only allowed to have quoted keys, so just parse a string! */
+ json_parse_string(state, string);
+ }
+}
+
+json_weak void json_parse_object(struct json_parse_state_s *state,
+ int is_global_object,
+ struct json_object_s *object);
+void json_parse_object(struct json_parse_state_s *state,
+ int is_global_object,
+ struct json_object_s *object) {
+ const size_t flags_bitset = state->flags_bitset;
+ const size_t size = state->size;
+ const char *const src = state->src;
+ size_t elements = 0;
+ int allow_comma = 0;
+ struct json_object_element_s *previous = json_null;
+
+ if (is_global_object) {
+ /* if we skipped some whitespace, and then found an opening '{' of an. */
+ /* object, we actually have a normal JSON object at the root of the DOM...
+ */
+ if ('{' == src[state->offset]) {
+ /* . and we don't actually have a global object after all! */
+ is_global_object = 0;
+ }
+ }
+
+ if (!is_global_object) {
+ /* skip leading '{'. */
+ state->offset++;
+ }
+
+ (void)json_skip_all_skippables(state);
+
+ /* reset elements. */
+ elements = 0;
+
+ while (state->offset < size) {
+ struct json_object_element_s *element = json_null;
+ struct json_string_s *string = json_null;
+ struct json_value_s *value = json_null;
+
+ if (!is_global_object) {
+ (void)json_skip_all_skippables(state);
+
+ if ('}' == src[state->offset]) {
+ /* skip trailing '}'. */
+ state->offset++;
+
+ /* finished the object! */
+ break;
+ }
+ }
+ else {
+ if (json_skip_all_skippables(state)) {
+ /* global object ends when the file ends! */
+ break;
+ }
+ }
+
+ /* if we parsed at least one element previously, grok for a comma. */
+ if (allow_comma) {
+ if (',' == src[state->offset]) {
+ /* skip comma. */
+ state->offset++;
+ allow_comma = 0;
+ continue;
+ }
+ }
+
+ element = (struct json_object_element_s *)state->dom;
+
+ state->dom += sizeof(struct json_object_element_s);
+
+ if (json_null == previous) {
+ /* this is our first element, so record it in our object. */
+ object->start = element;
+ }
+ else {
+ previous->next = element;
+ }
+
+ previous = element;
+
+ if (json_parse_flags_allow_location_information & flags_bitset) {
+ struct json_string_ex_s *string_ex =
+ (struct json_string_ex_s *)state->dom;
+ state->dom += sizeof(struct json_string_ex_s);
+
+ string_ex->offset = state->offset;
+ string_ex->line_no = state->line_no;
+ string_ex->row_no = state->offset - state->line_offset;
+
+ string = &(string_ex->string);
+ }
+ else {
+ string = (struct json_string_s *)state->dom;
+ state->dom += sizeof(struct json_string_s);
+ }
+
+ element->name = string;
+
+ (void)json_parse_key(state, string);
+
+ (void)json_skip_all_skippables(state);
+
+ /* skip colon or equals. */
+ state->offset++;
+
+ (void)json_skip_all_skippables(state);
+
+ if (json_parse_flags_allow_location_information & flags_bitset) {
+ struct json_value_ex_s *value_ex = (struct json_value_ex_s *)state->dom;
+ state->dom += sizeof(struct json_value_ex_s);
+
+ value_ex->offset = state->offset;
+ value_ex->line_no = state->line_no;
+ value_ex->row_no = state->offset - state->line_offset;
+
+ value = &(value_ex->value);
+ }
+ else {
+ value = (struct json_value_s *)state->dom;
+ state->dom += sizeof(struct json_value_s);
+ }
+
+ element->value = value;
+
+ json_parse_value(state, /* is_global_object = */ 0, value);
+
+ /* successfully parsed a name/value pair! */
+ elements++;
+ allow_comma = 1;
+ }
+
+ /* if we had at least one element, end the linked list. */
+ if (previous) {
+ previous->next = json_null;
+ }
+
+ if (0 == elements) {
+ object->start = json_null;
+ }
+
+ object->length = elements;
+}
+
+json_weak void json_parse_array(struct json_parse_state_s *state,
+ struct json_array_s *array);
+void json_parse_array(struct json_parse_state_s *state,
+ struct json_array_s *array) {
+ const char *const src = state->src;
+ const size_t size = state->size;
+ size_t elements = 0;
+ int allow_comma = 0;
+ struct json_array_element_s *previous = json_null;
+
+ /* skip leading '['. */
+ state->offset++;
+
+ (void)json_skip_all_skippables(state);
+
+ /* reset elements. */
+ elements = 0;
+
+ do {
+ struct json_array_element_s *element = json_null;
+ struct json_value_s *value = json_null;
+
+ (void)json_skip_all_skippables(state);
+
+ if (']' == src[state->offset]) {
+ /* skip trailing ']'. */
+ state->offset++;
+
+ /* finished the array! */
+ break;
+ }
+
+ /* if we parsed at least one element previously, grok for a comma. */
+ if (allow_comma) {
+ if (',' == src[state->offset]) {
+ /* skip comma. */
+ state->offset++;
+ allow_comma = 0;
+ continue;
+ }
+ }
+
+ element = (struct json_array_element_s *)state->dom;
+
+ state->dom += sizeof(struct json_array_element_s);
+
+ if (json_null == previous) {
+ /* this is our first element, so record it in our array. */
+ array->start = element;
+ }
+ else {
+ previous->next = element;
+ }
+
+ previous = element;
+
+ if (json_parse_flags_allow_location_information & state->flags_bitset) {
+ struct json_value_ex_s *value_ex = (struct json_value_ex_s *)state->dom;
+ state->dom += sizeof(struct json_value_ex_s);
+
+ value_ex->offset = state->offset;
+ value_ex->line_no = state->line_no;
+ value_ex->row_no = state->offset - state->line_offset;
+
+ value = &(value_ex->value);
+ }
+ else {
+ value = (struct json_value_s *)state->dom;
+ state->dom += sizeof(struct json_value_s);
+ }
+
+ element->value = value;
+
+ json_parse_value(state, /* is_global_object = */ 0, value);
+
+ /* successfully parsed an array element! */
+ elements++;
+ allow_comma = 1;
+ } while (state->offset < size);
+
+ /* end the linked list. */
+ if (previous) {
+ previous->next = json_null;
+ }
+
+ if (0 == elements) {
+ array->start = json_null;
+ }
+
+ array->length = elements;
+}
+
+json_weak void json_parse_number(struct json_parse_state_s *state,
+ struct json_number_s *number);
+void json_parse_number(struct json_parse_state_s *state,
+ struct json_number_s *number) {
+ const size_t flags_bitset = state->flags_bitset;
+ size_t offset = state->offset;
+ const size_t size = state->size;
+ size_t bytes_written = 0;
+ const char *const src = state->src;
+ char *data = state->data;
+
+ number->number = data;
+
+ if (json_parse_flags_allow_hexadecimal_numbers & flags_bitset) {
+ if (('0' == src[offset]) &&
+ (('x' == src[offset + 1]) || ('X' == src[offset + 1]))) {
+ /* consume hexadecimal digits. */
+ while ((offset < size) &&
+ (('0' <= src[offset] && src[offset] <= '9') ||
+ ('a' <= src[offset] && src[offset] <= 'f') ||
+ ('A' <= src[offset] && src[offset] <= 'F') ||
+ ('x' == src[offset]) || ('X' == src[offset]))) {
+ data[bytes_written++] = src[offset++];
+ }
+ }
+ }
+
+ while (offset < size) {
+ int end = 0;
+
+ switch (src[offset]) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ case 'e':
+ case 'E':
+ case '+':
+ case '-':
+ data[bytes_written++] = src[offset++];
+ break;
+ default:
+ end = 1;
+ break;
+ }
+
+ if (0 != end) {
+ break;
+ }
+ }
+
+ if (json_parse_flags_allow_inf_and_nan & flags_bitset) {
+ const size_t inf_strlen = 8; /* = strlen("Infinity");. */
+ const size_t nan_strlen = 3; /* = strlen("NaN");. */
+
+ if (offset + inf_strlen < size) {
+ if ('I' == src[offset]) {
+ size_t i;
+ /* We found our special 'Infinity' keyword! */
+ for (i = 0; i < inf_strlen; i++) {
+ data[bytes_written++] = src[offset++];
+ }
+ }
+ }
+
+ if (offset + nan_strlen < size) {
+ if ('N' == src[offset]) {
+ size_t i;
+ /* We found our special 'NaN' keyword! */
+ for (i = 0; i < nan_strlen; i++) {
+ data[bytes_written++] = src[offset++];
+ }
+ }
+ }
+ }
+
+ /* record the size of the number. */
+ number->number_size = bytes_written;
+ /* add null terminator to number string. */
+ data[bytes_written++] = '\0';
+ /* move data along. */
+ state->data += bytes_written;
+ /* update offset. */
+ state->offset = offset;
+}
+
+json_weak void json_parse_value(struct json_parse_state_s *state,
+ int is_global_object, struct json_value_s *value);
+void json_parse_value(struct json_parse_state_s *state,
+ int is_global_object, struct json_value_s *value) {
+ const size_t flags_bitset = state->flags_bitset;
+ const char *const src = state->src;
+ const size_t size = state->size;
+ size_t offset;
+
+ (void)json_skip_all_skippables(state);
+
+ /* cache offset now. */
+ offset = state->offset;
+
+ if (is_global_object) {
+ value->type = json_type_object;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_object_s);
+ json_parse_object(state, /* is_global_object = */ 1,
+ (struct json_object_s *)value->payload);
+ }
+ else {
+ switch (src[offset]) {
+ case '"':
+ case '\'':
+ value->type = json_type_string;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_string_s);
+ json_parse_string(state, (struct json_string_s *)value->payload);
+ break;
+ case '{':
+ value->type = json_type_object;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_object_s);
+ json_parse_object(state, /* is_global_object = */ 0,
+ (struct json_object_s *)value->payload);
+ break;
+ case '[':
+ value->type = json_type_array;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_array_s);
+ json_parse_array(state, (struct json_array_s *)value->payload);
+ break;
+ case '-':
+ case '+':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '.':
+ value->type = json_type_number;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_number_s);
+ json_parse_number(state, (struct json_number_s *)value->payload);
+ break;
+ default:
+ if ((offset + 4) <= size && 't' == src[offset + 0] &&
+ 'r' == src[offset + 1] && 'u' == src[offset + 2] &&
+ 'e' == src[offset + 3]) {
+ value->type = json_type_true;
+ value->payload = json_null;
+ state->offset += 4;
+ }
+ else if ((offset + 5) <= size && 'f' == src[offset + 0] &&
+ 'a' == src[offset + 1] && 'l' == src[offset + 2] &&
+ 's' == src[offset + 3] && 'e' == src[offset + 4]) {
+ value->type = json_type_false;
+ value->payload = json_null;
+ state->offset += 5;
+ }
+ else if ((offset + 4) <= size && 'n' == src[offset + 0] &&
+ 'u' == src[offset + 1] && 'l' == src[offset + 2] &&
+ 'l' == src[offset + 3]) {
+ value->type = json_type_null;
+ value->payload = json_null;
+ state->offset += 4;
+ }
+ else if ((json_parse_flags_allow_inf_and_nan & flags_bitset) &&
+ (offset + 3) <= size && 'N' == src[offset + 0] &&
+ 'a' == src[offset + 1] && 'N' == src[offset + 2]) {
+ value->type = json_type_number;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_number_s);
+ json_parse_number(state, (struct json_number_s *)value->payload);
+ }
+ else if ((json_parse_flags_allow_inf_and_nan & flags_bitset) &&
+ (offset + 8) <= size && 'I' == src[offset + 0] &&
+ 'n' == src[offset + 1] && 'f' == src[offset + 2] &&
+ 'i' == src[offset + 3] && 'n' == src[offset + 4] &&
+ 'i' == src[offset + 5] && 't' == src[offset + 6] &&
+ 'y' == src[offset + 7]) {
+ value->type = json_type_number;
+ value->payload = state->dom;
+ state->dom += sizeof(struct json_number_s);
+ json_parse_number(state, (struct json_number_s *)value->payload);
+ }
+ break;
+ }
+ }
+}
+
+struct json_value_s *
+ json_parse_ex(const void *src, size_t src_size, size_t flags_bitset,
+ void *(*alloc_func_ptr)(void *user_data, size_t size),
+ void *user_data, struct json_parse_result_s *result) {
+ struct json_parse_state_s state;
+ void *allocation;
+ struct json_value_s *value;
+ size_t total_size;
+ int input_error;
+
+ if (result) {
+ result->error = json_parse_error_none;
+ result->error_offset = 0;
+ result->error_line_no = 0;
+ result->error_row_no = 0;
+ }
+
+ if (json_null == src) {
+ /* invalid src pointer was null! */
+ return json_null;
+ }
+
+ state.src = (const char *)src;
+ state.size = src_size;
+ state.offset = 0;
+ state.line_no = 1;
+ state.line_offset = 0;
+ state.error = json_parse_error_none;
+ state.dom_size = 0;
+ state.data_size = 0;
+ state.flags_bitset = flags_bitset;
+
+ input_error = json_get_value_size(
+ &state, (int)(json_parse_flags_allow_global_object & state.flags_bitset));
+
+ if (0 == input_error) {
+ json_skip_all_skippables(&state);
+
+ if (state.offset != state.size) {
+ /* our parsing didn't have an error, but there are characters remaining in
+ * the input that weren't part of the JSON! */
+
+ state.error = json_parse_error_unexpected_trailing_characters;
+ input_error = 1;
+ }
+ }
+
+ if (input_error) {
+ /* parsing value's size failed (most likely an invalid JSON DOM!). */
+ if (result) {
+ result->error = state.error;
+ result->error_offset = state.offset;
+ result->error_line_no = state.line_no;
+ result->error_row_no = state.offset - state.line_offset;
+ }
+ return json_null;
+ }
+
+ /* our total allocation is the combination of the dom and data sizes (we. */
+ /* first encode the structure of the JSON, and then the data referenced by. */
+ /* the JSON values). */
+ total_size = state.dom_size + state.data_size;
+
+ if (json_null == alloc_func_ptr) {
+ allocation = malloc(total_size);
+ }
+ else {
+ allocation = alloc_func_ptr(user_data, total_size);
+ }
+
+ if (json_null == allocation) {
+ /* malloc failed! */
+ if (result) {
+ result->error = json_parse_error_allocator_failed;
+ result->error_offset = 0;
+ result->error_line_no = 0;
+ result->error_row_no = 0;
+ }
+
+ return json_null;
+ }
+
+ /* reset offset so we can reuse it. */
+ state.offset = 0;
+
+ /* reset the line information so we can reuse it. */
+ state.line_no = 1;
+ state.line_offset = 0;
+
+ state.dom = (char *)allocation;
+ state.data = state.dom + state.dom_size;
+
+ if (json_parse_flags_allow_location_information & state.flags_bitset) {
+ struct json_value_ex_s *value_ex = (struct json_value_ex_s *)state.dom;
+ state.dom += sizeof(struct json_value_ex_s);
+
+ value_ex->offset = state.offset;
+ value_ex->line_no = state.line_no;
+ value_ex->row_no = state.offset - state.line_offset;
+
+ value = &(value_ex->value);
+ }
+ else {
+ value = (struct json_value_s *)state.dom;
+ state.dom += sizeof(struct json_value_s);
+ }
+
+ json_parse_value(
+ &state, (int)(json_parse_flags_allow_global_object & state.flags_bitset),
+ value);
+
+ return (struct json_value_s *)allocation;
+}
+
+struct json_value_s *json_parse(const void *src, size_t src_size) {
+ return json_parse_ex(src, src_size, json_parse_flags_default, json_null,
+ json_null, json_null);
+}
+
+struct json_string_s *json_value_as_string(struct json_value_s *const value) {
+ if (value->type != json_type_string) {
+ return json_null;
+ }
+
+ return (struct json_string_s *)value->payload;
+}
+
+struct json_number_s *json_value_as_number(struct json_value_s *const value) {
+ if (value->type != json_type_number) {
+ return json_null;
+ }
+
+ return (struct json_number_s *)value->payload;
+}
+
+struct json_object_s *json_value_as_object(struct json_value_s *const value) {
+ if (value->type != json_type_object) {
+ return json_null;
+ }
+
+ return (struct json_object_s *)value->payload;
+}
+
+struct json_array_s *json_value_as_array(struct json_value_s *const value) {
+ if (value->type != json_type_array) {
+ return json_null;
+ }
+
+ return (struct json_array_s *)value->payload;
+}
+
+int json_value_is_true(const struct json_value_s *const value) {
+ return value->type == json_type_true;
+}
+
+int json_value_is_false(const struct json_value_s *const value) {
+ return value->type == json_type_false;
+}
+
+int json_value_is_null(const struct json_value_s *const value) {
+ return value->type == json_type_null;
+}
+
+json_weak int json_write_minified_get_value_size(const struct json_value_s *value,
+ size_t *size);
+
+json_weak int json_write_get_number_size(const struct json_number_s *number,
+ size_t *size);
+int json_write_get_number_size(const struct json_number_s *number,
+ size_t *size) {
+ json_uintmax_t parsed_number;
+ size_t i;
+
+ if (number->number_size >= 2) {
+ switch (number->number[1]) {
+ default:
+ break;
+ case 'x':
+ case 'X':
+ /* the number is a json_parse_flags_allow_hexadecimal_numbers hexadecimal
+ * so we have to do extra work to convert it to a non-hexadecimal for JSON
+ * output. */
+ parsed_number = json_strtoumax(number->number, json_null, 0);
+
+ i = 0;
+
+ while (0 != parsed_number) {
+ parsed_number /= 10;
+ i++;
+ }
+
+ *size += i;
+ return 0;
+ }
+ }
+
+ /* check to see if the number has leading/trailing decimal point. */
+ i = 0;
+
+ /* skip any leading '+' or '-'. */
+ if ((i < number->number_size) &&
+ (('+' == number->number[i]) || ('-' == number->number[i]))) {
+ i++;
+ }
+
+ /* check if we have infinity. */
+ if ((i < number->number_size) && ('I' == number->number[i])) {
+ const char *inf = "Infinity";
+ size_t k;
+
+ for (k = i; k < number->number_size; k++) {
+ const char c = *inf++;
+
+ /* Check if we found the Infinity string! */
+ if ('\0' == c) {
+ break;
+ }
+ else if (c != number->number[k]) {
+ break;
+ }
+ }
+
+ if ('\0' == *inf) {
+ /* Inf becomes 1.7976931348623158e308 because JSON can't support it. */
+ *size += 22;
+
+ /* if we had a leading '-' we need to record it in the JSON output. */
+ if ('-' == number->number[0]) {
+ *size += 1;
+ }
+ }
+
+ return 0;
+ }
+
+ /* check if we have nan. */
+ if ((i < number->number_size) && ('N' == number->number[i])) {
+ const char *nan = "NaN";
+ size_t k;
+
+ for (k = i; k < number->number_size; k++) {
+ const char c = *nan++;
+
+ /* Check if we found the NaN string! */
+ if ('\0' == c) {
+ break;
+ }
+ else if (c != number->number[k]) {
+ break;
+ }
+ }
+
+ if ('\0' == *nan) {
+ /* NaN becomes 1 because JSON can't support it. */
+ *size += 1;
+
+ return 0;
+ }
+ }
+
+ /* if we had a leading decimal point. */
+ if ((i < number->number_size) && ('.' == number->number[i])) {
+ /* 1 + because we had a leading decimal point. */
+ *size += 1;
+ goto cleanup;
+ }
+
+ for (; i < number->number_size; i++) {
+ const char c = number->number[i];
+ if (!('0' <= c && c <= '9')) {
+ break;
+ }
+ }
+
+ /* if we had a trailing decimal point. */
+ if ((i + 1 == number->number_size) && ('.' == number->number[i])) {
+ /* 1 + because we had a trailing decimal point. */
+ *size += 1;
+ goto cleanup;
+ }
+
+cleanup:
+ *size += number->number_size; /* the actual string of the number. */
+
+ /* if we had a leading '+' we don't record it in the JSON output. */
+ if ('+' == number->number[0]) {
+ *size -= 1;
+ }
+
+ return 0;
+}
+
+json_weak int json_write_get_string_size(const struct json_string_s *string,
+ size_t *size);
+int json_write_get_string_size(const struct json_string_s *string,
+ size_t *size) {
+ size_t i;
+ for (i = 0; i < string->string_size; i++) {
+ switch (string->string[i]) {
+ case '"':
+ case '\\':
+ case '\b':
+ case '\f':
+ case '\n':
+ case '\r':
+ case '\t':
+ *size += 2;
+ break;
+ default:
+ *size += 1;
+ break;
+ }
+ }
+
+ *size += 2; /* need to encode the surrounding '"' characters. */
+
+ return 0;
+}
+
+json_weak int json_write_minified_get_array_size(const struct json_array_s *array,
+ size_t *size);
+int json_write_minified_get_array_size(const struct json_array_s *array,
+ size_t *size) {
+ struct json_array_element_s *element;
+
+ *size += 2; /* '[' and ']'. */
+
+ if (1 < array->length) {
+ *size += array->length - 1; /* ','s seperate each element. */
+ }
+
+ for (element = array->start; json_null != element; element = element->next) {
+ if (json_write_minified_get_value_size(element->value, size)) {
+ /* value was malformed! */
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+json_weak int
+json_write_minified_get_object_size(const struct json_object_s *object,
+ size_t *size);
+int
+json_write_minified_get_object_size(const struct json_object_s *object,
+ size_t *size) {
+ struct json_object_element_s *element;
+
+ *size += 2; /* '{' and '}'. */
+
+ *size += object->length; /* ':'s seperate each name/value pair. */
+
+ if (1 < object->length) {
+ *size += object->length - 1; /* ','s seperate each element. */
+ }
+
+ for (element = object->start; json_null != element; element = element->next) {
+ if (json_write_get_string_size(element->name, size)) {
+ /* string was malformed! */
+ return 1;
+ }
+
+ if (json_write_minified_get_value_size(element->value, size)) {
+ /* value was malformed! */
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+json_weak int json_write_minified_get_value_size(const struct json_value_s *value,
+ size_t *size);
+int json_write_minified_get_value_size(const struct json_value_s *value,
+ size_t *size) {
+ switch (value->type) {
+ default:
+ /* unknown value type found! */
+ return 1;
+ case json_type_number:
+ return json_write_get_number_size((struct json_number_s *)value->payload,
+ size);
+ case json_type_string:
+ return json_write_get_string_size((struct json_string_s *)value->payload,
+ size);
+ case json_type_array:
+ return json_write_minified_get_array_size(
+ (struct json_array_s *)value->payload, size);
+ case json_type_object:
+ return json_write_minified_get_object_size(
+ (struct json_object_s *)value->payload, size);
+ case json_type_true:
+ *size += 4; /* the string "true". */
+ return 0;
+ case json_type_false:
+ *size += 5; /* the string "false". */
+ return 0;
+ case json_type_null:
+ *size += 4; /* the string "null". */
+ return 0;
+ }
+}
+
+json_weak char *json_write_minified_value(const struct json_value_s *value,
+ char *data);
+
+json_weak char *json_write_number(const struct json_number_s *number, char *data);
+char *json_write_number(const struct json_number_s *number, char *data) {
+ json_uintmax_t parsed_number, backup;
+ size_t i;
+
+ if (number->number_size >= 2) {
+ switch (number->number[1]) {
+ default:
+ break;
+ case 'x':
+ case 'X':
+ /* The number is a json_parse_flags_allow_hexadecimal_numbers hexadecimal
+ * so we have to do extra work to convert it to a non-hexadecimal for JSON
+ * output. */
+ parsed_number = json_strtoumax(number->number, json_null, 0);
+
+ /* We need a copy of parsed number twice, so take a backup of it. */
+ backup = parsed_number;
+
+ i = 0;
+
+ while (0 != parsed_number) {
+ parsed_number /= 10;
+ i++;
+ }
+
+ /* Restore parsed_number to its original value stored in the backup. */
+ parsed_number = backup;
+
+ /* Now use backup to take a copy of i, or the length of the string. */
+ backup = i;
+
+ do {
+ *(data + i - 1) = '0' + (char)(parsed_number % 10);
+ parsed_number /= 10;
+ i--;
+ } while (0 != parsed_number);
+
+ data += backup;
+
+ return data;
+ }
+ }
+
+ /* check to see if the number has leading/trailing decimal point. */
+ i = 0;
+
+ /* skip any leading '-'. */
+ if ((i < number->number_size) &&
+ (('+' == number->number[i]) || ('-' == number->number[i]))) {
+ i++;
+ }
+
+ /* check if we have infinity. */
+ if ((i < number->number_size) && ('I' == number->number[i])) {
+ const char *inf = "Infinity";
+ size_t k;
+
+ for (k = i; k < number->number_size; k++) {
+ const char c = *inf++;
+
+ /* Check if we found the Infinity string! */
+ if ('\0' == c) {
+ break;
+ }
+ else if (c != number->number[k]) {
+ break;
+ }
+ }
+
+ if ('\0' == *inf++) {
+ const char *dbl_max;
+
+ /* if we had a leading '-' we need to record it in the JSON output. */
+ if ('-' == number->number[0]) {
+ *data++ = '-';
+ }
+
+ /* Inf becomes 1.7976931348623158e308 because JSON can't support it. */
+ for (dbl_max = "1.7976931348623158e308"; '\0' != *dbl_max; dbl_max++) {
+ *data++ = *dbl_max;
+ }
+
+ return data;
+ }
+ }
+
+ /* check if we have nan. */
+ if ((i < number->number_size) && ('N' == number->number[i])) {
+ const char *nan = "NaN";
+ size_t k;
+
+ for (k = i; k < number->number_size; k++) {
+ const char c = *nan++;
+
+ /* Check if we found the NaN string! */
+ if ('\0' == c) {
+ break;
+ }
+ else if (c != number->number[k]) {
+ break;
+ }
+ }
+
+ if ('\0' == *nan++) {
+ /* NaN becomes 0 because JSON can't support it. */
+ *data++ = '0';
+ return data;
+ }
+ }
+
+ /* if we had a leading decimal point. */
+ if ((i < number->number_size) && ('.' == number->number[i])) {
+ i = 0;
+
+ /* skip any leading '+'. */
+ if ('+' == number->number[i]) {
+ i++;
+ }
+
+ /* output the leading '-' if we had one. */
+ if ('-' == number->number[i]) {
+ *data++ = '-';
+ i++;
+ }
+
+ /* insert a '0' to fix the leading decimal point for JSON output. */
+ *data++ = '0';
+
+ /* and output the rest of the number as normal. */
+ for (; i < number->number_size; i++) {
+ *data++ = number->number[i];
+ }
+
+ return data;
+ }
+
+ for (; i < number->number_size; i++) {
+ const char c = number->number[i];
+ if (!('0' <= c && c <= '9')) {
+ break;
+ }
+ }
+
+ /* if we had a trailing decimal point. */
+ if ((i + 1 == number->number_size) && ('.' == number->number[i])) {
+ i = 0;
+
+ /* skip any leading '+'. */
+ if ('+' == number->number[i]) {
+ i++;
+ }
+
+ /* output the leading '-' if we had one. */
+ if ('-' == number->number[i]) {
+ *data++ = '-';
+ i++;
+ }
+
+ /* and output the rest of the number as normal. */
+ for (; i < number->number_size; i++) {
+ *data++ = number->number[i];
+ }
+
+ /* insert a '0' to fix the trailing decimal point for JSON output. */
+ *data++ = '0';
+
+ return data;
+ }
+
+ i = 0;
+
+ /* skip any leading '+'. */
+ if ('+' == number->number[i]) {
+ i++;
+ }
+
+ for (; i < number->number_size; i++) {
+ *data++ = number->number[i];
+ }
+
+ return data;
+}
+
+json_weak char *json_write_string(const struct json_string_s *string, char *data);
+char *json_write_string(const struct json_string_s *string, char *data) {
+ size_t i;
+
+ *data++ = '"'; /* open the string. */
+
+ for (i = 0; i < string->string_size; i++) {
+ switch (string->string[i]) {
+ case '"':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = '"';
+ break;
+ case '\\':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = '\\';
+ break;
+ case '\b':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = 'b';
+ break;
+ case '\f':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = 'f';
+ break;
+ case '\n':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = 'n';
+ break;
+ case '\r':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = 'r';
+ break;
+ case '\t':
+ *data++ = '\\'; /* escape the control character. */
+ *data++ = 't';
+ break;
+ default:
+ *data++ = string->string[i];
+ break;
+ }
+ }
+
+ *data++ = '"'; /* close the string. */
+
+ return data;
+}
+
+json_weak char *json_write_minified_array(const struct json_array_s *array,
+ char *data);
+char *json_write_minified_array(const struct json_array_s *array,
+ char *data) {
+ struct json_array_element_s *element = json_null;
+
+ *data++ = '['; /* open the array. */
+
+ for (element = array->start; json_null != element; element = element->next) {
+ if (element != array->start) {
+ *data++ = ','; /* ','s seperate each element. */
+ }
+
+ data = json_write_minified_value(element->value, data);
+
+ if (json_null == data) {
+ /* value was malformed! */
+ return json_null;
+ }
+ }
+
+ *data++ = ']'; /* close the array. */
+
+ return data;
+}
+
+json_weak char *json_write_minified_object(const struct json_object_s *object,
+ char *data);
+char *json_write_minified_object(const struct json_object_s *object,
+ char *data) {
+ struct json_object_element_s *element = json_null;
+
+ *data++ = '{'; /* open the object. */
+
+ for (element = object->start; json_null != element;
+ element = element->next) {
+ if (element != object->start) {
+ *data++ = ','; /* ','s seperate each element. */
+ }
+
+ data = json_write_string(element->name, data);
+
+ if (json_null == data) {
+ /* string was malformed! */
+ return json_null;
+ }
+
+ *data++ = ':'; /* ':'s seperate each name/value pair. */
+
+ data = json_write_minified_value(element->value, data);
+
+ if (json_null == data) {
+ /* value was malformed! */
+ return json_null;
+ }
+ }
+
+ *data++ = '}'; /* close the object. */
+
+ return data;
+}
+
+json_weak char *json_write_minified_value(const struct json_value_s *value,
+ char *data);
+char *json_write_minified_value(const struct json_value_s *value,
+ char *data) {
+ switch (value->type) {
+ default:
+ /* unknown value type found! */
+ return json_null;
+ case json_type_number:
+ return json_write_number((struct json_number_s *)value->payload, data);
+ case json_type_string:
+ return json_write_string((struct json_string_s *)value->payload, data);
+ case json_type_array:
+ return json_write_minified_array((struct json_array_s *)value->payload,
+ data);
+ case json_type_object:
+ return json_write_minified_object((struct json_object_s *)value->payload,
+ data);
+ case json_type_true:
+ data[0] = 't';
+ data[1] = 'r';
+ data[2] = 'u';
+ data[3] = 'e';
+ return data + 4;
+ case json_type_false:
+ data[0] = 'f';
+ data[1] = 'a';
+ data[2] = 'l';
+ data[3] = 's';
+ data[4] = 'e';
+ return data + 5;
+ case json_type_null:
+ data[0] = 'n';
+ data[1] = 'u';
+ data[2] = 'l';
+ data[3] = 'l';
+ return data + 4;
+ }
+}
+
+void *json_write_minified(const struct json_value_s *value, size_t *out_size) {
+ size_t size = 0;
+ char *data = json_null;
+ char *data_end = json_null;
+
+ if (json_null == value) {
+ return json_null;
+ }
+
+ if (json_write_minified_get_value_size(value, &size)) {
+ /* value was malformed! */
+ return json_null;
+ }
+
+ size += 1; /* for the '\0' null terminating character. */
+
+ data = (char *)malloc(size);
+
+ if (json_null == data) {
+ /* malloc failed! */
+ return json_null;
+ }
+
+ data_end = json_write_minified_value(value, data);
+
+ if (json_null == data_end) {
+ /* bad chi occurred! */
+ free(data);
+ return json_null;
+ }
+
+ /* null terminated the string. */
+ *data_end = '\0';
+
+ if (json_null != out_size) {
+ *out_size = size;
+ }
+
+ return data;
+}
+
+json_weak int json_write_pretty_get_value_size(const struct json_value_s *value,
+ size_t depth, size_t indent_size,
+ size_t newline_size, size_t *size);
+
+json_weak int json_write_pretty_get_array_size(const struct json_array_s *array,
+ size_t depth, size_t indent_size,
+ size_t newline_size, size_t *size);
+int json_write_pretty_get_array_size(const struct json_array_s *array,
+ size_t depth, size_t indent_size,
+ size_t newline_size, size_t *size) {
+ struct json_array_element_s *element;
+
+ *size += 1; /* '['. */
+
+ if (0 < array->length) {
+ /* if we have any elements we need to add a newline after our '['. */
+ *size += newline_size;
+
+ *size += array->length - 1; /* ','s seperate each element. */
+
+ for (element = array->start; json_null != element;
+ element = element->next) {
+ /* each element gets an indent. */
+ *size += (depth + 1) * indent_size;
+
+ if (json_write_pretty_get_value_size(element->value, depth + 1,
+ indent_size, newline_size, size)) {
+ /* value was malformed! */
+ return 1;
+ }
+
+ /* each element gets a newline too. */
+ *size += newline_size;
+ }
+
+ /* since we wrote out some elements, need to add a newline and indentation.
+ */
+ /* to the trailing ']'. */
+ *size += depth * indent_size;
+ }
+
+ *size += 1; /* ']'. */
+
+ return 0;
+}
+
+json_weak int json_write_pretty_get_object_size(const struct json_object_s *object,
+ size_t depth, size_t indent_size,
+ size_t newline_size,
+ size_t *size);
+int json_write_pretty_get_object_size(const struct json_object_s *object,
+ size_t depth, size_t indent_size,
+ size_t newline_size,
+ size_t *size) {
+ struct json_object_element_s *element;
+
+ *size += 1; /* '{'. */
+
+ if (0 < object->length) {
+ *size += newline_size; /* need a newline next. */
+
+ *size += object->length - 1; /* ','s seperate each element. */
+
+ for (element = object->start; json_null != element;
+ element = element->next) {
+ /* each element gets an indent and newline. */
+ *size += (depth + 1) * indent_size;
+ *size += newline_size;
+
+ if (json_write_get_string_size(element->name, size)) {
+ /* string was malformed! */
+ return 1;
+ }
+
+ *size += 3; /* seperate each name/value pair with " : ". */
+
+ if (json_write_pretty_get_value_size(element->value, depth + 1,
+ indent_size, newline_size, size)) {
+ /* value was malformed! */
+ return 1;
+ }
+ }
+
+ *size += depth * indent_size;
+ }
+
+ *size += 1; /* '}'. */
+
+ return 0;
+}
+
+json_weak int json_write_pretty_get_value_size(const struct json_value_s *value,
+ size_t depth, size_t indent_size,
+ size_t newline_size, size_t *size);
+int json_write_pretty_get_value_size(const struct json_value_s *value,
+ size_t depth, size_t indent_size,
+ size_t newline_size, size_t *size) {
+ switch (value->type) {
+ default:
+ /* unknown value type found! */
+ return 1;
+ case json_type_number:
+ return json_write_get_number_size((struct json_number_s *)value->payload,
+ size);
+ case json_type_string:
+ return json_write_get_string_size((struct json_string_s *)value->payload,
+ size);
+ case json_type_array:
+ return json_write_pretty_get_array_size(
+ (struct json_array_s *)value->payload, depth, indent_size, newline_size,
+ size);
+ case json_type_object:
+ return json_write_pretty_get_object_size(
+ (struct json_object_s *)value->payload, depth, indent_size,
+ newline_size, size);
+ case json_type_true:
+ *size += 4; /* the string "true". */
+ return 0;
+ case json_type_false:
+ *size += 5; /* the string "false". */
+ return 0;
+ case json_type_null:
+ *size += 4; /* the string "null". */
+ return 0;
+ }
+}
+
+json_weak char *json_write_pretty_value(const struct json_value_s *value,
+ size_t depth, const char *indent,
+ const char *newline, char *data);
+
+json_weak char *json_write_pretty_array(const struct json_array_s *array,
+ size_t depth, const char *indent,
+ const char *newline, char *data);
+char *json_write_pretty_array(const struct json_array_s *array,
+ size_t depth, const char *indent,
+ const char *newline, char *data) {
+ size_t k, m;
+ struct json_array_element_s *element;
+
+ *data++ = '['; /* open the array. */
+
+ if (0 < array->length) {
+ for (k = 0; '\0' != newline[k]; k++) {
+ *data++ = newline[k];
+ }
+
+ for (element = array->start; json_null != element;
+ element = element->next) {
+ if (element != array->start) {
+ *data++ = ','; /* ','s seperate each element. */
+
+ for (k = 0; '\0' != newline[k]; k++) {
+ *data++ = newline[k];
+ }
+ }
+
+ for (k = 0; k < depth + 1; k++) {
+ for (m = 0; '\0' != indent[m]; m++) {
+ *data++ = indent[m];
+ }
+ }
+
+ data = json_write_pretty_value(element->value, depth + 1, indent, newline,
+ data);
+
+ if (json_null == data) {
+ /* value was malformed! */
+ return json_null;
+ }
+ }
+
+ for (k = 0; '\0' != newline[k]; k++) {
+ *data++ = newline[k];
+ }
+
+ for (k = 0; k < depth; k++) {
+ for (m = 0; '\0' != indent[m]; m++) {
+ *data++ = indent[m];
+ }
+ }
+ }
+
+ *data++ = ']'; /* close the array. */
+
+ return data;
+}
+
+json_weak char *json_write_pretty_object(const struct json_object_s *object,
+ size_t depth, const char *indent,
+ const char *newline, char *data);
+char *json_write_pretty_object(const struct json_object_s *object,
+ size_t depth, const char *indent,
+ const char *newline, char *data) {
+ size_t k, m;
+ struct json_object_element_s *element;
+
+ *data++ = '{'; /* open the object. */
+
+ if (0 < object->length) {
+ for (k = 0; '\0' != newline[k]; k++) {
+ *data++ = newline[k];
+ }
+
+ for (element = object->start; json_null != element;
+ element = element->next) {
+ if (element != object->start) {
+ *data++ = ','; /* ','s seperate each element. */
+
+ for (k = 0; '\0' != newline[k]; k++) {
+ *data++ = newline[k];
+ }
+ }
+
+ for (k = 0; k < depth + 1; k++) {
+ for (m = 0; '\0' != indent[m]; m++) {
+ *data++ = indent[m];
+ }
+ }
+
+ data = json_write_string(element->name, data);
+
+ if (json_null == data) {
+ /* string was malformed! */
+ return json_null;
+ }
+
+ /* " : "s seperate each name/value pair. */
+ *data++ = ' ';
+ *data++ = ':';
+ *data++ = ' ';
+
+ data = json_write_pretty_value(element->value, depth + 1, indent, newline,
+ data);
+
+ if (json_null == data) {
+ /* value was malformed! */
+ return json_null;
+ }
+ }
+
+ for (k = 0; '\0' != newline[k]; k++) {
+ *data++ = newline[k];
+ }
+
+ for (k = 0; k < depth; k++) {
+ for (m = 0; '\0' != indent[m]; m++) {
+ *data++ = indent[m];
+ }
+ }
+ }
+
+ *data++ = '}'; /* close the object. */
+
+ return data;
+}
+
+json_weak char *json_write_pretty_value(const struct json_value_s *value,
+ size_t depth, const char *indent,
+ const char *newline, char *data);
+char *json_write_pretty_value(const struct json_value_s *value,
+ size_t depth, const char *indent,
+ const char *newline, char *data) {
+ switch (value->type) {
+ default:
+ /* unknown value type found! */
+ return json_null;
+ case json_type_number:
+ return json_write_number((struct json_number_s *)value->payload, data);
+ case json_type_string:
+ return json_write_string((struct json_string_s *)value->payload, data);
+ case json_type_array:
+ return json_write_pretty_array((struct json_array_s *)value->payload, depth,
+ indent, newline, data);
+ case json_type_object:
+ return json_write_pretty_object((struct json_object_s *)value->payload,
+ depth, indent, newline, data);
+ case json_type_true:
+ data[0] = 't';
+ data[1] = 'r';
+ data[2] = 'u';
+ data[3] = 'e';
+ return data + 4;
+ case json_type_false:
+ data[0] = 'f';
+ data[1] = 'a';
+ data[2] = 'l';
+ data[3] = 's';
+ data[4] = 'e';
+ return data + 5;
+ case json_type_null:
+ data[0] = 'n';
+ data[1] = 'u';
+ data[2] = 'l';
+ data[3] = 'l';
+ return data + 4;
+ }
+}
+
+void *json_write_pretty(const struct json_value_s *value, const char *indent,
+ const char *newline, size_t *out_size) {
+ size_t size = 0;
+ size_t indent_size = 0;
+ size_t newline_size = 0;
+ char *data = json_null;
+ char *data_end = json_null;
+
+ if (json_null == value) {
+ return json_null;
+ }
+
+ if (json_null == indent) {
+ indent = " "; /* default to two spaces. */
+ }
+
+ if (json_null == newline) {
+ newline = "\n"; /* default to linux newlines. */
+ }
+
+ while ('\0' != indent[indent_size]) {
+ ++indent_size; /* skip non-null terminating characters. */
+ }
+
+ while ('\0' != newline[newline_size]) {
+ ++newline_size; /* skip non-null terminating characters. */
+ }
+
+ if (json_write_pretty_get_value_size(value, 0, indent_size, newline_size,
+ &size)) {
+ /* value was malformed! */
+ return json_null;
+ }
+
+ size += 1; /* for the '\0' null terminating character. */
+
+ data = (char *)malloc(size);
+
+ if (json_null == data) {
+ /* malloc failed! */
+ return json_null;
+ }
+
+ data_end = json_write_pretty_value(value, 0, indent, newline, data);
+
+ if (json_null == data_end) {
+ /* bad chi occurred! */
+ free(data);
+ return json_null;
+ }
+
+ /* null terminated the string. */
+ *data_end = '\0';
+
+ if (json_null != out_size) {
+ *out_size = size;
+ }
+
+ return data;
+}
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#elif defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
+#endif /* SHEREDOM_JSON_H_INCLUDED. */
Application development package for Dali 3D engine toolkit - headers and package config
##############################
+# dali-scene-loader
+##############################
+%define dali2_scene_loader dali2-scene-loader
+%package -n %{dali2_scene_loader}
+Summary: DLI scene loading library
+Group: System/Libraries
+License: Apache-2.0
+
+BuildRequires: pkgconfig(dali2-toolkit)
+
+%description -n %{dali2_scene_loader}
+Provides functionality for loading and displaying DLI format scenes. See README.md for more details.
+
+%package -n %{dali2_scene_loader}-devel
+Summary: Development components for dali-scene-loader
+Group: Development/Building
+Requires: %{dali2_scene_loader} = %{version}-%{release}
+
+%description -n %{dali2_scene_loader}-devel
+Development components for dali-scene-loader.
+
+##############################
# Preparation
##############################
%prep
%define dali_toolkit_style_files %{dali_data_ro_dir}/toolkit/styles/
%define dev_include_path %{_includedir}
+%define dali_xml_file_dir %TZ_SYS_RO_PACKAGES
+
# PO
{
cd %{_builddir}/dali2-toolkit-%{version}/dali-toolkit/po
LDFLAGS+=" --coverage "
%endif
+%ifarch %{arm}
+CXXFLAGS+=" -D_ARCH_ARM_"
+%endif
+
libtoolize --force
cd %{_builddir}/dali2-toolkit-%{version}/build/tizen
%{dali_toolkit_style_files}/1920x1080/*
%{dali_toolkit_style_files}/default-feedback-theme.json
%{_datadir}/locale/*/LC_MESSAGES/*
+
+%files -n %{dali2_scene_loader}
+%if 0%{?enable_dali_smack_rules}
+%manifest dali-scene-loader.manifest-smack
+%else
+%manifest dali-scene-loader.manifest
+%endif
+%defattr(-,root,root,-)
+%{_libdir}/lib%{dali2_scene_loader}.so
+%license LICENSE
+
+%files -n %{dali2_scene_loader}-devel
+%defattr(-,root,root,-)
+%{_includedir}/dali-scene-loader/public-api/*
+%{_libdir}/pkgconfig/dali2-scene-loader.pc