Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 2,271 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Request Random N... | 19683657 | 609 days ago | IN | 0 ETH | 0.00247767 | ||||
| Request Random N... | 19481226 | 637 days ago | IN | 0 ETH | 0.00528336 | ||||
| Request Random N... | 19481212 | 637 days ago | IN | 0 ETH | 0.00533838 | ||||
| Request Random N... | 19224460 | 673 days ago | IN | 0 ETH | 0.00603548 | ||||
| Request Random N... | 19164113 | 682 days ago | IN | 0 ETH | 0.00509928 | ||||
| Request Random N... | 19016732 | 703 days ago | IN | 0 ETH | 0.0052903 | ||||
| Request Random N... | 18875652 | 722 days ago | IN | 0 ETH | 0.00387932 | ||||
| Request Random N... | 18873580 | 723 days ago | IN | 0 ETH | 0.00311362 | ||||
| Request Random N... | 18844621 | 727 days ago | IN | 0 ETH | 0.0048903 | ||||
| Request Random N... | 18396017 | 790 days ago | IN | 0 ETH | 0.0018717 | ||||
| Request Random N... | 18069942 | 835 days ago | IN | 0 ETH | 0.00259498 | ||||
| Request Random N... | 17900478 | 859 days ago | IN | 0 ETH | 0.00430799 | ||||
| Request Random N... | 17835622 | 868 days ago | IN | 0 ETH | 0.0059086 | ||||
| Request Random N... | 17798843 | 873 days ago | IN | 0 ETH | 0.00496194 | ||||
| Request Random N... | 17416781 | 927 days ago | IN | 0 ETH | 0.00918989 | ||||
| Request Random N... | 17416770 | 927 days ago | IN | 0 ETH | 0.00568176 | ||||
| Request Random N... | 17408976 | 928 days ago | IN | 0 ETH | 0.00492584 | ||||
| Request Random N... | 17389494 | 931 days ago | IN | 0 ETH | 0.00915094 | ||||
| Request Random N... | 17370005 | 933 days ago | IN | 0 ETH | 0.01254116 | ||||
| Request Random N... | 17338185 | 938 days ago | IN | 0 ETH | 0.01199951 | ||||
| Request Random N... | 17301274 | 943 days ago | IN | 0 ETH | 0.0063454 | ||||
| Request Random N... | 17301264 | 943 days ago | IN | 0 ETH | 0.00671371 | ||||
| Request Random N... | 17296313 | 944 days ago | IN | 0 ETH | 0.0153486 | ||||
| Request Random N... | 17264580 | 948 days ago | IN | 0 ETH | 0.00756497 | ||||
| Request Random N... | 17228200 | 953 days ago | IN | 0 ETH | 0.01046617 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
DGFamilyReveal
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/security/ReentrancyGuard.sol";
import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "./DGFamilyCollection.sol";
import "./DGFamilyGlassBox.sol";
/**
* DGFamily Glass Box Reveal
* https://drops.unxd.com/dgfamily
*
* The contract will handle the reveal phase of the DGFamily Glass Boxes.
* After the sale is done and reveal phase starts, users will able to burn their glass box in return for
* the Black, Gold and Platinum Boxes.
*/
contract DGFamilyReveal is
Ownable,
VRFConsumerBaseV2,
ReentrancyGuard
{
/**************************************************************************************************
* DGFamilyCollection will have total supply of 5000. The distribution of Platinum/Gold/Black boxes
* will be as below. Box Types are identified by token index range.
*
*
* Platinum Boxes: #1-75 (Index Range)
* #48, 56, 57, 59, 61, 62, 63, 64, 65, 68, 70, 71, 72, 73, 74
* 15 Platinum boxes.
*
* Gold Boxes: #76-750 (Index Range)
* #76-745
* 670 Gold boxes.
*
* Black Boxes: #751-5000 (Index Range)
* #751-5000
* 4250 Black boxes.
*
* Seed contains => 15 Platinum Boxes, 670 Gold Boxes and 4250 Black Boxes
* Total => 4935
***************************************************************************************************/
uint16[] public seed = [1982,739,329,2506,4524,4704,4814,3891,2602,2490,3157,4885,2933,4976,1081,581,3689,3884,3543,3842,4142,459,1318,1127,1461,4650,1351,1108,777,4114,4411,1530,1244,4376,2414,4075,2286,2380,3972,2420,4314,3824,3430,4308,491,3452,440,1532,2000,2004,856,1812,3967,3533,2045,1203,3260,1770,1873,277,1314,2502,634,3953,2465,2471,3635,4003,1768,3657,4713,2464,3994,2835,1181,3387,4515,1022,723,2144,2669,4329,611,4226,1551,3300,4959,3105,325,3568,3650,4792,3400,1672,4293,4387,4591,3943,1922,2632,2383,1212,4196,2336,137,1284,2972,2294,2926,419,900,3490,2702,2213,4550,4210,4184,1695,3028,1913,3909,4219,1055,2351,1923,3512,3252,961,4581,802,2338,3145,3863,2682,3679,1225,1280,2649,1330,2064,2910,4415,4577,3916,4034,3336,1698,4574,3547,2656,3254,3000,4449,4397,4047,1851,484,2511,1715,1370,1419,4123,960,1712,2493,3869,2214,1586,1125,3807,1092,4276,2115,2781,2335,3797,3627,165,2979,1533,4110,3858,4364,2805,4652,4145,4883,4863,959,4815,2151,2517,4115,3843,1360,3988,4944,463,3036,1619,4060,626,2252,2706,2855,4183,2551,1363,3287,3762,2154,1078,4816,3160,4005,4306,1664,679,2954,2242,4008,725,2008,3444,307,2598,2999,174,3043,4750,4942,804,2267,2293,83,3589,1501,1412,1058,3605,1068,3816,3859,3900,2634,534,4663,762,1261,3131,4084,2067,4995,2296,878,3272,2364,4583,1792,2514,898,81,3309,881,1806,1131,1909,3277,138,1771,521,3022,203,4957,4731,1494,1159,4407,3381,391,327,939,1392,2853,4136,1731,134,1333,710,248,3436,4349,4181,3698,1520,2412,3258,1458,3425,563,542,1285,1478,1408,3806,3787,2526,4447,3721,4560,3991,1624,3067,1841,2928,1298,360,1060,615,3371,975,48,924,4831,1590,3643,4682,3322,4910,4953,3801,3873,3729,866,973,582,1282,4602,1544,3694,2863,2750,941,1579,1847,585,1825,1192,1155,4057,1391,3504,2794,362,4365,2995,4541,1647,1437,2413,1785,3138,1576,2530,3491,240,2422,2840,3155,2310,4690,483,1186,4997,1820,1434,3745,510,1308,1206,97,1445,2223,2023,4645,987,2857,1657,2181,4379,4138,4277,431,4505,3486,2816,2749,3421,3435,630,1705,3071,1299,4066,981,2468,2977,1254,1228,4199,1233,2695,4511,2836,4729,3132,4299,547,3507,3077,197,2406,382,3324,253,4435,2913,2982,1523,1042,98,1279,4620,4232,1278,3788,2041,3699,4171,4632,105,4952,2106,4044,1149,1492,1365,2087,3455,4268,2730,2873,2694,1562,4634,3583,2731,1780,4822,1782,4758,1334,296,103,4772,208,189,2691,449,2878,2219,995,1652,2035,114,696,291,1453,4283,2469,4091,3646,2714,2581,194,4941,1502,1482,3493,3935,758,2117,2301,1987,2801,3754,2432,3274,1767,4636,2271,4400,2316,3166,2898,82,948,2342,4987,4784,3087,2368,2520,3195,4147,1634,4383,3103,3813,374,3135,3626,3914,4933,3722,436,4968,476,202,2437,4346,1510,1324,2195,71,418,2893,1410,3056,1905,2636,4585,1917,848,3571,4187,4290,544,2220,2906,4639,4730,953,321,4593,4594,241,2049,1100,1522,1152,2932,1584,2556,3714,807,2344,1725,3771,3123,937,62,4683,2567,3753,4320,785,2537,3828,3339,3063,513,790,3883,3919,1143,952,870,3550,4370,2016,2311,4889,2480,4605,3271,257,3737,4829,4036,3017,1822,683,1934,2202,3625,1033,4681,1660,1387,928,2235,2429,2653,825,4113,4961,3775,2994,1145,1489,4966,1327,1539,4448,4791,3704,968,2618,4835,2947,3211,3544,4394,2819,1843,1994,2326,2668,4733,2444,2174,1459,603,849,753,3382,2279,3564,2789,3031,1114,73,3233,3594,4434,254,3081,2676,3276,2329,3178,3481,3107,4766,2849,4898,3165,3534,141,59,330,3705,4143,2531,4556,543,2975,1388,2047,2780,4589,1650,2983,3340,283,2862,2216,3094,3848,2450,3653,761,3227,1176,4700,199,1691,1118,1582,922,3767,1856,811,1182,4543,2442,4744,4990,4923,1999,4190,2454,308,2425,4444,4770,4310,1739,1080,245,624,4646,2478,4569,1472,2472,3222,4530,2964,2631,2763,3251,389,2260,4102,2489,2762,3289,1427,4201,4539,2321,3035,4390,3514,4954,4261,914,2619,3538,4342,1306,2738,485,3569,693,3232,3680,984,4271,3137,4369,1372,343,2384,285,2597,1439,3197,4432,359,781,1375,172,1749,4549,3736,3203,185,4629,3204,1267,1928,1493,3118,4212,1593,2667,1699,445,602,810,1985,4104,755,3755,4464,4980,3257,926,1648,3551,3062,2052,4446,3262,2914,1608,2470,2175,4691,4068,1303,3263,473,537,3759,1386,2247,4146,3027,2937,398,4782,1973,2146,4211,4536,3315,1726,3793,962,1264,1071,4059,2698,1260,4736,4317,954,2569,242,1018,4203,3172,3572,4072,2014,3199,226,1636,1550,2160,2881,1497,686,1742,181,4103,2130,357,1897,3110,947,4827,4288,1732,3372,2011,2317,3658,1556,1052,3996,4894,460,2739,272,413,2377,1028,4624,4258,1718,3691,3428,1171,3112,3268,2399,2859,4847,2681,2692,1621,3255,1823,4479,631,4897,4476,2449,4790,376,2095,3218,2962,4238,1561,1703,4506,2145,4130,3665,1754,2395,2509,239,1347,605,2021,1304,1602,2949,3932,3465,1026,3323,3440,2098,4374,2733,3634,403,3116,3990,2729,3928,839,2249,907,2270,2677,2261,3766,815,3226,1775,1357,2020,353,4930,2589,2657,3866,1701,1626,1027,4077,2800,3299,1491,4494,3416,4779,3337,2108,4015,2770,1744,421,1349,1241,1123,1090,681,3221,2843,3184,735,2375,1290,3423,3237,4958,3836,3005,1547,2093,4689,2813,3096,3390,976,3862,1727,3969,1571,4762,4338,4126,4315,2229,3407,3414,2183,985,4220,3212,1148,4603,1289,1563,122,2611,2563,344,2693,3789,3537,2679,872,4875,379,2769,2904,2939,882,1620,1629,1878,3069,247,2829,3683,409,4586,2911,1471,4046,3642,3383,3007,1988,1216,3106,1037,1972,2903,3662,1700,1021,1266,2080,2790,1888,2663,86,2582,3822,859,4865,1135,996,3453,1061,4107,4208,3117,3530,861,3854,3182,3068,2578,3908,899,1777,978,578,4886,4433,4592,429,3325,2723,935,4544,2486,3835,444,2193,3867,1237,148,1816,1361,2573,2178,3159,2157,2328,368,2234,712,4793,3450,2415,664,1756,273,4019,4765,3021,507,1681,2211,3220,2027,4485,3844,271,428,4820,472,120,1047,3685,1094,4915,3366,2541,1631,3707,1312,3174,910,408,1311,1069,4975,3670,4493,4635,3716,149,1464,4956,1323,4783,235,4481,1671,4207,1371,4611,4527,2806,4676,4879,367,4571,3238,850,3298,4726,2461,1991,95,2612,2887,2231,1665,4841,1188,3621,3820,1044,1964,852,2104,1043,1804,1173,969,2428,2852,2613,349,1603,3697,3638,1442,1366,2699,498,4426,3427,4913,1339,3219,2285,4122,891,531,4561,1142,3104,160,2284,2837,385,223,583,1947,4422,465,668,3037,1622,4245,3113,3556,348,2244,1019,1029,4105,3224,4509,1835,3827,2834,2096,4798,1505,4257,4474,2900,4401,1861,3817,3558,4600,1645,4182,687,3541,3193,2462,136,3633,1736,4093,3095,1846,1219,663,1553,2799,897,854,1567,1554,1384,2605,1531,4513,3080,4027,2291,3185,2167,3825,355,738,1301,4131,970,559,3821,3351,4922,2929,1779,1008,3168,2680,3904,4710,92,4388,4672,2268,1961,1638,2272,131,3812,4007,4333,519,3051,4339,4760,4868,4162,613,4937,126,3622,791,1892,3437,4562,108,3772,774,452,1908,4035,3295,2617,4609,3865,4425,1197,4157,4969,354,4393,4794,2783,2720,358,934,4525,4234,4484,1256,229,2674,1085,3102,3109,2028,4846,1331,1024,1251,1642,728,4854,2128,4160,220,523,4614,1309,2273,1185,2350,4533,1802,2498,3266,1697,2484,1297,4359,3933,765,2243,3294,1015,3948,4647,2269,2105,4278,3246,2212,299,3945,4297,1591,2851,3180,3877,564,1355,1710,797,3923,812,2076,378,688,1803,2441,180,3023,1676,3949,1190,4193,3576,2917,597,276,3244,4752,1463,4654,680,2547,575,4498,1223,1852,1980,2038,2924,844,745,3957,4086,1979,3401,3595,3004,1077,352,474,971,4361,350,4021,90,411,731,256,4860,2481,4535,3673,2934,3242,1772,4492,826,3874,783,4064,3020,430,2078,3415,1097,3259,1234,4295,3147,614,3353,2330,4243,3173,3075,4112,2970,4964,3925,1500,76,4523,857,586,3024,2628,911,1977,1300,3645,4418,4517,682,4141,1268,480,1187,468,265,2879,2057,1653,3579,1545,1837,2719,1307,2060,991,4522,113,4095,3942,2403,2149,2705,1870,4231,1036,3879,4597,1242,3678,426,3800,4716,309,2974,3032,1430,3256,3040,604,4356,4127,2670,361,2387,4304,218,3397,2488,4380,1543,2124,4725,963,1659,1766,3446,1855,1864,892,3962,3809,2847,2362,2205,3388,3922,3319,4451,860,1824,116,1054,2624,4692,2411,567,1692,4595,3659,4247,675,1938,1574,167,4623,2518,1295,1320,1679,268,3194,3146,2473,4172,2640,654,1422,4625,3142,4089,1658,3808,2177,3954,2239,3718,4668,2308,591,315,3603,4849,1273,2046,1103,1128,4368,2081,2830,540,3739,4626,3559,4578,2576,3764,943,267,1787,3030,871,2094,2485,3847,3245,771,3347,2512,2978,3768,217,3887,3845,3190,4722,767,988,4098,1329,3369,1941,1031,2356,2540,3210,1446,1259,3492,372,3700,2854,396,3307,282,339,2072,596,3555,4176,1121,2409,3770,4951,4244,2894,684,685,3496,4140,3982,1088,4548,4316,2192,264,628,2088,3676,1321,2734,1073,3536,2654,894,384,1737,4657,1483,79,3488,3839,1828,1178,4463,1238,3125,4092,4256,1328,2500,2897,4706,904,2895,3757,2861,732,2599,923,1095,1084,972,642,1833,1200,4416,599,2194,1685,1046,338,186,1838,1070,865,1163,3053,3655,1460,4839,486,4168,2793,800,2074,2560,1517,2665,499,1112,4164,806,4006,1939,2561,475,4708,632,1305,3432,1168,3868,1253,3318,716,100,571,1906,2985,2361,4996,4437,1907,3346,244,144,1689,4266,1287,2355,2245,392,4431,2110,2884,2572,1845,3644,863,3208,3419,893,4512,2539,1476,3320,3153,4640,4009,3979,2522,3223,594,1874,2155,478,1064,1157,2447,2885,4621,1839,2007,3581,1034,2998,1853,1911,3418,2950,346,1723,224,2546,1881,3019,656,1221,4773,2760,3973,4398,620,913,4331,1496,3384,4325,3511,135,2768,1557,673,3395,4781,780,1195,2759,292,3368,2419,4367,4938,2376,715,3396,1326,1383,184,587,3682,4087,3931,1891,263,1252,1479,2960,3777,347,1294,1826,3499,757,2297,3273,1120,1429,2024,2061,3710,3885,1104,1751,3393,4842,4495,4327,1945,269,951,4714,4653,3615,2352,3964,908,2165,4807,4267,1438,1503,4502,1729,2942,737,3915,4606,1537,3344,219,3701,188,4737,1546,3610,2554,492,3647,3506,4026,4921,3086,335,3712,4534,2276,877,2388,4935,659,727,3695,4471,530,3191,4094,2838,3380,539,1840,3016,1343,4178,422,1106,3516,290,2848,2992,2869,2864,3703,3934,4477,4677,3341,4916,565,130,4661,4074,2558,2779,2029,4575,858,3413,1560,4312,512,4223,2944,2622,4490,2527,3164,3128,1183,590,4303,1010,332,3314,4462,697,2655,2186,3886,1848,4040,3161,3897,2525,2651,2044,2264,3779,1643,4873,3668,2224,4851,1540,786,4926,1875,1342,433,4909,4810,2391,4472,4125,1616,3464,2263,1504,1776,3472,3881,751,1717,1513,375,2238,4225,577,3002,1919,3375,2445,316,3365,669,3740,1598,2776,297,2557,2082,1208,820,788,702,1124,318,3151,3607,658,443,1836,4011,2955,3763,4358,4892,1374,4340,4215,2164,266,2389,2034,4555,1518,1470,1524,2253,1205,145,1377,417,4504,3774,2332,2877,3838,903,966,526,4684,4988,4042,2168,3279,1255,230,4081,1398,1609,412,1249,1635,3612,1797,481,4108,3815,3187,2233,399,1585,1111,4828,639,1527,3872,404,3590,4545,4853,3520,1741,919,2716,221,901,4866,2936,3518,2986,1338,4742,3726,2018,1368,637,2135,4192,3189,312,225,2726,4582,420,1210,4389,1451,4109,4823,1041,393,1432,4200,3826,171,3296,3150,1487,3304,831,3426,1759,3539,916,2583,1201,156,3206,885,822,4440,2747,2876,4250,1269,3756,4630,4570,2398,2688,2591,4801,2961,3898,1526,3014,3420,2492,4384,4870,1706,3941,1435,4950,2114,1788,1396,4465,2984,4588,4755,2017,2315,4806,1086,552,423,4205,1337,3529,3089,3479,3769,4642,1915,1783,4055,1162,2182,4496,1115,1101,1716,1456,3154,1172,4206,864,795,2139,1910,1179,1745,2844,3938,4510,1072,4135,4012,1552,1669,380,1981,3029,4764,2491,3527,3352,1485,340,2077,336,3687,4185,4745,2025,1793,3213,2322,3692,2754,2940,2129,4204,2150,1644,1270,2808,1743,207,4984,538,1013,3663,1651,2807,3144,4177,3983,1730,4862,2068,3906,1413,1414,2871,4023,2666,3391,3064,1293,1757,456,1367,1000,1789,4302,4151,895,4579,2373,302,1568,4242,4443,1462,3798,3278,1807,2659,535,3306,4649,3732,3378,4900,5000,946,4323,3373,711,3574,177,3654,4170,4457,518,875,979,1379,4285,139,2804,667,3025,2169,1226,4608,4929,4821,2185,1154,1623,2112,3409,2153,3761,958,3328,2907,4743,3297,2086,259,2644,734,4939,1498,660,1475,4031,1817,3671,94,4641,3335,2030,2295,2070,3292,1380,1395,1240,1421,3870,2604,1693,2309,2246,1808,549,289,4321,3084,2516,3580,4693,3308,929,1296,880,994,2922,4727,3467,1473,1929,4763,2543,1713,2784,4079,592,4615,3119,2457,187,72,2171,2621,1818,68,2559,1005,3785,588,569,1409,566,950,448,1344,204,2773,4450,3350,809,4396,1275,3652,3234,832,706,3261,4227,2479,1769,2319,1575,2307,390,938,3513,2858,736,1440,4313,3100,2938,2372,2303,2378,1765,666,827,4420,3837,4809,665,1735,1827,580,3083,677,4106,3410,1017,740,1102,2248,4382,1755,4254,4063,4466,4826,1904,1606,3731,2382,4275,4132,3291,1746,2802,4292,3079,1748,3917,1549,295,2191,3624,763,3469,1834,4402,2991,3567,2767,2393,2013,1230,3475,838,1170,2091,4882,2102,4062,3834,2727,1733,4259,3546,191,281,999,782,1193,3358,742,2645,2981,608,1704,3065,942,4856,2856,3059,215,2324,2188,3681,1958,3892,2113,1974,381,4728,4454,3796,692,179,4097,1661,4209,3792,4757,334,4328,3735,4761,1962,609,1983,3902,1656,1231,4442,884,3773,4843,2386,3101,3709,1863,550,1633,2431,1778,2590,4998,127,3880,2392,2638,4850,2390,3896,2965,4381,2700,1687,4631,1358,371,2718,3519,2593,2586,3598,3963,2339,4024,1402,1415,2577,3713,709,2402,3048,4282,1096,889,4662,3743,514,1014,2340,4048,4749,323,3478,4372,4085,4139,3563,3050,405,1426,2262,3152,2288,600,3377,2513,1040,3629,4797,2189,834,4439,2161,3742,4924,1196,2782,370,1469,3602,4638,2348,3045,2968,1079,1535,2460,560,3628,500,2571,4054,3057,1248,1302,2615,4161,4326,3672,678,3802,1137,2084,4073,4311,2133,701,2056,814,2635,515,3531,4724,3462,1113,324,3631,3376,2127,4152,1310,1566,821,1666,3570,4335,3198,2320,3981,4453,3445,2658,1992,1117,4217,2476,63,1800,3039,2051,4409,3250,4274,4022,3810,3134,1618,182,1588,3814,2883,4030,4590,3566,930,617,2032,70,874,3441,940,1158,4001,4812,4038,1418,4799,3554,3505,1680,3750,3577,805,1857,2764,833,462,1087,801,4000,3143,2545,104,2083,293,2085,2006,4202,2236,4404,246,3176,789,1565,3247,1403,1936,2417,1516,482,249,4832,3549,2265,328,2803,4118,2043,3760,4627,4658,1406,4216,4872,3525,3677,4165,1336,570,4927,3281,4616,1995,1728,1003,3431,4753,4845,2923,2121,503,211,2504,1862,1417,2230,3910,4679,1684,867,124,4788,896,3348,579,2987,1686,1214,446,3360,4838,3829,1016,4878,977,2289,447,3186,2880,998,1405,4601,2459,4039,956,1605,754,1023,4405,4262,853,2400,3449,3724,3738,517,965,1604,2534,1511,2510,3412,1933,4117,2550,434,2905,1564,3140,1397,4065,2079,4553,4584,1536,2822,2710,2902,1452,107,3690,337,2792,4651,2435,4236,4598,3748,4613,1394,2012,2633,388,2170,4972,2111,4903,2980,4345,4777,3952,4248,140,3875,2818,4090,4891,730,4399,3085,1525,4531,4041,1011,3744,4778,2349,1335,1969,986,1955,2927,982,2163,589,2463,439,4241,3501,845,1682,1762,3330,4912,2179,3357,1617,1714,4497,2796,3433,3985,622,3121,3907,1573,2912,1831,3399,4412,3955,1641,3980,1989,3893,2222,2280,1871,154,2515,4711,4013,1133,2650,1488,3974,1045,1667,4385,1696,572,2701,505,497,3855,3976,2712,855,1615,3664,2722,4644,529,1194,1721,2809,123,4818,722,3267,3231,3747,647,4322,2203,3442,1257,2687,4343,1578,2675,2254,4840,1577,2711,3727,905,3447,4643,2916,2100,2609,689,4970,983,3216,3317,2870,3540,495,2812,1529,425,132,2627,671,1896,616,2092,159,2548,3575,1007,3127,3749,489,2497,4803,584,3477,1447,2908,989,4529,2777,1997,4558,170,3044,3460,1105,4436,2595,1688,4337,1009,4269,2538,2066,3588,2298,2626,3283,1799,1819,1872,2026,2724,3636,4813,4305,4235,766,4230,2901,2503,2367,142,2131,4373,3124,1512,129,1752,636,4622,4718,493,4659,1424,4967,4887,1628,4925,3901,2033,441,3930,2325,4540,4516,4428,3402,3927,1613,435,2292,3149,190,2728,902,3355,2090,1935,3649,2416,835,322,3434,4739,1747,3136,2440,106,250,1986,2042,4707,3818,2405,4709,3169,373,3009,2436,876,152,1180,326,2620,2467,3587,1724,1946,3288,3282,4076,2865,3585,4100,927,2875,4948,3911,676,3711,3523,4352,1654,2359,3230,2208,2772,3214,2240,80,4618,4445,2574,4088,4195,1286,1139,401,561,4377,4985,4307,4702,1153,4945,1416,3548,88,3899,65,576,1316,1960,2446,4675,726,1811,3999,3741,1354,3329,4552,3385,655,4392,4071,650,4901,2642,1786,2827,3090,4741,3944,2751,4301,4263,1345,4148,4688,402,4685,784,4294,4888,1382,4438,1890,3162,3379,4869,3010,1930,1359,3674,3648,1509,231,4334,2715,2031,4417,2890,2662,1006,3331,2673,3066,4286,288,2505,1083,2766,4194,3619,490,2448,96,1854,4363,4551,1595,1877,3179,1109,183,364,477,593,4768,1570,4175,2736,1407,2162,2109,2652,2660,4747,209,2116,119,1976,1271,619,3466,1191,1655,4715,2443,3986,2166,1592,1352,4908,3454,1998,4129,3993,453,2158,1420,2956,646,1053,1805,3895,4936,3013,548,3666,1056,2241,1720,993,4229,212,651,2053,1499,1601,3229,3463,3565,3217,2394,3667,3482,944,4918,4353,4824,1001,2811,3209,1246,2069,1927,2643,4289,4965,2896,2401,3042,4080,4069,787,365,1199,4940,1075,274,703,4355,3156,2421,3474,2482,2282,1559,2283,3617,3639,4134,2685,4962,4911,4811,3936,2788,4296,717,3823,817,1953,1263,2495,3929,3864,3181,168,568,3456,2299,1607,4017,3097,110,4043,3139,4429,1449,4251,4705,310,4051,2381,3239,2533,2785,162,1627,1639,427,279,4805,1441,3470,2791,733,918,1646,3099,2614,1683,4991,886,1506,3992,3126,836,2690,2989,4855,3122,1288,4010,997,741,4478,284,317,4932,2973,2775,3170,4410,1004,3001,1901,3058,1521,1957,3386,2996,213,2521,2001,3398,3856,1903,1177,2226,3937,4723,494,555,1222,4270,1719,4830,3008,4458,3088,3522,4150,2228,4360,2197,3215,2126,3356,4233,2346,1912,414,2741,4413,828,4703,4992,238,4696,4351,2507,4617,3561,2159,2584,3995,2187,3965,1098,4789,1858,2397,146,3111,743,601,1332,4198,525,4880,2637,2278,4537,2499,1116,3498,4249,621,1224,341,1217,1385,3725,1709,4983,3280,3183,3429,4971,1378,2771,2966,1810,2990,1971,957,3924,1815,2353,4721,1039,1722,3461,125,3417,4214,1239,457,532,2608,1763,2697,2639,1794,3141,2062,1951,206,2594,1599,454,1151,3243,3303,520,4720,3448,2019,3424,4222,2725,4687,2120,3946,1859,1450,4332,2696,980,369,3012,1632,4599,2580,471,2250,4756,627,4596,3133,2872,2815,3958,4666,173,2585,4974,3819,278,1126,3596,1136,4330,4319,1089,4375,2737,2347,2713,1528,1428,1784,176,2795,3706,56,3786,2404,4371,2587,3241,3484,2275,3959,4169,1668,2010,1990,4189,690,3591,3830,1814,4083,2758,255,2073,261,1373,4280,1161,2433,4566,3656,4284,633,2237,1952,4124,111,3411,2536,2005,4049,3497,2918,461,818,4699,2360,3326,4717,1996,74,163,1600,4480,2314,1538,3114,3606,2899,1144,4133,837,1860,1949,541,1832,1984,3846,1189,2039,4128,3364,3987,2152,2036,4701,3966,3033,2274,275,4943,4771,4067,4610,4166,1663,3438,1707,1813,458,4395,4671,4336,2055,1876,4546,1166,3799,3553,3200,4354,232,4928,2455,2752,356,1886,4045,4748,3526,4163,3977,1076,4475,1868,2089,2592,724,4858,2786,4612,1258,1548,3302,3363,1581,662,1740,210,4774,3049,2920,4240,606,2743,1882,1051,3489,1791,4680,4052,2125,228,3311,1274,792,3235,101,4607,3790,2173,2071,4500,3515,2438,2266,3599,3578,3804,2564,4526,205,2756,4697,1236,705,1012,2101,4503,4033,1809,1448,2418,4902,3641,3108,1542,4920,653,721,3078,2817,4014,2976,3240,2142,2184,4817,4344,699,3781,3120,3361,2304,1346,1879,2232,4563,2930,2508,395,816,3970,931,2206,4348,450,3961,2757,2218,2277,161,1211,3532,3301,1141,504,3269,4775,796,4264,4559,1924,2683,3060,3072,1773,2732,2040,1966,1829,4501,672,3524,768,4004,3502,1091,3675,2641,2704,2686,598,1884,3851,2141,2458,258,1245,1587,227,3614,1959,3660,2337,1926,1948,301,1443,1062,1940,1431,2826,2369,574,3018,2054,3861,4993,1213,1790,830,652,3521,1381,2892,2198,2661,432,3780,2221,846,3394,4734,2562,640,294,3784,4487,2603,1690,3630,4486,2742,2745,3073,3495,3582,4669,1844,2354,527,3327,3354,1589,237,1235,2137,4116,4572,1534,2707,1277,1132,4137,3971,879,649,3850,2037,3960,3876,4673,4459,2846,424,2941,386,3006,3026,2370,260,2201,4456,2345,4144,1612,3651,2496,2625,1507,1468,3803,2022,4896,2379,2426,4859,1350,3054,3926,128,1898,3831,3584,4028,674,4386,793,4557,704,2385,4834,3734,4488,3483,3349,3684,4796,407,314,2287,2671,912,2343,516,4667,1893,1894,1319,4468,4825,3794,3316,342,3192,1281,2868,3860,2523,251,2943,1059,3158,4877,2501,4769,4473,829,467,3163,4637,2607,4053,2787,2969,4159,3510,3618,2575,612,157,2579,1348,2823,1390,4580,4499,2255,3717,3471,470,3248,2957,3888,794,4255,4947,4224,1678,4300,3765,1369,4167,2407,84,2544,1950,1262,2842,2156,3778,915,4050,2553,1030,2227,488,2860,657,4576,4508,2357,1750,1849,2630,3076,554,558,3443,3833,4016,773,1796,3321,117,4554,1866,3857,3609,868,4906,2180,1393,888,2629,2945,1490,3715,4408,3912,2549,3290,2841,1243,3367,1760,175,1942,1937,4955,3557,4173,2251,1597,3457,1140,2993,4751,3552,1583,1207,3669,4279,1411,2601,1484,2915,3129,3408,1032,4155,1276,2519,3878,4686,3148,3093,3310,3719,1150,303,720,3728,3975,3509,752,1272,1610,4120,2951,4291,4518,4695,506,511,890,2453,1340,1364,270,2410,2334,2050,1895,2257,1887,4648,2209,3130,3611,351,648,756,397,4180,147,3795,3091,2331,1674,1283,1202,1821,2570,4977,3811,3950,2798,1480,4406,2610,524,4260,2281,1147,661,2058,2215,4213,4532,3720,4904,2176,4470,2606,1555,2946,4366,2147,4154,2333,4881,3920,1467,4341,2866,234,3038,4002,1389,3623,193,3997,3751,2721,4664,719,2555,1466,4018,1465,3968,437,4780,4149,2225,2988,4934,3293,3708,3508,1925,3207,2689,3503,2959,2761,1572,3225,3913,776,3600,3723,4919,99,3494,1798,1594,469,3175,2833,4800,4298,3196,2744,3947,3951,2009,2207,1156,556,2341,3034,4547,2753,936,1764,394,4158,3205,4221,4808,4318,502,1404,625,1956,3047,4324,3422,2065,1900,2596,233,3473,2327,2318,2483,4857,4419,3545,1400,508,2494,3752,1353,1250,4452,707,1356,4712,1675,4735,4978,333,4099,1734,1662,2487,61,2423,4787,851,2210,2256,2456,2451,546,2200,3055,2717,3989,496,618,3003,1425,4061,1247,1067,4430,2143,3597,1889,3480,3265,4287,643,645,3270,847,1795,764,3805,3333,2874,1850,4121,2952,670,479,3468,2882,1515,1093,3921,4981,416,2199,4469,320,2703,2302,216,166,89,383,1965,1673,4587,2258,3535,4191,4568,3459,4403,1541,3517,4427,1914,3733,1322,1781,133,1902,1063,3688,718,1918,4179,2568,778,841,2196,1082,1175,4252,2474,3249,1677,4678,2839,311,4802,3608,1020,2919,487,1830,2204,1455,3236,3359,3343,1943,4391,4656,887,698,1963,2845,1220,695,1580,4874,4907,1921,2306,1637,1160,1184,595,2797,3404,2963,1066,222,1880,1931,2312,4357,1774,1057,842,4836,2313,4848,3620,109,3782,178,3601,2909,4489,1708,2103,1869,4025,3956,2259,2190,3889,2953,1865,4272,4101,3905,883,4871,150,4899,3313,196,3082,4963,3061,1209,2935,2600,2408,1753,2566,729,1167,3284,4759,700,2831,4694,1640,2825,3918,1433,115,4078,3542,1313,2363,4483,4804,1630,4058,3882,3696,3758,3984,1325,3592,4890,4989,1134,3593,3345,4424,4960,2434,3894,1265,3528,1883,2684,121,3202,4564,533,3852,4633,2063,819,3228,1694,779,623,1920,1916,769,2565,2891,236,2623,4670,1495,2524,3776,112,1146,3451,1025,2118,262,1074,843,3586,551,3305,3560,4660,2967,3011,2921,2099,2535,2140,1315,2889,964,1099,3940,1970,4655,2850,1174,1569,3177,1486,4740,4507,1481,4754,3403,2925,1899,2122,3661,1198,2290,4767,3285,305,4514,4738,691,2828,2746,1229,2466,102,4467,313,3312,992,522,644,1291,744,91,921,3439,298,3998,195,3783,2814,4538,2002,1932,4819,2958,1711,4565,557,3693,4999,4917,4893,87,4876,1362,3853,1227,949,4521,713,2740,2672,2616,345,2003,1625,3275,1519,201,4895,4455,304,442,2678,3286,4931,1975,3052,2424,2532,509,1035,3849,932,1204,4378,1107,1457,1119,2374,3389,4665,4949,1614,2217,4237,77,1341,2075,803,3613,3485,1129,1758,4197,4174,3046,3746,2748,2132,1978,708,118,4795,169,192,78,3115,1399,2396,387,3342,1169,2552,2886,3890,2452,4461,4441,4982,545,143,3978,306,4265,2542,1477,1065,2439,4861,629,2648,4619,366,823,1611,151,3562,2810,3702,4362,2888,3405,4423,3167,2778,4491,455,4421,4867,4020,1944,2015,4119,772,3939,3791,4350,4156,158,2300,917,4567,1317,990,300,869,4253,610,694,3092,4884,775,4082,813,536,3458,57,3616,1423,3332,1049,4979,280,2172,319,3871,2867,3171,363,3201,4414,1110,3632,808,862,2588,331,2708,4520,3188,3392,955,438,3015,4786,641,3500,909,2646,2477,4719,4032,3832,4698,1122,2323,1968,873,4347,4604,3264,3604,3903,1885,164,3374,2774,4153,3730,1292,4281,4746,3074,1508,798,286,974,1558,2430,3070,638,4905,4096,4188,1596,4542,2048,501,2997,1738,553,4986,2647,4070,1867,287,1436,4273,4239,2709,4111,4973,760,1454,2097,1954,410,3840,85,1474,464,2824,945,4460,4837,2366,2119,2427,200,1050,4186,1165,198,153,377,920,3362,1702,2735,3637,1444,1232,2148,635,1842,3098,2123,2371,243,4732,2820,925,451,4519,1993,3253,4628,2305,2931,1048,2755,3334,759,64,1002,1761,406,3686,1038,4994,93,3041,933,4218,906,2134,607,2136,4037,770,155,2664,1215,1801,415,3573,1376,3640,1514,2358,2821,1670,1401,4844,4309,4482,4785,4914,840,3370,4833,4852,714,2365,967,799,214,3338,2059,2107,4864,4228,3476,1218,1130,2971,4946,400,4776,4246,4573,562,466,1967,528,824,252,2832,2765,2475,4056,2948,1138,4029,4674,4528,3406,2529,3487,1164,1649,573,3841,2528,2138];
/******************************************************************************************************
* Chainlink: Starts
*******************************************************************************************************/
// chainlink contract interfaces
VRFCoordinatorV2Interface COORDINATOR;
LinkTokenInterface LINKTOKEN;
// Chainlink subscription ID.
uint64 public subscriptionId;
// Chainlink vrfCoordinator
// see https://docs.chain.link/docs/vrf-contracts/#configurations
address public vrfCoordinator;
// Chainlink LINK token contract. For other networks,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
address public link;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
bytes32 private keyHash;
uint32 private callbackGasLimit = 2500000;
uint16 private requestConfirmations = 3;
// Chainlink request Id to sender address map.
mapping(uint256 => address) public requestIdToSender;
// Chainlink request Id to glass box tokenId map.
mapping(uint256 => uint256[]) public requestIdToTokenIds;
/******************************************************************************************************
* Chainlink: Ends
*******************************************************************************************************/
// After the initial sale phase is complete, reveal phase will be started.
// During reveal phase users will burn their tokens to get the DGFamily token.
bool public revealPhaseStarted = false;
// the primary dgFamily contract address.
address public dgFamilyContractAddress;
// the glass-box contract address.
address public glassBoxContractAddress;
// These are three types of boxes users will get in return for their glass box.
enum BoxType {
BLACK,
GOLD,
PLATINUM
}
// max token operations allowed in 1 go.
uint8 private constant BATCH_SIZE = 10;
// max random number requests that can be done per token.
uint8 public randomNumberRequestsLimit = 1;
// all payments will be directly sent to this wallet address.
address private platformWallet;
// this is the fixed nft reveal fees
uint256 public revealFees;
// This stores tokenIds and current number of requests done for random number.
mapping(uint256 => uint8) public randomNumberRequests;
// This stores tokenIds of the all the glass box NFTs which are revealed.
mapping(uint256 => bool) public revealedTokens;
// This stores glass box tokenIds and their corresponding revealed dgFamily tokenIds.
mapping(uint256 => uint256) public revealedResults;
// This stores the short code for Black/Gold/Platinum.
mapping(uint8 => BoxType) public boxTypeMapping;
// This event is emitted when random numbers are requested for a specific set of tokenIds
event RandomNumberRequested(uint256[] tokenIds, uint256 requestId);
// This event is emitted when random numbers are generated for a specific requestId
event RandomNumberGenerated(uint256 requestId, uint256[] randomNumbers);
// This event is emitted during the reveal phase when a glass box is burned and user receives Black/Gold/Platinum
// box in return.
event Revealed(uint256 glassBoxTokenId, uint256 dgTokenId, BoxType boxType);
constructor(
address _dgFamilyContractAddress,
address _glassBoxContractAddress,
address _platformWallet,
uint256 _revealFees,
uint64 _subscriptionId,
address _vrfCoordinator,
address _link,
bytes32 _keyHash
)
VRFConsumerBaseV2(_vrfCoordinator)
{
dgFamilyContractAddress = _dgFamilyContractAddress;
glassBoxContractAddress = _glassBoxContractAddress;
platformWallet = _platformWallet;
revealFees = _revealFees;
COORDINATOR = VRFCoordinatorV2Interface(_vrfCoordinator);
LINKTOKEN = LinkTokenInterface(link);
subscriptionId = _subscriptionId;
vrfCoordinator = _vrfCoordinator;
link = _link;
keyHash = _keyHash;
boxTypeMapping[1] = BoxType.BLACK;
boxTypeMapping[2] = BoxType.GOLD;
boxTypeMapping[3] = BoxType.PLATINUM;
}
modifier basicChecks(
uint256 tokenId
) {
require(revealPhaseStarted, "REVEAL_PHASE_NOT_INITIATED");
DGFamilyGlassBox glassBoxContract = DGFamilyGlassBox(
glassBoxContractAddress
);
address ownerAddress = glassBoxContract.ownerOf(tokenId);
require(ownerAddress == msg.sender, "ONLY_OWNER_CAN_CALL_THIS_METHOD");
bool isApprovedForAll = glassBoxContract.isApprovedForAll(ownerAddress, address(this));
require(isApprovedForAll, "APPROVAL_NOT_GIVEN");
_;
}
/******************************************************************************************************
* Set Platform Wallet Address
* @param _platformWallet: new wallet address
*******************************************************************************************************/
function setPlatformWallet(
address _platformWallet
)
external
onlyOwner
{
require(_platformWallet != address(0), "ADDRESS_CAN_NOT_BE_ZERO");
platformWallet = _platformWallet;
}
/******************************************************************************************************
* Set Reveal Fees
* @param revealFees: new fee amount
*******************************************************************************************************/
function setRevealFees(
uint256 _revealFees
)
external
onlyOwner
{
revealFees = _revealFees;
}
/******************************************************************************************************
* Set Chainlink Key Hash.
* @param _keyHash: new key hash value
*******************************************************************************************************/
function setChainlinkKeyHash(
bytes32 _keyHash
)
external
onlyOwner
{
keyHash = _keyHash;
}
/*******************************************************************************************************
* @dev Overridden function to prevent Owner from relinquishing Ownership by accident.
*******************************************************************************************************/
function renounceOwnership()
public
view
override
onlyOwner
{
revert("CAN_NOT_RENOUNCE_OWNERSHIP");
}
/******************************************************************************************************
* Toggle the reveal phase.
* Once in reveal phase glass boxes can be burned to get the actual DGFamily NFT.
*******************************************************************************************************/
function toggleRevealPhase()
public
onlyOwner
{
revealPhaseStarted = !revealPhaseStarted;
}
/******************************************************************************************************
* Set the max limit for number of random number requests allowed per tokenId.
* @param newLimit: new max limit
*******************************************************************************************************/
function setRandomNumberRequestsLimit(
uint8 newLimit
)
external
onlyOwner
{
randomNumberRequestsLimit = newLimit;
}
/******************************************************************************************************
* Reset the number of random number requests done for a specific tokenId.
* @param tokenId: tokenId of glass box
*******************************************************************************************************/
function resetRandomNumbersRequested(
uint256 tokenId
)
external
onlyOwner
{
randomNumberRequests[tokenId] = 0;
}
/*******************************************************************************************************
* Check if specific glass box NFT is already revealed or not.
*******************************************************************************************************/
function checkIfRevealed(
uint256 tokenId
)
public
view
returns (bool)
{
return revealedTokens[tokenId];
}
/***********************************************************************************************************
* User will call this to initial reveal phase for specific glass box token ids.
* This will call Chainlink requestRandomWords to generate random number. The response will be handled by
* fulfillRandomWords as callback once the request is complete.
***********************************************************************************************************/
function requestRandomNumber(
uint256[] memory tokenIds
)
external
payable
nonReentrant
{
DGFamilyGlassBox glassBoxContract = DGFamilyGlassBox(
glassBoxContractAddress
);
bool isApprovedForAll = glassBoxContract.isApprovedForAll(msg.sender, address(this));
require(revealPhaseStarted, "REVEAL_PHASE_NOT_INITIATED");
require(isApprovedForAll, "APPROVAL_NOT_GIVEN");
require((tokenIds.length > 0) && (tokenIds.length <= BATCH_SIZE), "BATCH_SIZE_INVALID");
// run more validations and update randomNumberRequests map
for(uint256 i = 0; i < tokenIds.length; i = i + 1) {
uint256 tokenId = tokenIds[i];
address ownerAddress = glassBoxContract.ownerOf(tokenId);
require(ownerAddress == msg.sender, "ONLY_OWNER_CAN_CALL_THIS_METHOD");
require(!revealedTokens[tokenId], "BOX_ALREADY_CLAIMED");
require(randomNumberRequests[tokenId] < randomNumberRequestsLimit, "RANDOM_NUMBER_LIMIT_REACHED");
// update random number request count.
randomNumberRequests[tokenId] = randomNumberRequests[tokenId] + 1;
}
// transfer fees to platform wallet.
if (revealFees > 0) {
uint256 totalFees = revealFees * tokenIds.length;
require(msg.value == totalFees, "INVALID_REVEAL_FEES_AMOUNT");
(bool sent, ) = platformWallet.call{value: msg.value}("");
require(sent, "FAILED_TO_SEND_REVEAL_FEES");
}
// request random numbers from chain link
uint32 numbers = uint32(tokenIds.length);
uint256 requestId = COORDINATOR.requestRandomWords(
keyHash,
subscriptionId,
requestConfirmations,
callbackGasLimit,
numbers
);
requestIdToTokenIds[requestId] = tokenIds;
requestIdToSender[requestId] = msg.sender;
emit RandomNumberRequested(tokenIds, requestId);
}
/***********************************************************************************************************
* This is the callback for the Chainlink requestRandomWords method called during the revealBox
* execution.
* See https://docs.chain.link/docs/get-a-random-number/
*
* Reveal the actual NFT from the DGFamily collection.
* Here we burn the initial glass box NFT user has and then selects a random box from the
* Black, Gold or Platinum boxes seed. New box NFT will be minted here. Meta info will be
* updated by capturing the Reveal event data by UNXD backend.
***********************************************************************************************************/
function fulfillRandomWords(
uint256 requestId,
uint256[] memory randomWords
)
internal
virtual
override
{
DGFamilyGlassBox glassBoxContract = DGFamilyGlassBox(
glassBoxContractAddress
);
DGFamilyCollection dgFamilyContract = DGFamilyCollection(
dgFamilyContractAddress
);
address sender = requestIdToSender[requestId];
uint256[] memory tokenIds = requestIdToTokenIds[requestId];
emit RandomNumberGenerated(requestId, randomWords);
for(uint8 i = 0; i < tokenIds.length; i = i + 1) {
uint256 tokenId = tokenIds[i];
uint256 randomNumber = randomWords[i];
uint256 randomIndex = randomNumber % seed.length; // get random number between 0 to seed length.
if (revealedTokens[tokenId]) {
// tokenId is already revealed.
continue;
}
// mark tokenId as claimed.
revealedTokens[tokenId] = true;
// burn the token
glassBoxContract.transferFrom(sender, 0x000000000000000000000000000000000000dEaD, tokenId);
// reveal the box type.
uint16 revealedBoxTokenId = seed[randomIndex];
BoxType boxType = BoxType.BLACK;
if (revealedBoxTokenId >=1 && revealedBoxTokenId <=75) {
boxType = BoxType.PLATINUM;
} else if (revealedBoxTokenId >=76 && revealedBoxTokenId <= 750) {
boxType = BoxType.GOLD;
}
// reduce the seed array size.
seed[randomIndex] = seed[seed.length - 1];
seed.pop();
// save revealed result
revealedResults[tokenId] = revealedBoxTokenId;
// mint dg family token.
dgFamilyContract.generate(sender, revealedBoxTokenId);
emit Revealed(tokenId, revealedBoxTokenId, boxType);
}
}
}//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "openzeppelin-solidity/contracts/security/ReentrancyGuard.sol";
import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "../biconomy/EIP712MetaTransaction.sol";
import "./DGFamilyCollection.sol";
/**
* DGFamily Glass box Collection
* https://drops.unxd.com/dgfamily
*
* This is the initial glass box collection for DGFamily Sale.
* Glass Box NFTs will be available at a fixed price. After the sale is done and reveal phase starts,
* users will burn their glass box in return for the Black, Gold and Platinum Boxes.
*/
contract DGFamilyGlassBox is
ERC721URIStorage,
Ownable,
EIP712MetaTransaction,
VRFConsumerBaseV2,
ReentrancyGuard
{
using Strings for uint256;
using SafeMath for uint256;
/**************************************************************************************************
* DGFamilyCollection will have total supply of 5000. The distribution of Platinum/Gold/Black boxes
* will be as below. Box Types are identified by token index range.
*
*
* Platinum Boxes: #1-75 (Index Range)
* #48, 56, 57, 59, 61, 62, 63, 64, 65, 68, 70, 71, 72, 73, 74
* 15 Platinum boxes.
*
* Gold Boxes: #76-750 (Index Range)
* #76-745
* 670 Gold boxes.
*
* Black Boxes: #751-5000 (Index Range)
* #751-5000
* 4250 Black boxes.
*
* Seed contains => 15 Platinum Boxes, 670 Gold Boxes and 4250 Black Boxes
* Total => 4935
***************************************************************************************************/
uint16[] public seed = [1982,739,329,2506,4524,4704,4814,3891,2602,2490,3157,4885,2933,4976,1081,581,3689,3884,3543,3842,4142,459,1318,1127,1461,4650,1351,1108,777,4114,4411,1530,1244,4376,2414,4075,2286,2380,3972,2420,4314,3824,3430,4308,491,3452,440,1532,2000,2004,856,1812,3967,3533,2045,1203,3260,1770,1873,277,1314,2502,634,3953,2465,2471,3635,4003,1768,3657,4713,2464,3994,2835,1181,3387,4515,1022,723,2144,2669,4329,611,4226,1551,3300,4959,3105,325,3568,3650,4792,3400,1672,4293,4387,4591,3943,1922,2632,2383,1212,4196,2336,137,1284,2972,2294,2926,419,900,3490,2702,2213,4550,4210,4184,1695,3028,1913,3909,4219,1055,2351,1923,3512,3252,961,4581,802,2338,3145,3863,2682,3679,1225,1280,2649,1330,2064,2910,4415,4577,3916,4034,3336,1698,4574,3547,2656,3254,3000,4449,4397,4047,1851,484,2511,1715,1370,1419,4123,960,1712,2493,3869,2214,1586,1125,3807,1092,4276,2115,2781,2335,3797,3627,165,2979,1533,4110,3858,4364,2805,4652,4145,4883,4863,959,4815,2151,2517,4115,3843,1360,3988,4944,463,3036,1619,4060,626,2252,2706,2855,4183,2551,1363,3287,3762,2154,1078,4816,3160,4005,4306,1664,679,2954,2242,4008,725,2008,3444,307,2598,2999,174,3043,4750,4942,804,2267,2293,83,3589,1501,1412,1058,3605,1068,3816,3859,3900,2634,534,4663,762,1261,3131,4084,2067,4995,2296,878,3272,2364,4583,1792,2514,898,81,3309,881,1806,1131,1909,3277,138,1771,521,3022,203,4957,4731,1494,1159,4407,3381,391,327,939,1392,2853,4136,1731,134,1333,710,248,3436,4349,4181,3698,1520,2412,3258,1458,3425,563,542,1285,1478,1408,3806,3787,2526,4447,3721,4560,3991,1624,3067,1841,2928,1298,360,1060,615,3371,975,48,924,4831,1590,3643,4682,3322,4910,4953,3801,3873,3729,866,973,582,1282,4602,1544,3694,2863,2750,941,1579,1847,585,1825,1192,1155,4057,1391,3504,2794,362,4365,2995,4541,1647,1437,2413,1785,3138,1576,2530,3491,240,2422,2840,3155,2310,4690,483,1186,4997,1820,1434,3745,510,1308,1206,97,1445,2223,2023,4645,987,2857,1657,2181,4379,4138,4277,431,4505,3486,2816,2749,3421,3435,630,1705,3071,1299,4066,981,2468,2977,1254,1228,4199,1233,2695,4511,2836,4729,3132,4299,547,3507,3077,197,2406,382,3324,253,4435,2913,2982,1523,1042,98,1279,4620,4232,1278,3788,2041,3699,4171,4632,105,4952,2106,4044,1149,1492,1365,2087,3455,4268,2730,2873,2694,1562,4634,3583,2731,1780,4822,1782,4758,1334,296,103,4772,208,189,2691,449,2878,2219,995,1652,2035,114,696,291,1453,4283,2469,4091,3646,2714,2581,194,4941,1502,1482,3493,3935,758,2117,2301,1987,2801,3754,2432,3274,1767,4636,2271,4400,2316,3166,2898,82,948,2342,4987,4784,3087,2368,2520,3195,4147,1634,4383,3103,3813,374,3135,3626,3914,4933,3722,436,4968,476,202,2437,4346,1510,1324,2195,71,418,2893,1410,3056,1905,2636,4585,1917,848,3571,4187,4290,544,2220,2906,4639,4730,953,321,4593,4594,241,2049,1100,1522,1152,2932,1584,2556,3714,807,2344,1725,3771,3123,937,62,4683,2567,3753,4320,785,2537,3828,3339,3063,513,790,3883,3919,1143,952,870,3550,4370,2016,2311,4889,2480,4605,3271,257,3737,4829,4036,3017,1822,683,1934,2202,3625,1033,4681,1660,1387,928,2235,2429,2653,825,4113,4961,3775,2994,1145,1489,4966,1327,1539,4448,4791,3704,968,2618,4835,2947,3211,3544,4394,2819,1843,1994,2326,2668,4733,2444,2174,1459,603,849,753,3382,2279,3564,2789,3031,1114,73,3233,3594,4434,254,3081,2676,3276,2329,3178,3481,3107,4766,2849,4898,3165,3534,141,59,330,3705,4143,2531,4556,543,2975,1388,2047,2780,4589,1650,2983,3340,283,2862,2216,3094,3848,2450,3653,761,3227,1176,4700,199,1691,1118,1582,922,3767,1856,811,1182,4543,2442,4744,4990,4923,1999,4190,2454,308,2425,4444,4770,4310,1739,1080,245,624,4646,2478,4569,1472,2472,3222,4530,2964,2631,2763,3251,389,2260,4102,2489,2762,3289,1427,4201,4539,2321,3035,4390,3514,4954,4261,914,2619,3538,4342,1306,2738,485,3569,693,3232,3680,984,4271,3137,4369,1372,343,2384,285,2597,1439,3197,4432,359,781,1375,172,1749,4549,3736,3203,185,4629,3204,1267,1928,1493,3118,4212,1593,2667,1699,445,602,810,1985,4104,755,3755,4464,4980,3257,926,1648,3551,3062,2052,4446,3262,2914,1608,2470,2175,4691,4068,1303,3263,473,537,3759,1386,2247,4146,3027,2937,398,4782,1973,2146,4211,4536,3315,1726,3793,962,1264,1071,4059,2698,1260,4736,4317,954,2569,242,1018,4203,3172,3572,4072,2014,3199,226,1636,1550,2160,2881,1497,686,1742,181,4103,2130,357,1897,3110,947,4827,4288,1732,3372,2011,2317,3658,1556,1052,3996,4894,460,2739,272,413,2377,1028,4624,4258,1718,3691,3428,1171,3112,3268,2399,2859,4847,2681,2692,1621,3255,1823,4479,631,4897,4476,2449,4790,376,2095,3218,2962,4238,1561,1703,4506,2145,4130,3665,1754,2395,2509,239,1347,605,2021,1304,1602,2949,3932,3465,1026,3323,3440,2098,4374,2733,3634,403,3116,3990,2729,3928,839,2249,907,2270,2677,2261,3766,815,3226,1775,1357,2020,353,4930,2589,2657,3866,1701,1626,1027,4077,2800,3299,1491,4494,3416,4779,3337,2108,4015,2770,1744,421,1349,1241,1123,1090,681,3221,2843,3184,735,2375,1290,3423,3237,4958,3836,3005,1547,2093,4689,2813,3096,3390,976,3862,1727,3969,1571,4762,4338,4126,4315,2229,3407,3414,2183,985,4220,3212,1148,4603,1289,1563,122,2611,2563,344,2693,3789,3537,2679,872,4875,379,2769,2904,2939,882,1620,1629,1878,3069,247,2829,3683,409,4586,2911,1471,4046,3642,3383,3007,1988,1216,3106,1037,1972,2903,3662,1700,1021,1266,2080,2790,1888,2663,86,2582,3822,859,4865,1135,996,3453,1061,4107,4208,3117,3530,861,3854,3182,3068,2578,3908,899,1777,978,578,4886,4433,4592,429,3325,2723,935,4544,2486,3835,444,2193,3867,1237,148,1816,1361,2573,2178,3159,2157,2328,368,2234,712,4793,3450,2415,664,1756,273,4019,4765,3021,507,1681,2211,3220,2027,4485,3844,271,428,4820,472,120,1047,3685,1094,4915,3366,2541,1631,3707,1312,3174,910,408,1311,1069,4975,3670,4493,4635,3716,149,1464,4956,1323,4783,235,4481,1671,4207,1371,4611,4527,2806,4676,4879,367,4571,3238,850,3298,4726,2461,1991,95,2612,2887,2231,1665,4841,1188,3621,3820,1044,1964,852,2104,1043,1804,1173,969,2428,2852,2613,349,1603,3697,3638,1442,1366,2699,498,4426,3427,4913,1339,3219,2285,4122,891,531,4561,1142,3104,160,2284,2837,385,223,583,1947,4422,465,668,3037,1622,4245,3113,3556,348,2244,1019,1029,4105,3224,4509,1835,3827,2834,2096,4798,1505,4257,4474,2900,4401,1861,3817,3558,4600,1645,4182,687,3541,3193,2462,136,3633,1736,4093,3095,1846,1219,663,1553,2799,897,854,1567,1554,1384,2605,1531,4513,3080,4027,2291,3185,2167,3825,355,738,1301,4131,970,559,3821,3351,4922,2929,1779,1008,3168,2680,3904,4710,92,4388,4672,2268,1961,1638,2272,131,3812,4007,4333,519,3051,4339,4760,4868,4162,613,4937,126,3622,791,1892,3437,4562,108,3772,774,452,1908,4035,3295,2617,4609,3865,4425,1197,4157,4969,354,4393,4794,2783,2720,358,934,4525,4234,4484,1256,229,2674,1085,3102,3109,2028,4846,1331,1024,1251,1642,728,4854,2128,4160,220,523,4614,1309,2273,1185,2350,4533,1802,2498,3266,1697,2484,1297,4359,3933,765,2243,3294,1015,3948,4647,2269,2105,4278,3246,2212,299,3945,4297,1591,2851,3180,3877,564,1355,1710,797,3923,812,2076,378,688,1803,2441,180,3023,1676,3949,1190,4193,3576,2917,597,276,3244,4752,1463,4654,680,2547,575,4498,1223,1852,1980,2038,2924,844,745,3957,4086,1979,3401,3595,3004,1077,352,474,971,4361,350,4021,90,411,731,256,4860,2481,4535,3673,2934,3242,1772,4492,826,3874,783,4064,3020,430,2078,3415,1097,3259,1234,4295,3147,614,3353,2330,4243,3173,3075,4112,2970,4964,3925,1500,76,4523,857,586,3024,2628,911,1977,1300,3645,4418,4517,682,4141,1268,480,1187,468,265,2879,2057,1653,3579,1545,1837,2719,1307,2060,991,4522,113,4095,3942,2403,2149,2705,1870,4231,1036,3879,4597,1242,3678,426,3800,4716,309,2974,3032,1430,3256,3040,604,4356,4127,2670,361,2387,4304,218,3397,2488,4380,1543,2124,4725,963,1659,1766,3446,1855,1864,892,3962,3809,2847,2362,2205,3388,3922,3319,4451,860,1824,116,1054,2624,4692,2411,567,1692,4595,3659,4247,675,1938,1574,167,4623,2518,1295,1320,1679,268,3194,3146,2473,4172,2640,654,1422,4625,3142,4089,1658,3808,2177,3954,2239,3718,4668,2308,591,315,3603,4849,1273,2046,1103,1128,4368,2081,2830,540,3739,4626,3559,4578,2576,3764,943,267,1787,3030,871,2094,2485,3847,3245,771,3347,2512,2978,3768,217,3887,3845,3190,4722,767,988,4098,1329,3369,1941,1031,2356,2540,3210,1446,1259,3492,372,3700,2854,396,3307,282,339,2072,596,3555,4176,1121,2409,3770,4951,4244,2894,684,685,3496,4140,3982,1088,4548,4316,2192,264,628,2088,3676,1321,2734,1073,3536,2654,894,384,1737,4657,1483,79,3488,3839,1828,1178,4463,1238,3125,4092,4256,1328,2500,2897,4706,904,2895,3757,2861,732,2599,923,1095,1084,972,642,1833,1200,4416,599,2194,1685,1046,338,186,1838,1070,865,1163,3053,3655,1460,4839,486,4168,2793,800,2074,2560,1517,2665,499,1112,4164,806,4006,1939,2561,475,4708,632,1305,3432,1168,3868,1253,3318,716,100,571,1906,2985,2361,4996,4437,1907,3346,244,144,1689,4266,1287,2355,2245,392,4431,2110,2884,2572,1845,3644,863,3208,3419,893,4512,2539,1476,3320,3153,4640,4009,3979,2522,3223,594,1874,2155,478,1064,1157,2447,2885,4621,1839,2007,3581,1034,2998,1853,1911,3418,2950,346,1723,224,2546,1881,3019,656,1221,4773,2760,3973,4398,620,913,4331,1496,3384,4325,3511,135,2768,1557,673,3395,4781,780,1195,2759,292,3368,2419,4367,4938,2376,715,3396,1326,1383,184,587,3682,4087,3931,1891,263,1252,1479,2960,3777,347,1294,1826,3499,757,2297,3273,1120,1429,2024,2061,3710,3885,1104,1751,3393,4842,4495,4327,1945,269,951,4714,4653,3615,2352,3964,908,2165,4807,4267,1438,1503,4502,1729,2942,737,3915,4606,1537,3344,219,3701,188,4737,1546,3610,2554,492,3647,3506,4026,4921,3086,335,3712,4534,2276,877,2388,4935,659,727,3695,4471,530,3191,4094,2838,3380,539,1840,3016,1343,4178,422,1106,3516,290,2848,2992,2869,2864,3703,3934,4477,4677,3341,4916,565,130,4661,4074,2558,2779,2029,4575,858,3413,1560,4312,512,4223,2944,2622,4490,2527,3164,3128,1183,590,4303,1010,332,3314,4462,697,2655,2186,3886,1848,4040,3161,3897,2525,2651,2044,2264,3779,1643,4873,3668,2224,4851,1540,786,4926,1875,1342,433,4909,4810,2391,4472,4125,1616,3464,2263,1504,1776,3472,3881,751,1717,1513,375,2238,4225,577,3002,1919,3375,2445,316,3365,669,3740,1598,2776,297,2557,2082,1208,820,788,702,1124,318,3151,3607,658,443,1836,4011,2955,3763,4358,4892,1374,4340,4215,2164,266,2389,2034,4555,1518,1470,1524,2253,1205,145,1377,417,4504,3774,2332,2877,3838,903,966,526,4684,4988,4042,2168,3279,1255,230,4081,1398,1609,412,1249,1635,3612,1797,481,4108,3815,3187,2233,399,1585,1111,4828,639,1527,3872,404,3590,4545,4853,3520,1741,919,2716,221,901,4866,2936,3518,2986,1338,4742,3726,2018,1368,637,2135,4192,3189,312,225,2726,4582,420,1210,4389,1451,4109,4823,1041,393,1432,4200,3826,171,3296,3150,1487,3304,831,3426,1759,3539,916,2583,1201,156,3206,885,822,4440,2747,2876,4250,1269,3756,4630,4570,2398,2688,2591,4801,2961,3898,1526,3014,3420,2492,4384,4870,1706,3941,1435,4950,2114,1788,1396,4465,2984,4588,4755,2017,2315,4806,1086,552,423,4205,1337,3529,3089,3479,3769,4642,1915,1783,4055,1162,2182,4496,1115,1101,1716,1456,3154,1172,4206,864,795,2139,1910,1179,1745,2844,3938,4510,1072,4135,4012,1552,1669,380,1981,3029,4764,2491,3527,3352,1485,340,2077,336,3687,4185,4745,2025,1793,3213,2322,3692,2754,2940,2129,4204,2150,1644,1270,2808,1743,207,4984,538,1013,3663,1651,2807,3144,4177,3983,1730,4862,2068,3906,1413,1414,2871,4023,2666,3391,3064,1293,1757,456,1367,1000,1789,4302,4151,895,4579,2373,302,1568,4242,4443,1462,3798,3278,1807,2659,535,3306,4649,3732,3378,4900,5000,946,4323,3373,711,3574,177,3654,4170,4457,518,875,979,1379,4285,139,2804,667,3025,2169,1226,4608,4929,4821,2185,1154,1623,2112,3409,2153,3761,958,3328,2907,4743,3297,2086,259,2644,734,4939,1498,660,1475,4031,1817,3671,94,4641,3335,2030,2295,2070,3292,1380,1395,1240,1421,3870,2604,1693,2309,2246,1808,549,289,4321,3084,2516,3580,4693,3308,929,1296,880,994,2922,4727,3467,1473,1929,4763,2543,1713,2784,4079,592,4615,3119,2457,187,72,2171,2621,1818,68,2559,1005,3785,588,569,1409,566,950,448,1344,204,2773,4450,3350,809,4396,1275,3652,3234,832,706,3261,4227,2479,1769,2319,1575,2307,390,938,3513,2858,736,1440,4313,3100,2938,2372,2303,2378,1765,666,827,4420,3837,4809,665,1735,1827,580,3083,677,4106,3410,1017,740,1102,2248,4382,1755,4254,4063,4466,4826,1904,1606,3731,2382,4275,4132,3291,1746,2802,4292,3079,1748,3917,1549,295,2191,3624,763,3469,1834,4402,2991,3567,2767,2393,2013,1230,3475,838,1170,2091,4882,2102,4062,3834,2727,1733,4259,3546,191,281,999,782,1193,3358,742,2645,2981,608,1704,3065,942,4856,2856,3059,215,2324,2188,3681,1958,3892,2113,1974,381,4728,4454,3796,692,179,4097,1661,4209,3792,4757,334,4328,3735,4761,1962,609,1983,3902,1656,1231,4442,884,3773,4843,2386,3101,3709,1863,550,1633,2431,1778,2590,4998,127,3880,2392,2638,4850,2390,3896,2965,4381,2700,1687,4631,1358,371,2718,3519,2593,2586,3598,3963,2339,4024,1402,1415,2577,3713,709,2402,3048,4282,1096,889,4662,3743,514,1014,2340,4048,4749,323,3478,4372,4085,4139,3563,3050,405,1426,2262,3152,2288,600,3377,2513,1040,3629,4797,2189,834,4439,2161,3742,4924,1196,2782,370,1469,3602,4638,2348,3045,2968,1079,1535,2460,560,3628,500,2571,4054,3057,1248,1302,2615,4161,4326,3672,678,3802,1137,2084,4073,4311,2133,701,2056,814,2635,515,3531,4724,3462,1113,324,3631,3376,2127,4152,1310,1566,821,1666,3570,4335,3198,2320,3981,4453,3445,2658,1992,1117,4217,2476,63,1800,3039,2051,4409,3250,4274,4022,3810,3134,1618,182,1588,3814,2883,4030,4590,3566,930,617,2032,70,874,3441,940,1158,4001,4812,4038,1418,4799,3554,3505,1680,3750,3577,805,1857,2764,833,462,1087,801,4000,3143,2545,104,2083,293,2085,2006,4202,2236,4404,246,3176,789,1565,3247,1403,1936,2417,1516,482,249,4832,3549,2265,328,2803,4118,2043,3760,4627,4658,1406,4216,4872,3525,3677,4165,1336,570,4927,3281,4616,1995,1728,1003,3431,4753,4845,2923,2121,503,211,2504,1862,1417,2230,3910,4679,1684,867,124,4788,896,3348,579,2987,1686,1214,446,3360,4838,3829,1016,4878,977,2289,447,3186,2880,998,1405,4601,2459,4039,956,1605,754,1023,4405,4262,853,2400,3449,3724,3738,517,965,1604,2534,1511,2510,3412,1933,4117,2550,434,2905,1564,3140,1397,4065,2079,4553,4584,1536,2822,2710,2902,1452,107,3690,337,2792,4651,2435,4236,4598,3748,4613,1394,2012,2633,388,2170,4972,2111,4903,2980,4345,4777,3952,4248,140,3875,2818,4090,4891,730,4399,3085,1525,4531,4041,1011,3744,4778,2349,1335,1969,986,1955,2927,982,2163,589,2463,439,4241,3501,845,1682,1762,3330,4912,2179,3357,1617,1714,4497,2796,3433,3985,622,3121,3907,1573,2912,1831,3399,4412,3955,1641,3980,1989,3893,2222,2280,1871,154,2515,4711,4013,1133,2650,1488,3974,1045,1667,4385,1696,572,2701,505,497,3855,3976,2712,855,1615,3664,2722,4644,529,1194,1721,2809,123,4818,722,3267,3231,3747,647,4322,2203,3442,1257,2687,4343,1578,2675,2254,4840,1577,2711,3727,905,3447,4643,2916,2100,2609,689,4970,983,3216,3317,2870,3540,495,2812,1529,425,132,2627,671,1896,616,2092,159,2548,3575,1007,3127,3749,489,2497,4803,584,3477,1447,2908,989,4529,2777,1997,4558,170,3044,3460,1105,4436,2595,1688,4337,1009,4269,2538,2066,3588,2298,2626,3283,1799,1819,1872,2026,2724,3636,4813,4305,4235,766,4230,2901,2503,2367,142,2131,4373,3124,1512,129,1752,636,4622,4718,493,4659,1424,4967,4887,1628,4925,3901,2033,441,3930,2325,4540,4516,4428,3402,3927,1613,435,2292,3149,190,2728,902,3355,2090,1935,3649,2416,835,322,3434,4739,1747,3136,2440,106,250,1986,2042,4707,3818,2405,4709,3169,373,3009,2436,876,152,1180,326,2620,2467,3587,1724,1946,3288,3282,4076,2865,3585,4100,927,2875,4948,3911,676,3711,3523,4352,1654,2359,3230,2208,2772,3214,2240,80,4618,4445,2574,4088,4195,1286,1139,401,561,4377,4985,4307,4702,1153,4945,1416,3548,88,3899,65,576,1316,1960,2446,4675,726,1811,3999,3741,1354,3329,4552,3385,655,4392,4071,650,4901,2642,1786,2827,3090,4741,3944,2751,4301,4263,1345,4148,4688,402,4685,784,4294,4888,1382,4438,1890,3162,3379,4869,3010,1930,1359,3674,3648,1509,231,4334,2715,2031,4417,2890,2662,1006,3331,2673,3066,4286,288,2505,1083,2766,4194,3619,490,2448,96,1854,4363,4551,1595,1877,3179,1109,183,364,477,593,4768,1570,4175,2736,1407,2162,2109,2652,2660,4747,209,2116,119,1976,1271,619,3466,1191,1655,4715,2443,3986,2166,1592,1352,4908,3454,1998,4129,3993,453,2158,1420,2956,646,1053,1805,3895,4936,3013,548,3666,1056,2241,1720,993,4229,212,651,2053,1499,1601,3229,3463,3565,3217,2394,3667,3482,944,4918,4353,4824,1001,2811,3209,1246,2069,1927,2643,4289,4965,2896,2401,3042,4080,4069,787,365,1199,4940,1075,274,703,4355,3156,2421,3474,2482,2282,1559,2283,3617,3639,4134,2685,4962,4911,4811,3936,2788,4296,717,3823,817,1953,1263,2495,3929,3864,3181,168,568,3456,2299,1607,4017,3097,110,4043,3139,4429,1449,4251,4705,310,4051,2381,3239,2533,2785,162,1627,1639,427,279,4805,1441,3470,2791,733,918,1646,3099,2614,1683,4991,886,1506,3992,3126,836,2690,2989,4855,3122,1288,4010,997,741,4478,284,317,4932,2973,2775,3170,4410,1004,3001,1901,3058,1521,1957,3386,2996,213,2521,2001,3398,3856,1903,1177,2226,3937,4723,494,555,1222,4270,1719,4830,3008,4458,3088,3522,4150,2228,4360,2197,3215,2126,3356,4233,2346,1912,414,2741,4413,828,4703,4992,238,4696,4351,2507,4617,3561,2159,2584,3995,2187,3965,1098,4789,1858,2397,146,3111,743,601,1332,4198,525,4880,2637,2278,4537,2499,1116,3498,4249,621,1224,341,1217,1385,3725,1709,4983,3280,3183,3429,4971,1378,2771,2966,1810,2990,1971,957,3924,1815,2353,4721,1039,1722,3461,125,3417,4214,1239,457,532,2608,1763,2697,2639,1794,3141,2062,1951,206,2594,1599,454,1151,3243,3303,520,4720,3448,2019,3424,4222,2725,4687,2120,3946,1859,1450,4332,2696,980,369,3012,1632,4599,2580,471,2250,4756,627,4596,3133,2872,2815,3958,4666,173,2585,4974,3819,278,1126,3596,1136,4330,4319,1089,4375,2737,2347,2713,1528,1428,1784,176,2795,3706,56,3786,2404,4371,2587,3241,3484,2275,3959,4169,1668,2010,1990,4189,690,3591,3830,1814,4083,2758,255,2073,261,1373,4280,1161,2433,4566,3656,4284,633,2237,1952,4124,111,3411,2536,2005,4049,3497,2918,461,818,4699,2360,3326,4717,1996,74,163,1600,4480,2314,1538,3114,3606,2899,1144,4133,837,1860,1949,541,1832,1984,3846,1189,2039,4128,3364,3987,2152,2036,4701,3966,3033,2274,275,4943,4771,4067,4610,4166,1663,3438,1707,1813,458,4395,4671,4336,2055,1876,4546,1166,3799,3553,3200,4354,232,4928,2455,2752,356,1886,4045,4748,3526,4163,3977,1076,4475,1868,2089,2592,724,4858,2786,4612,1258,1548,3302,3363,1581,662,1740,210,4774,3049,2920,4240,606,2743,1882,1051,3489,1791,4680,4052,2125,228,3311,1274,792,3235,101,4607,3790,2173,2071,4500,3515,2438,2266,3599,3578,3804,2564,4526,205,2756,4697,1236,705,1012,2101,4503,4033,1809,1448,2418,4902,3641,3108,1542,4920,653,721,3078,2817,4014,2976,3240,2142,2184,4817,4344,699,3781,3120,3361,2304,1346,1879,2232,4563,2930,2508,395,816,3970,931,2206,4348,450,3961,2757,2218,2277,161,1211,3532,3301,1141,504,3269,4775,796,4264,4559,1924,2683,3060,3072,1773,2732,2040,1966,1829,4501,672,3524,768,4004,3502,1091,3675,2641,2704,2686,598,1884,3851,2141,2458,258,1245,1587,227,3614,1959,3660,2337,1926,1948,301,1443,1062,1940,1431,2826,2369,574,3018,2054,3861,4993,1213,1790,830,652,3521,1381,2892,2198,2661,432,3780,2221,846,3394,4734,2562,640,294,3784,4487,2603,1690,3630,4486,2742,2745,3073,3495,3582,4669,1844,2354,527,3327,3354,1589,237,1235,2137,4116,4572,1534,2707,1277,1132,4137,3971,879,649,3850,2037,3960,3876,4673,4459,2846,424,2941,386,3006,3026,2370,260,2201,4456,2345,4144,1612,3651,2496,2625,1507,1468,3803,2022,4896,2379,2426,4859,1350,3054,3926,128,1898,3831,3584,4028,674,4386,793,4557,704,2385,4834,3734,4488,3483,3349,3684,4796,407,314,2287,2671,912,2343,516,4667,1893,1894,1319,4468,4825,3794,3316,342,3192,1281,2868,3860,2523,251,2943,1059,3158,4877,2501,4769,4473,829,467,3163,4637,2607,4053,2787,2969,4159,3510,3618,2575,612,157,2579,1348,2823,1390,4580,4499,2255,3717,3471,470,3248,2957,3888,794,4255,4947,4224,1678,4300,3765,1369,4167,2407,84,2544,1950,1262,2842,2156,3778,915,4050,2553,1030,2227,488,2860,657,4576,4508,2357,1750,1849,2630,3076,554,558,3443,3833,4016,773,1796,3321,117,4554,1866,3857,3609,868,4906,2180,1393,888,2629,2945,1490,3715,4408,3912,2549,3290,2841,1243,3367,1760,175,1942,1937,4955,3557,4173,2251,1597,3457,1140,2993,4751,3552,1583,1207,3669,4279,1411,2601,1484,2915,3129,3408,1032,4155,1276,2519,3878,4686,3148,3093,3310,3719,1150,303,720,3728,3975,3509,752,1272,1610,4120,2951,4291,4518,4695,506,511,890,2453,1340,1364,270,2410,2334,2050,1895,2257,1887,4648,2209,3130,3611,351,648,756,397,4180,147,3795,3091,2331,1674,1283,1202,1821,2570,4977,3811,3950,2798,1480,4406,2610,524,4260,2281,1147,661,2058,2215,4213,4532,3720,4904,2176,4470,2606,1555,2946,4366,2147,4154,2333,4881,3920,1467,4341,2866,234,3038,4002,1389,3623,193,3997,3751,2721,4664,719,2555,1466,4018,1465,3968,437,4780,4149,2225,2988,4934,3293,3708,3508,1925,3207,2689,3503,2959,2761,1572,3225,3913,776,3600,3723,4919,99,3494,1798,1594,469,3175,2833,4800,4298,3196,2744,3947,3951,2009,2207,1156,556,2341,3034,4547,2753,936,1764,394,4158,3205,4221,4808,4318,502,1404,625,1956,3047,4324,3422,2065,1900,2596,233,3473,2327,2318,2483,4857,4419,3545,1400,508,2494,3752,1353,1250,4452,707,1356,4712,1675,4735,4978,333,4099,1734,1662,2487,61,2423,4787,851,2210,2256,2456,2451,546,2200,3055,2717,3989,496,618,3003,1425,4061,1247,1067,4430,2143,3597,1889,3480,3265,4287,643,645,3270,847,1795,764,3805,3333,2874,1850,4121,2952,670,479,3468,2882,1515,1093,3921,4981,416,2199,4469,320,2703,2302,216,166,89,383,1965,1673,4587,2258,3535,4191,4568,3459,4403,1541,3517,4427,1914,3733,1322,1781,133,1902,1063,3688,718,1918,4179,2568,778,841,2196,1082,1175,4252,2474,3249,1677,4678,2839,311,4802,3608,1020,2919,487,1830,2204,1455,3236,3359,3343,1943,4391,4656,887,698,1963,2845,1220,695,1580,4874,4907,1921,2306,1637,1160,1184,595,2797,3404,2963,1066,222,1880,1931,2312,4357,1774,1057,842,4836,2313,4848,3620,109,3782,178,3601,2909,4489,1708,2103,1869,4025,3956,2259,2190,3889,2953,1865,4272,4101,3905,883,4871,150,4899,3313,196,3082,4963,3061,1209,2935,2600,2408,1753,2566,729,1167,3284,4759,700,2831,4694,1640,2825,3918,1433,115,4078,3542,1313,2363,4483,4804,1630,4058,3882,3696,3758,3984,1325,3592,4890,4989,1134,3593,3345,4424,4960,2434,3894,1265,3528,1883,2684,121,3202,4564,533,3852,4633,2063,819,3228,1694,779,623,1920,1916,769,2565,2891,236,2623,4670,1495,2524,3776,112,1146,3451,1025,2118,262,1074,843,3586,551,3305,3560,4660,2967,3011,2921,2099,2535,2140,1315,2889,964,1099,3940,1970,4655,2850,1174,1569,3177,1486,4740,4507,1481,4754,3403,2925,1899,2122,3661,1198,2290,4767,3285,305,4514,4738,691,2828,2746,1229,2466,102,4467,313,3312,992,522,644,1291,744,91,921,3439,298,3998,195,3783,2814,4538,2002,1932,4819,2958,1711,4565,557,3693,4999,4917,4893,87,4876,1362,3853,1227,949,4521,713,2740,2672,2616,345,2003,1625,3275,1519,201,4895,4455,304,442,2678,3286,4931,1975,3052,2424,2532,509,1035,3849,932,1204,4378,1107,1457,1119,2374,3389,4665,4949,1614,2217,4237,77,1341,2075,803,3613,3485,1129,1758,4197,4174,3046,3746,2748,2132,1978,708,118,4795,169,192,78,3115,1399,2396,387,3342,1169,2552,2886,3890,2452,4461,4441,4982,545,143,3978,306,4265,2542,1477,1065,2439,4861,629,2648,4619,366,823,1611,151,3562,2810,3702,4362,2888,3405,4423,3167,2778,4491,455,4421,4867,4020,1944,2015,4119,772,3939,3791,4350,4156,158,2300,917,4567,1317,990,300,869,4253,610,694,3092,4884,775,4082,813,536,3458,57,3616,1423,3332,1049,4979,280,2172,319,3871,2867,3171,363,3201,4414,1110,3632,808,862,2588,331,2708,4520,3188,3392,955,438,3015,4786,641,3500,909,2646,2477,4719,4032,3832,4698,1122,2323,1968,873,4347,4604,3264,3604,3903,1885,164,3374,2774,4153,3730,1292,4281,4746,3074,1508,798,286,974,1558,2430,3070,638,4905,4096,4188,1596,4542,2048,501,2997,1738,553,4986,2647,4070,1867,287,1436,4273,4239,2709,4111,4973,760,1454,2097,1954,410,3840,85,1474,464,2824,945,4460,4837,2366,2119,2427,200,1050,4186,1165,198,153,377,920,3362,1702,2735,3637,1444,1232,2148,635,1842,3098,2123,2371,243,4732,2820,925,451,4519,1993,3253,4628,2305,2931,1048,2755,3334,759,64,1002,1761,406,3686,1038,4994,93,3041,933,4218,906,2134,607,2136,4037,770,155,2664,1215,1801,415,3573,1376,3640,1514,2358,2821,1670,1401,4844,4309,4482,4785,4914,840,3370,4833,4852,714,2365,967,799,214,3338,2059,2107,4864,4228,3476,1218,1130,2971,4946,400,4776,4246,4573,562,466,1967,528,824,252,2832,2765,2475,4056,2948,1138,4029,4674,4528,3406,2529,3487,1164,1649,573,3841,2528,2138];
/******************************************************************************************************
* Chainlink: Starts
*******************************************************************************************************/
// chainlink contract interfaces
VRFCoordinatorV2Interface COORDINATOR;
LinkTokenInterface LINKTOKEN;
// Chainlink subscription ID.
uint64 public subscriptionId;
// Chainlink vrfCoordinator
// see https://docs.chain.link/docs/vrf-contracts/#configurations
address public vrfCoordinator;
// Chainlink LINK token contract. For other networks,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
address public link;
// The gas lane to use, which specifies the maximum gas price to bump to.
// For a list of available gas lanes on each network,
// see https://docs.chain.link/docs/vrf-contracts/#configurations
bytes32 private keyHash;
uint32 private callbackGasLimit = 200000;
uint16 private requestConfirmations = 30;
uint32 private numWords = 1;
// This is the random number generated by chain link vrf.
uint256 private chainlinkRandomNumber;
// This will be some random prime number set during reveal phase and
// is used in reveal calculations
uint256 private primeNumber;
// This is the chainlink requestId for vrf.
uint256 private requestId;
/******************************************************************************************************
* Chainlink: Ends
*******************************************************************************************************/
// base uri for meta data
string private baseURI;
// current token index minted.
uint256 private tokenIndex;
// current total public supply.
uint256 public totalSupply;
// royalty percentage for secondary sales in UNXD marketplace.
uint256 public royaltyPercentage;
// max total public supply for glass boxes
uint256 public constant MAX_PUBLIC_SUPPLY = 4935;
// After the initial sale phase is complete, reveal phase will be started.
// During reveal phase users will burn their tokens to get the DGFamily token.
bool public revealPhaseStarted = false;
// the primary dgFamily contract address.
address public dgFamilyContractAddress;
// These are three types of boxes users will get in return for their glass box.
enum BoxType {
BLACK,
GOLD,
PLATINUM
}
// This is the list of whitelisted system wallet addresses. These are used by UNXD backend api to place
// generate requests for glass box tokens.
mapping(address => bool) public systems;
// This stores tokenIds of the all the glass box NFTs which are revealed.
mapping(uint256 => bool) public revealedTokens;
// This store the Black/Gold/Platinum box type revealed for each glass box token id.
mapping(uint256 => BoxType) public revealedResults;
// This stores the short code for Black/Gold/Platinum.
mapping(uint8 => BoxType) public boxTypeMapping;
// This event is emitted once the royalty percentage is changed for this collection.
event RoyaltyPercentageChanged(uint256 indexed newPercentage);
// This event is emitted if the base URI is updated for the collection.
event BaseUriUpdated(string indexed uri);
// This event is emitted if the list of whitelisted system address change.
event SystemAddressUpdated(address someAddress, bool enabled);
// This event is emitted during the reveal phase when a glass box is burned and user receives Black/Gold/Platinum
// box in return.
event Revealed(uint256 glassBoxTokenId, uint256 dgTokenId, BoxType boxType);
constructor(
string memory _tokenName,
string memory _tokenSymbol,
string memory _baseURI1,
uint256 _royaltyPercentage,
address _dgFamilyContractAddress,
uint64 _subscriptionId,
address _vrfCoordinator,
address _link,
bytes32 _keyHash
)
ERC721(_tokenName, _tokenSymbol)
EIP712MetaTransaction("DGFamilyGlassBox", "1")
VRFConsumerBaseV2(_vrfCoordinator)
{
baseURI = _baseURI1;
royaltyPercentage = _royaltyPercentage;
dgFamilyContractAddress = _dgFamilyContractAddress;
COORDINATOR = VRFCoordinatorV2Interface(_vrfCoordinator);
LINKTOKEN = LinkTokenInterface(link);
subscriptionId = _subscriptionId;
vrfCoordinator = _vrfCoordinator;
link = _link;
keyHash = _keyHash;
boxTypeMapping[1] = BoxType.BLACK;
boxTypeMapping[2] = BoxType.GOLD;
boxTypeMapping[3] = BoxType.PLATINUM;
}
/***
* Check for only accessible by authorized system addresses.
*/
modifier onlySystem() {
require(systems[msgSender()], "SYSTEM_UNAUTHORIZED_ACCESS");
_;
}
/***
* Check for only accessible by authorized system addresses or owner.
*/
modifier onlySystemOrOwner() {
require(
systems[msgSender()] || owner() == msgSender(),
"UNAUTHORIZED_ACCESS"
);
_;
}
/**
* Set system address. These addresses are used to generate tokens through secured * * unxd-api calls.
* @param someAddress: new address to add.
* @param enabled: enable/disable access.
*/
function setSystem(address someAddress, bool enabled) external onlyOwner {
require(someAddress != address(0), "INVALID_ADDRESS");
systems[someAddress] = enabled;
emit SystemAddressUpdated(someAddress, enabled);
}
/**
* Set baseURI for metafile root path.
* @dev Emits "BaseUriUpdates"
* @param uri: The new uri for tokenURI base.
*/
function setBaseURI(string memory uri) external onlyOwner {
baseURI = uri;
emit BaseUriUpdated(baseURI);
}
/**
* Sets royalty percentage for secondary sale.
* @dev Emits "RoyaltyPercentageChanged"
* @param _percentage: The percentage of royalty to be deducted.
*/
function setRoyaltyPercentage(uint256 _percentage) external onlyOwner {
royaltyPercentage = _percentage;
emit RoyaltyPercentageChanged(royaltyPercentage);
}
/**
* Mint NFT tokens. This will be called by the UNXD system wallets. Owner can also call this for specific cases.
* @param numberOfTokens: The quantity of tokens to be minted.
* @param destination: The minted token receiver.
*/
function generate(uint256 numberOfTokens, address destination)
external
onlySystemOrOwner
nonReentrant
{
require(destination != address(0), "ADDRESS_CAN_NOT_BE_ZERO");
require(
(!revealPhaseStarted),
"PERMISSION_DENIED_REVEAL_PHASE_STARTED"
);
require(
(totalSupply.add(numberOfTokens)) <= MAX_PUBLIC_SUPPLY,
"MAX_PUBLIC_SUPPLY_REACHED"
);
for (uint256 i = 0; i < numberOfTokens; i = i.add(1)) {
tokenIndex = totalSupply.add(1);
totalSupply = totalSupply.add(1);
_safeMint(destination, tokenIndex);
}
}
/**
* Get royalty amount at any specific price.
* @param _price: price for sale.
*/
function getRoyaltyInfo(uint256 _price)
external
view
returns (uint256 royaltyAmount, address royaltyReceiver)
{
require(_price > 0, "PRICE_CAN_NOT_BE_ZERO");
uint256 royalty = (_price.mul(royaltyPercentage)).div(100);
return (royalty, owner());
}
/**
* Provides token URI of the NFT.
* @param _tokenId: target NFT.
* @return The URI string for the token's metadata file.
*/
function tokenURI(uint256 _tokenId)
public
view
override(ERC721URIStorage)
returns (string memory)
{
if (totalSupply == 0) {
return _baseURI();
}
require(_exists(_tokenId), "TOKEN_DOES_NOT_EXIST");
/// @dev Convert string to bytes so we can check if it's empty or not.
return string(abi.encodePacked(_baseURI(), _tokenId.toString()));
}
/**
* @dev See {IERC721-transferFrom}.
* @param from: address of sender.
* @param to: address of receiver.
* @param tokenId: tokenId nft being transferred.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(
_isApprovedOrOwner(msgSender(), tokenId),
"CALLER_NOT_APPROVED"
);
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
* @param from: address of sender.
* @param to: address of receiver.
* @param tokenId: tokenId nft being transferred.
* @param _data: any additional data.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(
_isApprovedOrOwner(msgSender(), tokenId),
"CALLER_NOT_APPROVED"
);
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Overridden function to prevent Owner from relinquishing Ownership by accident.
*/
function renounceOwnership() public view override onlyOwner {
revert("CAN_NOT_RENOUNCE_OWNERSHIP");
}
/**
* Approval.
* @param to: address to approve.
* @param tokenId: NFT to approve.
*/
function approve(address to, uint256 tokenId) public virtual override {
address tokenOwner = ERC721.ownerOf(tokenId);
require(to != tokenOwner, "ERC721:APPROVAL_TO_CURRENT_OWNER");
require(
msgSender() == tokenOwner ||
isApprovedForAll(tokenOwner, msgSender()),
"ERC721:APPROVE_CALLER_NOT_OWNER_OR_APPROVED_FOR_ALL"
);
_approve(to, tokenId);
}
/**
* Get baseURI of collection.
*/
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
/**
* Check if specific glass box NFT is already revealed or not.
*/
function checkIfRevealed(uint256 _tokenId) public view returns (bool) {
return revealedTokens[_tokenId];
}
/**
* Start reveal phase.
* Once in reveal phase glass boxes can be burned to get the actual DGFamily NFT.
* We request the Chainlink requestRandomWords to generate random number. The response will be handled by
* fulfillRandomWords as callback once the request is complete.
*/
function startRevealPhase(uint16 _primeNumber) public onlyOwner {
require(!revealPhaseStarted, "REVEAL_PHASE_ALREADY_INITIATED");
primeNumber = _primeNumber;
requestId = COORDINATOR.requestRandomWords(
keyHash,
subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
}
/***********************************************************************************************************
* This is the callback for the Chainlink requestRandomWords method called during the startRevealPhase
* execution.
* We store the random number and start the reveal phase.
***********************************************************************************************************/
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
// get random number between 0 to 999,999,999,999,999.
chainlinkRandomNumber = (randomWords[0].mod(999999999999999));
revealPhaseStarted = true;
}
/***********************************************************************************************************
* Reveal the actual NFT from the DGFamily collection.
* Here we burn the initial glass box NFT user has and mint a random box from the
* Black, Gold or Platinum boxes seed. Meta info will be
* updated by capturing the Reveal event data by unxd backend.
***********************************************************************************************************/
function revealBox(uint256 tokenId) public {
require(
_isApprovedOrOwner(msgSender(), tokenId),
"CALLER_NOT_APPROVED"
);
require(revealPhaseStarted, "REVEAL_PHASE_NOT_INITIATED");
require(!revealedTokens[tokenId], "BOX_ALREADY_REVEALED");
// mark tokenId as revealed and burn the token.
revealedTokens[tokenId] = true;
_burn(tokenId);
// reveal the box type.
uint256 randomIndex = (((primeNumber * tokenId) + chainlinkRandomNumber) % seed.length);
uint16 revealedBoxTokenId = seed[randomIndex];
BoxType boxType = BoxType.BLACK;
if (revealedBoxTokenId >=1 && revealedBoxTokenId <=75) {
boxType = BoxType.PLATINUM;
} else if (revealedBoxTokenId >=76 && revealedBoxTokenId <= 750) {
boxType = BoxType.GOLD;
}
DGFamilyCollection dgFamilyContract = DGFamilyCollection(
dgFamilyContractAddress
);
uint256 dgFamilyTokenId = dgFamilyContract.generate(msgSender(), revealedBoxTokenId);
emit Revealed(tokenId, dgFamilyTokenId, boxType);
}
}//SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.9;
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/access/Ownable.sol";
import "openzeppelin-solidity/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "openzeppelin-solidity/contracts/utils/Strings.sol";
import "../biconomy/EIP712MetaTransaction.sol";
/**
* DGFamily Collection
* https://drops.unxd.com/dgfamily
*/
contract DGFamilyCollection is
ERC721URIStorage,
Ownable,
EIP712MetaTransaction
{
using Strings for uint256;
using SafeMath for uint256;
string private baseURI;
uint256 public constant MAX_PUBLIC_SUPPLY = 5000;
uint256 public totalSupply;
uint256 public royaltyPercentage;
address public glassBoxContract;
address public privateSaleContract;
mapping(uint256 => bool) public privateSaleTokenIds;
/*********************************
* EVENTS
*********************************/
event RoyaltyPercentageChanged(uint256 indexed newPercentage);
event BaseUriUpdated(string indexed uri);
/** @notice Initiator
* @param tokenName The name of the NFT token
* @param tokenSymbol The symbol of the NFT tokens
* @param _baseUri The tokenURI base string
* @param _royaltyPercentage Percentage of royalty to be taken per sale
* @param _privateSaleTokenIds List of tokensIds to used in private sale
*/
constructor(
string memory tokenName,
string memory tokenSymbol,
string memory _baseUri,
uint256 _royaltyPercentage,
uint256[] memory _privateSaleTokenIds
)
ERC721(tokenName, tokenSymbol)
EIP712MetaTransaction("NftCollectionBatch", "1")
{
baseURI = _baseUri;
royaltyPercentage = _royaltyPercentage;
for (uint256 i = 0; i < _privateSaleTokenIds.length; i = i.add(1)) {
privateSaleTokenIds[_privateSaleTokenIds[i]] = true;
}
}
modifier onlyGlassBoxOrOwnerOrPrivateSale() {
require(
glassBoxContract == msgSender() || owner() == msgSender() || privateSaleContract == msgSender(),
"UNAUTHORIZED_ACCESS"
);
_;
}
/** @notice Set baseURI for metafile root path
* @dev Emits "BaseUriUpdates"
* @param uri The new uri for tokenURI bsae
*/
function setBaseURI(string memory uri) external onlyOwner {
baseURI = uri;
emit BaseUriUpdated(baseURI);
}
/** @notice Sets royalty percentage for secondary sale
* @dev Emits "RoyaltyPercentageChanged"
* @param _percentage The percentage of royalty to be deducted
*/
function setRoyaltyPercentage(uint256 _percentage) external onlyOwner {
royaltyPercentage = _percentage;
emit RoyaltyPercentageChanged(royaltyPercentage);
}
/**
* Mint the NFT.
* @param destination wallet address
* @return tokenId of newly minted nft.
*/
function generate(address destination, uint256 tokenIndex)
external
onlyGlassBoxOrOwnerOrPrivateSale
returns (uint256)
{
require(destination != address(0), "ADDRESS_CAN_NOT_BE_ZERO");
require(
totalSupply < MAX_PUBLIC_SUPPLY,
"MAX_PUBLIC_SUPPLY_REACHED"
);
if ((privateSaleContract == msgSender()) || (owner() == msgSender())) {
require(
privateSaleTokenIds[tokenIndex],
"PRIVATE_SALE_PERMISSION_DENIED"
);
}
totalSupply = totalSupply.add(1);
_safeMint(destination, tokenIndex);
return tokenIndex;
}
/**
* Get royalty amount at any specific price.
* @param _price: price for sale.
*/
function getRoyaltyInfo(uint256 _price)
external
view
returns (uint256 royaltyAmount, address royaltyReceiver)
{
require(_price > 0, "PRICE_CAN_NOT_BE_ZERO");
uint256 royalty = (_price.mul(royaltyPercentage)).div(100);
return (royalty, owner());
}
/**
* Set the glass box contract address which will be calling the generate NFT method.
* @param _address: glass box contract address.
*/
function setGlassBoxContract(address _address) external onlyOwner {
glassBoxContract = _address;
}
/**
* Set the private sale contract address which will be calling the generate NFT method.
* @param _address: contract address.
*/
function setPrivateSaleContract(address _address) external onlyOwner {
privateSaleContract = _address;
}
/** @notice Provides token URI of the NFT
* @param _tokenId The id of the specific NFT
* @return The URI string for the token's metadata file
*/
function tokenURI(uint256 _tokenId)
public
view
override(ERC721URIStorage)
returns (string memory)
{
if (totalSupply == 0) {
return _baseURI();
}
require(_exists(_tokenId), "TOKEN_DOES_NOT_EXIST");
/// @dev Convert string to bytes so we can check if it's empty or not.
return string(abi.encodePacked(_baseURI(), _tokenId.toString()));
}
/**
* @dev See {IERC721-transferFrom}.
* @notice Only Trusted Marketplace contract can use
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(
_isApprovedOrOwner(msgSender(), tokenId),
"CALLER_NOT_APPROVED"
);
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
* @notice Only Trusted Marketplace contract can use
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(
_isApprovedOrOwner(msgSender(), tokenId),
"CALLER_NOT_APPROVED"
);
_safeTransfer(from, to, tokenId, _data);
}
/// @dev Overridden function to prevent Owner from relinquishing Ownership by accident
function renounceOwnership() public view override onlyOwner {
revert("CAN_NOT_RENOUNCE_OWNERSHIP");
}
/**@dev Returns baseURI
*/
function approve(address to, uint256 tokenId) public virtual override {
address tokenOwner = ERC721.ownerOf(tokenId);
require(to != tokenOwner, "ERC721:APPROVAL_TO_CURRENT_OWNER");
require(
msgSender() == tokenOwner ||
isApprovedForAll(tokenOwner, msgSender()),
"ERC721:APPROVE_CALLER_NOT_OWNER_OR_APPROVED_FOR_ALL"
);
_approve(to, tokenId);
}
/**
* Get base URI for collection.
*/
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
}//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
import "./EIP712Base.sol";
import "openzeppelin-solidity/contracts/utils/math/SafeMath.sol";
contract EIP712MetaTransaction is EIP712Base {
using SafeMath for uint256;
bytes32 private constant META_TRANSACTION_TYPEHASH =
keccak256(
bytes(
"MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
)
);
event MetaTransactionExecuted(
address userAddress,
address payable relayerAddress,
bytes functionSignature
);
mapping(address => uint256) private nonces;
/*
* Meta transaction structure.
* No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
* He should call the desired function directly in that case.
*/
struct MetaTransaction {
uint256 nonce;
address from;
bytes functionSignature;
}
constructor(string memory name, string memory version)
EIP712Base(name, version)
{}
function convertBytesToBytes4(bytes memory inBytes)
internal
pure
returns (bytes4 outBytes4)
{
if (inBytes.length == 0) {
return 0x0;
}
assembly {
outBytes4 := mload(add(inBytes, 32))
}
}
function executeMetaTransaction(
address userAddress,
bytes memory functionSignature,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) public payable returns (bytes memory) {
bytes4 destinationFunctionSig = convertBytesToBytes4(functionSignature);
require(
destinationFunctionSig != msg.sig,
"functionSignature can not be of executeMetaTransaction method"
);
MetaTransaction memory metaTx = MetaTransaction({
nonce: nonces[userAddress],
from: userAddress,
functionSignature: functionSignature
});
require(
verify(userAddress, metaTx, sigR, sigS, sigV),
"Signer and signature do not match"
);
nonces[userAddress] = nonces[userAddress].add(1);
// Append userAddress at the end to extract it from calling context
(bool success, bytes memory returnData) = address(this).call(
abi.encodePacked(functionSignature, userAddress)
);
require(success, string(returnData));
emit MetaTransactionExecuted(
userAddress,
payable(msg.sender),
functionSignature
);
return returnData;
}
function hashMetaTransaction(MetaTransaction memory metaTx)
internal
pure
returns (bytes32)
{
return
keccak256(
abi.encode(
META_TRANSACTION_TYPEHASH,
metaTx.nonce,
metaTx.from,
keccak256(metaTx.functionSignature)
)
);
}
function getNonce(address user) external view returns (uint256 nonce) {
nonce = nonces[user];
}
function verify(
address user,
MetaTransaction memory metaTx,
bytes32 sigR,
bytes32 sigS,
uint8 sigV
) internal view returns (bool) {
address signer = ecrecover(
toTypedMessageHash(hashMetaTransaction(metaTx)),
sigV,
sigR,
sigS
);
require(signer != address(0), "Invalid signature");
return signer == user;
}
function msgSender() internal view returns (address sender) {
if (msg.sender == address(this)) {
bytes memory array = msg.data;
uint256 index = msg.data.length;
assembly {
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
sender := and(
mload(add(array, index)),
0xffffffffffffffffffffffffffffffffffffffff
)
}
} else {
sender = msg.sender;
}
return sender;
}
}//SPDX-License-Identifier: MIT
pragma solidity 0.8.9;
contract EIP712Base {
struct EIP712Domain {
string name;
string version;
address verifyingContract;
bytes32 salt;
}
bytes32 internal constant EIP712_DOMAIN_TYPEHASH =
keccak256(
bytes(
"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
)
);
bytes32 internal domainSeparator;
constructor(string memory name, string memory version) {
domainSeparator = keccak256(
abi.encode(
EIP712_DOMAIN_TYPEHASH,
keccak256(bytes(name)),
keccak256(bytes(version)),
address(this),
bytes32(getChainID())
)
);
}
function getChainID() internal view returns (uint256 id) {
assembly {
id := chainid()
}
}
function getDomainSeparator() private view returns (bytes32) {
return domainSeparator;
}
/**
* Accept message hash and returns hash message in EIP712 compatible form
* So that it can be used to recover signer from signature signed using EIP712 formatted data
* https://eips.ethereum.org/EIPS/eip-712
* "\\x19" makes the encoding deterministic
* "\\x01" is the version byte to make it compatible to EIP-191
*/
function toTypedMessageHash(bytes32 messageHash)
internal
view
returns (bytes32)
{
return
keccak256(
abi.encodePacked("\x19\x01", getDomainSeparator(), messageHash)
);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (utils/math/SafeMath.sol)
pragma solidity ^0.8.0;
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)
pragma solidity ^0.8.0;
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)
pragma solidity ^0.8.0;
import "../ERC721.sol";
/**
* @dev ERC721 token with storage based token URI management.
*/
abstract contract ERC721URIStorage is ERC721 {
using Strings for uint256;
// Optional mapping for token URIs
mapping(uint256 => string) private _tokenURIs;
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
string memory base = _baseURI();
// If there is no base URI, return the token URI.
if (bytes(base).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(base, _tokenURI));
}
return super.tokenURI(tokenId);
}
/**
* @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
_tokenURIs[tokenId] = _tokenURI;
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual override {
super._burn(tokenId);
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721Receiver {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the caller.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool _approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/ERC721.sol)
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
/**
* @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
* the Metadata extension, but not including the Enumerable extension, which is available separately as
* {ERC721Enumerable}.
*/
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
// Token name
string private _name;
// Token symbol
string private _symbol;
// Mapping from token ID to owner address
mapping(uint256 => address) private _owners;
// Mapping owner address to token count
mapping(address => uint256) private _balances;
// Mapping from token ID to approved address
mapping(uint256 => address) private _tokenApprovals;
// Mapping from owner to operator approvals
mapping(address => mapping(address => bool)) private _operatorApprovals;
/**
* @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev See {IERC721-balanceOf}.
*/
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _balances[owner];
}
/**
* @dev See {IERC721-ownerOf}.
*/
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: owner query for nonexistent token");
return owner;
}
/**
* @dev See {IERC721Metadata-name}.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev See {IERC721Metadata-symbol}.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`. Empty
* by default, can be overridden in child contracts.
*/
function _baseURI() internal view virtual returns (string memory) {
return "";
}
/**
* @dev See {IERC721-approve}.
*/
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
/**
* @dev See {IERC721-getApproved}.
*/
function getApproved(uint256 tokenId) public view virtual override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
/**
* @dev See {IERC721-setApprovalForAll}.
*/
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
/**
* @dev See {IERC721-isApprovedForAll}.
*/
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
/**
* @dev See {IERC721-transferFrom}.
*/
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_transfer(from, to, tokenId);
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
/**
* @dev See {IERC721-safeTransferFrom}.
*/
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
_safeTransfer(from, to, tokenId, _data);
}
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* `_data` is additional data, it has no specified format and it is sent in call to `to`.
*
* This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
* implement alternative mechanisms to perform token transfer, such as signature-based.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
}
/**
* @dev Returns whether `tokenId` exists.
*
* Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
*
* Tokens start existing when they are minted (`_mint`),
* and stop existing when they are burned (`_burn`).
*/
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
/**
* @dev Returns whether `spender` is allowed to manage `tokenId`.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
/**
* @dev Safely mints `tokenId` and transfers it to `to`.
*
* Requirements:
*
* - `tokenId` must not exist.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
*
* Emits a {Transfer} event.
*/
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
/**
* @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
* forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
*/
function _safeMint(
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
/**
* @dev Mints `tokenId` and transfers it to `to`.
*
* WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
*
* Requirements:
*
* - `tokenId` must not exist.
* - `to` cannot be the zero address.
*
* Emits a {Transfer} event.
*/
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
/**
* @dev Destroys `tokenId`.
* The approval is cleared when the token is burned.
*
* Requirements:
*
* - `tokenId` must exist.
*
* Emits a {Transfer} event.
*/
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
// Clear approvals
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
/**
* @dev Transfers `tokenId` from `from` to `to`.
* As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
*
* Emits a {Transfer} event.
*/
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
/**
* @dev Approve `to` to operate on `tokenId`
*
* Emits a {Approval} event.
*/
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
/**
* @dev Approve `operator` to operate on all of `owner` tokens
*
* Emits a {ApprovalForAll} event.
*/
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
/**
* @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
* The call is not executed if the target address is not a contract.
*
* @param from address representing the previous owner of the given token ID
* @param to target address that will receive the tokens
* @param tokenId uint256 ID of the token to be transferred
* @param _data bytes optional data to send along with the call
* @return bool whether the call correctly returned the expected magic value
*/
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
/**
* @dev Hook that is called before any token transfer. This includes minting
* and burning.
*
* Calling conditions:
*
* - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
* transferred to `to`.
* - When `from` is zero, `tokenId` will be minted for `to`.
* - When `to` is zero, ``from``'s `tokenId` will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
/**
* @dev Hook that is called after any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface VRFCoordinatorV2Interface {
/**
* @notice Get configuration relevant for making requests
* @return minimumRequestConfirmations global min for request confirmations
* @return maxGasLimit global max for request gas limit
* @return s_provingKeyHashes list of registered key hashes
*/
function getRequestConfig()
external
view
returns (
uint16,
uint32,
bytes32[] memory
);
/**
* @notice Request a set of random words.
* @param keyHash - Corresponds to a particular oracle job which uses
* that key for generating the VRF proof. Different keyHash's have different gas price
* ceilings, so you can select a specific one to bound your maximum per request cost.
* @param subId - The ID of the VRF subscription. Must be funded
* with the minimum subscription balance required for the selected keyHash.
* @param minimumRequestConfirmations - How many blocks you'd like the
* oracle to wait before responding to the request. See SECURITY CONSIDERATIONS
* for why you may want to request more. The acceptable range is
* [minimumRequestBlockConfirmations, 200].
* @param callbackGasLimit - How much gas you'd like to receive in your
* fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords
* may be slightly less than this amount because of gas used calling the function
* (argument decoding etc.), so you may need to request slightly more than you expect
* to have inside fulfillRandomWords. The acceptable range is
* [0, maxGasLimit]
* @param numWords - The number of uint256 random values you'd like to receive
* in your fulfillRandomWords callback. Note these numbers are expanded in a
* secure way by the VRFCoordinator from a single random value supplied by the oracle.
* @return requestId - A unique identifier of the request. Can be used to match
* a request to a response in fulfillRandomWords.
*/
function requestRandomWords(
bytes32 keyHash,
uint64 subId,
uint16 minimumRequestConfirmations,
uint32 callbackGasLimit,
uint32 numWords
) external returns (uint256 requestId);
/**
* @notice Create a VRF subscription.
* @return subId - A unique subscription id.
* @dev You can manage the consumer set dynamically with addConsumer/removeConsumer.
* @dev Note to fund the subscription, use transferAndCall. For example
* @dev LINKTOKEN.transferAndCall(
* @dev address(COORDINATOR),
* @dev amount,
* @dev abi.encode(subId));
*/
function createSubscription() external returns (uint64 subId);
/**
* @notice Get a VRF subscription.
* @param subId - ID of the subscription
* @return balance - LINK balance of the subscription in juels.
* @return reqCount - number of requests for this subscription, determines fee tier.
* @return owner - owner of the subscription.
* @return consumers - list of consumer address which are able to use this subscription.
*/
function getSubscription(uint64 subId)
external
view
returns (
uint96 balance,
uint64 reqCount,
address owner,
address[] memory consumers
);
/**
* @notice Request subscription owner transfer.
* @param subId - ID of the subscription
* @param newOwner - proposed new owner of the subscription
*/
function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external;
/**
* @notice Request subscription owner transfer.
* @param subId - ID of the subscription
* @dev will revert if original owner of subId has
* not requested that msg.sender become the new owner.
*/
function acceptSubscriptionOwnerTransfer(uint64 subId) external;
/**
* @notice Add a consumer to a VRF subscription.
* @param subId - ID of the subscription
* @param consumer - New consumer which can use the subscription
*/
function addConsumer(uint64 subId, address consumer) external;
/**
* @notice Remove a consumer from a VRF subscription.
* @param subId - ID of the subscription
* @param consumer - Consumer to remove from the subscription
*/
function removeConsumer(uint64 subId, address consumer) external;
/**
* @notice Cancel a subscription
* @param subId - ID of the subscription
* @param to - Where to send the remaining LINK to
*/
function cancelSubscription(uint64 subId, address to) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface LinkTokenInterface {
function allowance(address owner, address spender) external view returns (uint256 remaining);
function approve(address spender, uint256 value) external returns (bool success);
function balanceOf(address owner) external view returns (uint256 balance);
function decimals() external view returns (uint8 decimalPlaces);
function decreaseApproval(address spender, uint256 addedValue) external returns (bool success);
function increaseApproval(address spender, uint256 subtractedValue) external;
function name() external view returns (string memory tokenName);
function symbol() external view returns (string memory tokenSymbol);
function totalSupply() external view returns (uint256 totalTokensIssued);
function transfer(address to, uint256 value) external returns (bool success);
function transferAndCall(
address to,
uint256 value,
bytes calldata data
) external returns (bool success);
function transferFrom(
address from,
address to,
uint256 value
) external returns (bool success);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/** ****************************************************************************
* @notice Interface for contracts using VRF randomness
* *****************************************************************************
* @dev PURPOSE
*
* @dev Reggie the Random Oracle (not his real job) wants to provide randomness
* @dev to Vera the verifier in such a way that Vera can be sure he's not
* @dev making his output up to suit himself. Reggie provides Vera a public key
* @dev to which he knows the secret key. Each time Vera provides a seed to
* @dev Reggie, he gives back a value which is computed completely
* @dev deterministically from the seed and the secret key.
*
* @dev Reggie provides a proof by which Vera can verify that the output was
* @dev correctly computed once Reggie tells it to her, but without that proof,
* @dev the output is indistinguishable to her from a uniform random sample
* @dev from the output space.
*
* @dev The purpose of this contract is to make it easy for unrelated contracts
* @dev to talk to Vera the verifier about the work Reggie is doing, to provide
* @dev simple access to a verifiable source of randomness. It ensures 2 things:
* @dev 1. The fulfillment came from the VRFCoordinator
* @dev 2. The consumer contract implements fulfillRandomWords.
* *****************************************************************************
* @dev USAGE
*
* @dev Calling contracts must inherit from VRFConsumerBase, and can
* @dev initialize VRFConsumerBase's attributes in their constructor as
* @dev shown:
*
* @dev contract VRFConsumer {
* @dev constructor(<other arguments>, address _vrfCoordinator, address _link)
* @dev VRFConsumerBase(_vrfCoordinator) public {
* @dev <initialization with other arguments goes here>
* @dev }
* @dev }
*
* @dev The oracle will have given you an ID for the VRF keypair they have
* @dev committed to (let's call it keyHash). Create subscription, fund it
* @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface
* @dev subscription management functions).
* @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations,
* @dev callbackGasLimit, numWords),
* @dev see (VRFCoordinatorInterface for a description of the arguments).
*
* @dev Once the VRFCoordinator has received and validated the oracle's response
* @dev to your request, it will call your contract's fulfillRandomWords method.
*
* @dev The randomness argument to fulfillRandomWords is a set of random words
* @dev generated from your requestId and the blockHash of the request.
*
* @dev If your contract could have concurrent requests open, you can use the
* @dev requestId returned from requestRandomWords to track which response is associated
* @dev with which randomness request.
* @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind,
* @dev if your contract could have multiple requests in flight simultaneously.
*
* @dev Colliding `requestId`s are cryptographically impossible as long as seeds
* @dev differ.
*
* *****************************************************************************
* @dev SECURITY CONSIDERATIONS
*
* @dev A method with the ability to call your fulfillRandomness method directly
* @dev could spoof a VRF response with any random value, so it's critical that
* @dev it cannot be directly called by anything other than this base contract
* @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
*
* @dev For your users to trust that your contract's random behavior is free
* @dev from malicious interference, it's best if you can write it so that all
* @dev behaviors implied by a VRF response are executed *during* your
* @dev fulfillRandomness method. If your contract must store the response (or
* @dev anything derived from it) and use it later, you must ensure that any
* @dev user-significant behavior which depends on that stored value cannot be
* @dev manipulated by a subsequent VRF request.
*
* @dev Similarly, both miners and the VRF oracle itself have some influence
* @dev over the order in which VRF responses appear on the blockchain, so if
* @dev your contract could have multiple VRF requests in flight simultaneously,
* @dev you must ensure that the order in which the VRF responses arrive cannot
* @dev be used to manipulate your contract's user-significant behavior.
*
* @dev Since the block hash of the block which contains the requestRandomness
* @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
* @dev miner could, in principle, fork the blockchain to evict the block
* @dev containing the request, forcing the request to be included in a
* @dev different block with a different hash, and therefore a different input
* @dev to the VRF. However, such an attack would incur a substantial economic
* @dev cost. This cost scales with the number of blocks the VRF oracle waits
* @dev until it calls responds to a request. It is for this reason that
* @dev that you can signal to an oracle you'd like them to wait longer before
* @dev responding to the request (however this is not enforced in the contract
* @dev and so remains effective only in the case of unmodified oracle software).
*/
abstract contract VRFConsumerBaseV2 {
error OnlyCoordinatorCanFulfill(address have, address want);
address private immutable vrfCoordinator;
/**
* @param _vrfCoordinator address of VRFCoordinator contract
*/
constructor(address _vrfCoordinator) {
vrfCoordinator = _vrfCoordinator;
}
/**
* @notice fulfillRandomness handles the VRF response. Your contract must
* @notice implement it. See "SECURITY CONSIDERATIONS" above for important
* @notice principles to keep in mind when implementing your fulfillRandomness
* @notice method.
*
* @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this
* @dev signature, and will call it once it has verified the proof
* @dev associated with the randomness. (It is triggered via a call to
* @dev rawFulfillRandomness, below.)
*
* @param requestId The Id initially returned by requestRandomness
* @param randomWords the VRF output expanded to the requested number of words
*/
function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual;
// rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
// proof. rawFulfillRandomness then calls fulfillRandomness, after validating
// the origin of the call
function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external {
if (msg.sender != vrfCoordinator) {
revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator);
}
fulfillRandomWords(requestId, randomWords);
}
}{
"remappings": [],
"optimizer": {
"enabled": false,
"runs": 200
},
"evmVersion": "london",
"libraries": {},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_dgFamilyContractAddress","type":"address"},{"internalType":"address","name":"_glassBoxContractAddress","type":"address"},{"internalType":"address","name":"_platformWallet","type":"address"},{"internalType":"uint256","name":"_revealFees","type":"uint256"},{"internalType":"uint64","name":"_subscriptionId","type":"uint64"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"randomNumbers","type":"uint256[]"}],"name":"RandomNumberGenerated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"RandomNumberRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"glassBoxTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dgTokenId","type":"uint256"},{"indexed":false,"internalType":"enum DGFamilyReveal.BoxType","name":"boxType","type":"uint8"}],"name":"Revealed","type":"event"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"boxTypeMapping","outputs":[{"internalType":"enum DGFamilyReveal.BoxType","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"checkIfRevealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dgFamilyContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"glassBoxContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"link","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"randomNumberRequests","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomNumberRequestsLimit","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdToSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIdToTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"requestRandomNumber","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"resetRandomNumbersRequested","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revealPhaseStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"revealedResults","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"revealedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"seed","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"name":"setChainlinkKeyHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_platformWallet","type":"address"}],"name":"setPlatformWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"newLimit","type":"uint8"}],"name":"setRandomNumberRequestsLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_revealFees","type":"uint256"}],"name":"setRevealFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleRevealPhase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vrfCoordinator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a060405260405180620268e001604052806107be61ffff1681526020016102e361ffff16815260200161014961ffff1681526020016109ca61ffff1681526020016111ac61ffff16815260200161126061ffff1681526020016112ce61ffff168152602001610f3361ffff168152602001610a2a61ffff1681526020016109ba61ffff168152602001610c5561ffff16815260200161131561ffff168152602001610b7561ffff16815260200161137061ffff16815260200161043961ffff16815260200161024561ffff168152602001610e6961ffff168152602001610f2c61ffff168152602001610dd761ffff168152602001610f0261ffff16815260200161102e61ffff1681526020016101cb61ffff16815260200161052661ffff16815260200161046761ffff1681526020016105b561ffff16815260200161122a61ffff16815260200161054761ffff16815260200161045461ffff16815260200161030961ffff16815260200161101261ffff16815260200161113b61ffff1681526020016105fa61ffff1681526020016104dc61ffff16815260200161111861ffff16815260200161096e61ffff168152602001610feb61ffff1681526020016108ee61ffff16815260200161094c61ffff168152602001610f8461ffff16815260200161097461ffff1681526020016110da61ffff168152602001610ef061ffff168152602001610d6661ffff1681526020016110d461ffff1681526020016101eb61ffff168152602001610d7c61ffff1681526020016101b861ffff1681526020016105fc61ffff1681526020016107d061ffff1681526020016107d461ffff16815260200161035861ffff16815260200161071461ffff168152602001610f7f61ffff168152602001610dcd61ffff1681526020016107fd61ffff1681526020016104b361ffff168152602001610cbc61ffff1681526020016106ea61ffff16815260200161075161ffff16815260200161011561ffff16815260200161052261ffff1681526020016109c661ffff16815260200161027a61ffff168152602001610f7161ffff1681526020016109a161ffff1681526020016109a761ffff168152602001610e3361ffff168152602001610fa361ffff1681526020016106e861ffff168152602001610e4961ffff16815260200161126961ffff1681526020016109a061ffff168152602001610f9a61ffff168152602001610b1361ffff16815260200161049d61ffff168152602001610d3b61ffff1681526020016111a361ffff1681526020016103fe61ffff1681526020016102d361ffff16815260200161086061ffff168152602001610a6d61ffff1681526020016110e961ffff16815260200161026361ffff16815260200161108261ffff16815260200161060f61ffff168152602001610ce461ffff16815260200161135f61ffff168152602001610c2161ffff16815260200161014561ffff168152602001610df061ffff168152602001610e4261ffff1681526020016112b861ffff168152602001610d4861ffff16815260200161068861ffff1681526020016110c561ffff16815260200161112361ffff1681526020016111ef61ffff168152602001610f6761ffff16815260200161078261ffff168152602001610a4861ffff16815260200161094f61ffff1681526020016104bc61ffff16815260200161106461ffff16815260200161092061ffff168152602001608961ffff16815260200161050461ffff168152602001610b9c61ffff1681526020016108f661ffff168152602001610b6e61ffff1681526020016101a361ffff16815260200161038461ffff168152602001610da261ffff168152602001610a8e61ffff1681526020016108a561ffff1681526020016111c661ffff16815260200161107261ffff16815260200161105861ffff16815260200161069f61ffff168152602001610bd461ffff16815260200161077961ffff168152602001610f4561ffff16815260200161107b61ffff16815260200161041f61ffff16815260200161092f61ffff16815260200161078361ffff168152602001610db861ffff168152602001610cb461ffff1681526020016103c161ffff1681526020016111e561ffff16815260200161032261ffff16815260200161092261ffff168152602001610c4961ffff168152602001610f1761ffff168152602001610a7a61ffff168152602001610e5f61ffff1681526020016104c961ffff16815260200161050061ffff168152602001610a5961ffff16815260200161053261ffff16815260200161081061ffff168152602001610b5e61ffff16815260200161113f61ffff1681526020016111e161ffff168152602001610f4c61ffff168152602001610fc261ffff168152602001610d0861ffff1681526020016106a261ffff1681526020016111de61ffff168152602001610ddb61ffff168152602001610a6061ffff168152602001610cb661ffff168152602001610bb861ffff16815260200161116161ffff16815260200161112d61ffff168152602001610fcf61ffff16815260200161073b61ffff1681526020016101e461ffff1681526020016109cf61ffff1681526020016106b361ffff16815260200161055a61ffff16815260200161058b61ffff16815260200161101b61ffff1681526020016103c061ffff1681526020016106b061ffff1681526020016109bd61ffff168152602001610f1d61ffff1681526020016108a661ffff16815260200161063261ffff16815260200161046561ffff168152602001610edf61ffff16815260200161044461ffff1681526020016110b461ffff16815260200161084361ffff168152602001610add61ffff16815260200161091f61ffff168152602001610ed561ffff168152602001610e2b61ffff16815260200160a561ffff168152602001610ba361ffff1681526020016105fd61ffff16815260200161100e61ffff168152602001610f1261ffff16815260200161110c61ffff168152602001610af561ffff16815260200161122c61ffff16815260200161103161ffff16815260200161131361ffff1681526020016112ff61ffff1681526020016103bf61ffff1681526020016112cf61ffff16815260200161086761ffff1681526020016109d561ffff16815260200161101361ffff168152602001610f0361ffff16815260200161055061ffff168152602001610f9461ffff16815260200161135061ffff1681526020016101cf61ffff168152602001610bdc61ffff16815260200161065361ffff168152602001610fdc61ffff16815260200161027261ffff1681526020016108cc61ffff168152602001610a9261ffff168152602001610b2761ffff16815260200161105761ffff1681526020016109f761ffff16815260200161055361ffff168152602001610cd761ffff168152602001610eb261ffff16815260200161086a61ffff16815260200161043661ffff1681526020016112d061ffff168152602001610c5861ffff168152602001610fa561ffff1681526020016110d261ffff16815260200161068061ffff1681526020016102a761ffff168152602001610b8a61ffff1681526020016108c261ffff168152602001610fa861ffff1681526020016102d561ffff1681526020016107d861ffff168152602001610d7461ffff16815260200161013361ffff168152602001610a2661ffff168152602001610bb761ffff16815260200160ae61ffff168152602001610be361ffff16815260200161128e61ffff16815260200161134e61ffff16815260200161032461ffff1681526020016108db61ffff1681526020016108f561ffff168152602001605361ffff168152602001610e0561ffff1681526020016105dd61ffff16815260200161058461ffff16815260200161042261ffff168152602001610e1561ffff16815260200161042c61ffff168152602001610ee861ffff168152602001610f1361ffff168152602001610f3c61ffff168152602001610a4a61ffff16815260200161021661ffff16815260200161123761ffff1681526020016102fa61ffff1681526020016104ed61ffff168152602001610c3b61ffff168152602001610ff461ffff16815260200161081361ffff16815260200161138361ffff1681526020016108f861ffff16815260200161036e61ffff168152602001610cc861ffff16815260200161093c61ffff1681526020016111e761ffff16815260200161070061ffff1681526020016109d261ffff16815260200161038261ffff168152602001605161ffff168152602001610ced61ffff16815260200161037161ffff16815260200161070e61ffff16815260200161046b61ffff16815260200161077561ffff168152602001610ccd61ffff168152602001608a61ffff1681526020016106eb61ffff16815260200161020961ffff168152602001610bce61ffff16815260200160cb61ffff16815260200161135d61ffff16815260200161127b61ffff1681526020016105d661ffff16815260200161048761ffff16815260200161113761ffff168152602001610d3561ffff16815260200161018761ffff16815260200161014761ffff1681526020016103ab61ffff16815260200161057061ffff168152602001610b2561ffff16815260200161102861ffff1681526020016106c361ffff168152602001608661ffff16815260200161053561ffff1681526020016102c661ffff16815260200160f861ffff168152602001610d6c61ffff1681526020016110fd61ffff16815260200161105561ffff168152602001610e7261ffff1681526020016105f061ffff16815260200161096c61ffff168152602001610cba61ffff1681526020016105b261ffff168152602001610d6161ffff16815260200161023361ffff16815260200161021e61ffff16815260200161050561ffff1681526020016105c661ffff16815260200161058061ffff168152602001610ede61ffff168152602001610ecb61ffff1681526020016109de61ffff16815260200161115f61ffff168152602001610e8961ffff1681526020016111d061ffff168152602001610f9761ffff16815260200161065861ffff168152602001610bfb61ffff16815260200161073161ffff168152602001610b7061ffff16815260200161051261ffff16815260200161016861ffff16815260200161042461ffff16815260200161026761ffff168152602001610d2b61ffff1681526020016103cf61ffff168152602001603061ffff16815260200161039c61ffff1681526020016112df61ffff16815260200161063661ffff168152602001610e3b61ffff16815260200161124a61ffff168152602001610cfa61ffff16815260200161132e61ffff16815260200161135961ffff168152602001610ed961ffff168152602001610f2161ffff168152602001610e9161ffff16815260200161036261ffff1681526020016103cd61ffff16815260200161024661ffff16815260200161050261ffff1681526020016111fa61ffff16815260200161060861ffff168152602001610e6e61ffff168152602001610b2f61ffff168152602001610abe61ffff1681526020016103ad61ffff16815260200161062b61ffff16815260200161073761ffff16815260200161024961ffff16815260200161072161ffff1681526020016104a861ffff16815260200161048361ffff168152602001610fd961ffff16815260200161056f61ffff168152602001610db061ffff168152602001610aea61ffff16815260200161016a61ffff16815260200161110d61ffff168152602001610bb361ffff1681526020016111bd61ffff16815260200161066f61ffff16815260200161059d61ffff16815260200161096d61ffff1681526020016106f961ffff168152602001610c4261ffff16815260200161062861ffff1681526020016109e261ffff168152602001610da361ffff16815260200160f061ffff16815260200161097661ffff168152602001610b1861ffff168152602001610c5361ffff16815260200161090661ffff16815260200161125261ffff1681526020016101e361ffff1681526020016104a261ffff16815260200161138561ffff16815260200161071c61ffff16815260200161059a61ffff168152602001610ea161ffff1681526020016101fe61ffff16815260200161051c61ffff1681526020016104b661ffff168152602001606161ffff1681526020016105a561ffff1681526020016108af61ffff1681526020016107e761ffff16815260200161122561ffff1681526020016103db61ffff168152602001610b2961ffff16815260200161067961ffff16815260200161088561ffff16815260200161111b61ffff16815260200161102a61ffff1681526020016110b561ffff1681526020016101af61ffff16815260200161119961ffff168152602001610d9e61ffff168152602001610b0061ffff168152602001610abd61ffff168152602001610d5d61ffff168152602001610d6b61ffff16815260200161027661ffff1681526020016106a961ffff168152602001610bff61ffff16815260200161051361ffff168152602001610fe261ffff1681526020016103d561ffff1681526020016109a461ffff168152602001610ba161ffff1681526020016104e661ffff1681526020016104cc61ffff16815260200161106761ffff1681526020016104d161ffff168152602001610a8761ffff16815260200161119f61ffff168152602001610b1461ffff16815260200161127961ffff168152602001610c3c61ffff1681526020016110cb61ffff16815260200161022361ffff168152602001610db361ffff168152602001610c0561ffff16815260200160c561ffff16815260200161096661ffff16815260200161017e61ffff168152602001610cfc61ffff16815260200160fd61ffff16815260200161115361ffff168152602001610b6161ffff168152602001610ba661ffff1681526020016105f361ffff16815260200161041261ffff168152602001606261ffff1681526020016104ff61ffff16815260200161120c61ffff16815260200161108861ffff1681526020016104fe61ffff168152602001610ecc61ffff1681526020016107f961ffff168152602001610e7361ffff16815260200161104b61ffff16815260200161121861ffff168152602001606961ffff16815260200161135861ffff16815260200161083a61ffff168152602001610fcc61ffff16815260200161047d61ffff1681526020016105d461ffff16815260200161055561ffff16815260200161082761ffff168152602001610d7f61ffff1681526020016110ac61ffff168152602001610aaa61ffff168152602001610b3961ffff168152602001610a8661ffff16815260200161061a61ffff16815260200161121a61ffff168152602001610dff61ffff168152602001610aab61ffff1681526020016106f461ffff1681526020016112d661ffff1681526020016106f661ffff16815260200161129661ffff16815260200161053661ffff16815260200161012861ffff168152602001606761ffff1681526020016112a461ffff16815260200160d061ffff16815260200160bd61ffff168152602001610a8361ffff1681526020016101c161ffff168152602001610b3e61ffff1681526020016108ab61ffff1681526020016103e361ffff16815260200161067461ffff1681526020016107f361ffff168152602001607261ffff1681526020016102b861ffff16815260200161012361ffff1681526020016105ad61ffff1681526020016110bb61ffff1681526020016109a561ffff168152602001610ffb61ffff168152602001610e3e61ffff168152602001610a9a61ffff168152602001610a1561ffff16815260200160c261ffff16815260200161134d61ffff1681526020016105de61ffff1681526020016105ca61ffff168152602001610da561ffff168152602001610f5f61ffff1681526020016102f661ffff16815260200161084561ffff1681526020016108fd61ffff1681526020016107c361ffff168152602001610af161ffff168152602001610eaa61ffff16815260200161098061ffff168152602001610cca61ffff1681526020016106e761ffff16815260200161121c61ffff1681526020016108df61ffff16815260200161113061ffff16815260200161090c61ffff168152602001610c5e61ffff168152602001610b5261ffff168152602001605261ffff1681526020016103b461ffff16815260200161092661ffff16815260200161137b61ffff1681526020016112b061ffff168152602001610c0f61ffff16815260200161094061ffff1681526020016109d861ffff168152602001610c7b61ffff16815260200161103361ffff16815260200161066261ffff16815260200161111f61ffff168152602001610c1f61ffff168152602001610ee561ffff16815260200161017661ffff168152602001610c3f61ffff168152602001610e2a61ffff168152602001610f4a61ffff16815260200161134561ffff168152602001610e8a61ffff1681526020016101b461ffff16815260200161136861ffff1681526020016101dc61ffff16815260200160ca61ffff16815260200161098561ffff1681526020016110fa61ffff1681526020016105e661ffff16815260200161052c61ffff16815260200161089361ffff168152602001604761ffff1681526020016101a261ffff168152602001610b4d61ffff16815260200161058261ffff168152602001610bf061ffff16815260200161077161ffff168152602001610a4c61ffff1681526020016111e961ffff16815260200161077d61ffff16815260200161035061ffff168152602001610df361ffff16815260200161105b61ffff1681526020016110c261ffff16815260200161022061ffff1681526020016108ac61ffff168152602001610b5a61ffff16815260200161121f61ffff16815260200161127a61ffff1681526020016103b961ffff16815260200161014161ffff1681526020016111f161ffff1681526020016111f261ffff16815260200160f161ffff16815260200161080161ffff16815260200161044c61ffff1681526020016105f261ffff16815260200161048061ffff168152602001610b7461ffff16815260200161063061ffff1681526020016109fc61ffff168152602001610e8261ffff16815260200161032761ffff16815260200161092861ffff1681526020016106bd61ffff168152602001610ebb61ffff168152602001610c3361ffff1681526020016103a961ffff168152602001603e61ffff16815260200161124b61ffff168152602001610a0761ffff168152602001610ea961ffff1681526020016110e061ffff16815260200161031161ffff1681526020016109e961ffff168152602001610ef461ffff168152602001610d0b61ffff168152602001610bf761ffff16815260200161020161ffff16815260200161031661ffff168152602001610f2b61ffff168152602001610f4f61ffff16815260200161047761ffff1681526020016103b861ffff16815260200161036661ffff168152602001610dde61ffff16815260200161111261ffff1681526020016107e061ffff16815260200161090761ffff16815260200161131961ffff1681526020016109b061ffff1681526020016111fd61ffff168152602001610cc761ffff16815260200161010161ffff168152602001610e9961ffff1681526020016112dd61ffff168152602001610fc461ffff168152602001610bc961ffff16815260200161071e61ffff1681526020016102ab61ffff16815260200161078e61ffff16815260200161089a61ffff168152602001610e2961ffff16815260200161040961ffff16815260200161124961ffff16815260200161067c61ffff16815260200161056b61ffff1681526020016103a061ffff1681526020016108bb61ffff16815260200161097d61ffff168152602001610a5d61ffff16815260200161033961ffff16815260200161101161ffff16815260200161136161ffff168152602001610ebf61ffff168152602001610bb261ffff16815260200161047961ffff1681526020016105d161ffff16815260200161136661ffff16815260200161052f61ffff16815260200161060361ffff16815260200161116061ffff1681526020016112b761ffff168152602001610e7861ffff1681526020016103c861ffff168152602001610a3a61ffff1681526020016112e361ffff168152602001610b8361ffff168152602001610c8b61ffff168152602001610dd861ffff16815260200161112a61ffff168152602001610b0361ffff16815260200161073361ffff1681526020016107ca61ffff16815260200161091661ffff168152602001610a6c61ffff16815260200161127d61ffff16815260200161098c61ffff16815260200161087e61ffff1681526020016105b361ffff16815260200161025b61ffff16815260200161035161ffff1681526020016102f161ffff168152602001610d3661ffff1681526020016108e761ffff168152602001610dec61ffff168152602001610ae561ffff168152602001610bd761ffff16815260200161045a61ffff168152602001604961ffff168152602001610ca161ffff168152602001610e0a61ffff16815260200161115261ffff16815260200160fe61ffff168152602001610c0961ffff168152602001610a7461ffff168152602001610ccc61ffff16815260200161091961ffff168152602001610c6a61ffff168152602001610d9961ffff168152602001610c2361ffff16815260200161129e61ffff168152602001610b2161ffff16815260200161132261ffff168152602001610c5d61ffff168152602001610dce61ffff168152602001608d61ffff168152602001603b61ffff16815260200161014a61ffff168152602001610e7961ffff16815260200161102f61ffff1681526020016109e361ffff1681526020016111cc61ffff16815260200161021f61ffff168152602001610b9f61ffff16815260200161056c61ffff1681526020016107ff61ffff168152602001610adc61ffff1681526020016111ed61ffff16815260200161067261ffff168152602001610ba761ffff168152602001610d0c61ffff16815260200161011b61ffff168152602001610b2e61ffff1681526020016108a861ffff168152602001610c1661ffff168152602001610f0861ffff16815260200161099261ffff168152602001610e4561ffff1681526020016102f961ffff168152602001610c9b61ffff16815260200161049861ffff16815260200161125c61ffff16815260200160c761ffff16815260200161069b61ffff16815260200161045e61ffff16815260200161062e61ffff16815260200161039a61ffff168152602001610eb761ffff16815260200161074061ffff16815260200161032b61ffff16815260200161049e61ffff1681526020016111bf61ffff16815260200161098a61ffff16815260200161128861ffff16815260200161137e61ffff16815260200161133b61ffff1681526020016107cf61ffff16815260200161105e61ffff16815260200161099661ffff16815260200161013461ffff16815260200161097961ffff16815260200161115c61ffff1681526020016112a261ffff1681526020016110d661ffff1681526020016106cb61ffff16815260200161043861ffff16815260200160f561ffff16815260200161027061ffff16815260200161122661ffff1681526020016109ae61ffff1681526020016111d961ffff1681526020016105c061ffff1681526020016109a861ffff168152602001610c9661ffff1681526020016111b261ffff168152602001610b9461ffff168152602001610a4761ffff168152602001610acb61ffff168152602001610cb361ffff16815260200161018561ffff1681526020016108d461ffff16815260200161100661ffff1681526020016109b961ffff168152602001610aca61ffff168152602001610cd961ffff16815260200161059361ffff16815260200161106961ffff1681526020016111bb61ffff16815260200161091161ffff168152602001610bdb61ffff16815260200161112661ffff168152602001610dba61ffff16815260200161135a61ffff1681526020016110a561ffff16815260200161039261ffff168152602001610a3b61ffff168152602001610dd261ffff1681526020016110f661ffff16815260200161051a61ffff168152602001610ab261ffff1681526020016101e561ffff168152602001610df161ffff1681526020016102b561ffff168152602001610ca061ffff168152602001610e6061ffff1681526020016103d861ffff1681526020016110af61ffff168152602001610c4161ffff16815260200161111161ffff16815260200161055c61ffff16815260200161015761ffff16815260200161095061ffff16815260200161011d61ffff168152602001610a2561ffff16815260200161059f61ffff168152602001610c7d61ffff16815260200161115061ffff16815260200161016761ffff16815260200161030d61ffff16815260200161055f61ffff16815260200160ac61ffff1681526020016106d561ffff1681526020016111c561ffff168152602001610e9861ffff168152602001610c8361ffff16815260200160b961ffff16815260200161121561ffff168152602001610c8461ffff1681526020016104f361ffff16815260200161078861ffff1681526020016105d561ffff168152602001610c2e61ffff16815260200161107461ffff16815260200161063961ffff168152602001610a6b61ffff1681526020016106a361ffff1681526020016101bd61ffff16815260200161025a61ffff16815260200161032a61ffff1681526020016107c161ffff16815260200161100861ffff1681526020016102f361ffff168152602001610eab61ffff16815260200161117061ffff16815260200161137461ffff168152602001610cb961ffff16815260200161039e61ffff16815260200161067061ffff168152602001610ddf61ffff168152602001610bf661ffff16815260200161080461ffff16815260200161115e61ffff168152602001610cbe61ffff168152602001610b6261ffff16815260200161064861ffff1681526020016109a661ffff16815260200161087f61ffff16815260200161125361ffff168152602001610fe461ffff16815260200161051761ffff168152602001610cbf61ffff1681526020016101d961ffff16815260200161021961ffff168152602001610eaf61ffff16815260200161056a61ffff1681526020016108c761ffff16815260200161103261ffff168152602001610bd361ffff168152602001610b7961ffff16815260200161018e61ffff1681526020016112ae61ffff1681526020016107b561ffff16815260200161086261ffff16815260200161107361ffff1681526020016111b861ffff168152602001610cf361ffff1681526020016106be61ffff168152602001610ed161ffff1681526020016103c261ffff1681526020016104f061ffff16815260200161042f61ffff168152602001610fdb61ffff168152602001610a8a61ffff1681526020016104ec61ffff16815260200161128061ffff1681526020016110dd61ffff1681526020016103ba61ffff168152602001610a0961ffff16815260200160f261ffff1681526020016103fa61ffff16815260200161106b61ffff168152602001610c6461ffff168152602001610df461ffff168152602001610fe861ffff1681526020016107de61ffff168152602001610c7f61ffff16815260200160e261ffff16815260200161066461ffff16815260200161060e61ffff16815260200161087061ffff168152602001610b4161ffff1681526020016105d961ffff1681526020016102ae61ffff1681526020016106ce61ffff16815260200160b561ffff16815260200161100761ffff16815260200161085261ffff16815260200161016561ffff16815260200161076961ffff168152602001610c2661ffff1681526020016103b361ffff1681526020016112db61ffff1681526020016110c061ffff1681526020016106c461ffff168152602001610d2c61ffff1681526020016107db61ffff16815260200161090d61ffff168152602001610e4a61ffff16815260200161061461ffff16815260200161041c61ffff168152602001610f9c61ffff16815260200161131e61ffff1681526020016101cc61ffff168152602001610ab361ffff16815260200161011061ffff16815260200161019d61ffff16815260200161094961ffff16815260200161040461ffff16815260200161121061ffff1681526020016110a261ffff1681526020016106b661ffff168152602001610e6b61ffff168152602001610d6461ffff16815260200161049361ffff168152602001610c2861ffff168152602001610cc461ffff16815260200161095f61ffff168152602001610b2b61ffff1681526020016112ef61ffff168152602001610a7961ffff168152602001610a8461ffff16815260200161065561ffff168152602001610cb761ffff16815260200161071f61ffff16815260200161117f61ffff16815260200161027761ffff16815260200161132161ffff16815260200161117c61ffff16815260200161099161ffff1681526020016112b661ffff16815260200161017861ffff16815260200161082f61ffff168152602001610c9261ffff168152602001610b9261ffff16815260200161108e61ffff16815260200161061961ffff1681526020016106a761ffff16815260200161119a61ffff16815260200161086161ffff16815260200161102261ffff168152602001610e5161ffff1681526020016106da61ffff16815260200161095b61ffff1681526020016109cd61ffff16815260200160ef61ffff16815260200161054361ffff16815260200161025d61ffff1681526020016107e561ffff16815260200161051861ffff16815260200161064261ffff168152602001610b8561ffff168152602001610f5c61ffff168152602001610d8961ffff16815260200161040261ffff168152602001610cfb61ffff168152602001610d7061ffff16815260200161083261ffff16815260200161111661ffff168152602001610aad61ffff168152602001610e3261ffff16815260200161019361ffff168152602001610c2c61ffff168152602001610f9661ffff168152602001610aa961ffff168152602001610f5861ffff16815260200161034761ffff1681526020016108c961ffff16815260200161038b61ffff1681526020016108de61ffff168152602001610a7561ffff1681526020016108d561ffff168152602001610eb661ffff16815260200161032f61ffff168152602001610c9a61ffff1681526020016106ef61ffff16815260200161054d61ffff1681526020016107e461ffff16815260200161016161ffff16815260200161134261ffff168152602001610a1d61ffff168152602001610a6161ffff168152602001610f1a61ffff1681526020016106a561ffff16815260200161065a61ffff16815260200161040361ffff168152602001610fed61ffff168152602001610af061ffff168152602001610ce361ffff1681526020016105d361ffff16815260200161118e61ffff168152602001610d5861ffff1681526020016112ab61ffff168152602001610d0961ffff16815260200161083c61ffff168152602001610faf61ffff168152602001610ad261ffff1681526020016106d061ffff1681526020016101a561ffff16815260200161054561ffff1681526020016104d961ffff16815260200161046361ffff16815260200161044261ffff1681526020016102a961ffff168152602001610c9561ffff168152602001610b1b61ffff168152602001610c7061ffff1681526020016102df61ffff16815260200161094761ffff16815260200161050a61ffff168152602001610d5f61ffff168152602001610ca561ffff16815260200161135e61ffff168152602001610efc61ffff168152602001610bbd61ffff16815260200161060b61ffff16815260200161082d61ffff16815260200161125161ffff168152602001610afd61ffff168152602001610c1861ffff168152602001610d3e61ffff1681526020016103d061ffff168152602001610f1661ffff1681526020016106bf61ffff168152602001610f8161ffff16815260200161062361ffff16815260200161129a61ffff1681526020016110f261ffff16815260200161101e61ffff1681526020016110db61ffff1681526020016108b561ffff168152602001610d4f61ffff168152602001610d5661ffff16815260200161088761ffff1681526020016103d961ffff16815260200161107c61ffff168152602001610c8c61ffff16815260200161047c61ffff1681526020016111fb61ffff16815260200161050961ffff16815260200161061b61ffff168152602001607a61ffff168152602001610a3361ffff168152602001610a0361ffff16815260200161015861ffff168152602001610a8561ffff168152602001610ecd61ffff168152602001610dd161ffff168152602001610a7761ffff16815260200161036861ffff16815260200161130b61ffff16815260200161017b61ffff168152602001610ad161ffff168152602001610b5861ffff168152602001610b7b61ffff16815260200161037261ffff16815260200161065461ffff16815260200161065d61ffff16815260200161075661ffff168152602001610bfd61ffff16815260200160f761ffff168152602001610b0d61ffff168152602001610e6361ffff16815260200161019961ffff1681526020016111ea61ffff168152602001610b5f61ffff1681526020016105bf61ffff168152602001610fce61ffff168152602001610e3a61ffff168152602001610d3761ffff168152602001610bbf61ffff1681526020016107c461ffff1681526020016104c061ffff168152602001610c2261ffff16815260200161040d61ffff1681526020016107b461ffff168152602001610b5761ffff168152602001610e4e61ffff1681526020016106a461ffff1681526020016103fd61ffff1681526020016104f261ffff16815260200161082061ffff168152602001610ae661ffff16815260200161076061ffff168152602001610a6761ffff168152602001605661ffff168152602001610a1661ffff168152602001610eee61ffff16815260200161035b61ffff16815260200161130161ffff16815260200161046f61ffff1681526020016103e461ffff168152602001610d7d61ffff16815260200161042561ffff16815260200161100b61ffff16815260200161107061ffff168152602001610c2d61ffff168152602001610dca61ffff16815260200161035d61ffff168152602001610f0e61ffff168152602001610c6e61ffff168152602001610bfc61ffff168152602001610a1261ffff168152602001610f4461ffff16815260200161038361ffff1681526020016106f161ffff1681526020016103d261ffff16815260200161024261ffff16815260200161131661ffff16815260200161115161ffff1681526020016111f061ffff1681526020016101ad61ffff168152602001610cfd61ffff168152602001610aa361ffff1681526020016103a761ffff1681526020016111c061ffff1681526020016109b661ffff168152602001610efb61ffff1681526020016101bc61ffff16815260200161089161ffff168152602001610f1b61ffff1681526020016104d561ffff168152602001609461ffff16815260200161071861ffff16815260200161055161ffff168152602001610a0d61ffff16815260200161088261ffff168152602001610c5761ffff16815260200161086d61ffff16815260200161091861ffff16815260200161017061ffff1681526020016108ba61ffff1681526020016102c861ffff1681526020016112b961ffff168152602001610d7a61ffff16815260200161096f61ffff16815260200161029861ffff1681526020016106dc61ffff16815260200161011161ffff168152602001610fb361ffff16815260200161129d61ffff168152602001610bcd61ffff1681526020016101fb61ffff16815260200161069161ffff1681526020016108a361ffff168152602001610c9461ffff1681526020016107eb61ffff16815260200161118561ffff168152602001610f0461ffff16815260200161010f61ffff1681526020016101ac61ffff1681526020016112d461ffff1681526020016101d861ffff168152602001607861ffff16815260200161041761ffff168152602001610e6561ffff16815260200161044661ffff16815260200161133361ffff168152602001610d2661ffff1681526020016109ed61ffff16815260200161065f61ffff168152602001610e7b61ffff16815260200161052061ffff168152602001610c6661ffff16815260200161038e61ffff16815260200161019861ffff16815260200161051f61ffff16815260200161042d61ffff16815260200161136f61ffff168152602001610e5661ffff16815260200161118d61ffff16815260200161121b61ffff168152602001610e8461ffff168152602001609561ffff1681526020016105b861ffff16815260200161135c61ffff16815260200161052b61ffff1681526020016112af61ffff16815260200160eb61ffff16815260200161118161ffff16815260200161068761ffff16815260200161106f61ffff16815260200161055b61ffff16815260200161120361ffff1681526020016111af61ffff168152602001610af661ffff16815260200161124461ffff16815260200161130f61ffff16815260200161016f61ffff1681526020016111db61ffff168152602001610ca661ffff16815260200161035261ffff168152602001610ce261ffff16815260200161127661ffff16815260200161099d61ffff1681526020016107c761ffff168152602001605f61ffff168152602001610a3461ffff168152602001610b4761ffff1681526020016108b761ffff16815260200161068161ffff1681526020016112e961ffff1681526020016104a461ffff168152602001610e2561ffff168152602001610eec61ffff16815260200161041461ffff1681526020016107ac61ffff16815260200161035461ffff16815260200161083861ffff16815260200161041361ffff16815260200161070c61ffff16815260200161049561ffff1681526020016103c961ffff16815260200161097c61ffff168152602001610b2461ffff168152602001610a3561ffff16815260200161015d61ffff16815260200161064361ffff168152602001610e7161ffff168152602001610e3661ffff1681526020016105a261ffff16815260200161055661ffff168152602001610a8b61ffff1681526020016101f261ffff16815260200161114a61ffff168152602001610d6361ffff16815260200161133161ffff16815260200161053b61ffff168152602001610c9361ffff1681526020016108ed61ffff16815260200161101a61ffff16815260200161037b61ffff16815260200161021361ffff1681526020016111d161ffff16815260200161047661ffff168152602001610c2061ffff16815260200160a061ffff1681526020016108ec61ffff168152602001610b1561ffff16815260200161018161ffff16815260200160df61ffff16815260200161024761ffff16815260200161079b61ffff16815260200161114661ffff1681526020016101d161ffff16815260200161029c61ffff168152602001610bdd61ffff16815260200161065661ffff16815260200161109561ffff168152602001610c2961ffff168152602001610de461ffff16815260200161015c61ffff1681526020016108c461ffff1681526020016103fb61ffff16815260200161040561ffff16815260200161100961ffff168152602001610c9861ffff16815260200161119d61ffff16815260200161072b61ffff168152602001610ef361ffff168152602001610b1261ffff16815260200161083061ffff1681526020016112be61ffff1681526020016105e161ffff1681526020016110a161ffff16815260200161117a61ffff168152602001610b5461ffff16815260200161113161ffff16815260200161074561ffff168152602001610ee961ffff168152602001610de661ffff1681526020016111f861ffff16815260200161066d61ffff16815260200161105661ffff1681526020016102af61ffff168152602001610dd561ffff168152602001610c7961ffff16815260200161099e61ffff168152602001608861ffff168152602001610e3161ffff1681526020016106c861ffff168152602001610ffd61ffff168152602001610c1761ffff16815260200161073661ffff1681526020016104c361ffff16815260200161029761ffff16815260200161061161ffff168152602001610aef61ffff16815260200161038161ffff16815260200161035661ffff16815260200161061f61ffff16815260200161061261ffff16815260200161056861ffff168152602001610a2d61ffff1681526020016105fb61ffff1681526020016111a161ffff168152602001610c0861ffff168152602001610fbb61ffff1681526020016108f361ffff168152602001610c7161ffff16815260200161087761ffff168152602001610ef161ffff16815260200161016361ffff1681526020016102e261ffff16815260200161051561ffff16815260200161102361ffff1681526020016103ca61ffff16815260200161022f61ffff168152602001610eed61ffff168152602001610d1761ffff16815260200161133a61ffff168152602001610b7161ffff1681526020016106f361ffff1681526020016103f061ffff168152602001610c6061ffff168152602001610a7861ffff168152602001610f4061ffff16815260200161126661ffff168152602001605c61ffff16815260200161112461ffff16815260200161124061ffff1681526020016108dc61ffff1681526020016107a961ffff16815260200161066661ffff1681526020016108e061ffff168152602001608361ffff168152602001610ee461ffff168152602001610fa761ffff1681526020016110ed61ffff16815260200161020761ffff168152602001610beb61ffff1681526020016110f361ffff16815260200161129861ffff16815260200161130461ffff16815260200161104261ffff16815260200161026561ffff16815260200161134961ffff168152602001607e61ffff168152602001610e2661ffff16815260200161031761ffff16815260200161076461ffff168152602001610d6d61ffff1681526020016111d261ffff168152602001606c61ffff168152602001610ebc61ffff16815260200161030661ffff1681526020016101c461ffff16815260200161077461ffff168152602001610fc361ffff168152602001610cdf61ffff168152602001610a3961ffff16815260200161120161ffff168152602001610f1961ffff16815260200161114961ffff1681526020016104ad61ffff16815260200161103d61ffff16815260200161136961ffff16815260200161016261ffff16815260200161112961ffff1681526020016112ba61ffff168152602001610adf61ffff168152602001610aa061ffff16815260200161016661ffff1681526020016103a661ffff1681526020016111ad61ffff16815260200161108a61ffff16815260200161118461ffff1681526020016104e861ffff16815260200160e561ffff168152602001610a7261ffff16815260200161043d61ffff168152602001610c1e61ffff168152602001610c2561ffff1681526020016107ec61ffff1681526020016112ee61ffff16815260200161053361ffff16815260200161040061ffff1681526020016104e361ffff16815260200161066a61ffff1681526020016102d861ffff1681526020016112f661ffff16815260200161085061ffff16815260200161104061ffff16815260200160dc61ffff16815260200161020b61ffff16815260200161120661ffff16815260200161051d61ffff1681526020016108e161ffff1681526020016104a161ffff16815260200161092e61ffff1681526020016111b561ffff16815260200161070a61ffff1681526020016109c261ffff168152602001610cc261ffff1681526020016106a161ffff1681526020016109b461ffff16815260200161051161ffff16815260200161110761ffff168152602001610f5d61ffff1681526020016102fd61ffff1681526020016108c361ffff168152602001610cde61ffff1681526020016103f761ffff168152602001610f6c61ffff16815260200161122761ffff1681526020016108dd61ffff16815260200161083961ffff1681526020016110b661ffff168152602001610cae61ffff1681526020016108a461ffff16815260200161012b61ffff168152602001610f6961ffff1681526020016110c961ffff16815260200161063761ffff168152602001610b2361ffff168152602001610c6c61ffff168152602001610f2561ffff16815260200161023461ffff16815260200161054b61ffff1681526020016106ae61ffff16815260200161031d61ffff168152602001610f5361ffff16815260200161032c61ffff16815260200161081c61ffff16815260200161017a61ffff1681526020016102b061ffff16815260200161070b61ffff16815260200161098961ffff16815260200160b461ffff168152602001610bcf61ffff16815260200161068c61ffff168152602001610f6d61ffff1681526020016104a661ffff16815260200161106161ffff168152602001610df861ffff168152602001610b6561ffff16815260200161025561ffff16815260200161011461ffff168152602001610cac61ffff16815260200161129061ffff1681526020016105b761ffff16815260200161122e61ffff1681526020016102a861ffff1681526020016109f361ffff16815260200161023f61ffff16815260200161119261ffff1681526020016104c761ffff16815260200161073c61ffff1681526020016107bc61ffff1681526020016107f661ffff168152602001610b6c61ffff16815260200161034c61ffff1681526020016102e961ffff168152602001610f7561ffff168152602001610ff661ffff1681526020016107bb61ffff168152602001610d4961ffff168152602001610e0b61ffff168152602001610bbc61ffff16815260200161043561ffff16815260200161016061ffff1681526020016101da61ffff1681526020016103cb61ffff16815260200161110961ffff16815260200161015e61ffff168152602001610fb561ffff168152602001605a61ffff16815260200161019b61ffff1681526020016102db61ffff16815260200161010061ffff1681526020016112fc61ffff1681526020016109b161ffff1681526020016111b761ffff168152602001610e5961ffff168152602001610b7661ffff168152602001610caa61ffff1681526020016106ec61ffff16815260200161118c61ffff16815260200161033a61ffff168152602001610f2261ffff16815260200161030f61ffff168152602001610fe061ffff168152602001610bcc61ffff1681526020016101ae61ffff16815260200161081e61ffff168152602001610d5761ffff16815260200161044961ffff168152602001610cbb61ffff1681526020016104d261ffff1681526020016110c761ffff168152602001610c4b61ffff16815260200161026661ffff168152602001610d1961ffff16815260200161091a61ffff16815260200161109361ffff168152602001610c6561ffff168152602001610c0361ffff16815260200161101061ffff168152602001610b9a61ffff16815260200161136461ffff168152602001610f5561ffff1681526020016105dc61ffff168152602001604c61ffff1681526020016111ab61ffff16815260200161035961ffff16815260200161024a61ffff168152602001610bd061ffff168152602001610a4461ffff16815260200161038f61ffff1681526020016107b961ffff16815260200161051461ffff168152602001610e3d61ffff16815260200161114261ffff1681526020016111a561ffff1681526020016102aa61ffff16815260200161102d61ffff1681526020016104f461ffff1681526020016101e061ffff1681526020016104a361ffff1681526020016101d461ffff16815260200161010961ffff168152602001610b3f61ffff16815260200161080961ffff16815260200161067561ffff168152602001610dfb61ffff16815260200161060961ffff16815260200161072d61ffff168152602001610a9f61ffff16815260200161051b61ffff16815260200161080c61ffff1681526020016103df61ffff1681526020016111aa61ffff168152602001607161ffff168152602001610fff61ffff168152602001610f6661ffff16815260200161096361ffff16815260200161086561ffff168152602001610a9161ffff16815260200161074e61ffff16815260200161108761ffff16815260200161040c61ffff168152602001610f2761ffff1681526020016111f561ffff1681526020016104da61ffff168152602001610e5e61ffff1681526020016101aa61ffff168152602001610ed861ffff16815260200161126c61ffff16815260200161013561ffff168152602001610b9e61ffff168152602001610bd861ffff16815260200161059661ffff168152602001610cb861ffff168152602001610be061ffff16815260200161025c61ffff16815260200161110461ffff16815260200161101f61ffff168152602001610a6e61ffff16815260200161016961ffff16815260200161095361ffff1681526020016110d061ffff16815260200160da61ffff168152602001610d4561ffff1681526020016109b861ffff16815260200161111c61ffff16815260200161060761ffff16815260200161084c61ffff16815260200161127561ffff1681526020016103c361ffff16815260200161067b61ffff1681526020016106e661ffff168152602001610d7661ffff16815260200161073f61ffff16815260200161074861ffff16815260200161037c61ffff168152602001610f7a61ffff168152602001610ee161ffff168152602001610b1f61ffff16815260200161093a61ffff16815260200161089d61ffff168152602001610d3c61ffff168152602001610f5261ffff168152602001610cf761ffff16815260200161116361ffff16815260200161035c61ffff16815260200161072061ffff168152602001607461ffff16815260200161041e61ffff168152602001610a4061ffff16815260200161125461ffff16815260200161096b61ffff16815260200161023761ffff16815260200161069c61ffff1681526020016111f361ffff168152602001610e4b61ffff16815260200161109761ffff1681526020016102a361ffff16815260200161079261ffff16815260200161062661ffff16815260200160a761ffff16815260200161120f61ffff1681526020016109d661ffff16815260200161050f61ffff16815260200161052861ffff16815260200161068f61ffff16815260200161010c61ffff168152602001610c7a61ffff168152602001610c4a61ffff1681526020016109a961ffff16815260200161104c61ffff168152602001610a5061ffff16815260200161028e61ffff16815260200161058e61ffff16815260200161121161ffff168152602001610c4661ffff168152602001610ff961ffff16815260200161067a61ffff168152602001610ee061ffff16815260200161088161ffff168152602001610f7261ffff1681526020016108bf61ffff168152602001610e8661ffff16815260200161123c61ffff16815260200161090461ffff16815260200161024f61ffff16815260200161013b61ffff168152602001610e1361ffff1681526020016112f161ffff1681526020016104f961ffff1681526020016107fe61ffff16815260200161044f61ffff16815260200161046861ffff16815260200161111061ffff16815260200161082161ffff168152602001610b0e61ffff16815260200161021c61ffff168152602001610e9b61ffff16815260200161121261ffff168152602001610de761ffff1681526020016111e261ffff168152602001610a1061ffff168152602001610eb461ffff1681526020016103af61ffff16815260200161010b61ffff1681526020016106fb61ffff168152602001610bd661ffff16815260200161036761ffff16815260200161082e61ffff1681526020016109b561ffff168152602001610f0761ffff168152602001610cad61ffff16815260200161030361ffff168152602001610d1361ffff1681526020016109d061ffff168152602001610ba261ffff168152602001610eb861ffff16815260200160d961ffff168152602001610f2f61ffff168152602001610f0561ffff168152602001610c7661ffff16815260200161127261ffff1681526020016102ff61ffff1681526020016103dc61ffff16815260200161100261ffff16815260200161053161ffff168152602001610d2961ffff16815260200161079561ffff16815260200161040761ffff16815260200161093461ffff1681526020016109ec61ffff168152602001610c8a61ffff1681526020016105a661ffff1681526020016104eb61ffff168152602001610da461ffff16815260200161017461ffff168152602001610e7461ffff168152602001610b2661ffff16815260200161018c61ffff168152602001610ceb61ffff16815260200161011a61ffff16815260200161015361ffff16815260200161081861ffff16815260200161025461ffff168152602001610de361ffff16815260200161105061ffff16815260200161046161ffff16815260200161096961ffff168152602001610eba61ffff16815260200161135761ffff16815260200161109461ffff168152602001610b4e61ffff1681526020016102ac61ffff1681526020016102ad61ffff168152602001610da861ffff16815260200161102c61ffff168152602001610f8e61ffff16815260200161044061ffff1681526020016111c461ffff1681526020016110dc61ffff16815260200161089061ffff16815260200161010861ffff16815260200161027461ffff16815260200161082861ffff168152602001610e5c61ffff16815260200161052961ffff168152602001610aae61ffff16815260200161043161ffff168152602001610dd061ffff168152602001610a5e61ffff16815260200161037e61ffff16815260200161018061ffff1681526020016106c961ffff16815260200161123161ffff1681526020016105cb61ffff168152602001604f61ffff168152602001610da061ffff168152602001610eff61ffff16815260200161072461ffff16815260200161049a61ffff16815260200161116f61ffff1681526020016104d661ffff168152602001610c3561ffff168152602001610ffc61ffff1681526020016110a061ffff16815260200161053061ffff1681526020016109c461ffff168152602001610b5161ffff16815260200161126261ffff16815260200161038861ffff168152602001610b4f61ffff168152602001610ead61ffff168152602001610b2d61ffff1681526020016102dc61ffff168152602001610a2761ffff16815260200161039b61ffff16815260200161044761ffff16815260200161043c61ffff1681526020016103cc61ffff16815260200161028261ffff16815260200161072961ffff1681526020016104b061ffff16815260200161114061ffff16815260200161025761ffff16815260200161089261ffff16815260200161069561ffff16815260200161041661ffff16815260200161015261ffff16815260200160ba61ffff16815260200161072e61ffff16815260200161042e61ffff16815260200161036161ffff16815260200161048b61ffff168152602001610bed61ffff168152602001610e4761ffff1681526020016105b461ffff1681526020016112e761ffff1681526020016101e661ffff16815260200161104861ffff168152602001610ae961ffff16815260200161032061ffff16815260200161081a61ffff168152602001610a0061ffff1681526020016105ed61ffff168152602001610a6961ffff1681526020016101f361ffff16815260200161045861ffff16815260200161104461ffff16815260200161032661ffff168152602001610fa661ffff16815260200161079361ffff168152602001610a0161ffff1681526020016101db61ffff16815260200161126461ffff16815260200161027861ffff16815260200161051961ffff168152602001610d6861ffff16815260200161049061ffff168152602001610f1c61ffff1681526020016104e561ffff168152602001610cf661ffff1681526020016102cc61ffff168152602001606461ffff16815260200161023b61ffff16815260200161077261ffff168152602001610ba961ffff16815260200161093961ffff16815260200161138461ffff16815260200161115561ffff16815260200161077361ffff168152602001610d1261ffff16815260200160f461ffff168152602001609061ffff16815260200161069961ffff1681526020016110aa61ffff16815260200161050761ffff16815260200161093361ffff1681526020016108c561ffff16815260200161018861ffff16815260200161114f61ffff16815260200161083e61ffff168152602001610b4461ffff168152602001610a0c61ffff16815260200161073561ffff168152602001610e3c61ffff16815260200161035f61ffff168152602001610c8861ffff168152602001610d5b61ffff16815260200161037d61ffff1681526020016111a061ffff1681526020016109eb61ffff1681526020016105c461ffff168152602001610cf861ffff168152602001610c5161ffff16815260200161122061ffff168152602001610fa961ffff168152602001610f8b61ffff1681526020016109da61ffff168152602001610c9761ffff16815260200161025261ffff16815260200161075261ffff16815260200161086b61ffff1681526020016101de61ffff16815260200161042861ffff16815260200161048561ffff16815260200161098f61ffff168152602001610b4561ffff16815260200161120d61ffff16815260200161072f61ffff1681526020016107d761ffff168152602001610dfd61ffff16815260200161040a61ffff168152602001610bb661ffff16815260200161073d61ffff16815260200161077761ffff168152602001610d5a61ffff168152602001610b8661ffff16815260200161015a61ffff1681526020016106bb61ffff16815260200160e061ffff1681526020016109f261ffff16815260200161075961ffff168152602001610bcb61ffff16815260200161029061ffff1681526020016104c561ffff1681526020016112a561ffff168152602001610ac861ffff168152602001610f8561ffff16815260200161112e61ffff16815260200161026c61ffff16815260200161039161ffff1681526020016110eb61ffff1681526020016105d861ffff168152602001610d3861ffff1681526020016110e561ffff168152602001610db761ffff168152602001608761ffff168152602001610ad061ffff16815260200161061561ffff1681526020016102a161ffff168152602001610d4361ffff1681526020016112ad61ffff16815260200161030c61ffff1681526020016104ab61ffff168152602001610ac761ffff16815260200161012461ffff168152602001610d2861ffff16815260200161097361ffff16815260200161110f61ffff16815260200161134a61ffff16815260200161094861ffff1681526020016102cb61ffff168152602001610d4461ffff16815260200161052e61ffff16815260200161056761ffff16815260200160b861ffff16815260200161024b61ffff168152602001610e6261ffff168152602001610ff761ffff168152602001610f5b61ffff16815260200161076361ffff16815260200161010761ffff1681526020016104e461ffff1681526020016105c761ffff168152602001610b9061ffff168152602001610ec161ffff16815260200161015b61ffff16815260200161050e61ffff16815260200161072261ffff168152602001610dab61ffff1681526020016102f561ffff1681526020016108f961ffff168152602001610cc961ffff16815260200161046061ffff16815260200161059561ffff1681526020016107e861ffff16815260200161080d61ffff168152602001610e7e61ffff168152602001610f2d61ffff16815260200161045061ffff1681526020016106d761ffff168152602001610d4161ffff1681526020016112ea61ffff16815260200161118f61ffff1681526020016110e761ffff16815260200161079961ffff16815260200161010d61ffff1681526020016103b761ffff16815260200161126a61ffff16815260200161122d61ffff168152602001610e1f61ffff16815260200161093061ffff168152602001610f7c61ffff16815260200161038c61ffff16815260200161087561ffff1681526020016112c761ffff1681526020016110ab61ffff16815260200161059e61ffff1681526020016105df61ffff16815260200161119661ffff1681526020016106c161ffff168152602001610b7e61ffff1681526020016102e161ffff168152602001610f4b61ffff1681526020016111fe61ffff16815260200161060161ffff168152602001610d1061ffff16815260200160db61ffff168152602001610e7561ffff16815260200160bc61ffff16815260200161128161ffff16815260200161060a61ffff168152602001610e1a61ffff1681526020016109fa61ffff1681526020016101ec61ffff168152602001610e3f61ffff168152602001610db261ffff168152602001610fba61ffff16815260200161133961ffff168152602001610c0e61ffff16815260200161014f61ffff168152602001610e8061ffff1681526020016111b661ffff1681526020016108e461ffff16815260200161036d61ffff16815260200161095461ffff16815260200161134761ffff16815260200161029361ffff1681526020016102d761ffff168152602001610e6f61ffff16815260200161117761ffff16815260200161021261ffff168152602001610c7761ffff168152602001610ffe61ffff168152602001610b1661ffff168152602001610d3461ffff16815260200161021b61ffff16815260200161073061ffff168152602001610bc861ffff16815260200161053f61ffff16815260200161105261ffff1681526020016101a661ffff16815260200161045261ffff168152602001610dbc61ffff16815260200161012261ffff168152602001610b2061ffff168152602001610bb061ffff168152602001610b3561ffff168152602001610b3061ffff168152602001610e7761ffff168152602001610f5e61ffff16815260200161117d61ffff16815260200161124561ffff168152602001610d0d61ffff16815260200161133461ffff16815260200161023561ffff168152602001608261ffff16815260200161123561ffff168152602001610fea61ffff1681526020016109fe61ffff168152602001610adb61ffff1681526020016107ed61ffff1681526020016111df61ffff16815260200161035a61ffff168152602001610d5561ffff16815260200161061861ffff1681526020016110d861ffff16815260200161020061ffff16815260200161107f61ffff168152602001610b8061ffff168152602001610a3e61ffff16815260200161118a61ffff1681526020016109df61ffff168152602001610c5c61ffff168152602001610c3861ffff16815260200161049f61ffff16815260200161024e61ffff1681526020016110cf61ffff1681526020016103f261ffff16815260200161014c61ffff168152602001610cf261ffff16815260200161116e61ffff1681526020016102b961ffff168152602001610a5f61ffff16815260200161088a61ffff168152602001610f2e61ffff16815260200161073861ffff168152602001610fc861ffff168152602001610c5961ffff168152602001610f3961ffff1681526020016109dd61ffff168152602001610a5b61ffff1681526020016107fc61ffff1681526020016108d861ffff168152602001610ec361ffff16815260200161066b61ffff16815260200161130961ffff168152602001610e5461ffff1681526020016108b061ffff1681526020016112f361ffff16815260200161060461ffff16815260200161031261ffff16815260200161133e61ffff16815260200161075361ffff16815260200161053e61ffff1681526020016101b161ffff16815260200161132d61ffff1681526020016112ca61ffff16815260200161095761ffff16815260200161117861ffff16815260200161101d61ffff16815260200161065061ffff168152602001610d8861ffff1681526020016108d761ffff1681526020016105e061ffff1681526020016106f061ffff168152602001610d9061ffff168152602001610f2961ffff1681526020016102ef61ffff1681526020016106b561ffff1681526020016105e961ffff16815260200161017761ffff1681526020016108be61ffff16815260200161108161ffff16815260200161024161ffff168152602001610bba61ffff16815260200161077f61ffff168152602001610d2f61ffff16815260200161098d61ffff16815260200161013c61ffff168152602001610d2561ffff16815260200161029d61ffff168152602001610e9c61ffff16815260200161063e61ffff168152602001610ad861ffff16815260200161012961ffff1681526020016109fd61ffff16815260200161082261ffff1681526020016104b861ffff16815260200161033461ffff16815260200161031461ffff1681526020016102be61ffff16815260200161046461ffff16815260200161013e61ffff168152602001610c4f61ffff168152602001610e1761ffff16815260200161029261ffff1681526020016101bb61ffff16815260200161072c61ffff168152602001610fab61ffff168152602001610b8b61ffff168152602001610eb361ffff16815260200161110661ffff16815260200161131c61ffff16815260200161055e61ffff1681526020016110f461ffff16815260200161107761ffff16815260200161087461ffff16815260200161010a61ffff16815260200161095561ffff1681526020016107f261ffff1681526020016111cb61ffff1681526020016105ee61ffff1681526020016105be61ffff1681526020016105f461ffff1681526020016108cd61ffff1681526020016104b561ffff168152602001609161ffff16815260200161056161ffff1681526020016101a161ffff16815260200161119861ffff168152602001610ebe61ffff16815260200161091c61ffff168152602001610b3d61ffff168152602001610efe61ffff16815260200161038761ffff1681526020016103c661ffff16815260200161020e61ffff16815260200161124c61ffff16815260200161137c61ffff168152602001610fca61ffff16815260200161087861ffff168152602001610ccf61ffff1681526020016104e761ffff16815260200160e661ffff168152602001610ff161ffff16815260200161057661ffff16815260200161064961ffff16815260200161019c61ffff1681526020016104e161ffff16815260200161066361ffff168152602001610e1c61ffff16815260200161070561ffff1681526020016101e161ffff16815260200161100c61ffff168152602001610ee761ffff168152602001610c7361ffff1681526020016108b961ffff16815260200161018f61ffff16815260200161063161ffff16815260200161045761ffff1681526020016112dc61ffff16815260200161027f61ffff1681526020016105f761ffff168152602001610f2061ffff16815260200161019461ffff168152602001610e0661ffff1681526020016111c161ffff1681526020016112f561ffff168152602001610dc061ffff1681526020016106cd61ffff16815260200161039761ffff168152602001610a9c61ffff16815260200160dd61ffff16815260200161038561ffff16815260200161130261ffff168152602001610b7861ffff168152602001610dbe61ffff168152602001610baa61ffff16815260200161053a61ffff16815260200161128661ffff168152602001610e8e61ffff1681526020016107e261ffff16815260200161055861ffff16815260200161027d61ffff16815260200161085761ffff16815260200161106061ffff168152602001610c7561ffff16815260200161013861ffff16815260200160e161ffff168152602001610aa661ffff1681526020016111e661ffff1681526020016101a461ffff1681526020016104ba61ffff16815260200161112561ffff1681526020016105ab61ffff16815260200161100d61ffff1681526020016112d761ffff16815260200161041161ffff16815260200161018961ffff16815260200161059861ffff16815260200161106861ffff168152602001610ef261ffff16815260200160ab61ffff168152602001610ce061ffff168152602001610c4e61ffff1681526020016105cf61ffff168152602001610ce861ffff16815260200161033f61ffff168152602001610d6261ffff1681526020016106df61ffff168152602001610dd361ffff16815260200161039461ffff168152602001610a1761ffff1681526020016104b161ffff168152602001609c61ffff168152602001610c8661ffff16815260200161037561ffff16815260200161033661ffff16815260200161115861ffff168152602001610abb61ffff168152602001610b3c61ffff16815260200161109a61ffff1681526020016104f561ffff168152602001610eac61ffff16815260200161121661ffff1681526020016111da61ffff16815260200161095e61ffff168152602001610a8061ffff168152602001610a1f61ffff1681526020016112c161ffff168152602001610b9161ffff168152602001610f3a61ffff1681526020016105f661ffff168152602001610bc661ffff168152602001610d5c61ffff1681526020016109bc61ffff16815260200161112061ffff16815260200161130661ffff1681526020016106aa61ffff168152602001610f6561ffff16815260200161059b61ffff16815260200161135661ffff16815260200161084261ffff1681526020016106fc61ffff16815260200161057461ffff16815260200161117161ffff168152602001610ba861ffff1681526020016111ec61ffff16815260200161129361ffff1681526020016107e161ffff16815260200161090b61ffff1681526020016112c661ffff16815260200161043e61ffff16815260200161022861ffff1681526020016101a761ffff16815260200161106d61ffff16815260200161053961ffff168152602001610dc961ffff168152602001610c1161ffff168152602001610d9761ffff168152602001610eb961ffff16815260200161122261ffff16815260200161077b61ffff1681526020016106f761ffff168152602001610fd761ffff16815260200161048a61ffff16815260200161088661ffff16815260200161119061ffff16815260200161045b61ffff16815260200161044d61ffff1681526020016106b461ffff1681526020016105b061ffff168152602001610c5261ffff16815260200161049461ffff16815260200161106e61ffff16815260200161036061ffff16815260200161031b61ffff16815260200161085b61ffff16815260200161077661ffff16815260200161049b61ffff1681526020016106d161ffff168152602001610b1c61ffff168152602001610f6261ffff16815260200161119e61ffff16815260200161043061ffff16815260200161102761ffff168152602001610fac61ffff16815260200161061061ffff16815260200161068561ffff16815260200161017c61ffff1681526020016107bd61ffff168152602001610bd561ffff16815260200161129c61ffff1681526020016109bb61ffff168152602001610dc761ffff168152602001610d1861ffff1681526020016105cd61ffff16815260200161015461ffff16815260200161081d61ffff16815260200161015061ffff168152602001610e6761ffff16815260200161105961ffff16815260200161128961ffff1681526020016107e961ffff16815260200161070161ffff168152602001610c8d61ffff16815260200161091261ffff168152602001610e6c61ffff168152602001610ac261ffff168152602001610b7c61ffff16815260200161085161ffff16815260200161106c61ffff16815260200161086661ffff16815260200161066c61ffff1681526020016104f661ffff168152602001610af861ffff1681526020016106cf61ffff16815260200160cf61ffff16815260200161137861ffff16815260200161021a61ffff1681526020016103f561ffff168152602001610e4f61ffff16815260200161067361ffff168152602001610af761ffff168152602001610c4861ffff16815260200161105161ffff168152602001610f8f61ffff1681526020016106c261ffff1681526020016112fe61ffff16815260200161081461ffff168152602001610f4261ffff16815260200161058561ffff16815260200161058661ffff168152602001610b3761ffff168152602001610fb761ffff168152602001610a6a61ffff168152602001610d3f61ffff168152602001610bf861ffff16815260200161050d61ffff1681526020016106dd61ffff1681526020016101c861ffff16815260200161055761ffff1681526020016103e861ffff1681526020016106fd61ffff1681526020016110ce61ffff16815260200161103761ffff16815260200161037f61ffff1681526020016111e361ffff16815260200161094561ffff16815260200161012e61ffff16815260200161062061ffff16815260200161109261ffff16815260200161115b61ffff1681526020016105b661ffff168152602001610ed661ffff168152602001610cce61ffff16815260200161070f61ffff168152602001610a6361ffff16815260200161021761ffff168152602001610cea61ffff16815260200161122961ffff168152602001610e9461ffff168152602001610d3261ffff16815260200161132461ffff16815260200161138861ffff1681526020016103b261ffff1681526020016110e361ffff168152602001610d2d61ffff1681526020016102c761ffff168152602001610df661ffff16815260200160b161ffff168152602001610e4661ffff16815260200161104a61ffff16815260200161116961ffff16815260200161020661ffff16815260200161036b61ffff1681526020016103d361ffff16815260200161056361ffff1681526020016110bd61ffff168152602001608b61ffff168152602001610af461ffff16815260200161029b61ffff168152602001610bd161ffff16815260200161087961ffff1681526020016104ca61ffff16815260200161120061ffff16815260200161134161ffff1681526020016112d561ffff16815260200161088961ffff16815260200161048261ffff16815260200161065761ffff16815260200161084061ffff168152602001610d5161ffff16815260200161086961ffff168152602001610eb161ffff1681526020016103be61ffff168152602001610d0061ffff168152602001610b5b61ffff16815260200161128761ffff168152602001610ce161ffff16815260200161082661ffff16815260200161010361ffff168152602001610a5461ffff1681526020016102de61ffff16815260200161134b61ffff1681526020016105da61ffff16815260200161029461ffff1681526020016105c361ffff168152602001610fbf61ffff16815260200161071961ffff168152602001610e5761ffff168152602001605e61ffff16815260200161122161ffff168152602001610d0761ffff1681526020016107ee61ffff1681526020016108f761ffff16815260200161081661ffff168152602001610cdc61ffff16815260200161056461ffff16815260200161057361ffff1681526020016104d861ffff16815260200161058d61ffff168152602001610f1e61ffff168152602001610a2c61ffff16815260200161069d61ffff16815260200161090561ffff1681526020016108c661ffff16815260200161071061ffff16815260200161022561ffff16815260200161012161ffff1681526020016110e161ffff168152602001610c0c61ffff1681526020016109d461ffff168152602001610dfc61ffff16815260200161125561ffff168152602001610cec61ffff1681526020016103a161ffff16815260200161051061ffff16815260200161037061ffff1681526020016103e261ffff168152602001610b6a61ffff16815260200161127761ffff168152602001610d8b61ffff1681526020016105c161ffff16815260200161078961ffff16815260200161129b61ffff1681526020016109ef61ffff1681526020016106b161ffff168152602001610ae061ffff168152602001610fef61ffff16815260200161025061ffff16815260200161120761ffff168152602001610c2f61ffff16815260200161099961ffff16815260200160bb61ffff168152602001604861ffff16815260200161087b61ffff168152602001610a3d61ffff16815260200161071a61ffff168152602001604461ffff1681526020016109ff61ffff1681526020016103ed61ffff168152602001610ec961ffff16815260200161024c61ffff16815260200161023961ffff16815260200161058161ffff16815260200161023661ffff1681526020016103b661ffff1681526020016101c061ffff16815260200161054061ffff16815260200160cc61ffff168152602001610ad561ffff16815260200161116261ffff168152602001610d1661ffff16815260200161032961ffff16815260200161112c61ffff1681526020016104fb61ffff168152602001610e4461ffff168152602001610ca261ffff16815260200161034061ffff1681526020016102c261ffff168152602001610cbd61ffff16815260200161108361ffff1681526020016109af61ffff1681526020016106e961ffff16815260200161090f61ffff16815260200161062761ffff16815260200161090361ffff16815260200161018661ffff1681526020016103aa61ffff168152602001610db961ffff168152602001610b2a61ffff1681526020016102e061ffff1681526020016105a061ffff1681526020016110d961ffff168152602001610c1c61ffff168152602001610b7a61ffff16815260200161094461ffff1681526020016108ff61ffff16815260200161094a61ffff1681526020016106e561ffff16815260200161029a61ffff16815260200161033b61ffff16815260200161114461ffff168152602001610efd61ffff1681526020016112c961ffff16815260200161029961ffff1681526020016106c761ffff16815260200161072361ffff16815260200161024461ffff168152602001610c0b61ffff1681526020016102a561ffff16815260200161100a61ffff168152602001610d5261ffff1681526020016103f961ffff1681526020016102e461ffff16815260200161044e61ffff1681526020016108c861ffff16815260200161111e61ffff1681526020016106db61ffff16815260200161109e61ffff168152602001610fdf61ffff16815260200161117261ffff1681526020016112da61ffff16815260200161077061ffff16815260200161064661ffff168152602001610e9361ffff16815260200161094e61ffff1681526020016110b361ffff16815260200161102461ffff168152602001610cdb61ffff1681526020016106d261ffff168152602001610af261ffff1681526020016110c461ffff168152602001610c0761ffff1681526020016106d461ffff168152602001610f4d61ffff16815260200161060d61ffff16815260200161012761ffff16815260200161088f61ffff168152602001610e2861ffff1681526020016102fb61ffff168152602001610d8d61ffff16815260200161072a61ffff16815260200161113261ffff168152602001610baf61ffff168152602001610def61ffff168152602001610acf61ffff16815260200161095961ffff1681526020016107dd61ffff1681526020016104ce61ffff168152602001610d9361ffff16815260200161034661ffff16815260200161049261ffff16815260200161082b61ffff16815260200161131261ffff16815260200161083661ffff168152602001610fde61ffff168152602001610efa61ffff168152602001610aa761ffff1681526020016106c561ffff1681526020016110a361ffff168152602001610dda61ffff16815260200160bf61ffff16815260200161011961ffff1681526020016103e761ffff16815260200161030e61ffff1681526020016104a961ffff168152602001610d1e61ffff1681526020016102e661ffff168152602001610a5561ffff168152602001610ba561ffff16815260200161026061ffff1681526020016106a861ffff168152602001610bf961ffff1681526020016103ae61ffff1681526020016112f861ffff168152602001610b2861ffff168152602001610bf361ffff16815260200160d761ffff16815260200161091461ffff16815260200161088c61ffff168152602001610e6161ffff1681526020016107a661ffff168152602001610f3461ffff16815260200161084161ffff1681526020016107b661ffff16815260200161017d61ffff16815260200161127861ffff16815260200161116661ffff168152602001610ed461ffff1681526020016102b461ffff16815260200160b361ffff16815260200161100161ffff16815260200161067d61ffff16815260200161107161ffff168152602001610ed061ffff16815260200161129561ffff16815260200161014e61ffff1681526020016110e861ffff168152602001610e9761ffff16815260200161129961ffff1681526020016107aa61ffff16815260200161026161ffff1681526020016107bf61ffff168152602001610f3e61ffff16815260200161067861ffff1681526020016104cf61ffff16815260200161115a61ffff16815260200161037461ffff168152602001610ebd61ffff1681526020016112eb61ffff16815260200161095261ffff168152602001610c1d61ffff168152602001610e7d61ffff16815260200161074761ffff16815260200161022661ffff16815260200161066161ffff16815260200161097f61ffff1681526020016106f261ffff168152602001610a1e61ffff16815260200161138661ffff168152602001607f61ffff168152602001610f2861ffff16815260200161095861ffff168152602001610a4e61ffff1681526020016112f261ffff16815260200161095661ffff168152602001610f3861ffff168152602001610b9561ffff16815260200161111d61ffff168152602001610a8c61ffff16815260200161069761ffff16815260200161121761ffff16815260200161054e61ffff16815260200161017361ffff168152602001610a9e61ffff168152602001610dbf61ffff168152602001610a2161ffff168152602001610a1a61ffff168152602001610e0e61ffff168152602001610f7b61ffff16815260200161092361ffff168152602001610fb861ffff16815260200161057a61ffff16815260200161058761ffff168152602001610a1161ffff168152602001610e8161ffff1681526020016102c561ffff16815260200161096261ffff168152602001610be861ffff1681526020016110ba61ffff16815260200161044861ffff16815260200161037961ffff16815260200161123661ffff168152602001610e9f61ffff16815260200161020261ffff1681526020016103f661ffff16815260200161092461ffff168152602001610fd061ffff16815260200161128d61ffff16815260200161014361ffff168152602001610d9661ffff16815260200161111461ffff168152602001610ff561ffff16815260200161102b61ffff168152602001610deb61ffff168152602001610bea61ffff16815260200161019561ffff16815260200161059261ffff1681526020016108d661ffff168152602001610c5061ffff1681526020016108f061ffff16815260200161025861ffff168152602001610d3161ffff1681526020016109d161ffff16815260200161041061ffff168152602001610e2d61ffff1681526020016112bd61ffff16815260200161088d61ffff16815260200161034261ffff16815260200161115761ffff16815260200161087161ffff168152602001610e9e61ffff16815260200161133c61ffff1681526020016104ac61ffff168152602001610ade61ffff16815260200161017261ffff1681526020016105bd61ffff168152602001610e1261ffff16815260200161121e61ffff16815260200161092c61ffff168152602001610be561ffff168152602001610b9861ffff16815260200161043761ffff1681526020016105ff61ffff16815260200161099c61ffff16815260200161023061ffff168152602001610e2c61ffff1681526020016101f461ffff168152602001610a0b61ffff168152602001610fd661ffff168152602001610bf161ffff1681526020016104e061ffff16815260200161051661ffff168152602001610a3761ffff16815260200161104161ffff1681526020016110e661ffff168152602001610e5861ffff1681526020016102a661ffff168152602001610eda61ffff16815260200161047161ffff16815260200161082461ffff168152602001610fe961ffff1681526020016110d761ffff16815260200161085561ffff1681526020016102bd61ffff16815260200161080861ffff16815260200161032e61ffff168152602001610a4b61ffff16815260200161020361ffff168152602001610dcb61ffff16815260200161127461ffff168152602001610d8661ffff16815260200161045961ffff16815260200161014461ffff168152602001610e2f61ffff168152602001610d3061ffff16815260200161084f61ffff16815260200161103861ffff16815260200161051e61ffff16815260200161061e61ffff16815260200161033561ffff16815260200161068261ffff168152602001610df261ffff1681526020016110ef61ffff168152602001610c7e61ffff16815260200161091061ffff168152602001610f8d61ffff16815260200161116561ffff168152602001610d7561ffff168152602001610a6261ffff1681526020016107c861ffff16815260200161045d61ffff16815260200161107961ffff1681526020016109ac61ffff168152602001603f61ffff16815260200161070861ffff168152602001610bdf61ffff16815260200161080361ffff16815260200161113961ffff168152602001610cb261ffff1681526020016110b261ffff168152602001610fb661ffff168152602001610ee261ffff168152602001610c3e61ffff16815260200161065261ffff16815260200160b661ffff16815260200161063461ffff168152602001610ee661ffff168152602001610b4361ffff168152602001610fbe61ffff1681526020016111ee61ffff168152602001610dee61ffff1681526020016103a261ffff16815260200161026961ffff1681526020016107f061ffff168152602001604661ffff16815260200161036a61ffff168152602001610d7161ffff1681526020016103ac61ffff16815260200161048661ffff168152602001610fa161ffff1681526020016112cc61ffff168152602001610fc661ffff16815260200161058a61ffff1681526020016112bf61ffff168152602001610de261ffff168152602001610db161ffff16815260200161069061ffff168152602001610ea661ffff168152602001610df961ffff16815260200161032561ffff16815260200161074161ffff168152602001610acc61ffff16815260200161034161ffff1681526020016101ce61ffff16815260200161043f61ffff16815260200161032161ffff168152602001610fa061ffff168152602001610c4761ffff1681526020016109f161ffff168152602001606861ffff16815260200161082361ffff16815260200161012561ffff16815260200161082561ffff1681526020016107d661ffff16815260200161106a61ffff1681526020016108bc61ffff16815260200161113461ffff16815260200160f661ffff168152602001610c6861ffff16815260200161031561ffff16815260200161061d61ffff168152602001610caf61ffff16815260200161057b61ffff16815260200161079061ffff16815260200161097161ffff1681526020016105ec61ffff1681526020016101e261ffff16815260200160f961ffff1681526020016112e061ffff168152602001610ddd61ffff1681526020016108d961ffff16815260200161014861ffff168152602001610af361ffff16815260200161101661ffff1681526020016107fb61ffff168152602001610eb061ffff16815260200161121361ffff16815260200161123261ffff16815260200161057e61ffff16815260200161107861ffff16815260200161130861ffff168152602001610dc561ffff168152602001610e5d61ffff16815260200161104561ffff16815260200161053861ffff16815260200161023a61ffff16815260200161133f61ffff168152602001610cd161ffff16815260200161120861ffff1681526020016107cb61ffff1681526020016106c061ffff1681526020016103eb61ffff168152602001610d6761ffff16815260200161129161ffff1681526020016112ed61ffff168152602001610b6b61ffff16815260200161084961ffff1681526020016101f761ffff16815260200160d361ffff1681526020016109c861ffff16815260200161074661ffff16815260200161058961ffff1681526020016108b661ffff168152602001610f4661ffff16815260200161124761ffff16815260200161069461ffff16815260200161036361ffff168152602001607c61ffff1681526020016112b461ffff16815260200161038061ffff168152602001610d1461ffff16815260200161024361ffff168152602001610bab61ffff16815260200161069661ffff1681526020016104be61ffff1681526020016101be61ffff168152602001610d2061ffff1681526020016112e661ffff168152602001610ef561ffff1681526020016103f861ffff16815260200161130e61ffff1681526020016103d161ffff1681526020016108f161ffff1681526020016101bf61ffff168152602001610c7261ffff168152602001610b4061ffff1681526020016103e661ffff16815260200161057d61ffff1681526020016111f961ffff16815260200161099b61ffff168152602001610fc761ffff1681526020016103bc61ffff16815260200161064561ffff1681526020016102f261ffff1681526020016103ff61ffff16815260200161113561ffff1681526020016110a661ffff16815260200161035561ffff16815260200161096061ffff168152602001610d7961ffff168152602001610e8c61ffff168152602001610e9a61ffff16815260200161020561ffff1681526020016103c561ffff16815260200161064461ffff1681526020016109e661ffff1681526020016105e761ffff1681526020016109ce61ffff168152602001610d5461ffff16815260200161078d61ffff16815260200161101561ffff1681526020016109f661ffff1681526020016101b261ffff168152602001610b5961ffff16815260200161061c61ffff168152602001610c4461ffff16815260200161057561ffff168152602001610fe161ffff16815260200161081f61ffff1681526020016111c961ffff1681526020016111e861ffff16815260200161060061ffff168152602001610b0661ffff168152602001610a9661ffff168152602001610b5661ffff1681526020016105ac61ffff168152602001606b61ffff168152602001610e6a61ffff16815260200161015161ffff168152602001610ae861ffff16815260200161122b61ffff16815260200161098361ffff16815260200161108c61ffff1681526020016111f661ffff168152602001610ea461ffff16815260200161120561ffff16815260200161057261ffff1681526020016107dc61ffff168152602001610a4961ffff16815260200161018461ffff16815260200161087a61ffff16815260200161136c61ffff16815260200161083f61ffff16815260200161132761ffff168152602001610ba461ffff1681526020016110f961ffff1681526020016112a961ffff168152602001610f7061ffff16815260200161109861ffff168152602001608c61ffff168152602001610f2361ffff168152602001610b0261ffff168152602001610ffa61ffff16815260200161131b61ffff1681526020016102da61ffff16815260200161112f61ffff168152602001610c0d61ffff1681526020016105f561ffff1681526020016111b361ffff168152602001610fc961ffff1681526020016103f361ffff168152602001610ea061ffff1681526020016112aa61ffff16815260200161092d61ffff16815260200161053761ffff1681526020016107b161ffff1681526020016103da61ffff1681526020016107a361ffff168152602001610b6f61ffff1681526020016103d661ffff16815260200161087361ffff16815260200161024d61ffff16815260200161099f61ffff1681526020016101b761ffff16815260200161109161ffff168152602001610dad61ffff16815260200161034d61ffff16815260200161069261ffff1681526020016106e261ffff168152602001610d0261ffff16815260200161133061ffff16815260200161088361ffff168152602001610d1d61ffff16815260200161065161ffff1681526020016106b261ffff16815260200161119161ffff168152602001610aec61ffff168152602001610d6961ffff168152602001610f9161ffff16815260200161026e61ffff168152602001610c3161ffff168152602001610f4361ffff16815260200161062561ffff168152602001610b6061ffff16815260200161072761ffff168152602001610d4761ffff16815260200161113c61ffff168152602001610f7361ffff16815260200161066961ffff168152602001610f8c61ffff1681526020016107c561ffff168152602001610f3561ffff1681526020016108ae61ffff1681526020016108e861ffff16815260200161074f61ffff168152602001609a61ffff1681526020016109d361ffff16815260200161126761ffff168152602001610fad61ffff16815260200161046d61ffff168152602001610a5a61ffff1681526020016105d061ffff168152602001610f8661ffff16815260200161041561ffff16815260200161068361ffff16815260200161112161ffff1681526020016106a061ffff16815260200161023c61ffff168152602001610a8d61ffff1681526020016101f961ffff1681526020016101f161ffff168152602001610f0f61ffff168152602001610f8861ffff168152602001610a9861ffff16815260200161035761ffff16815260200161064f61ffff168152602001610e5061ffff168152602001610aa261ffff16815260200161122461ffff16815260200161021161ffff1681526020016104aa61ffff1681526020016106b961ffff168152602001610af961ffff168152602001607b61ffff1681526020016112d261ffff1681526020016102d261ffff168152602001610cc361ffff168152602001610c9f61ffff168152602001610ea361ffff16815260200161028761ffff1681526020016110e261ffff16815260200161089b61ffff168152602001610d7261ffff1681526020016104e961ffff168152602001610a7f61ffff1681526020016110f761ffff16815260200161062a61ffff168152602001610a7361ffff1681526020016108ce61ffff1681526020016112e861ffff16815260200161062961ffff168152602001610a9761ffff168152602001610e8f61ffff16815260200161038961ffff168152602001610d7761ffff16815260200161122361ffff168152602001610b6461ffff16815260200161083461ffff168152602001610a3161ffff1681526020016102b161ffff16815260200161136a61ffff1681526020016103d761ffff168152602001610c9061ffff168152602001610cf561ffff168152602001610b3661ffff168152602001610dd461ffff1681526020016101ef61ffff168152602001610afc61ffff1681526020016105f961ffff1681526020016101a961ffff168152602001608461ffff168152602001610a4361ffff16815260200161029f61ffff16815260200161076861ffff16815260200161026861ffff16815260200161082c61ffff168152602001609f61ffff1681526020016109f461ffff168152602001610df761ffff1681526020016103ef61ffff168152602001610c3761ffff168152602001610ea561ffff1681526020016101e961ffff1681526020016109c161ffff1681526020016112c361ffff16815260200161024861ffff168152602001610d9561ffff1681526020016105a761ffff168152602001610b5c61ffff1681526020016103dd61ffff1681526020016111b161ffff168152602001610ad961ffff1681526020016107cd61ffff1681526020016111ce61ffff16815260200160aa61ffff168152602001610be461ffff168152602001610d8461ffff16815260200161045161ffff16815260200161115461ffff168152602001610a2361ffff16815260200161069861ffff1681526020016110f161ffff1681526020016103f161ffff1681526020016110ad61ffff1681526020016109ea61ffff16815260200161081261ffff168152602001610e0461ffff1681526020016108fa61ffff168152602001610a4261ffff168152602001610cd361ffff16815260200161070761ffff16815260200161071b61ffff16815260200161075061ffff1681526020016107ea61ffff168152602001610aa461ffff168152602001610e3461ffff1681526020016112cd61ffff1681526020016110d161ffff16815260200161108b61ffff1681526020016102fe61ffff16815260200161108661ffff168152602001610b5561ffff1681526020016109c761ffff16815260200161093f61ffff168152602001608e61ffff16815260200161085361ffff16815260200161111561ffff168152602001610c3461ffff1681526020016105e861ffff168152602001608161ffff1681526020016106d861ffff16815260200161027c61ffff16815260200161120e61ffff16815260200161126e61ffff1681526020016101ed61ffff16815260200161123361ffff16815260200161059061ffff16815260200161136761ffff16815260200161131761ffff16815260200161065c61ffff16815260200161133d61ffff168152602001610f3d61ffff1681526020016107f161ffff1681526020016101b961ffff168152602001610f5a61ffff16815260200161091561ffff1681526020016111bc61ffff1681526020016111a461ffff16815260200161114c61ffff168152602001610d4a61ffff168152602001610f5761ffff16815260200161064d61ffff1681526020016101b361ffff1681526020016108f461ffff168152602001610c4d61ffff16815260200160be61ffff168152602001610aa861ffff16815260200161038661ffff168152602001610d1b61ffff16815260200161082a61ffff16815260200161078f61ffff168152602001610e4161ffff16815260200161097061ffff16815260200161034361ffff16815260200161014261ffff168152602001610d6a61ffff16815260200161128361ffff1681526020016106d361ffff168152602001610c4061ffff16815260200161098861ffff168152602001606a61ffff16815260200160fa61ffff1681526020016107c261ffff1681526020016107fa61ffff16815260200161126361ffff168152602001610eea61ffff16815260200161096561ffff16815260200161126561ffff168152602001610c6161ffff16815260200161017561ffff168152602001610bc161ffff16815260200161098461ffff16815260200161036c61ffff168152602001609861ffff16815260200161049c61ffff16815260200161014661ffff168152602001610a3c61ffff1681526020016109a361ffff168152602001610e0361ffff1681526020016106bc61ffff16815260200161079a61ffff168152602001610cd861ffff168152602001610cd261ffff168152602001610fec61ffff168152602001610b3161ffff168152602001610e0161ffff16815260200161100461ffff16815260200161039f61ffff168152602001610b3b61ffff16815260200161135461ffff168152602001610f4761ffff1681526020016102a461ffff168152602001610e7f61ffff168152602001610dc361ffff16815260200161110061ffff16815260200161067661ffff16815260200161093761ffff168152602001610c9e61ffff1681526020016108a061ffff168152602001610ad461ffff168152602001610c8e61ffff1681526020016108c061ffff168152602001605061ffff16815260200161120a61ffff16815260200161115d61ffff168152602001610a0e61ffff168152602001610ff861ffff16815260200161106361ffff16815260200161050661ffff16815260200161047361ffff16815260200161019161ffff16815260200161023161ffff16815260200161111961ffff16815260200161137961ffff1681526020016110d361ffff16815260200161125e61ffff16815260200161048161ffff16815260200161135161ffff16815260200161058861ffff168152602001610ddc61ffff168152602001605861ffff168152602001610f3b61ffff168152602001604161ffff16815260200161024061ffff16815260200161052461ffff1681526020016107a861ffff16815260200161098e61ffff16815260200161124361ffff1681526020016102d661ffff16815260200161071361ffff168152602001610f9f61ffff168152602001610e9d61ffff16815260200161054a61ffff168152602001610d0161ffff1681526020016111c861ffff168152602001610d3961ffff16815260200161028f61ffff16815260200161112861ffff168152602001610fe761ffff16815260200161028a61ffff16815260200161132561ffff168152602001610a5261ffff1681526020016106fa61ffff168152602001610b0b61ffff168152602001610c1261ffff16815260200161128561ffff168152602001610f6861ffff168152602001610abf61ffff1681526020016110cd61ffff1681526020016110a761ffff16815260200161054161ffff16815260200161103461ffff16815260200161125061ffff16815260200161019261ffff16815260200161124d61ffff16815260200161031061ffff1681526020016110c661ffff16815260200161131861ffff16815260200161056661ffff16815260200161115661ffff16815260200161076261ffff168152602001610c5a61ffff168152602001610d3361ffff16815260200161130561ffff168152602001610bc261ffff16815260200161078a61ffff16815260200161054f61ffff168152602001610e5a61ffff168152602001610e4061ffff1681526020016105e561ffff16815260200160e761ffff1681526020016110ee61ffff168152602001610a9b61ffff1681526020016107ef61ffff16815260200161114161ffff168152602001610b4a61ffff168152602001610a6661ffff1681526020016103ee61ffff168152602001610d0361ffff168152602001610a7161ffff168152602001610bfa61ffff1681526020016110be61ffff16815260200161012061ffff1681526020016109c961ffff16815260200161043b61ffff168152602001610ace61ffff16815260200161106261ffff168152602001610e2361ffff1681526020016101ea61ffff16815260200161099061ffff168152602001606061ffff16815260200161073e61ffff16815260200161110b61ffff1681526020016111c761ffff16815260200161063b61ffff16815260200161075561ffff168152602001610c6b61ffff16815260200161045561ffff16815260200160b761ffff16815260200161016c61ffff1681526020016101dd61ffff16815260200161025161ffff1681526020016112a061ffff16815260200161062261ffff16815260200161104f61ffff168152602001610ab061ffff16815260200161057f61ffff16815260200161087261ffff16815260200161083d61ffff168152602001610a5c61ffff168152602001610a6461ffff16815260200161128b61ffff16815260200160d161ffff16815260200161084461ffff168152602001607761ffff1681526020016107b861ffff1681526020016104f761ffff16815260200161026b61ffff168152602001610d8a61ffff1681526020016104a761ffff16815260200161067761ffff16815260200161126b61ffff16815260200161098b61ffff168152602001610f9261ffff16815260200161087661ffff16815260200161063861ffff16815260200161054861ffff16815260200161132c61ffff168152602001610d7e61ffff1681526020016107ce61ffff16815260200161102161ffff168152602001610f9961ffff1681526020016101c561ffff16815260200161086e61ffff16815260200161058c61ffff168152602001610b8c61ffff16815260200161028661ffff16815260200161041d61ffff16815260200161070d61ffff168152602001610f3761ffff16815260200161134861ffff168152602001610bc561ffff16815260200161022461ffff168152602001610e5261ffff16815260200161042061ffff1681526020016108c161ffff1681526020016106b861ffff1681526020016103e161ffff16815260200161108561ffff16815260200160d461ffff16815260200161028b61ffff16815260200161080561ffff1681526020016105db61ffff16815260200161064161ffff168152602001610c9d61ffff168152602001610d8761ffff168152602001610ded61ffff168152602001610c9161ffff16815260200161095a61ffff168152602001610e5361ffff168152602001610d9a61ffff1681526020016103b061ffff16815260200161133661ffff16815260200161110161ffff1681526020016112d861ffff1681526020016103e961ffff168152602001610afb61ffff168152602001610c8961ffff1681526020016104de61ffff16815260200161081561ffff16815260200161078761ffff168152602001610a5361ffff1681526020016110c161ffff16815260200161136561ffff168152602001610b5061ffff16815260200161096161ffff168152602001610be261ffff168152602001610ff061ffff168152602001610fe561ffff16815260200161031361ffff16815260200161016d61ffff1681526020016104af61ffff16815260200161134c61ffff16815260200161043361ffff16815260200161011261ffff1681526020016102bf61ffff16815260200161110361ffff168152602001610c5461ffff16815260200161097561ffff168152602001610d9261ffff1681526020016109b261ffff1681526020016108ea61ffff16815260200161061761ffff1681526020016108eb61ffff168152602001610e2161ffff168152602001610e3761ffff16815260200161102661ffff168152602001610a7d61ffff16815260200161136261ffff16815260200161132f61ffff1681526020016112cb61ffff168152602001610f6061ffff168152602001610ae461ffff1681526020016110c861ffff1681526020016102cd61ffff168152602001610eef61ffff16815260200161033161ffff1681526020016107a161ffff1681526020016104ef61ffff1681526020016109bf61ffff168152602001610f5961ffff168152602001610f1861ffff168152602001610c6d61ffff16815260200160a861ffff16815260200161023861ffff168152602001610d8061ffff1681526020016108fb61ffff16815260200161064761ffff168152602001610fb161ffff168152602001610c1961ffff168152602001606e61ffff168152602001610fcb61ffff168152602001610c4361ffff16815260200161114d61ffff1681526020016105a961ffff16815260200161109b61ffff16815260200161126161ffff16815260200161013661ffff168152602001610fd361ffff16815260200161094d61ffff168152602001610ca761ffff1681526020016109e561ffff168152602001610ae161ffff16815260200160a261ffff16815260200161065b61ffff16815260200161066761ffff1681526020016101ab61ffff16815260200161011761ffff1681526020016112c561ffff1681526020016105a161ffff168152602001610d8e61ffff168152602001610ae761ffff1681526020016102dd61ffff16815260200161039661ffff16815260200161066e61ffff168152602001610c1b61ffff168152602001610a3661ffff16815260200161069361ffff16815260200161137f61ffff16815260200161037661ffff1681526020016105e261ffff168152602001610f9861ffff168152602001610c3661ffff16815260200161034461ffff168152602001610a8261ffff168152602001610bad61ffff1681526020016112f761ffff168152602001610c3261ffff16815260200161050861ffff168152602001610faa61ffff1681526020016103e561ffff1681526020016102e561ffff16815260200161117e61ffff16815260200161011c61ffff16815260200161013d61ffff16815260200161134461ffff168152602001610b9d61ffff168152602001610ad761ffff168152602001610c6261ffff16815260200161113a61ffff1681526020016103ec61ffff168152602001610bb961ffff16815260200161076d61ffff168152602001610bf261ffff1681526020016105f161ffff1681526020016107a561ffff168152602001610d3a61ffff168152602001610bb461ffff16815260200160d561ffff1681526020016109d961ffff1681526020016107d161ffff168152602001610d4661ffff168152602001610f1061ffff16815260200161076f61ffff16815260200161049961ffff1681526020016108b261ffff168152602001610f6161ffff16815260200161127361ffff1681526020016101ee61ffff16815260200161022b61ffff1681526020016104c661ffff1681526020016110ae61ffff1681526020016106b761ffff1681526020016112de61ffff168152602001610bc061ffff16815260200161116a61ffff168152602001610c1061ffff168152602001610dc261ffff16815260200161103661ffff1681526020016108b461ffff16815260200161110861ffff16815260200161089561ffff168152602001610c8f61ffff16815260200161084e61ffff168152602001610d1c61ffff16815260200161108961ffff16815260200161092a61ffff16815260200161077861ffff16815260200161019e61ffff168152602001610ab561ffff16815260200161113d61ffff16815260200161033c61ffff16815260200161125f61ffff16815260200161138061ffff16815260200160ee61ffff16815260200161125861ffff1681526020016110ff61ffff1681526020016109cb61ffff16815260200161120961ffff168152602001610de961ffff16815260200161086f61ffff168152602001610a1861ffff168152602001610f9b61ffff16815260200161088b61ffff168152602001610f7d61ffff16815260200161044a61ffff1681526020016112b561ffff16815260200161074261ffff16815260200161095d61ffff168152602001609261ffff168152602001610c2761ffff1681526020016102e761ffff16815260200161025961ffff16815260200161053461ffff16815260200161106661ffff16815260200161020d61ffff16815260200161131061ffff168152602001610a4d61ffff1681526020016108e661ffff1681526020016111b961ffff1681526020016109c361ffff16815260200161045c61ffff168152602001610daa61ffff16815260200161109961ffff16815260200161026d61ffff1681526020016104c861ffff16815260200161015561ffff1681526020016104c161ffff16815260200161056961ffff168152602001610e8d61ffff1681526020016106ad61ffff16815260200161137761ffff168152602001610cd061ffff168152602001610c6f61ffff168152602001610d6561ffff16815260200161136b61ffff16815260200161056261ffff168152602001610ad361ffff168152602001610b9661ffff16815260200161071261ffff168152602001610bae61ffff1681526020016107b361ffff1681526020016103bd61ffff168152602001610f5461ffff16815260200161071761ffff16815260200161093161ffff16815260200161127161ffff16815260200161040f61ffff1681526020016106ba61ffff168152602001610d8561ffff168152602001607d61ffff168152602001610d5961ffff16815260200161107661ffff1681526020016104d761ffff1681526020016101c961ffff16815260200161021461ffff168152602001610a3061ffff1681526020016106e361ffff168152602001610a8961ffff168152602001610a4f61ffff16815260200161070261ffff168152602001610c4561ffff16815260200161080e61ffff16815260200161079f61ffff16815260200160ce61ffff168152602001610a2261ffff16815260200161063f61ffff1681526020016101c661ffff16815260200161047f61ffff168152602001610cab61ffff168152602001610ce761ffff16815260200161020861ffff16815260200161127061ffff168152602001610d7861ffff1681526020016107e361ffff168152602001610d6061ffff16815260200161107e61ffff168152602001610aa561ffff16815260200161124f61ffff16815260200161084861ffff168152602001610f6a61ffff16815260200161074361ffff1681526020016105aa61ffff1681526020016110ec61ffff168152602001610a8861ffff1681526020016103d461ffff16815260200161017161ffff168152602001610bc461ffff16815260200161066061ffff1681526020016111f761ffff168152602001610a1461ffff1681526020016101d761ffff1681526020016108ca61ffff16815260200161129461ffff16815260200161027361ffff1681526020016111f461ffff168152602001610c3d61ffff168152602001610b3861ffff168152602001610aff61ffff168152602001610f7661ffff16815260200161123a61ffff16815260200160ad61ffff168152602001610a1961ffff16815260200161136e61ffff168152602001610eeb61ffff16815260200161011661ffff16815260200161046661ffff168152602001610e0c61ffff16815260200161047061ffff1681526020016110ea61ffff1681526020016110df61ffff16815260200161044161ffff16815260200161111761ffff168152602001610ab161ffff16815260200161092b61ffff168152602001610a9961ffff1681526020016105f861ffff16815260200161059461ffff1681526020016106f861ffff16815260200160b061ffff168152602001610aeb61ffff168152602001610e7a61ffff168152602001603861ffff168152602001610eca61ffff16815260200161096461ffff16815260200161111361ffff168152602001610a1b61ffff168152602001610ca961ffff168152602001610d9c61ffff1681526020016108e361ffff168152602001610f7761ffff16815260200161104961ffff16815260200161068461ffff1681526020016107da61ffff1681526020016107c661ffff16815260200161105d61ffff1681526020016102b261ffff168152602001610e0761ffff168152602001610ef661ffff16815260200161071661ffff168152602001610ff361ffff168152602001610ac661ffff16815260200160ff61ffff16815260200161081961ffff16815260200161010561ffff16815260200161055d61ffff1681526020016110b861ffff16815260200161048961ffff16815260200161098161ffff1681526020016111d661ffff168152602001610e4861ffff1681526020016110bc61ffff16815260200161027961ffff1681526020016108bd61ffff1681526020016107a061ffff16815260200161101c61ffff168152602001606f61ffff168152602001610d5361ffff1681526020016109e861ffff1681526020016107d561ffff168152602001610fd161ffff168152602001610da961ffff168152602001610b6661ffff1681526020016101cd61ffff16815260200161033261ffff16815260200161125b61ffff16815260200161093861ffff168152602001610cfe61ffff16815260200161126d61ffff1681526020016107cc61ffff168152602001604a61ffff16815260200160a361ffff16815260200161064061ffff16815260200161118061ffff16815260200161090a61ffff16815260200161060261ffff168152602001610c2a61ffff168152602001610e1661ffff168152602001610b5361ffff16815260200161047861ffff16815260200161102561ffff16815260200161034561ffff16815260200161074461ffff16815260200161079d61ffff16815260200161021d61ffff16815260200161072861ffff1681526020016107c061ffff168152602001610f0661ffff1681526020016104a561ffff1681526020016107f761ffff16815260200161102061ffff168152602001610d2461ffff168152602001610f9361ffff16815260200161086861ffff1681526020016107f461ffff16815260200161125d61ffff168152602001610f7e61ffff168152602001610bd961ffff1681526020016108e261ffff16815260200161011361ffff16815260200161134f61ffff1681526020016112a361ffff168152602001610fe361ffff16815260200161120261ffff16815260200161104661ffff16815260200161067f61ffff168152602001610d6e61ffff1681526020016106ab61ffff16815260200161071561ffff1681526020016101ca61ffff16815260200161112b61ffff16815260200161123f61ffff1681526020016110f061ffff16815260200161080761ffff16815260200161075461ffff1681526020016111c261ffff16815260200161048e61ffff168152602001610ed761ffff168152602001610de161ffff168152602001610c8061ffff16815260200161110261ffff16815260200160e861ffff16815260200161134061ffff16815260200161099761ffff168152602001610ac061ffff16815260200161016461ffff16815260200161075e61ffff168152602001610fcd61ffff16815260200161128c61ffff168152602001610dc661ffff16815260200161104361ffff168152602001610f8961ffff16815260200161043461ffff16815260200161117b61ffff16815260200161074c61ffff16815260200161082961ffff168152602001610a2061ffff1681526020016102d461ffff1681526020016112fa61ffff168152602001610ae261ffff16815260200161120461ffff1681526020016104ea61ffff16815260200161060c61ffff168152602001610ce661ffff168152602001610d2361ffff16815260200161062d61ffff16815260200161029661ffff1681526020016106cc61ffff16815260200160d261ffff1681526020016112a661ffff168152602001610be961ffff168152602001610b6861ffff16815260200161109061ffff16815260200161025e61ffff168152602001610ab761ffff16815260200161075a61ffff16815260200161041b61ffff168152602001610da161ffff1681526020016106ff61ffff16815260200161124861ffff168152602001610fd461ffff16815260200161084d61ffff16815260200160e461ffff168152602001610cef61ffff1681526020016104fa61ffff16815260200161031861ffff168152602001610ca361ffff168152602001606561ffff1681526020016111ff61ffff168152602001610ece61ffff16815260200161087d61ffff16815260200161081761ffff16815260200161119461ffff168152602001610dbb61ffff16815260200161098661ffff1681526020016108da61ffff168152602001610e0f61ffff168152602001610dfa61ffff168152602001610edc61ffff168152602001610a0461ffff1681526020016111ae61ffff16815260200160cd61ffff168152602001610ac461ffff16815260200161125961ffff1681526020016104d461ffff1681526020016102c161ffff1681526020016103f461ffff16815260200161083561ffff16815260200161119761ffff168152602001610fc161ffff16815260200161071161ffff1681526020016105a861ffff16815260200161097261ffff16815260200161132661ffff168152602001610e3961ffff168152602001610c2461ffff16815260200161060661ffff16815260200161133861ffff16815260200161028d61ffff1681526020016102d161ffff168152602001610c0661ffff168152602001610b0161ffff168152602001610fae61ffff168152602001610ba061ffff168152602001610ca861ffff16815260200161085e61ffff16815260200161088861ffff1681526020016112d161ffff1681526020016110f861ffff1681526020016102bb61ffff168152602001610ec561ffff168152602001610c3061ffff168152602001610d2161ffff16815260200161090061ffff16815260200161054261ffff16815260200161075761ffff1681526020016108b861ffff1681526020016111d361ffff168152602001610b7261ffff1681526020016109cc61ffff16815260200161018b61ffff16815260200161033061ffff168152602001610f8261ffff1681526020016103a361ffff16815260200161089e61ffff1681526020016110fc61ffff1681526020016101c261ffff168152602001610f7961ffff168152602001610ac561ffff1681526020016108aa61ffff1681526020016108e561ffff16815260200160a161ffff1681526020016104bb61ffff168152602001610dcc61ffff168152602001610ce561ffff16815260200161047561ffff1681526020016101f861ffff168152602001610cc561ffff1681526020016112a761ffff16815260200161031c61ffff1681526020016110a861ffff1681526020016111cf61ffff16815260200161078461ffff168152602001610a7b61ffff168152602001610bf461ffff168152602001610c0061ffff1681526020016106ed61ffff168152602001610aac61ffff1681526020016107f861ffff1681526020016107ae61ffff16815260200161072561ffff16815260200161119561ffff1681526020016102a061ffff168152602001610dc461ffff16815260200161030061ffff168152602001610fa461ffff168152602001610dae61ffff16815260200161044361ffff168152602001610e5b61ffff168152602001610a5161ffff168152602001610a9061ffff168152602001610a7e61ffff16815260200161025661ffff16815260200161075c61ffff168152602001610f0b61ffff16815260200161085d61ffff16815260200161099a61ffff16815260200161010261ffff1681526020016104dd61ffff16815260200161063361ffff16815260200160e361ffff168152602001610e1e61ffff1681526020016107a761ffff168152602001610e4c61ffff16815260200161092161ffff16815260200161078661ffff16815260200161079c61ffff16815260200161012d61ffff1681526020016105a361ffff16815260200161042661ffff16815260200161079461ffff16815260200161059761ffff168152602001610b0a61ffff16815260200161094161ffff16815260200161023e61ffff168152602001610bca61ffff16815260200161080661ffff168152602001610f1561ffff16815260200161138161ffff1681526020016104bd61ffff1681526020016106fe61ffff16815260200161033e61ffff16815260200161028c61ffff168152602001610dc161ffff16815260200161056561ffff168152602001610b4c61ffff16815260200161089661ffff168152602001610a6561ffff1681526020016101b061ffff168152602001610ec461ffff1681526020016108ad61ffff16815260200161034e61ffff168152602001610d4261ffff16815260200161127e61ffff168152602001610a0261ffff16815260200161028061ffff16815260200161012661ffff168152602001610ec861ffff16815260200161118761ffff168152602001610a2b61ffff16815260200161069a61ffff168152602001610e2e61ffff16815260200161118661ffff168152602001610ab661ffff168152602001610ab961ffff168152602001610c0161ffff168152602001610da761ffff168152602001610dfe61ffff16815260200161123d61ffff16815260200161073461ffff16815260200161093261ffff16815260200161020f61ffff168152602001610cff61ffff168152602001610d1a61ffff16815260200161063561ffff16815260200160ed61ffff1681526020016104d361ffff16815260200161085961ffff16815260200161101461ffff1681526020016111dc61ffff1681526020016105fe61ffff168152602001610a9361ffff1681526020016104fd61ffff16815260200161046c61ffff16815260200161102961ffff168152602001610f8361ffff16815260200161036f61ffff16815260200161028961ffff168152602001610f0a61ffff1681526020016107f561ffff168152602001610f7861ffff168152602001610f2461ffff16815260200161124161ffff16815260200161116b61ffff168152602001610b1e61ffff1681526020016101a861ffff168152602001610b7d61ffff16815260200161018261ffff168152602001610bbe61ffff168152602001610bd261ffff16815260200161094261ffff16815260200161010461ffff16815260200161089961ffff16815260200161116861ffff16815260200161092961ffff16815260200161103061ffff16815260200161064c61ffff168152602001610e4361ffff1681526020016109c061ffff168152602001610a4161ffff1681526020016105e361ffff1681526020016105bc61ffff168152602001610edb61ffff1681526020016107e661ffff16815260200161132061ffff16815260200161094b61ffff16815260200161097a61ffff1681526020016112fb61ffff16815260200161054661ffff168152602001610bee61ffff168152602001610f5661ffff168152602001608061ffff16815260200161076a61ffff168152602001610ef761ffff168152602001610e0061ffff168152602001610fbc61ffff1681526020016102a261ffff16815260200161112261ffff16815260200161031961ffff1681526020016111cd61ffff1681526020016102c061ffff16815260200161095161ffff1681526020016112e261ffff168152602001610e9661ffff16815260200161118861ffff168152602001610d9b61ffff168152602001610d1561ffff168152602001610e6461ffff1681526020016112bc61ffff16815260200161019761ffff16815260200161013a61ffff1681526020016108ef61ffff168152602001610a6f61ffff16815260200161039061ffff16815260200161092761ffff16815260200161020461ffff16815260200161123b61ffff16815260200161076561ffff16815260200161076661ffff16815260200161052761ffff16815260200161117461ffff1681526020016112d961ffff168152602001610ed261ffff168152602001610cf461ffff16815260200161015661ffff168152602001610c7861ffff16815260200161050161ffff168152602001610b3461ffff168152602001610f1461ffff1681526020016109db61ffff16815260200160fb61ffff168152602001610b7f61ffff16815260200161042361ffff168152602001610c5661ffff16815260200161130d61ffff1681526020016109c561ffff1681526020016112a161ffff16815260200161117961ffff16815260200161033d61ffff1681526020016101d361ffff168152602001610c5b61ffff16815260200161121d61ffff168152602001610a2f61ffff168152602001610fd561ffff168152602001610ae361ffff168152602001610b9961ffff16815260200161103f61ffff168152602001610db661ffff168152602001610e2261ffff168152602001610a0f61ffff16815260200161026461ffff168152602001609d61ffff168152602001610a1361ffff16815260200161054461ffff168152602001610b0761ffff16815260200161056e61ffff1681526020016111e461ffff16815260200161119361ffff1681526020016108cf61ffff168152602001610e8561ffff168152602001610d8f61ffff1681526020016101d661ffff168152602001610cb061ffff168152602001610b8d61ffff168152602001610f3061ffff16815260200161031a61ffff16815260200161109f61ffff16815260200161135361ffff16815260200161108061ffff16815260200161068e61ffff1681526020016110cc61ffff168152602001610eb561ffff16815260200161055961ffff16815260200161104761ffff16815260200161096761ffff168152602001605461ffff1681526020016109f061ffff16815260200161079e61ffff1681526020016104ee61ffff168152602001610b1a61ffff16815260200161086c61ffff168152602001610ec261ffff16815260200161039361ffff168152602001610fd261ffff1681526020016109f961ffff16815260200161040661ffff1681526020016108b361ffff1681526020016101e861ffff168152602001610b2c61ffff16815260200161029161ffff1681526020016111e061ffff16815260200161119c61ffff16815260200161093561ffff1681526020016106d661ffff16815260200161073961ffff168152602001610a4661ffff168152602001610c0461ffff16815260200161022a61ffff16815260200161022e61ffff168152602001610d7361ffff168152602001610ef961ffff168152602001610fb061ffff16815260200161030561ffff16815260200161070461ffff168152602001610cf961ffff168152602001607561ffff1681526020016111ca61ffff16815260200161074a61ffff168152602001610f1161ffff168152602001610e1961ffff16815260200161036461ffff16815260200161132a61ffff16815260200161088461ffff16815260200161057161ffff16815260200161037861ffff168152602001610a4561ffff168152602001610b8161ffff1681526020016105d261ffff168152602001610e8361ffff16815260200161113861ffff168152602001610f4861ffff1681526020016109f561ffff168152602001610cda61ffff168152602001610b1961ffff1681526020016104db61ffff168152602001610d2761ffff1681526020016106e061ffff16815260200160af61ffff16815260200161079661ffff16815260200161079161ffff16815260200161135b61ffff168152602001610de561ffff16815260200161104d61ffff1681526020016108cb61ffff16815260200161063d61ffff168152602001610d8161ffff16815260200161047461ffff168152602001610bb161ffff16815260200161128f61ffff168152602001610de061ffff16815260200161062f61ffff1681526020016104b761ffff168152602001610e5561ffff1681526020016110b761ffff16815260200161058361ffff168152602001610a2961ffff1681526020016105cc61ffff168152602001610b6361ffff168152602001610c3961ffff168152602001610d5061ffff16815260200161040861ffff16815260200161103b61ffff1681526020016104fc61ffff1681526020016109d761ffff168152602001610f2661ffff16815260200161124e61ffff168152602001610c4c61ffff168152602001610c1561ffff168152602001610cee61ffff168152602001610e8761ffff16815260200161047e61ffff16815260200161012f61ffff1681526020016102d061ffff168152602001610e9061ffff168152602001610f8761ffff168152602001610db561ffff1681526020016102f061ffff1681526020016104f861ffff16815260200161064a61ffff16815260200161101861ffff168152602001610b8761ffff1681526020016110c361ffff1681526020016111a661ffff16815260200161125761ffff1681526020016101fa61ffff1681526020016101ff61ffff16815260200161037a61ffff16815260200161099561ffff16815260200161053c61ffff16815260200161055461ffff16815260200161010e61ffff16815260200161096a61ffff16815260200161091e61ffff16815260200161080261ffff16815260200161076761ffff1681526020016108d161ffff16815260200161075f61ffff16815260200161122861ffff1681526020016108a161ffff168152602001610c3a61ffff168152602001610e1b61ffff16815260200161015f61ffff16815260200161028861ffff1681526020016102f461ffff16815260200161018d61ffff16815260200161105461ffff168152602001609361ffff168152602001610ed361ffff168152602001610c1361ffff16815260200161091b61ffff16815260200161068a61ffff16815260200161050361ffff1681526020016104b261ffff16815260200161071d61ffff168152602001610a0a61ffff16815260200161137161ffff168152602001610ee361ffff168152602001610f6e61ffff168152602001610aee61ffff1681526020016105c861ffff16815260200161113661ffff168152602001610a3261ffff16815260200161020c61ffff1681526020016110a461ffff1681526020016108e961ffff16815260200161047b61ffff16815260200161029561ffff16815260200161080a61ffff1681526020016108a761ffff16815260200161107561ffff1681526020016111b461ffff168152602001610e8861ffff16815260200161132861ffff16815260200161088061ffff16815260200161117661ffff168152602001610a2e61ffff16815260200161061361ffff168152602001610b8261ffff16815260200161110e61ffff16815260200161086361ffff16815260200161103a61ffff16815260200161091d61ffff16815260200161131161ffff168152602001610f5061ffff1681526020016105bb61ffff1681526020016110f561ffff168152602001610b3261ffff16815260200160ea61ffff168152602001610bde61ffff168152602001610fa261ffff16815260200161056d61ffff168152602001610e2761ffff16815260200160c161ffff168152602001610f9d61ffff168152602001610ea761ffff168152602001610aa161ffff16815260200161123861ffff1681526020016102cf61ffff1681526020016109fb61ffff1681526020016105ba61ffff168152602001610fb261ffff1681526020016105b961ffff168152602001610f8061ffff1681526020016101b561ffff1681526020016112ac61ffff16815260200161103561ffff1681526020016108b161ffff168152602001610bac61ffff16815260200161134661ffff168152602001610cdd61ffff168152602001610e7c61ffff168152602001610db461ffff16815260200161078561ffff168152602001610c8761ffff168152602001610a8161ffff168152602001610daf61ffff168152602001610b8f61ffff168152602001610ac961ffff16815260200161062461ffff168152602001610c9961ffff168152602001610f4961ffff16815260200161030861ffff168152602001610e1061ffff168152602001610e8b61ffff16815260200161133761ffff168152602001606361ffff168152602001610da661ffff16815260200161070661ffff16815260200161063a61ffff1681526020016101d561ffff168152602001610c6761ffff168152602001610b1161ffff1681526020016112c061ffff1681526020016110ca61ffff168152602001610c7c61ffff168152602001610ab861ffff168152602001610f6b61ffff168152602001610f6f61ffff1681526020016107d961ffff16815260200161089f61ffff16815260200161048461ffff16815260200161022c61ffff16815260200161092561ffff168152602001610bda61ffff1681526020016111c361ffff168152602001610ac161ffff1681526020016103a861ffff1681526020016106e461ffff16815260200161018a61ffff16815260200161103e61ffff168152602001610c8561ffff16815260200161107d61ffff1681526020016112c861ffff1681526020016110de61ffff1681526020016101f661ffff16815260200161057c61ffff16815260200161027161ffff1681526020016107a461ffff168152602001610be761ffff1681526020016110e461ffff168152602001610d5e61ffff16815260200161081161ffff16815260200161076c61ffff168152602001610a2461ffff16815260200160e961ffff168152602001610d9161ffff16815260200161091761ffff16815260200161090e61ffff1681526020016109b361ffff1681526020016112f961ffff16815260200161114361ffff168152602001610dd961ffff16815260200161057861ffff1681526020016101fc61ffff1681526020016109be61ffff168152602001610ea861ffff16815260200161054961ffff1681526020016104e261ffff16815260200161116461ffff1681526020016102c361ffff16815260200161054c61ffff16815260200161126861ffff16815260200161068b61ffff16815260200161127f61ffff16815260200161137261ffff16815260200161014d61ffff16815260200161100361ffff1681526020016106c661ffff16815260200161067e61ffff1681526020016109b761ffff168152602001603d61ffff16815260200161097761ffff1681526020016112b361ffff16815260200161035361ffff1681526020016108a261ffff1681526020016108d061ffff16815260200161099861ffff16815260200161099361ffff16815260200161022261ffff16815260200161089861ffff168152602001610bef61ffff168152602001610a9d61ffff168152602001610f9561ffff1681526020016101f061ffff16815260200161026a61ffff168152602001610bbb61ffff16815260200161059161ffff168152602001610fdd61ffff1681526020016104df61ffff16815260200161042b61ffff16815260200161114e61ffff16815260200161085f61ffff168152602001610e0d61ffff16815260200161076161ffff168152602001610d9861ffff168152602001610cc161ffff1681526020016110bf61ffff16815260200161028361ffff16815260200161028561ffff168152602001610cc661ffff16815260200161034f61ffff16815260200161070361ffff1681526020016102fc61ffff168152602001610edd61ffff168152602001610d0561ffff168152602001610b3a61ffff16815260200161073a61ffff16815260200161101961ffff168152602001610b8861ffff16815260200161029e61ffff1681526020016101df61ffff168152602001610d8c61ffff168152602001610b4261ffff1681526020016105eb61ffff16815260200161044561ffff168152602001610f5161ffff16815260200161137561ffff1681526020016101a061ffff16815260200161089761ffff16815260200161117561ffff16815260200161014061ffff168152602001610a8f61ffff1681526020016108fe61ffff16815260200160d861ffff16815260200160a661ffff168152602001605961ffff16815260200161017f61ffff1681526020016107ad61ffff16815260200161068961ffff1681526020016111eb61ffff1681526020016108d261ffff168152602001610dcf61ffff16815260200161105f61ffff1681526020016111d861ffff168152602001610d8361ffff16815260200161113361ffff16815260200161060561ffff168152602001610dbd61ffff16815260200161114b61ffff16815260200161077a61ffff168152602001610e9561ffff16815260200161052a61ffff1681526020016106f561ffff168152602001608561ffff16815260200161076e61ffff16815260200161042761ffff168152602001610e6861ffff1681526020016102ce61ffff16815260200161077e61ffff16815260200161105361ffff168152602001610a0861ffff16815260200161030a61ffff16815260200161034961ffff16815260200161089461ffff16815260200161043a61ffff16815260200161049761ffff16815260200161109c61ffff1681526020016109aa61ffff168152602001610cb161ffff16815260200161068d61ffff16815260200161124661ffff168152602001610b1761ffff16815260200161013761ffff1681526020016112c261ffff168152602001610e1861ffff1681526020016103fc61ffff168152602001610b6761ffff1681526020016101e761ffff16815260200161072661ffff16815260200161089c61ffff1681526020016105af61ffff168152602001610ca461ffff168152602001610d1f61ffff168152602001610d0f61ffff16815260200161079761ffff16815260200161112761ffff16815260200161123061ffff16815260200161037761ffff1681526020016102ba61ffff1681526020016107ab61ffff168152602001610b1d61ffff1681526020016104c461ffff1681526020016102b761ffff16815260200161062c61ffff16815260200161130a61ffff16815260200161132b61ffff16815260200161078161ffff16815260200161090261ffff16815260200161066561ffff16815260200161048861ffff1681526020016104a061ffff16815260200161025361ffff168152602001610aed61ffff168152602001610d4c61ffff168152602001610b9361ffff16815260200161042a61ffff16815260200160de61ffff16815260200161075861ffff16815260200161078b61ffff16815260200161090861ffff16815260200161110561ffff1681526020016106ee61ffff16815260200161042161ffff16815260200161034a61ffff1681526020016112e461ffff16815260200161090961ffff1681526020016112f061ffff168152602001610e2461ffff168152602001606d61ffff168152602001610ec661ffff16815260200160b261ffff168152602001610e1161ffff168152602001610b5d61ffff16815260200161118961ffff1681526020016106ac61ffff16815260200161083761ffff16815260200161074d61ffff168152602001610fb961ffff168152602001610f7461ffff1681526020016108d361ffff16815260200161088e61ffff168152602001610f3161ffff168152602001610b8961ffff16815260200161074961ffff1681526020016110b061ffff16815260200161100561ffff168152602001610f4161ffff16815260200161037361ffff16815260200161130761ffff168152602001609661ffff16815260200161132361ffff168152602001610cf161ffff16815260200160c461ffff168152602001610c0a61ffff16815260200161136361ffff168152602001610bf561ffff1681526020016104b961ffff168152602001610b7761ffff168152602001610a2861ffff16815260200161096861ffff1681526020016106d961ffff168152602001610a0661ffff1681526020016102d961ffff16815260200161048f61ffff168152602001610cd461ffff16815260200161129761ffff1681526020016102bc61ffff168152602001610b0f61ffff16815260200161125661ffff16815260200161066861ffff168152602001610b0961ffff168152602001610f4e61ffff16815260200161059961ffff168152602001607361ffff168152602001610fee61ffff168152602001610dd661ffff16815260200161052161ffff16815260200161093b61ffff16815260200161118361ffff1681526020016112c461ffff16815260200161065e61ffff168152602001610fda61ffff168152602001610f2a61ffff168152602001610e7061ffff168152602001610eae61ffff168152602001610f9061ffff16815260200161052d61ffff168152602001610e0861ffff16815260200161131a61ffff16815260200161137d61ffff16815260200161046e61ffff168152602001610e0961ffff168152602001610d1161ffff16815260200161114861ffff16815260200161136061ffff16815260200161098261ffff168152602001610f3661ffff1681526020016104f161ffff168152602001610dc861ffff16815260200161075b61ffff168152602001610a7c61ffff168152602001607961ffff168152602001610c8261ffff1681526020016111d461ffff16815260200161021561ffff168152602001610f0c61ffff16815260200161121961ffff16815260200161080f61ffff16815260200161033361ffff168152602001610c9c61ffff16815260200161069e61ffff16815260200161030b61ffff16815260200161026f61ffff16815260200161078061ffff16815260200161077c61ffff16815260200161030161ffff168152602001610a0561ffff168152602001610b4b61ffff16815260200160ec61ffff168152602001610a3f61ffff16815260200161123e61ffff1681526020016105d761ffff1681526020016109dc61ffff168152602001610ec061ffff168152602001607061ffff16815260200161047a61ffff168152602001610d7b61ffff16815260200161040161ffff16815260200161084661ffff16815260200161010661ffff16815260200161043261ffff16815260200161034b61ffff168152602001610e0261ffff16815260200161022761ffff168152602001610ce961ffff168152602001610de861ffff16815260200161123461ffff168152602001610b9761ffff168152602001610bc361ffff168152602001610b6961ffff16815260200161083361ffff1681526020016109e761ffff16815260200161085c61ffff16815260200161052361ffff168152602001610b4961ffff1681526020016103c461ffff16815260200161044b61ffff168152602001610f6461ffff1681526020016107b261ffff16815260200161122f61ffff168152602001610b2261ffff16815260200161049661ffff16815260200161062161ffff168152602001610c6961ffff1681526020016105ce61ffff16815260200161128461ffff16815260200161119b61ffff1681526020016105c961ffff16815260200161129261ffff168152602001610d4b61ffff168152602001610b6d61ffff16815260200161076b61ffff16815260200161084a61ffff168152602001610e4d61ffff1681526020016104ae61ffff1681526020016108f261ffff16815260200161129f61ffff168152602001610cd561ffff16815260200161013161ffff1681526020016111a261ffff16815260200161128261ffff1681526020016102b361ffff168152602001610b0c61ffff168152602001610aba61ffff1681526020016104cd61ffff1681526020016109a261ffff168152602001606661ffff16815260200161117361ffff16815260200161013961ffff168152602001610cf061ffff1681526020016103e061ffff16815260200161020a61ffff16815260200161028461ffff16815260200161050b61ffff1681526020016102e861ffff168152602001605b61ffff16815260200161039961ffff168152602001610d6f61ffff16815260200161012a61ffff168152602001610f9e61ffff16815260200160c361ffff168152602001610ec761ffff168152602001610afe61ffff1681526020016111ba61ffff1681526020016107d261ffff16815260200161078c61ffff1681526020016112d361ffff168152602001610b8e61ffff1681526020016106af61ffff1681526020016111d561ffff16815260200161022d61ffff168152602001610e6d61ffff16815260200161138761ffff16815260200161133561ffff16815260200161131d61ffff168152602001605761ffff16815260200161130c61ffff16815260200161055261ffff168152602001610f0d61ffff1681526020016104cb61ffff1681526020016103b561ffff1681526020016111a961ffff1681526020016102c961ffff168152602001610ab461ffff168152602001610a7061ffff168152602001610a3861ffff16815260200161015961ffff1681526020016107d361ffff16815260200161065961ffff168152602001610ccb61ffff1681526020016105ef61ffff16815260200160c961ffff16815260200161131f61ffff16815260200161116761ffff16815260200161013061ffff1681526020016101ba61ffff168152602001610a7661ffff168152602001610cd661ffff16815260200161134361ffff1681526020016107b761ffff168152602001610bec61ffff16815260200161097861ffff1681526020016109e461ffff1681526020016101fd61ffff16815260200161040b61ffff168152602001610f0961ffff1681526020016103a461ffff1681526020016104b461ffff16815260200161111a61ffff16815260200161045361ffff1681526020016105b161ffff16815260200161045f61ffff16815260200161094661ffff168152602001610d3d61ffff16815260200161123961ffff16815260200161135561ffff16815260200161064e61ffff1681526020016108a961ffff16815260200161108d61ffff168152602001604d61ffff16815260200161053d61ffff16815260200161081b61ffff16815260200161032361ffff168152602001610e1d61ffff168152602001610d9d61ffff16815260200161046961ffff1681526020016106de61ffff16815260200161106561ffff16815260200161104e61ffff168152602001610be661ffff168152602001610ea261ffff168152602001610abc61ffff16815260200161085461ffff1681526020016107ba61ffff1681526020016102c461ffff168152602001607661ffff1681526020016112bb61ffff16815260200160a961ffff16815260200160c061ffff168152602001604e61ffff168152602001610c2b61ffff16815260200161057761ffff16815260200161095c61ffff16815260200161018361ffff168152602001610d0e61ffff16815260200161049161ffff1681526020016109f861ffff168152602001610b4661ffff168152602001610f3261ffff16815260200161099461ffff16815260200161116d61ffff16815260200161115961ffff16815260200161137661ffff16815260200161022161ffff168152602001608f61ffff168152602001610f8a61ffff16815260200161013261ffff1681526020016110a961ffff1681526020016109ee61ffff1681526020016105c561ffff16815260200161042961ffff16815260200161098761ffff1681526020016112fd61ffff16815260200161027561ffff168152602001610a5861ffff16815260200161120b61ffff16815260200161016e61ffff16815260200161033761ffff16815260200161064b61ffff168152602001609761ffff168152602001610dea61ffff168152602001610afa61ffff168152602001610e7661ffff16815260200161110a61ffff168152602001610b4861ffff168152602001610d4d61ffff16815260200161114761ffff168152602001610c5f61ffff168152602001610ada61ffff16815260200161118b61ffff1681526020016101c761ffff16815260200161114561ffff16815260200161130361ffff168152602001610fb461ffff16815260200161079861ffff1681526020016107df61ffff16815260200161101761ffff16815260200161030461ffff168152602001610f6361ffff168152602001610ecf61ffff1681526020016110fe61ffff16815260200161103c61ffff168152602001609e61ffff1681526020016108fc61ffff16815260200161039561ffff1681526020016111d761ffff16815260200161052561ffff1681526020016103de61ffff16815260200161012c61ffff16815260200161036561ffff16815260200161109d61ffff16815260200161026261ffff1681526020016102b661ffff168152602001610c1461ffff16815260200161131461ffff16815260200161030761ffff168152602001610ff261ffff16815260200161032d61ffff16815260200161021861ffff168152602001610d8261ffff168152602001603961ffff168152602001610e2061ffff16815260200161058f61ffff168152602001610d0461ffff16815260200161041961ffff16815260200161137361ffff16815260200161011861ffff16815260200161087c61ffff16815260200161013f61ffff168152602001610f1f61ffff168152602001610b3361ffff168152602001610c6361ffff16815260200161016b61ffff168152602001610c8161ffff16815260200161113e61ffff16815260200161045661ffff168152602001610e3061ffff16815260200161032861ffff16815260200161035e61ffff168152602001610a1c61ffff16815260200161014b61ffff168152602001610a9461ffff1681526020016111a861ffff168152602001610c7461ffff168152602001610d4061ffff1681526020016103bb61ffff1681526020016101b661ffff168152602001610bc761ffff1681526020016112b261ffff16815260200161028161ffff168152602001610dac61ffff16815260200161038d61ffff168152602001610a5661ffff1681526020016109ad61ffff16815260200161126f61ffff168152602001610fc061ffff168152602001610ef861ffff16815260200161125a61ffff16815260200161046261ffff16815260200161091361ffff1681526020016107b061ffff16815260200161036961ffff1681526020016110fb61ffff1681526020016111fc61ffff168152602001610cc061ffff168152602001610e1461ffff168152602001610f3f61ffff16815260200161075d61ffff16815260200160a461ffff168152602001610d2e61ffff168152602001610ad661ffff16815260200161103961ffff168152602001610e9261ffff16815260200161050c61ffff1681526020016110b961ffff16815260200161128a61ffff168152602001610c0261ffff1681526020016105e461ffff16815260200161031e61ffff16815260200161011e61ffff1681526020016103ce61ffff16815260200161061661ffff16815260200161097e61ffff168152602001610bfe61ffff16815260200161027e61ffff16815260200161132961ffff16815260200161100061ffff16815260200161105c61ffff16815260200161063c61ffff1681526020016111be61ffff16815260200161080061ffff1681526020016101f561ffff168152602001610bb561ffff1681526020016106ca61ffff16815260200161022961ffff16815260200161137a61ffff168152602001610a5761ffff168152602001610fe661ffff16815260200161074b61ffff16815260200161011f61ffff16815260200161059c61ffff1681526020016110b161ffff16815260200161108f61ffff168152602001610a9561ffff16815260200161100f61ffff16815260200161136d61ffff1681526020016102f861ffff1681526020016105ae61ffff16815260200161083161ffff1681526020016107a261ffff16815260200161019a61ffff168152602001610f0061ffff168152602001605561ffff1681526020016105c261ffff1681526020016101d061ffff168152602001610b0861ffff1681526020016103b161ffff16815260200161116c61ffff1681526020016112e561ffff16815260200161093e61ffff16815260200161084761ffff16815260200161097b61ffff16815260200160c861ffff16815260200161041a61ffff16815260200161105a61ffff16815260200161048d61ffff16815260200160c661ffff168152602001609961ffff16815260200161017961ffff16815260200161039861ffff168152602001610d2261ffff1681526020016106a661ffff168152602001610aaf61ffff168152602001610e3561ffff1681526020016105a461ffff1681526020016104d061ffff16815260200161086461ffff16815260200161027b61ffff16815260200161073261ffff168152602001610c1a61ffff16815260200161084b61ffff16815260200161094361ffff16815260200160f361ffff16815260200161127c61ffff168152602001610b0461ffff16815260200161039d61ffff1681526020016101c361ffff1681526020016111a761ffff1681526020016107c961ffff168152602001610cb561ffff16815260200161121461ffff16815260200161090161ffff168152602001610b7361ffff16815260200161041861ffff168152602001610ac361ffff168152602001610d0661ffff1681526020016102f761ffff168152602001604061ffff1681526020016103ea61ffff1681526020016106e161ffff16815260200161019661ffff168152602001610e6661ffff16815260200161040e61ffff16815260200161138261ffff168152602001605d61ffff168152602001610be161ffff1681526020016103a561ffff16815260200161107a61ffff16815260200161038a61ffff16815260200161085661ffff16815260200161025f61ffff16815260200161085861ffff168152602001610fc561ffff16815260200161030261ffff168152602001609b61ffff168152602001610a6861ffff1681526020016104bf61ffff16815260200161070961ffff16815260200161019f61ffff168152602001610df561ffff16815260200161056061ffff168152602001610e3861ffff1681526020016105ea61ffff16815260200161093661ffff168152602001610b0561ffff16815260200161068661ffff16815260200161057961ffff1681526020016112ec61ffff1681526020016110d561ffff16815260200161118261ffff1681526020016112b161ffff16815260200161133261ffff16815260200161034861ffff168152602001610d2a61ffff1681526020016112e161ffff1681526020016112f461ffff1681526020016102ca61ffff16815260200161093d61ffff1681526020016103c761ffff16815260200161031f61ffff16815260200160d661ffff168152602001610d0a61ffff16815260200161080b61ffff16815260200161083b61ffff16815260200161130061ffff16815260200161108461ffff168152602001610d9461ffff1681526020016104c261ffff16815260200161046a61ffff168152602001610b9b61ffff16815260200161135261ffff16815260200161019061ffff1681526020016112a861ffff16815260200161109661ffff1681526020016111dd61ffff16815260200161023261ffff1681526020016101d261ffff1681526020016107af61ffff16815260200161021061ffff16815260200161033861ffff16815260200160fc61ffff168152602001610b1061ffff168152602001610acd61ffff1681526020016109ab61ffff168152602001610fd861ffff168152602001610b8461ffff16815260200161047261ffff168152602001610fbd61ffff16815260200161124261ffff1681526020016111b061ffff168152602001610d4e61ffff1681526020016109e161ffff168152602001610d9f61ffff16815260200161048c61ffff16815260200161067161ffff16815260200161023d61ffff168152602001610f0161ffff1681526020016109e061ffff16815260200161085a61ffff168152506002906113476200e6b39291906200eb80565b50622625a0600860006101000a81548163ffffffff021916908363ffffffff1602179055506003600860046101000a81548161ffff021916908361ffff1602179055506000600b60006101000a81548160ff0219169083151502179055506001600c60146101000a81548160ff021916908360ff1602179055503480156200e73a57600080fd5b5060405162011c8438038062011c8483398181016040528101906200e76091906200ed75565b826200e7816200e7756200eab460201b60201c565b6200eabc60201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050506001808190555087600b60016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555086600c60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600e8190555082600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600460146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555082600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600781905550600060126000600160ff16815260200190815260200160002060006101000a81548160ff021916908360028111156200ea1b576200ea1a6200ee3e565b5b0217905550600160126000600260ff16815260200190815260200160002060006101000a81548160ff021916908360028111156200ea5e576200ea5d6200ee3e565b5b0217905550600260126000600360ff16815260200190815260200160002060006101000a81548160ff021916908360028111156200eaa1576200eaa06200ee3e565b5b021790555050505050505050506200ee6d565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b82805482825590600052602060002090600f016010900481019282156200ec1e5791602002820160005b838211156200ebec57835183826101000a81548161ffff021916908361ffff16021790555092602001926002016020816001010492830192600103026200ebaa565b80156200ec1c5782816101000a81549061ffff02191690556002016020816001010492830192600103026200ebec565b505b5090506200ec2d91906200ec31565b5090565b5b808211156200ec4c5760008160009055506001016200ec32565b5090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200ec82826200ec55565b9050919050565b6200ec94816200ec75565b81146200eca057600080fd5b50565b6000815190506200ecb4816200ec89565b92915050565b6000819050919050565b6200eccf816200ecba565b81146200ecdb57600080fd5b50565b6000815190506200ecef816200ecc4565b92915050565b600067ffffffffffffffff82169050919050565b6200ed14816200ecf5565b81146200ed2057600080fd5b50565b6000815190506200ed34816200ed09565b92915050565b6000819050919050565b6200ed4f816200ed3a565b81146200ed5b57600080fd5b50565b6000815190506200ed6f816200ed44565b92915050565b600080600080600080600080610100898b0312156200ed99576200ed986200ec50565b5b60006200eda98b828c016200eca3565b98505060206200edbc8b828c016200eca3565b97505060406200edcf8b828c016200eca3565b96505060606200ede28b828c016200ecde565b95505060806200edf58b828c016200ed23565b94505060a06200ee088b828c016200eca3565b93505060c06200ee1b8b828c016200eca3565b92505060e06200ee2e8b828c016200ed5e565b9150509295985092959890939650565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b608051612df46200ee9060003960008181610ecd0152610f210152612df46000f3fe60806040526004361061019c5760003560e01c80635e5ffbc6116100ec578063944c9efa1161008a578063a3422ee111610064578063a3422ee1146105b9578063a3e56fa8146105e4578063bb2cf9311461060f578063f2fde38b1461064c5761019c565b8063944c9efa1461052657806395564837146105515780639583ddee1461058e5761019c565b806386f128dc116100c657806386f128dc1461047e5780638831e9cf146104955780638da5cb5b146104be5780638e2de4d3146104e95761019c565b80635e5ffbc6146104015780636f6745011461042a578063715018a6146104675761019c565b8063220889761161015957806340b275cf1161013357806340b275cf1461034757806354cfea17146103705780635b2ec42f146103995780635c238494146103d65761019c565b806322088976146102a2578063241ec797146102df578063373d911c1461031c5761019c565b806309c1ba2e146101a15780630bbf2942146101cc5780630ec532e0146101f55780630f16e875146102115780631c4695f41461024e5780631fe543e314610279575b600080fd5b3480156101ad57600080fd5b506101b6610675565b6040516101c39190611ca4565b60405180910390f35b3480156101d857600080fd5b506101f360048036038101906101ee9190611d09565b61068f565b005b61020f600480360381019061020a9190611e8f565b61073b565b005b34801561021d57600080fd5b5061023860048036038101906102339190611d09565b610e7b565b6040516102459190611ef3565b60405180910390f35b34801561025a57600080fd5b50610263610ea5565b6040516102709190611f4f565b60405180910390f35b34801561028557600080fd5b506102a0600480360381019061029b9190611f6a565b610ecb565b005b3480156102ae57600080fd5b506102c960048036038101906102c49190611d09565b610f8b565b6040516102d69190611fe2565b60405180910390f35b3480156102eb57600080fd5b5061030660048036038101906103019190611d09565b610fab565b604051610313919061200c565b60405180910390f35b34801561032857600080fd5b50610331610fc3565b60405161033e9190611f4f565b60405180910390f35b34801561035357600080fd5b5061036e6004803603810190610369919061205d565b610fe9565b005b34801561037c57600080fd5b5061039760048036038101906103929190611d09565b61106f565b005b3480156103a557600080fd5b506103c060048036038101906103bb9190611d09565b6110f5565b6040516103cd9190611ef3565b60405180910390f35b3480156103e257600080fd5b506103eb611115565b6040516103f8919061200c565b60405180910390f35b34801561040d57600080fd5b50610428600480360381019061042391906120b6565b61111b565b005b34801561043657600080fd5b50610451600480360381019061044c91906120b6565b6111b5565b60405161045e919061215a565b60405180910390f35b34801561047357600080fd5b5061047c6111d5565b005b34801561048a57600080fd5b5061049361128c565b005b3480156104a157600080fd5b506104bc60048036038101906104b791906121a1565b611334565b005b3480156104ca57600080fd5b506104d3611464565b6040516104e09190611f4f565b60405180910390f35b3480156104f557600080fd5b50610510600480360381019061050b9190611d09565b61148d565b60405161051d9190611f4f565b60405180910390f35b34801561053257600080fd5b5061053b6114c0565b6040516105489190611ef3565b60405180910390f35b34801561055d57600080fd5b5061057860048036038101906105739190611d09565b6114d3565b60405161058591906121eb565b60405180910390f35b34801561059a57600080fd5b506105a361150b565b6040516105b09190611fe2565b60405180910390f35b3480156105c557600080fd5b506105ce61151e565b6040516105db9190611f4f565b60405180910390f35b3480156105f057600080fd5b506105f9611544565b6040516106069190611f4f565b60405180910390f35b34801561061b57600080fd5b5061063660048036038101906106319190612206565b61156a565b604051610643919061200c565b60405180910390f35b34801561065857600080fd5b50610673600480360381019061066e91906121a1565b61159b565b005b600460149054906101000a900467ffffffffffffffff1681565b610697611693565b73ffffffffffffffffffffffffffffffffffffffff166106b5611464565b73ffffffffffffffffffffffffffffffffffffffff161461070b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610702906122a3565b60405180910390fd5b6000600f600083815260200190815260200160002060006101000a81548160ff021916908360ff16021790555050565b60026001541415610781576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107789061230f565b60405180910390fd5b60026001819055506000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663e985e9c533306040518363ffffffff1660e01b81526004016107ed92919061232f565b60206040518083038186803b15801561080557600080fd5b505afa158015610819573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083d9190612384565b9050600b60009054906101000a900460ff1661088e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610885906123fd565b60405180910390fd5b806108ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c590612469565b60405180910390fd5b600083511180156108e45750600a60ff16835111155b610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091a906124d5565b60405180910390fd5b60005b8351811015610b8f576000848281518110610944576109436124f5565b5b6020026020010151905060008473ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610989919061200c565b60206040518083038186803b1580156109a157600080fd5b505afa1580156109b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d99190612539565b90503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a40906125b2565b60405180910390fd5b6010600083815260200190815260200160002060009054906101000a900460ff1615610aaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa19061261e565b60405180910390fd5b600c60149054906101000a900460ff1660ff16600f600084815260200190815260200160002060009054906101000a900460ff1660ff1610610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b189061268a565b60405180910390fd5b6001600f600084815260200190815260200160002060009054906101000a900460ff16610b4e91906126d9565b600f600084815260200190815260200160002060006101000a81548160ff021916908360ff1602179055505050600181610b889190612710565b9050610926565b506000600e541115610cc15760008351600e54610bac9190612766565b9050803414610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061280c565b60405180910390fd5b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1634604051610c389061285d565b60006040518083038185875af1925050503d8060008114610c75576040519150601f19603f3d011682016040523d82523d6000602084013e610c7a565b606091505b5050905080610cbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb5906128be565b60405180910390fd5b50505b6000835190506000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d3b1d30600754600460149054906101000a900467ffffffffffffffff16600860049054906101000a900461ffff16600860009054906101000a900463ffffffff16876040518663ffffffff1660e01b8152600401610d6695949392919061290c565b602060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db89190612974565b905084600a60008381526020019081526020016000209080519060200190610de1929190611c17565b50336009600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f3f59ad8df24b1c45f7dee2f4fdf974bd333dca793f90068a444c29f7b5b9cc718582604051610e65929190612a5f565b60405180910390a1505050506001808190555050565b60006010600083815260200190815260200160002060009054906101000a900460ff169050919050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f7d57337f00000000000000000000000000000000000000000000000000000000000000006040517f1cf993f4000000000000000000000000000000000000000000000000000000008152600401610f7492919061232f565b60405180910390fd5b610f87828261169b565b5050565b600f6020528060005260406000206000915054906101000a900460ff1681565b60116020528060005260406000206000915090505481565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610ff1611693565b73ffffffffffffffffffffffffffffffffffffffff1661100f611464565b73ffffffffffffffffffffffffffffffffffffffff1614611065576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105c906122a3565b60405180910390fd5b8060078190555050565b611077611693565b73ffffffffffffffffffffffffffffffffffffffff16611095611464565b73ffffffffffffffffffffffffffffffffffffffff16146110eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e2906122a3565b60405180910390fd5b80600e8190555050565b60106020528060005260406000206000915054906101000a900460ff1681565b600e5481565b611123611693565b73ffffffffffffffffffffffffffffffffffffffff16611141611464565b73ffffffffffffffffffffffffffffffffffffffff1614611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e906122a3565b60405180910390fd5b80600c60146101000a81548160ff021916908360ff16021790555050565b60126020528060005260406000206000915054906101000a900460ff1681565b6111dd611693565b73ffffffffffffffffffffffffffffffffffffffff166111fb611464565b73ffffffffffffffffffffffffffffffffffffffff1614611251576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611248906122a3565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128390612adb565b60405180910390fd5b611294611693565b73ffffffffffffffffffffffffffffffffffffffff166112b2611464565b73ffffffffffffffffffffffffffffffffffffffff1614611308576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ff906122a3565b60405180910390fd5b600b60009054906101000a900460ff1615600b60006101000a81548160ff021916908315150217905550565b61133c611693565b73ffffffffffffffffffffffffffffffffffffffff1661135a611464565b73ffffffffffffffffffffffffffffffffffffffff16146113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a7906122a3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611420576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141790612b47565b60405180910390fd5b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b60009054906101000a900460ff1681565b600281815481106114e357600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b600c60149054906101000a900460ff1681565b600b60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a602052816000526040600020818154811061158657600080fd5b90600052602060002001600091509150505481565b6115a3611693565b73ffffffffffffffffffffffffffffffffffffffff166115c1611464565b73ffffffffffffffffffffffffffffffffffffffff1614611617576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160e906122a3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611687576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167e90612bd9565b60405180910390fd5b61169081611b53565b50565b600033905090565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600b60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060006009600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600a600087815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561178057602002820191906000526020600020905b81548152602001906001019080831161176c575b505050505090507fa3cbb93152ed2715170621d47c4aa5e85e0ae4733b16b251877c18360b3ccd6686866040516117b8929190612bf9565b60405180910390a160005b81518160ff161015611b4a576000828260ff16815181106117e7576117e66124f5565b5b602002602001015190506000878360ff1681518110611809576118086124f5565b5b602002602001015190506000600280549050826118269190612c58565b90506010600084815260200190815260200160002060009054906101000a900460ff161561185657505050611b36565b60016010600085815260200190815260200160002060006101000a81548160ff0219169083151502179055508773ffffffffffffffffffffffffffffffffffffffff166323b872dd8761dead866040518463ffffffff1660e01b81526004016118c193929190612c89565b600060405180830381600087803b1580156118db57600080fd5b505af11580156118ef573d6000803e3d6000fd5b50505050600060028281548110611909576119086124f5565b5b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600060018261ffff161015801561194b5750604b8261ffff1611155b15611959576002905061197f565b604c8261ffff161015801561197457506102ee8261ffff1611155b1561197e57600190505b5b600260016002805490506119939190612cc0565b815481106119a4576119a36124f5565b5b90600052602060002090601091828204019190066002029054906101000a900461ffff16600284815481106119dc576119db6124f5565b5b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506002805480611a1d57611a1c612cf4565b5b60019003818190600052602060002090601091828204019190066002026101000a81549061ffff021916905590558161ffff1660116000878152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff16633807aabd89846040518363ffffffff1660e01b8152600401611aa2929190612d5e565b602060405180830381600087803b158015611abc57600080fd5b505af1158015611ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af49190612974565b507f636094fd65795f24380cbd1bb4b2587fd8d385720be2091b4cd9042af8722ecd858383604051611b2893929190612d87565b60405180910390a150505050505b600181611b4391906126d9565b90506117c3565b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054828255906000526020600020908101928215611c53579160200282015b82811115611c52578251825591602001919060010190611c37565b5b509050611c609190611c64565b5090565b5b80821115611c7d576000816000905550600101611c65565b5090565b600067ffffffffffffffff82169050919050565b611c9e81611c81565b82525050565b6000602082019050611cb96000830184611c95565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b611ce681611cd3565b8114611cf157600080fd5b50565b600081359050611d0381611cdd565b92915050565b600060208284031215611d1f57611d1e611cc9565b5b6000611d2d84828501611cf4565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611d8482611d3b565b810181811067ffffffffffffffff82111715611da357611da2611d4c565b5b80604052505050565b6000611db6611cbf565b9050611dc28282611d7b565b919050565b600067ffffffffffffffff821115611de257611de1611d4c565b5b602082029050602081019050919050565b600080fd5b6000611e0b611e0684611dc7565b611dac565b90508083825260208201905060208402830185811115611e2e57611e2d611df3565b5b835b81811015611e575780611e438882611cf4565b845260208401935050602081019050611e30565b5050509392505050565b600082601f830112611e7657611e75611d36565b5b8135611e86848260208601611df8565b91505092915050565b600060208284031215611ea557611ea4611cc9565b5b600082013567ffffffffffffffff811115611ec357611ec2611cce565b5b611ecf84828501611e61565b91505092915050565b60008115159050919050565b611eed81611ed8565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611f3982611f0e565b9050919050565b611f4981611f2e565b82525050565b6000602082019050611f646000830184611f40565b92915050565b60008060408385031215611f8157611f80611cc9565b5b6000611f8f85828601611cf4565b925050602083013567ffffffffffffffff811115611fb057611faf611cce565b5b611fbc85828601611e61565b9150509250929050565b600060ff82169050919050565b611fdc81611fc6565b82525050565b6000602082019050611ff76000830184611fd3565b92915050565b61200681611cd3565b82525050565b60006020820190506120216000830184611ffd565b92915050565b6000819050919050565b61203a81612027565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60006020828403121561207357612072611cc9565b5b600061208184828501612048565b91505092915050565b61209381611fc6565b811461209e57600080fd5b50565b6000813590506120b08161208a565b92915050565b6000602082840312156120cc576120cb611cc9565b5b60006120da848285016120a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612123576121226120e3565b5b50565b600081905061213482612112565b919050565b600061214482612126565b9050919050565b61215481612139565b82525050565b600060208201905061216f600083018461214b565b92915050565b61217e81611f2e565b811461218957600080fd5b50565b60008135905061219b81612175565b92915050565b6000602082840312156121b7576121b6611cc9565b5b60006121c58482850161218c565b91505092915050565b600061ffff82169050919050565b6121e5816121ce565b82525050565b600060208201905061220060008301846121dc565b92915050565b6000806040838503121561221d5761221c611cc9565b5b600061222b85828601611cf4565b925050602061223c85828601611cf4565b9150509250929050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061228d602083612246565b915061229882612257565b602082019050919050565b600060208201905081810360008301526122bc81612280565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006122f9601f83612246565b9150612304826122c3565b602082019050919050565b60006020820190508181036000830152612328816122ec565b9050919050565b60006040820190506123446000830185611f40565b6123516020830184611f40565b9392505050565b61236181611ed8565b811461236c57600080fd5b50565b60008151905061237e81612358565b92915050565b60006020828403121561239a57612399611cc9565b5b60006123a88482850161236f565b91505092915050565b7f52455645414c5f50484153455f4e4f545f494e49544941544544000000000000600082015250565b60006123e7601a83612246565b91506123f2826123b1565b602082019050919050565b60006020820190508181036000830152612416816123da565b9050919050565b7f415050524f56414c5f4e4f545f474956454e0000000000000000000000000000600082015250565b6000612453601283612246565b915061245e8261241d565b602082019050919050565b6000602082019050818103600083015261248281612446565b9050919050565b7f42415443485f53495a455f494e56414c49440000000000000000000000000000600082015250565b60006124bf601283612246565b91506124ca82612489565b602082019050919050565b600060208201905081810360008301526124ee816124b2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008151905061253381612175565b92915050565b60006020828403121561254f5761254e611cc9565b5b600061255d84828501612524565b91505092915050565b7f4f4e4c595f4f574e45525f43414e5f43414c4c5f544849535f4d4554484f4400600082015250565b600061259c601f83612246565b91506125a782612566565b602082019050919050565b600060208201905081810360008301526125cb8161258f565b9050919050565b7f424f585f414c52454144595f434c41494d454400000000000000000000000000600082015250565b6000612608601383612246565b9150612613826125d2565b602082019050919050565b60006020820190508181036000830152612637816125fb565b9050919050565b7f52414e444f4d5f4e554d4245525f4c494d49545f524541434845440000000000600082015250565b6000612674601b83612246565b915061267f8261263e565b602082019050919050565b600060208201905081810360008301526126a381612667565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006126e482611fc6565b91506126ef83611fc6565b92508260ff03821115612705576127046126aa565b5b828201905092915050565b600061271b82611cd3565b915061272683611cd3565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561275b5761275a6126aa565b5b828201905092915050565b600061277182611cd3565b915061277c83611cd3565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127b5576127b46126aa565b5b828202905092915050565b7f494e56414c49445f52455645414c5f464545535f414d4f554e54000000000000600082015250565b60006127f6601a83612246565b9150612801826127c0565b602082019050919050565b60006020820190508181036000830152612825816127e9565b9050919050565b600081905092915050565b50565b600061284760008361282c565b915061285282612837565b600082019050919050565b60006128688261283a565b9150819050919050565b7f4641494c45445f544f5f53454e445f52455645414c5f46454553000000000000600082015250565b60006128a8601a83612246565b91506128b382612872565b602082019050919050565b600060208201905081810360008301526128d78161289b565b9050919050565b6128e781612027565b82525050565b600063ffffffff82169050919050565b612906816128ed565b82525050565b600060a08201905061292160008301886128de565b61292e6020830187611c95565b61293b60408301866121dc565b61294860608301856128fd565b61295560808301846128fd565b9695505050505050565b60008151905061296e81611cdd565b92915050565b60006020828403121561298a57612989611cc9565b5b60006129988482850161295f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6129d681611cd3565b82525050565b60006129e883836129cd565b60208301905092915050565b6000602082019050919050565b6000612a0c826129a1565b612a1681856129ac565b9350612a21836129bd565b8060005b83811015612a52578151612a3988826129dc565b9750612a44836129f4565b925050600181019050612a25565b5085935050505092915050565b60006040820190508181036000830152612a798185612a01565b9050612a886020830184611ffd565b9392505050565b7f43414e5f4e4f545f52454e4f554e43455f4f574e455253484950000000000000600082015250565b6000612ac5601a83612246565b9150612ad082612a8f565b602082019050919050565b60006020820190508181036000830152612af481612ab8565b9050919050565b7f414444524553535f43414e5f4e4f545f42455f5a45524f000000000000000000600082015250565b6000612b31601783612246565b9150612b3c82612afb565b602082019050919050565b60006020820190508181036000830152612b6081612b24565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612bc3602683612246565b9150612bce82612b67565b604082019050919050565b60006020820190508181036000830152612bf281612bb6565b9050919050565b6000604082019050612c0e6000830185611ffd565b8181036020830152612c208184612a01565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612c6382611cd3565b9150612c6e83611cd3565b925082612c7e57612c7d612c29565b5b828206905092915050565b6000606082019050612c9e6000830186611f40565b612cab6020830185611f40565b612cb86040830184611ffd565b949350505050565b6000612ccb82611cd3565b9150612cd683611cd3565b925082821015612ce957612ce86126aa565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000819050919050565b6000612d48612d43612d3e846121ce565b612d23565b611cd3565b9050919050565b612d5881612d2d565b82525050565b6000604082019050612d736000830185611f40565b612d806020830184612d4f565b9392505050565b6000606082019050612d9c6000830186611ffd565b612da96020830185612d4f565b612db6604083018461214b565b94935050505056fea26469706673582212201004cf1ceeaded2b51eee0891d9ede85a4a29b936b85a487ecfa884f56ffe3c464736f6c63430008090033000000000000000000000000eb6c5accafd8515c1b9e4c794bdc41532c5543ec00000000000000000000000068f4ba8018216542ac2ab8125166be66304dd71c000000000000000000000000ded8c5159ca3673f543d0f72043e4c655b35b96a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca8b15aa058056a19f94f93564b50b7bf0764f89634f21546869048e173928891e
Deployed Bytecode
0x60806040526004361061019c5760003560e01c80635e5ffbc6116100ec578063944c9efa1161008a578063a3422ee111610064578063a3422ee1146105b9578063a3e56fa8146105e4578063bb2cf9311461060f578063f2fde38b1461064c5761019c565b8063944c9efa1461052657806395564837146105515780639583ddee1461058e5761019c565b806386f128dc116100c657806386f128dc1461047e5780638831e9cf146104955780638da5cb5b146104be5780638e2de4d3146104e95761019c565b80635e5ffbc6146104015780636f6745011461042a578063715018a6146104675761019c565b8063220889761161015957806340b275cf1161013357806340b275cf1461034757806354cfea17146103705780635b2ec42f146103995780635c238494146103d65761019c565b806322088976146102a2578063241ec797146102df578063373d911c1461031c5761019c565b806309c1ba2e146101a15780630bbf2942146101cc5780630ec532e0146101f55780630f16e875146102115780631c4695f41461024e5780631fe543e314610279575b600080fd5b3480156101ad57600080fd5b506101b6610675565b6040516101c39190611ca4565b60405180910390f35b3480156101d857600080fd5b506101f360048036038101906101ee9190611d09565b61068f565b005b61020f600480360381019061020a9190611e8f565b61073b565b005b34801561021d57600080fd5b5061023860048036038101906102339190611d09565b610e7b565b6040516102459190611ef3565b60405180910390f35b34801561025a57600080fd5b50610263610ea5565b6040516102709190611f4f565b60405180910390f35b34801561028557600080fd5b506102a0600480360381019061029b9190611f6a565b610ecb565b005b3480156102ae57600080fd5b506102c960048036038101906102c49190611d09565b610f8b565b6040516102d69190611fe2565b60405180910390f35b3480156102eb57600080fd5b5061030660048036038101906103019190611d09565b610fab565b604051610313919061200c565b60405180910390f35b34801561032857600080fd5b50610331610fc3565b60405161033e9190611f4f565b60405180910390f35b34801561035357600080fd5b5061036e6004803603810190610369919061205d565b610fe9565b005b34801561037c57600080fd5b5061039760048036038101906103929190611d09565b61106f565b005b3480156103a557600080fd5b506103c060048036038101906103bb9190611d09565b6110f5565b6040516103cd9190611ef3565b60405180910390f35b3480156103e257600080fd5b506103eb611115565b6040516103f8919061200c565b60405180910390f35b34801561040d57600080fd5b50610428600480360381019061042391906120b6565b61111b565b005b34801561043657600080fd5b50610451600480360381019061044c91906120b6565b6111b5565b60405161045e919061215a565b60405180910390f35b34801561047357600080fd5b5061047c6111d5565b005b34801561048a57600080fd5b5061049361128c565b005b3480156104a157600080fd5b506104bc60048036038101906104b791906121a1565b611334565b005b3480156104ca57600080fd5b506104d3611464565b6040516104e09190611f4f565b60405180910390f35b3480156104f557600080fd5b50610510600480360381019061050b9190611d09565b61148d565b60405161051d9190611f4f565b60405180910390f35b34801561053257600080fd5b5061053b6114c0565b6040516105489190611ef3565b60405180910390f35b34801561055d57600080fd5b5061057860048036038101906105739190611d09565b6114d3565b60405161058591906121eb565b60405180910390f35b34801561059a57600080fd5b506105a361150b565b6040516105b09190611fe2565b60405180910390f35b3480156105c557600080fd5b506105ce61151e565b6040516105db9190611f4f565b60405180910390f35b3480156105f057600080fd5b506105f9611544565b6040516106069190611f4f565b60405180910390f35b34801561061b57600080fd5b5061063660048036038101906106319190612206565b61156a565b604051610643919061200c565b60405180910390f35b34801561065857600080fd5b50610673600480360381019061066e91906121a1565b61159b565b005b600460149054906101000a900467ffffffffffffffff1681565b610697611693565b73ffffffffffffffffffffffffffffffffffffffff166106b5611464565b73ffffffffffffffffffffffffffffffffffffffff161461070b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610702906122a3565b60405180910390fd5b6000600f600083815260200190815260200160002060006101000a81548160ff021916908360ff16021790555050565b60026001541415610781576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107789061230f565b60405180910390fd5b60026001819055506000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008173ffffffffffffffffffffffffffffffffffffffff1663e985e9c533306040518363ffffffff1660e01b81526004016107ed92919061232f565b60206040518083038186803b15801561080557600080fd5b505afa158015610819573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083d9190612384565b9050600b60009054906101000a900460ff1661088e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610885906123fd565b60405180910390fd5b806108ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108c590612469565b60405180910390fd5b600083511180156108e45750600a60ff16835111155b610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091a906124d5565b60405180910390fd5b60005b8351811015610b8f576000848281518110610944576109436124f5565b5b6020026020010151905060008473ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610989919061200c565b60206040518083038186803b1580156109a157600080fd5b505afa1580156109b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d99190612539565b90503373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610a49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a40906125b2565b60405180910390fd5b6010600083815260200190815260200160002060009054906101000a900460ff1615610aaa576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610aa19061261e565b60405180910390fd5b600c60149054906101000a900460ff1660ff16600f600084815260200190815260200160002060009054906101000a900460ff1660ff1610610b21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b189061268a565b60405180910390fd5b6001600f600084815260200190815260200160002060009054906101000a900460ff16610b4e91906126d9565b600f600084815260200190815260200160002060006101000a81548160ff021916908360ff1602179055505050600181610b889190612710565b9050610926565b506000600e541115610cc15760008351600e54610bac9190612766565b9050803414610bf0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be79061280c565b60405180910390fd5b6000600d60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1634604051610c389061285d565b60006040518083038185875af1925050503d8060008114610c75576040519150601f19603f3d011682016040523d82523d6000602084013e610c7a565b606091505b5050905080610cbe576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cb5906128be565b60405180910390fd5b50505b6000835190506000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635d3b1d30600754600460149054906101000a900467ffffffffffffffff16600860049054906101000a900461ffff16600860009054906101000a900463ffffffff16876040518663ffffffff1660e01b8152600401610d6695949392919061290c565b602060405180830381600087803b158015610d8057600080fd5b505af1158015610d94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db89190612974565b905084600a60008381526020019081526020016000209080519060200190610de1929190611c17565b50336009600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f3f59ad8df24b1c45f7dee2f4fdf974bd333dca793f90068a444c29f7b5b9cc718582604051610e65929190612a5f565b60405180910390a1505050506001808190555050565b60006010600083815260200190815260200160002060009054906101000a900460ff169050919050565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990973ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610f7d57337f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096040517f1cf993f4000000000000000000000000000000000000000000000000000000008152600401610f7492919061232f565b60405180910390fd5b610f87828261169b565b5050565b600f6020528060005260406000206000915054906101000a900460ff1681565b60116020528060005260406000206000915090505481565b600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610ff1611693565b73ffffffffffffffffffffffffffffffffffffffff1661100f611464565b73ffffffffffffffffffffffffffffffffffffffff1614611065576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161105c906122a3565b60405180910390fd5b8060078190555050565b611077611693565b73ffffffffffffffffffffffffffffffffffffffff16611095611464565b73ffffffffffffffffffffffffffffffffffffffff16146110eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110e2906122a3565b60405180910390fd5b80600e8190555050565b60106020528060005260406000206000915054906101000a900460ff1681565b600e5481565b611123611693565b73ffffffffffffffffffffffffffffffffffffffff16611141611464565b73ffffffffffffffffffffffffffffffffffffffff1614611197576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161118e906122a3565b60405180910390fd5b80600c60146101000a81548160ff021916908360ff16021790555050565b60126020528060005260406000206000915054906101000a900460ff1681565b6111dd611693565b73ffffffffffffffffffffffffffffffffffffffff166111fb611464565b73ffffffffffffffffffffffffffffffffffffffff1614611251576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611248906122a3565b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161128390612adb565b60405180910390fd5b611294611693565b73ffffffffffffffffffffffffffffffffffffffff166112b2611464565b73ffffffffffffffffffffffffffffffffffffffff1614611308576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ff906122a3565b60405180910390fd5b600b60009054906101000a900460ff1615600b60006101000a81548160ff021916908315150217905550565b61133c611693565b73ffffffffffffffffffffffffffffffffffffffff1661135a611464565b73ffffffffffffffffffffffffffffffffffffffff16146113b0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a7906122a3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611420576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161141790612b47565b60405180910390fd5b80600d60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60096020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600b60009054906101000a900460ff1681565b600281815481106114e357600080fd5b9060005260206000209060109182820401919006600202915054906101000a900461ffff1681565b600c60149054906101000a900460ff1681565b600b60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600a602052816000526040600020818154811061158657600080fd5b90600052602060002001600091509150505481565b6115a3611693565b73ffffffffffffffffffffffffffffffffffffffff166115c1611464565b73ffffffffffffffffffffffffffffffffffffffff1614611617576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161160e906122a3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611687576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161167e90612bd9565b60405180910390fd5b61169081611b53565b50565b600033905090565b6000600c60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600b60019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060006009600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506000600a600087815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561178057602002820191906000526020600020905b81548152602001906001019080831161176c575b505050505090507fa3cbb93152ed2715170621d47c4aa5e85e0ae4733b16b251877c18360b3ccd6686866040516117b8929190612bf9565b60405180910390a160005b81518160ff161015611b4a576000828260ff16815181106117e7576117e66124f5565b5b602002602001015190506000878360ff1681518110611809576118086124f5565b5b602002602001015190506000600280549050826118269190612c58565b90506010600084815260200190815260200160002060009054906101000a900460ff161561185657505050611b36565b60016010600085815260200190815260200160002060006101000a81548160ff0219169083151502179055508773ffffffffffffffffffffffffffffffffffffffff166323b872dd8761dead866040518463ffffffff1660e01b81526004016118c193929190612c89565b600060405180830381600087803b1580156118db57600080fd5b505af11580156118ef573d6000803e3d6000fd5b50505050600060028281548110611909576119086124f5565b5b90600052602060002090601091828204019190066002029054906101000a900461ffff169050600060018261ffff161015801561194b5750604b8261ffff1611155b15611959576002905061197f565b604c8261ffff161015801561197457506102ee8261ffff1611155b1561197e57600190505b5b600260016002805490506119939190612cc0565b815481106119a4576119a36124f5565b5b90600052602060002090601091828204019190066002029054906101000a900461ffff16600284815481106119dc576119db6124f5565b5b90600052602060002090601091828204019190066002026101000a81548161ffff021916908361ffff1602179055506002805480611a1d57611a1c612cf4565b5b60019003818190600052602060002090601091828204019190066002026101000a81549061ffff021916905590558161ffff1660116000878152602001908152602001600020819055508873ffffffffffffffffffffffffffffffffffffffff16633807aabd89846040518363ffffffff1660e01b8152600401611aa2929190612d5e565b602060405180830381600087803b158015611abc57600080fd5b505af1158015611ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af49190612974565b507f636094fd65795f24380cbd1bb4b2587fd8d385720be2091b4cd9042af8722ecd858383604051611b2893929190612d87565b60405180910390a150505050505b600181611b4391906126d9565b90506117c3565b50505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054828255906000526020600020908101928215611c53579160200282015b82811115611c52578251825591602001919060010190611c37565b5b509050611c609190611c64565b5090565b5b80821115611c7d576000816000905550600101611c65565b5090565b600067ffffffffffffffff82169050919050565b611c9e81611c81565b82525050565b6000602082019050611cb96000830184611c95565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b611ce681611cd3565b8114611cf157600080fd5b50565b600081359050611d0381611cdd565b92915050565b600060208284031215611d1f57611d1e611cc9565b5b6000611d2d84828501611cf4565b91505092915050565b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b611d8482611d3b565b810181811067ffffffffffffffff82111715611da357611da2611d4c565b5b80604052505050565b6000611db6611cbf565b9050611dc28282611d7b565b919050565b600067ffffffffffffffff821115611de257611de1611d4c565b5b602082029050602081019050919050565b600080fd5b6000611e0b611e0684611dc7565b611dac565b90508083825260208201905060208402830185811115611e2e57611e2d611df3565b5b835b81811015611e575780611e438882611cf4565b845260208401935050602081019050611e30565b5050509392505050565b600082601f830112611e7657611e75611d36565b5b8135611e86848260208601611df8565b91505092915050565b600060208284031215611ea557611ea4611cc9565b5b600082013567ffffffffffffffff811115611ec357611ec2611cce565b5b611ecf84828501611e61565b91505092915050565b60008115159050919050565b611eed81611ed8565b82525050565b6000602082019050611f086000830184611ee4565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000611f3982611f0e565b9050919050565b611f4981611f2e565b82525050565b6000602082019050611f646000830184611f40565b92915050565b60008060408385031215611f8157611f80611cc9565b5b6000611f8f85828601611cf4565b925050602083013567ffffffffffffffff811115611fb057611faf611cce565b5b611fbc85828601611e61565b9150509250929050565b600060ff82169050919050565b611fdc81611fc6565b82525050565b6000602082019050611ff76000830184611fd3565b92915050565b61200681611cd3565b82525050565b60006020820190506120216000830184611ffd565b92915050565b6000819050919050565b61203a81612027565b811461204557600080fd5b50565b60008135905061205781612031565b92915050565b60006020828403121561207357612072611cc9565b5b600061208184828501612048565b91505092915050565b61209381611fc6565b811461209e57600080fd5b50565b6000813590506120b08161208a565b92915050565b6000602082840312156120cc576120cb611cc9565b5b60006120da848285016120a1565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60038110612123576121226120e3565b5b50565b600081905061213482612112565b919050565b600061214482612126565b9050919050565b61215481612139565b82525050565b600060208201905061216f600083018461214b565b92915050565b61217e81611f2e565b811461218957600080fd5b50565b60008135905061219b81612175565b92915050565b6000602082840312156121b7576121b6611cc9565b5b60006121c58482850161218c565b91505092915050565b600061ffff82169050919050565b6121e5816121ce565b82525050565b600060208201905061220060008301846121dc565b92915050565b6000806040838503121561221d5761221c611cc9565b5b600061222b85828601611cf4565b925050602061223c85828601611cf4565b9150509250929050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061228d602083612246565b915061229882612257565b602082019050919050565b600060208201905081810360008301526122bc81612280565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006122f9601f83612246565b9150612304826122c3565b602082019050919050565b60006020820190508181036000830152612328816122ec565b9050919050565b60006040820190506123446000830185611f40565b6123516020830184611f40565b9392505050565b61236181611ed8565b811461236c57600080fd5b50565b60008151905061237e81612358565b92915050565b60006020828403121561239a57612399611cc9565b5b60006123a88482850161236f565b91505092915050565b7f52455645414c5f50484153455f4e4f545f494e49544941544544000000000000600082015250565b60006123e7601a83612246565b91506123f2826123b1565b602082019050919050565b60006020820190508181036000830152612416816123da565b9050919050565b7f415050524f56414c5f4e4f545f474956454e0000000000000000000000000000600082015250565b6000612453601283612246565b915061245e8261241d565b602082019050919050565b6000602082019050818103600083015261248281612446565b9050919050565b7f42415443485f53495a455f494e56414c49440000000000000000000000000000600082015250565b60006124bf601283612246565b91506124ca82612489565b602082019050919050565b600060208201905081810360008301526124ee816124b2565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008151905061253381612175565b92915050565b60006020828403121561254f5761254e611cc9565b5b600061255d84828501612524565b91505092915050565b7f4f4e4c595f4f574e45525f43414e5f43414c4c5f544849535f4d4554484f4400600082015250565b600061259c601f83612246565b91506125a782612566565b602082019050919050565b600060208201905081810360008301526125cb8161258f565b9050919050565b7f424f585f414c52454144595f434c41494d454400000000000000000000000000600082015250565b6000612608601383612246565b9150612613826125d2565b602082019050919050565b60006020820190508181036000830152612637816125fb565b9050919050565b7f52414e444f4d5f4e554d4245525f4c494d49545f524541434845440000000000600082015250565b6000612674601b83612246565b915061267f8261263e565b602082019050919050565b600060208201905081810360008301526126a381612667565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006126e482611fc6565b91506126ef83611fc6565b92508260ff03821115612705576127046126aa565b5b828201905092915050565b600061271b82611cd3565b915061272683611cd3565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561275b5761275a6126aa565b5b828201905092915050565b600061277182611cd3565b915061277c83611cd3565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156127b5576127b46126aa565b5b828202905092915050565b7f494e56414c49445f52455645414c5f464545535f414d4f554e54000000000000600082015250565b60006127f6601a83612246565b9150612801826127c0565b602082019050919050565b60006020820190508181036000830152612825816127e9565b9050919050565b600081905092915050565b50565b600061284760008361282c565b915061285282612837565b600082019050919050565b60006128688261283a565b9150819050919050565b7f4641494c45445f544f5f53454e445f52455645414c5f46454553000000000000600082015250565b60006128a8601a83612246565b91506128b382612872565b602082019050919050565b600060208201905081810360008301526128d78161289b565b9050919050565b6128e781612027565b82525050565b600063ffffffff82169050919050565b612906816128ed565b82525050565b600060a08201905061292160008301886128de565b61292e6020830187611c95565b61293b60408301866121dc565b61294860608301856128fd565b61295560808301846128fd565b9695505050505050565b60008151905061296e81611cdd565b92915050565b60006020828403121561298a57612989611cc9565b5b60006129988482850161295f565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6129d681611cd3565b82525050565b60006129e883836129cd565b60208301905092915050565b6000602082019050919050565b6000612a0c826129a1565b612a1681856129ac565b9350612a21836129bd565b8060005b83811015612a52578151612a3988826129dc565b9750612a44836129f4565b925050600181019050612a25565b5085935050505092915050565b60006040820190508181036000830152612a798185612a01565b9050612a886020830184611ffd565b9392505050565b7f43414e5f4e4f545f52454e4f554e43455f4f574e455253484950000000000000600082015250565b6000612ac5601a83612246565b9150612ad082612a8f565b602082019050919050565b60006020820190508181036000830152612af481612ab8565b9050919050565b7f414444524553535f43414e5f4e4f545f42455f5a45524f000000000000000000600082015250565b6000612b31601783612246565b9150612b3c82612afb565b602082019050919050565b60006020820190508181036000830152612b6081612b24565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000612bc3602683612246565b9150612bce82612b67565b604082019050919050565b60006020820190508181036000830152612bf281612bb6565b9050919050565b6000604082019050612c0e6000830185611ffd565b8181036020830152612c208184612a01565b90509392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612c6382611cd3565b9150612c6e83611cd3565b925082612c7e57612c7d612c29565b5b828206905092915050565b6000606082019050612c9e6000830186611f40565b612cab6020830185611f40565b612cb86040830184611ffd565b949350505050565b6000612ccb82611cd3565b9150612cd683611cd3565b925082821015612ce957612ce86126aa565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000819050919050565b6000612d48612d43612d3e846121ce565b612d23565b611cd3565b9050919050565b612d5881612d2d565b82525050565b6000604082019050612d736000830185611f40565b612d806020830184612d4f565b9392505050565b6000606082019050612d9c6000830186611ffd565b612da96020830185612d4f565b612db6604083018461214b565b94935050505056fea26469706673582212201004cf1ceeaded2b51eee0891d9ede85a4a29b936b85a487ecfa884f56ffe3c464736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000eb6c5accafd8515c1b9e4c794bdc41532c5543ec00000000000000000000000068f4ba8018216542ac2ab8125166be66304dd71c000000000000000000000000ded8c5159ca3673f543d0f72043e4c655b35b96a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008d000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca8b15aa058056a19f94f93564b50b7bf0764f89634f21546869048e173928891e
-----Decoded View---------------
Arg [0] : _dgFamilyContractAddress (address): 0xEb6C5acCafD8515c1b9E4c794bDC41532C5543EC
Arg [1] : _glassBoxContractAddress (address): 0x68F4Ba8018216542Ac2Ab8125166Be66304DD71c
Arg [2] : _platformWallet (address): 0xdeD8C5159CA3673f543D0F72043E4c655b35b96A
Arg [3] : _revealFees (uint256): 0
Arg [4] : _subscriptionId (uint64): 141
Arg [5] : _vrfCoordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [6] : _link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [7] : _keyHash (bytes32): 0x8b15aa058056a19f94f93564b50b7bf0764f89634f21546869048e173928891e
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 000000000000000000000000eb6c5accafd8515c1b9e4c794bdc41532c5543ec
Arg [1] : 00000000000000000000000068f4ba8018216542ac2ab8125166be66304dd71c
Arg [2] : 000000000000000000000000ded8c5159ca3673f543d0f72043e4c655b35b96a
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 000000000000000000000000000000000000000000000000000000000000008d
Arg [5] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [6] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [7] : 8b15aa058056a19f94f93564b50b7bf0764f89634f21546869048e173928891e
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.