diff --git a/.gitignore b/.gitignore index 8b94e49..602dbe8 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,9 @@ build # client dist +# docs +docs + # misc .DS_Store *.pem diff --git a/package-lock.json b/package-lock.json index 7c4d8f1..dda5f16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,8 @@ "prettier": "^3.0.3", "ts-jest": "^29.1.1", "tsconfig": "*", - "turbo": "latest" + "turbo": "latest", + "typedoc": "0.25.3" } }, "apps/docs": { @@ -4064,6 +4065,12 @@ "node": ">=8" } }, + "node_modules/ansi-sequence-parser": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", + "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==", + "dev": true + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -10834,6 +10841,12 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -11079,6 +11092,12 @@ "node": ">=12" } }, + "node_modules/lunr": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", + "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", + "dev": true + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -11120,6 +11139,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marked": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", + "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/meow": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.1.tgz", @@ -13102,6 +13133,18 @@ "node": ">=8" } }, + "node_modules/shiki": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz", + "integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==", + "dev": true, + "dependencies": { + "ansi-sequence-parser": "^1.1.0", + "jsonc-parser": "^3.2.0", + "vscode-oniguruma": "^1.7.0", + "vscode-textmate": "^8.0.0" + } + }, "node_modules/side-channel": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", @@ -14525,6 +14568,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/typedoc": { + "version": "0.25.3", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.3.tgz", + "integrity": "sha512-Ow8Bo7uY1Lwy7GTmphRIMEo6IOZ+yYUyrc8n5KXIZg1svpqhZSWgni2ZrDhe+wLosFS8yswowUzljTAV/3jmWw==", + "dev": true, + "dependencies": { + "lunr": "^2.3.9", + "marked": "^4.3.0", + "minimatch": "^9.0.3", + "shiki": "^0.14.1" + }, + "bin": { + "typedoc": "bin/typedoc" + }, + "engines": { + "node": ">= 16" + }, + "peerDependencies": { + "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x" + } + }, "node_modules/typescript": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", @@ -14793,6 +14857,18 @@ } } }, + "node_modules/vscode-oniguruma": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", + "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==", + "dev": true + }, + "node_modules/vscode-textmate": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", + "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==", + "dev": true + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -15112,7 +15188,7 @@ "axios": "^1.5.0", "ipfs-http-client": "59.0.0", "tsup": "7.2.0", - "viem": "^1.10.14" + "viem": "^1.10.9" }, "devDependencies": { "@turbo/gen": "^1.10.12", diff --git a/package.json b/package.json index 050aa00..639a0e5 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,17 @@ { "private": true, + "workspaces": [ + "apps/*", + "packages/*" + ], "scripts": { "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run lint", "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "test": "turbo test" + "test": "turbo test", + "docs": "typedoc", + "docs-all": "npm run docs --workspaces --if-present --verbose" }, "devDependencies": { "@types/jest": "^29.5.8", @@ -14,14 +20,11 @@ "prettier": "^3.0.3", "ts-jest": "^29.1.1", "tsconfig": "*", - "turbo": "latest" + "turbo": "latest", + "typedoc": "0.25.3" }, "name": "talentlayer-sdk", "packageManager": "yarn@1.22.19", - "workspaces": [ - "apps/*", - "packages/*" - ], "dependencies": { "@changesets/cli": "^2.26.2" } diff --git a/packages/client/package.json b/packages/client/package.json index 852880f..5e925dc 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -12,7 +12,8 @@ "prepare": "npm run build", "build": "tsup src/index.ts --format cjs,esm --dts", "dev": "npm run build -- --watch", - "test": "jest --verbose --coverage" + "test": "jest --verbose --coverage", + "docs": "typedoc --out docs" }, "devDependencies": { "@turbo/gen": "^1.10.12", diff --git a/packages/client/src/__mocks__/clientMocks.ts b/packages/client/src/__mocks__/clientMocks.ts index 7c46e7b..56d977c 100644 --- a/packages/client/src/__mocks__/clientMocks.ts +++ b/packages/client/src/__mocks__/clientMocks.ts @@ -1,3 +1,4 @@ +import { polygon } from "viem/chains"; import { getPaymentsByService, getProtocolAndPlatformsFees } from "../escrow/graphql/queries"; import { getPlatformById, getPlatformsByOwner, getProtocolById } from "../platform/graphql/queries"; import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, getProfiles, getUserTotalGains } from "../profile/graphql"; @@ -91,7 +92,7 @@ export class MockGraphQLClient { export class MockViemClient { writeContract = jest.fn(async () => testAddress) - chainId = 137; + chain = polygon; readContract = jest.fn(async () => "randomData") publicClient = { readContract: jest.fn(async () => "randomData"), diff --git a/packages/client/src/__mocks__/fixtures.ts b/packages/client/src/__mocks__/fixtures.ts index db0a6c0..0c8d96b 100644 --- a/packages/client/src/__mocks__/fixtures.ts +++ b/packages/client/src/__mocks__/fixtures.ts @@ -4,6 +4,8 @@ import { IProps } from "../services/types"; export const testAddress = "0xRacoon"; export const testName = 'racoon'; export const testUserId = '2371'; +export const testReferrerUserId = '2374'; +export const testReferralAmount = '4664642374'; export const testChainId = 137; export const testUserResponse = { data: { @@ -13,7 +15,7 @@ export const testUserResponse = { handle: 'talentlayer', rating: '0', delegates: [], - userStats: { numReceivedReviews: '0' }, + userStat: { numReceivedReviews: '0' }, updatedAt: '1680621215', createdAt: '1680608213', description: { @@ -65,7 +67,7 @@ export const mockGraphQlProtocolByIdResponse = { export const testIpfsHash = 'abcd'; export const testCid = testIpfsHash; export const testProfileData = { name: testName, about: testAbout }; -export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStats": { "numReceivedReviews": "0" }, "rating": "0" }] } } +export const testGetProfilesResponse = { "data": { "users": [{ "id": "11962", "address": "0x02289d0ebf8836e6f98af170b88b9f8eb889e2c6", "handle": "racoon", "userStat": { "numReceivedReviews": "0" }, "rating": "0" }] } } export const testUserTotalGainsResponse = { data: { user: { totalGains: [{ "id": "2371-0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "totalGain": "850000000", "token": { "id": "0xracoon", "name": "USD Coin (PoS)", "symbol": "USDC", "decimals": "6" } }] } } } export const testUserPaymentsResponse = { data: { payments: [{ "id": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85-975", "rateToken": { "address": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174", "decimals": "6", "name": "USD Coin (PoS)", "symbol": "USDC" }, "amount": "850000000", "transactionHash": "0x3eb5973863d712ce78dc757af04ca24a81d0376dbce604d002779475428e4a85", "paymentType": "Release", "createdAt": "1699361940", "service": { "id": "75", "cid": "abcd" } }] } } @@ -74,13 +76,13 @@ export const testPlatformResponse = { "data": { "platform": { "id": "1", "addres export const testPlatformResponseWithArbitrator = { "data": { "platform": { "id": "1", "address": "0xracoon", "name": "abcd", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0xracoon", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0xraqcoon", "description": null } } } export const testProposalId = '12-83'; export const testProposalIdWithDifferentRateToken = '12-84'; -export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } }; -export const testProposalResponseWithDifferentRateToken = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": testAddress }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } +export const testProposalResponse = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } }; +export const testProposalResponseWithDifferentRateToken = { "data": { "proposal": { "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": testAddress }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" } } } export const testProtocolAndPlatformResponse = { "data": { "protocols": [{ "protocolEscrowFeeRate": 100 }], "servicePlatform": { "originServiceFeeRate": 0 }, "proposalPlatform": { "originValidatedProposalFeeRate": 0 } } } export const testServiceId = '12'; // rest to 12 before comitting export const testAmount = BigInt('1000'); -export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; -export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } +export const testServiceResponse = { "data": { "service": { "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ", "rateToken": { "id": "0x0000000000000000000000000000000000000000", "address": "0x0000000000000000000000000000000000000000" }, "referralAmount": "0", "referrer": null, "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } } } }; +export const testSearchServicesResponse = { data: { "services": [{ "id": "12", "status": "Finished", "createdAt": "1683203526", "cid": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ","rateToken": { "id": "0x0000000000000000000000000000000000000000", "address": "0x0000000000000000000000000000000000000000" }, "referralAmount": "0", "referrer": null, "transaction": { "id": "2" }, "buyer": { "id": "11207", "handle": "0xrik", "address": "0x946f0711dfea25dc2ab60e6ff0df6dbda32ee6c6", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "seller": { "id": "83", "handle": "maartenvantwout" }, "proposals": [{ "id": "12-83" }], "validatedProposal": [{ "id": "12-83", "rateToken": { "address": "0x0000000000000000000000000000000000000000", "decimals": "18", "name": "Polygon", "symbol": "MATIC" }, "rateAmount": "10000000000000000000" }], "description": { "id": "QmdZhsfn1BhE3shW8TeR4f22MCG7nTWTtT55NkwH6McWfJ-1683203526", "title": "Create a logo", "video_url": null, "about": "Create a logo for our company", "startDate": null, "expectedEndDate": null, "rateAmount": "1000000000000000000", "rateToken": "0x0000000000000000000000000000000000000000", "keywords_raw": "ux/ui,3d graphic design software", "keywords": [] } }] } } export const testServiceDetails = { title: 'test title', about: 'test about', @@ -98,8 +100,8 @@ export const testPlatformDetails = { export const testOwnerAddress = '0xOwnerAddress'; export const testPlatformsByOwnerResponse = { "data": { "platforms": [{ "id": "1", "address": "0x4444444e2f8ccd0e323c959b02a93561b911f9b6", "name": "workx", "createdAt": "1681454011", "updatedAt": "1681454011", "originServiceFeeRate": 0, "originValidatedProposalFeeRate": 0, "servicePostingFee": "0", "proposalPostingFee": "0", "arbitrator": "0x0000000000000000000000000000000000000000", "arbitratorExtraData": "0x00000000", "arbitrationFeeTimeout": "864000", "cid": null, "signer": "0x4444444e2f8ccd0e323c959b02a93561b911f9b6", "description": null }] } } -export const testProposalsByServiceId = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } -export const testProposalsByUser = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStats": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } +export const testProposalsByServiceId = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } +export const testProposalsByUser = { "data": { "proposals": [{ "id": testProposalId, "seller": { "id": "83", "handle": "maartenvantwout", "address": "0x9c8ca52fa6f12fd7b70c6b6e9a2704149af676ea", "cid": "QmWm6biFCf1GwNj7u78ub7c1dgPDHphd285KzmtddYWQu9", "rating": "0", "userStat": { "numReceivedReviews": "0" } }, "platform": { "id": "1" }, "service": { "id": "12", "platform": { "id": "1" } }, "cid": "abcd", "rateToken": { "address": "0x0000000000000000000000000000000000000000" }, "rateAmount": "10000000000000000000", "description": { "about": "I would love to do this job", "video_url": null }, "status": "Validated", "expirationDate": "1685796297" }] } } export const testProposalDetails = { about: 'test about', video_url: 'hello world' } export const testExpirationDate = '123456'; export const testSignature = ''; diff --git a/packages/client/src/__tests__/talentLayerClient.spec.ts b/packages/client/src/__tests__/talentLayerClient.spec.ts index 71bd22e..e1a5c0c 100644 --- a/packages/client/src/__tests__/talentLayerClient.spec.ts +++ b/packages/client/src/__tests__/talentLayerClient.spec.ts @@ -8,7 +8,8 @@ import { Profile } from '../profile'; import { Proposal } from '../proposals'; import { Review } from '../reviews'; import { Service } from '../services'; -import { testPlatformId } from '../__mocks__/fixtures'; +import { CustomChainConfig } from '../types'; +import { testAddress, testPlatformId } from '../__mocks__/fixtures'; jest.mock('axios') @@ -30,8 +31,7 @@ describe('TalentLayerClient', () => { clientSecret: 'abcde', baseUrl: 'www.example.com' } - const viemConfig = {}; - const platformID = testPlatformId; + const signatureApiUrl = 'www.example.com'; client = new TalentLayerClient({ chainId: chainId, @@ -62,4 +62,118 @@ describe('TalentLayerClient', () => { expect(client.review).toBeInstanceOf(Review) }) }) -}); \ No newline at end of file +}); + +describe('TalentLayerClient:customchainConfig', () => { + let client: any; + + beforeEach(() => { + Object.defineProperty(globalThis, 'window', { + }); + const chainDefintion = { + id: 134, + name: 'iExec Sidechain', + network: 'iexec', + nativeCurrency: { + decimals: 18, + name: 'xRLC', + symbol: 'xRLC', + }, + rpcUrls: { + default: { + http: ['https://bellecour.iex.ec'], + }, + public: { + http: ['https://bellecour.iex.ec'], + }, + }, + blockExplorers: { + default: { + name: 'BlockScout', + url: 'https://blockscout-bellecour.iex.ec/', + }, + }, + testnet: false, + }; + + const customChainConfig: CustomChainConfig = { + networkId: 135, + chainDefinition: chainDefintion, + subgraphUrl: 'www.example.com', + contracts: { + talentLayerId: { + address: testAddress, + abi: {} + } + }, + escrowConfig: { + adminFee: '0', + adminWallet: testAddress, + timeoutPayment: 100, + }, + tokens: { + [testAddress]: { + address: testAddress, + symbol: 'RAC', + name: 'RACOON', + decimals: 18, + } + } + } + const ipfsConfig = { + clientId: 'abcd', + clientSecret: 'abcde', + baseUrl: 'www.example.com' + } + + const signatureApiUrl = 'www.example.com'; + client = new TalentLayerClient({ + ipfsConfig: ipfsConfig, + platformId: testPlatformId, + signatureApiUrl: signatureApiUrl, + customChainConfig + }) + + + }) + + + describe('constructor', () => { + it('should be initialised successfully when chain config is passed', () => { + expect(client).toBeDefined() + + }) + + it('should throw error if the sdk is intialised without networkId and customChainConfig', () => { + const ipfsConfig = { + clientId: 'abcd', + clientSecret: 'abcde', + baseUrl: 'www.example.com' + } + + const signatureApiUrl = 'www.example.com'; + expect(() => { + new TalentLayerClient({ + ipfsConfig: ipfsConfig, + platformId: testPlatformId, + signatureApiUrl: signatureApiUrl + }) + }).toThrow('At least one of chainId or customChainConfig need to be provided') + + + }) + }) + + describe('getters', () => { + it('should return all domain specific getters', async () => { + expect(client.platform).toBeInstanceOf(Platform) + expect(client.erc20).toBeInstanceOf(ERC20) + expect(client.proposal).toBeInstanceOf(Proposal) + expect(client.disputes).toBeInstanceOf(Disputes) + expect(client.service).toBeInstanceOf(Service) + expect(client.profile).toBeInstanceOf(Profile) + expect(client.escrow).toBeInstanceOf(Escrow) + expect(client.review).toBeInstanceOf(Review) + }) + }) +}) \ No newline at end of file diff --git a/packages/client/src/blockchain-bindings/erc20.ts b/packages/client/src/blockchain-bindings/erc20.ts index d98b9da..592f50f 100644 --- a/packages/client/src/blockchain-bindings/erc20.ts +++ b/packages/client/src/blockchain-bindings/erc20.ts @@ -2,8 +2,7 @@ import IPFSClient from '../ipfs'; import ERC20Contract from '../contracts/ABI/ERC20.json'; import { ViemClient } from '../viem'; -import { getChainConfig } from '../config'; -import { NetworkEnum } from '../types'; +import { ChainConfig } from '../types'; export interface IERC20 { balanceOf(tokenAddress: `0x${string}`): Promise; @@ -15,20 +14,20 @@ export class ERC20 { ipfsClient: IPFSClient; viemClient: ViemClient; platformID: number; - chainId: NetworkEnum; + chainConfig: ChainConfig; constructor( ipfsClient: IPFSClient, viemClient: ViemClient, platformId: number, - chainId: NetworkEnum, + chainConfig: ChainConfig ) { console.log('SDK: erc20 initialising: '); this.platformID = platformId; this.ipfsClient = ipfsClient; this.viemClient = viemClient; - this.chainId = chainId; + this.chainConfig = chainConfig; } public async balanceOf(tokenAddress: `0x${string}`): Promise { @@ -50,7 +49,7 @@ export class ERC20 { // @ts-ignore const [address] = await this.viemClient.client.getAddresses(); - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts['talentLayerEscrow']; // @ts-ignore @@ -68,7 +67,7 @@ export class ERC20 { // @ts-ignore const [address] = await this.viemClient.client.getAddresses(); - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts['talentLayerEscrow']; // @ts-ignore diff --git a/packages/client/src/contracts/ABI/TalentLayerEscrow.json b/packages/client/src/contracts/ABI/TalentLayerEscrow.json index 1e48db0..66c5dd9 100644 --- a/packages/client/src/contracts/ABI/TalentLayerEscrow.json +++ b/packages/client/src/contracts/ABI/TalentLayerEscrow.json @@ -360,6 +360,12 @@ "internalType": "uint256", "name": "_serviceId", "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_proposalId", + "type": "uint256" } ], "name": "Payment", @@ -391,6 +397,62 @@ "name": "ProtocolEscrowFeeRateUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReferralAmountClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_serviceId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReferralAmountReleased", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -629,6 +691,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_tokenAddress", + "type": "address" + } + ], + "name": "claimReferralBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -701,6 +781,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + } + ], + "name": "getClaimableReferralBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -807,6 +906,21 @@ "internalType": "uint256", "name": "arbitrationFeeTimeout", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalAmount", + "type": "uint256" } ], "internalType": "struct TalentLayerEscrow.Transaction", @@ -1147,8 +1261,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161501262000120600039600081816114df0152818161151f015281816118e80152818161192801526119b701526150126000f3fe6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140e6565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614103565b61070f565b6040516102079190614196565b61023061027936600461442c565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140e6565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614103565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a3565b611366565b3480156102fa57600080fd5b5061029e6103093660046140e6565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140e6565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c5565b61160d565b34801561035a57600080fd5b5061029e610369366004614103565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f1565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140e6565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614103565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614103565b611d08565b61029e61048b366004614103565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614555565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c5565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a5565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140e6565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e5565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140e6565b612733565b34801561058f57600080fd5b5061029e61059e366004614602565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610686919061465e565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108835761088361411c565b60048111156108945761089461411c565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d090614677565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc90614677565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147a7565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614872565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148ac565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148ac565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149d8565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b61411c565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d61411c565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a91906149ff565b604051602081830303815290604052805190602001208660a00151604051602001610f4591906149ff565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b03168152602001600060048111156110735761107361411c565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e061411c565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a61565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff1660048111156114255761142561411c565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f76833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b6d565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bb9565b6116bb5760405162461bcd60e51b81526004016109ac90614bdb565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c20565b92505081905550828160050160008282546117069190614c33565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c20565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a861411c565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d61411c565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f76833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b6d565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7683398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611abe57611abe61411c565b10611adb5760405162461bcd60e51b81526004016109ac90614c72565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d62565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc5919061465e565b90503482600b016000828254611bdb9190614c33565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611c7e906000906001903490614d85565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614daf565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611d6957611d6961411c565b10611d865760405162461bcd60e51b81526004016109ac90614c72565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d62565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e70919061465e565b90503482600a016000828254611e869190614c33565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611f269060009081903490614d85565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614daf565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c46565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc2565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bb9565b6120f05760405162461bcd60e51b81526004016109ac90614bdb565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c46565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddb565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a261411c565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614df8565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614df8565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bb9565b61245b5760405162461bcd60e51b81526004016109ac90614bdb565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c20565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149d8565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddb565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0b565b6129a061ffff861687614e0b565b610101546129b990600160a01b900461ffff1688614e0b565b6129c39190614c33565b6129cd9190614c33565b6129d79190614e22565b6129e19085614c33565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e44565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614df8565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e22565b90506000612d6a600286614e22565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb9181019061465e565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f768339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd61411c565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddb565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149d8565b613158565b60018460018111156130b7576130b761411c565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddb565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149d8565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c661411c565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d79565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed2565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b919061465e565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c20565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f96833981519152600160003460405161350d93929190614d85565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c20565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9683398151915260018034604051612b5793929190614d85565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bb9565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614eee565b6118dc613dc2565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614eee565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613df99092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bb9565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7683398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e08565b60008251118061399a5750805b15611cf157612a458383613e48565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147a7565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0b565b613a749190614e22565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0b565b613aa29190614e22565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0b565b613ad29190614e22565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c33565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c33565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c33565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc602052604090819020805460038201546006830154935192937f2ab2a30b19f7bc6e386d4ee60aa21ed23c127ce9fe26903da97edd54bad0375a93613cb4939288926001600160a01b0390911691889190614f39565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d1e57600080fd5b505af1158015613d32573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6b91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613de95760405162461bcd60e51b81526004016109ac90614eee565b6118dc613df461292a565b6135b7565b60606129e18484600085613f3e565b613e11816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecb91906149ff565b600060405180830381855af49150503d8060008114613f06576040519150601f19603f3d011682016040523d82523d6000602084013e613f0b565b606091505b5091509150613f338282604051806060016040528060278152602001614fb660279139614019565b925050505b92915050565b606082471015613f9f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbb91906149ff565b60006040518083038185875af1925050503d8060008114613ff8576040519150601f19603f3d011682016040523d82523d6000602084013e613ffd565b606091505b509150915061400e87838387614032565b979650505050505050565b606083156140285750816129e4565b6129e483836140a7565b606083156140a157825160000361409a576001600160a01b0385163b61409a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140b75781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614df8565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140f857600080fd5b81356129e4816140d1565b60006020828403121561411557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b600581106141425761414261411c565b9052565b60005b83811015614161578181015183820152602001614149565b50506000910152565b60008151808452614182816020860160208601614146565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141bd60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061422c8185018361ffff169052565b84015190506101406142438482018361ffff169052565b840151905061016061425a8482018361ffff169052565b8401519050610180614276848201836001600160a01b03169052565b84015190506101a061428a84820183614132565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142df61028086018461416a565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614328576143286142ef565b60405290565b60405160c0810167ffffffffffffffff81118282101715614328576143286142ef565b604051610160810167ffffffffffffffff81118282101715614328576143286142ef565b604051601f8201601f1916810167ffffffffffffffff8111828210171561439e5761439e6142ef565b604052919050565b600067ffffffffffffffff8211156143c0576143c06142ef565b50601f01601f191660200190565b60006143e16143dc846143a6565b614375565b90508281528383830111156143f557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261441d57600080fd5b6129e4838335602085016143ce565b6000806000806080858703121561444257600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446857600080fd5b6144748883890161440c565b9350606087013591508082111561448a57600080fd5b506144978782880161440c565b91505092959194509250565b600080604083850312156144b657600080fd5b50508035926020909101359150565b6000806000606084860312156144da57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450457600080fd5b823561450f816140d1565b9150602083013567ffffffffffffffff81111561452b57600080fd5b8301601f8101851361453c57600080fd5b61454b858235602084016143ce565b9150509250929050565b60008060006060848603121561456a57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561458f57600080fd5b61459b8682870161440c565b9150509250925092565b600080604083850312156145b857600080fd5b8235915060208301356145ca816140d1565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145f757600080fd5b81356129e4816145d5565b6000806000806080858703121561461857600080fd5b8435614623816140d1565b93506020850135614633816140d1565b92506040850135614643816140d1565b91506060850135614653816140d1565b939692955090935050565b60006020828403121561467057600080fd5b5051919050565b600181811c9082168061468b57607f821691505b6020821081036146ab57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c257600080fd5b81516146d06143dc826143a6565b8181528460208386010111156146e557600080fd5b6112fb826020830160208701614146565b80516002811061470557600080fd5b919050565b8051614705816140d1565b600060e0828403121561472757600080fd5b61472f614305565b905061473a826146f6565b8152602082015160208201526147526040830161470a565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478557600080fd5b614791848285016146b1565b60a08301525060c082015160c082015292915050565b600080604083850312156147ba57600080fd5b825167ffffffffffffffff808211156147d257600080fd5b9084019060c082870312156147e657600080fd5b6147ee61432e565b8251600581106147fd57600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482757600080fd5b614833888286016146b1565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486557600080fd5b5061454b85828601614715565b6000806040838503121561488557600080fd5b8251614890816140d1565b60208401519092506145ca816140d1565b8051614705816145d5565b6000602082840312156148be57600080fd5b815167ffffffffffffffff808211156148d657600080fd5b9083019061016082860312156148eb57600080fd5b6148f3614351565b8251815260208301518281111561490957600080fd5b614915878286016146b1565b60208301525060408301518281111561492d57600080fd5b614939878286016146b1565b60408301525061494b606084016148a1565b606082015261495c608084016148a1565b608082015260a083015160a082015260c083015160c082015261498160e0840161470a565b60e0820152610100808401518381111561499a57600080fd5b6149a6888287016146b1565b8284015250506101209150818301518282015261014091506149c982840161470a565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a11818460208701614146565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a425750805b601f850160051c820191505b8181101561370c57828155600101614a4e565b815167ffffffffffffffff811115614a7b57614a7b6142ef565b614a8f81614a898454614677565b84614a1b565b602080601f831160018114614ac45760008415614aac5750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af357888601518255948401946001909101908401614ad4565b5085821015614b115787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcb57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3857613f38614c0a565b80820180821115613f3857613f38614c0a565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf281614677565b808552602060018381168015614d0f5760018114614d2957614d57565b60ff1985168884015283151560051b880183019550614d57565b866000528260002060005b85811015614d4f5781548a8201860152908301908401614d34565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce5565b600281106115b1576115b161411c565b60608101614d9285614d75565b848252614d9e84614d75565b602082019390935260400152919050565b60208101614dbc83614d75565b91905290565b8281526040602082015260006129e16040830184614ce5565b600060208284031215614ded57600080fd5b81516129e4816140d1565b6020815260006129e4602083018461416a565b8082028115828204841417613f3857613f38614c0a565b600082614e3f57634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eb681840186614ce5565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce5565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101614f4986614d75565b60208201959095526001600160a01b03939093166040840152606083019190915260809091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b69c2c919d42e5c2c9dd12ae4177551a44b8a442d59efd6afb644fcd58deae8d64736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106101cd5760003560e01c80635a34257a116100f75780638b69fa0a11610095578063e308a09911610064578063e308a09914610523578063eb63612d14610543578063f2fde38b14610563578063f8c8765e1461058357600080fd5b80638b69fa0a146104a55780638da5cb5b146104c55780639dcc5daf146104e3578063ddd5e1b21461050357600080fd5b8063715018a6116100d1578063715018a6146104555780637b44cdb51461046a5780637e69b7b01461047d5780638456cb591461049057600080fd5b80635a34257a146103f45780635c975abb1461042a5780636e72b4521461044257600080fd5b80633659cfe61161016f5780633f4ba83a1161013e5780633f4ba83a1461036e5780634f1ef2861461038357806352d1902d14610396578063572b6c05146103ab57600080fd5b80633659cfe6146102ee5780633751d89c1461030e5780633a1121cd1461032e5780633ab4a6a41461034e57600080fd5b806315734fe7116101ab57806315734fe71461026b57806326d006681461027e5780632fbe3b03146102a0578063311a6c56146102ce57600080fd5b806306d6e63f146101d25780630a1a47d6146102105780630fa683d31461023e575b600080fd5b3480156101de57600080fd5b50610101546101f3906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021c57600080fd5b5061023061022b3660046140e6565b6105a3565b604051908152602001610207565b34801561024a57600080fd5b5061025e610259366004614103565b61070f565b6040516102079190614196565b61023061027936600461442c565b610a5d565b34801561028a57600080fd5b5061029e6102993660046140e6565b611303565b005b3480156102ac57600080fd5b506102306102bb366004614103565b6101026020526000908152604090205481565b3480156102da57600080fd5b5061029e6102e93660046144a3565b611366565b3480156102fa57600080fd5b5061029e6103093660046140e6565b6114d5565b34801561031a57600080fd5b5061029e6103293660046140e6565b6115b4565b34801561033a57600080fd5b5061029e6103493660046144c5565b61160d565b34801561035a57600080fd5b5061029e610369366004614103565b611716565b34801561037a57600080fd5b5061029e6118cc565b61029e6103913660046144f1565b6118de565b3480156103a257600080fd5b506102306119aa565b3480156103b757600080fd5b506103e46103c63660046140e6565b6001600160a01b031660009081526065602052604090205460ff1690565b6040519015158152602001610207565b34801561040057600080fd5b506101015461041790600160a01b900461ffff1681565b60405161ffff9091168152602001610207565b34801561043657600080fd5b5060665460ff166103e4565b61029e610450366004614103565b611a5d565b34801561046157600080fd5b5061029e611cf6565b61029e610478366004614103565b611d08565b61029e61048b366004614103565b611f82565b34801561049c57600080fd5b5061029e61203a565b3480156104b157600080fd5b5061029e6104c0366004614555565b61204a565b3480156104d157600080fd5b506033546001600160a01b03166101f3565b3480156104ef57600080fd5b5061029e6104fe3660046144c5565b6123ad565b34801561050f57600080fd5b5061029e61051e3660046145a5565b61249b565b34801561052f57600080fd5b5061029e61053e3660046140e6565b6126af565b34801561054f57600080fd5b5061029e61055e3660046145e5565b6126da565b34801561056f57600080fd5b5061029e61057e3660046140e6565b612733565b34801561058f57600080fd5b5061029e61059e366004614602565b6127a9565b6000806105ae61292a565b9050806001600160a01b03166105cc6033546001600160a01b031690565b6001600160a01b0316036106165750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa158015610662573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610686919061465e565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b1580156106cb57600080fd5b505afa1580156106df573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b6107a96040805161026081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081525090565b600082815260fc602090815260408083208151610260810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108835761088361411c565b60048111156108945761089461411c565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d820180546108d090614677565b80601f01602080910402602001604051908101604052809291908181526020018280546108fc90614677565b80156109495780601f1061091e57610100808354040283529160200191610949565b820191906000526020600020905b81548152906001019060200180831161092c57829003601f168201915b50505050508152602001600e8201548152505090506109686101035490565b8151106109b55760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b60006109bf61292a565b905081602001516001600160a01b0316816001600160a01b031614806109fa575081604001516001600160a01b0316816001600160a01b0316145b610a565760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b60648201526084016109ac565b5092915050565b6000610a67612939565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610abc573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ae491908101906147a7565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190614872565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610bc2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610bea91908101906148ac565b9050600084608001518660a0015103610c035781610c80565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610c3b9160040190815260200190565b600060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c8091908101906148ac565b90506000610c9b86606001518460600151846080015161297f565b60408701519091506001600160a01b0316610cf957803414610cf45760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b610d3c565b3415610d3c5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016109ac565b846001600160a01b0316610d4e61292a565b6001600160a01b031614610d745760405162461bcd60e51b81526004016109ac906149d8565b8a866020015114610dbf5760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b60448201526064016109ac565b428660c001511015610e065760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b60448201526064016109ac565b600087516004811115610e1b57610e1b61411c565b14610e685760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e00000000000000000060448201526064016109ac565b600086516001811115610e7d57610e7d61411c565b14610eca5760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e67000000000060448201526064016109ac565b8951602e14610f095760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b88604051602001610f1a91906149ff565b604051602081830303815290604052805190602001208660a00151604051602001610f4591906149ff565b6040516020818303038152906040528051906020012014610fa85760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e6765640000000060448201526064016109ac565b6000610fb46101035490565b9050604051806102600160405280828152602001876001600160a01b03168152602001866001600160a01b0316815260200188604001516001600160a01b0316815260200188606001518152602001600081526020018e81526020018d815260200161010160149054906101000a900461ffff1661ffff168152602001856060015161ffff168152602001846080015161ffff1681526020018560e001516001600160a01b03168152602001600060048111156110735761107361411c565b8152600060208083018290526040808401839052606080850184905242608080870191909152610100808c015160a080890191909152610120808e015160c0998a01528a885260fc87529685902089518155958901516001870180546001600160a01b039283166001600160a01b031991821617909155958a01516002880180549183169188169190911790559389015160038701805491861691909616179094559087015160048086019190915592870151600585015594860151600684015560e086015160078401559385015160088301805494870151610140880151610160890151909716600160301b026601000000000000600160d01b031961ffff9889166401000000000216640100000000600160d01b0319928916620100000263ffffffff19909816989094169790971795909517949094161793909317808355610180850151919391929160ff60d01b1990911690600160d01b9084908111156111e0576111e061411c565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906112269082614a61565b5061024082015181600e015590505061124461010380546001019055565b60fe546040516353eaf57560e11b8152600481018f9052602481018e9052604481018390526001600160a01b039091169063a7d5eaea90606401600060405180830381600087803b15801561129857600080fd5b505af11580156112ac573d6000803e3d6000fd5b5050505060408701516001600160a01b0316156112dd5760408701516112dd906001600160a01b03168730856129eb565b6112f188602001518860200151838e612a4b565b9750505050505050505b949350505050565b61130b612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600061137061292a565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b90920416146114035760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b60648201526084016109ac565b60036008820154600160d01b900460ff1660048111156114255761142561411c565b146114805760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b60648201526084016109ac565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e75622276866040516114bc91815260200190565b60405180910390a36114ce8285612bdf565b5050505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361151d5760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611566600080516020614f76833981519152546001600160a01b031690565b6001600160a01b03161461158c5760405162461bcd60e51b81526004016109ac90614b6d565b61159581612e69565b604080516000808252602082019092526115b191839190612e71565b50565b6115bc612b66565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee6910161135b565b611615612939565b60ff5483906001600160a01b0316632fa117e58261163161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561167b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169f9190614bb9565b6116bb5760405162461bcd60e51b81526004016109ac90614bdb565b6116c88360008685612fdc565b600083815260fc60205260408120600481018054919285926116eb908490614c20565b92505081905550828160050160008282546117069190614c33565b909155506114ce905084846132c7565b600081815260fc60205260409020600e810154600c8201546117389042614c20565b10156117865760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f7420706173736564207965740060448201526064016109ac565b60016008820154600160d01b900460ff1660048111156117a8576117a861411c565b0361182b57600a8101541561181c57600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611812576040519150601f19603f3d011682016040523d82523d6000602084013e611817565b606091505b505050505b611827826002612bdf565b5050565b60026008820154600160d01b900460ff16600481111561184d5761184d61411c565b0361182757600b810154156118c157600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d80600081146118b7576040519150601f19603f3d011682016040523d82523d6000602084013e6118bc565b606091505b505050505b611827826001612bdf565b6118d4612b66565b6118dc61330c565b565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036119265760405162461bcd60e51b81526004016109ac90614b21565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031661196f600080516020614f76833981519152546001600160a01b031690565b6001600160a01b0316146119955760405162461bcd60e51b81526004016109ac90614b6d565b61199e82612e69565b61182782826001612e71565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611a4a5760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016109ac565b50600080516020614f7683398151915290565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611a9c5760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611abe57611abe61411c565b10611adb5760405162461bcd60e51b81526004016109ac90614c72565b60028101546001600160a01b0316611af161292a565b6001600160a01b031614611b475760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d757374206265207468652072656365697665720060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611b8490600d860190600401614d62565b602060405180830381865afa158015611ba1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc5919061465e565b90503482600b016000828254611bdb9190614c33565b9091555050600b8201548114611c525760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611c7e906000906001903490614d85565b60405180910390a28082600a01541015611ce75760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600090614daf565b60405180910390a2505050565b611cf18382613364565b505050565b611cfe612b66565b6118dc60006135b7565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611d475760405162461bcd60e51b81526004016109ac90614c46565b60036008820154600160d01b900460ff166004811115611d6957611d6961411c565b10611d865760405162461bcd60e51b81526004016109ac90614c72565b60018101546001600160a01b0316611d9c61292a565b6001600160a01b031614611df25760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e64657200000060448201526064016109ac565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611e2f90600d860190600401614d62565b602060405180830381865afa158015611e4c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e70919061465e565b90503482600a016000828254611e869190614c33565b9091555050600a8201548114611efb5760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b60648201526084016109ac565b42600c8301556040518390600080516020614f9683398151915290611f269060009081903490614d85565b60405180910390a28082600b01541015611ce75760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611cda90600190614daf565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611fc15760405162461bcd60e51b81526004016109ac90614c46565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916120049190600d870190600401614dc2565b6000604051808303818588803b15801561201d57600080fd5b505af1158015612031573d6000803e3d6000fd5b50505050505050565b612042612b66565b6118dc613609565b60ff5483906001600160a01b0316632fa117e58261206661292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156120b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d49190614bb9565b6120f05760405162461bcd60e51b81526004016109ac90614bdb565b8151602e1461212f5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b60448201526064016109ac565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661216e5760405162461bcd60e51b81526004016109ac90614c46565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121dc9190614ddb565b60018301549091506001600160a01b038083169116148061220c575060028201546001600160a01b038281169116145b612280576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c65676174657360648201526084016109ac565b60046008830154600160d01b900460ff1660048111156122a2576122a261411c565b106123095760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b60648201526084016109ac565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c876040516123649190614df8565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd628660405161239d9190614df8565b60405180910390a3505050505050565b6123b5612939565b60ff5483906001600160a01b0316632fa117e5826123d161292a565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561241b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061243f9190614bb9565b61245b5760405162461bcd60e51b81526004016109ac90614bdb565b6124688360018685612fdc565b600083815260fc602052604081206004810180549192859261248b908490614c20565b909155506114ce90508484613647565b6124a3612939565b60006124ad61292a565b6001600160a01b03166124c86033546001600160a01b031690565b6001600160a01b0316036125075782156124f45760405162461bcd60e51b81526004016109ac906149d8565b50610101546001600160a01b03166125d4565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561254b57600080fd5b505afa15801561255f573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa1580156125ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125d19190614ddb565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806126375760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b60448201526064016109ac565b600084815260fd602090815260408083206001600160a01b03871684529091528120556126658284836136ad565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910160405180910390a250505050565b6126b7612b66565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b6126e2612b66565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd71309060200161135b565b61273b612b66565b6001600160a01b0381166127a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016109ac565b6115b1816135b7565b600054610100900460ff16158080156127c95750600054600160ff909116105b806127e35750303b1580156127e3575060005460ff166001145b6128465760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016109ac565b6000805460ff191660011790558015612869576000805461ff0019166101001790555b612871613787565b6128796137b6565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff805487841690831617905561010080548684169083161790556101018054928516929091169190911790556128d461010380546001019055565b6128de60646126da565b80156114ce576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b60006129346137dd565b905090565b60665460ff16156118dc5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016109ac565b600061271061299261ffff841686614e0b565b6129a061ffff861687614e0b565b610101546129b990600160a01b900461ffff1688614e0b565b6129c39190614c33565b6129cd9190614c33565b6129d79190614e22565b6129e19085614c33565b90505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612a45908590613816565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612b1f9d9c9b9a99989796959493929190614e44565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612b579190614df8565b60405180910390a25050505050565b612b6e61292a565b6001600160a01b0316612b896033546001600160a01b031690565b6001600160a01b0316146118dc5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ac565b600082815260fc602052604090206002821115612c2f5760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b60448201526064016109ac565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b0394851694909316929091906000198701612cea576040516001600160a01b038616908390600081818185875af1925050503d8060008114612cd3576040519150601f19603f3d011682016040523d82523d6000602084013e612cd8565b606091505b505050612ce58884613647565b612e25565b6001198701612d4e576040516001600160a01b038516908290600081818185875af1925050503d8060008114612d3c576040519150601f19603f3d011682016040523d82523d6000602084013e612d41565b606091505b505050612ce588846132c7565b6000612d5b600284614e22565b90506000612d6a600286614e22565b9050612d768a82613647565b612d808a826132c7565b6040516001600160a01b038816908390600081818185875af1925050503d8060008114612dc9576040519150601f19603f3d011682016040523d82523d6000602084013e612dce565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d8060008114612e1a576040519150601f19603f3d011682016040523d82523d6000602084013e612e1f565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f388604051612e5791815260200190565b60405180910390a25050505050505050565b6115b1612b66565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615612ea457611cf1836138e8565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612efe575060408051601f3d908101601f19168201909252612efb9181019061465e565b60015b612f615760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016109ac565b600080516020614f768339815191528114612fd05760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016109ac565b50611cf1838383613984565b600084815260fc6020526040812090846001811115612ffd57612ffd61411c565b036130a35760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561304b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306f9190614ddb565b60018201546001600160a01b0390811691161461309e5760405162461bcd60e51b81526004016109ac906149d8565b613158565b60018460018111156130b7576130b761411c565b036131585760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa158015613105573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131299190614ddb565b60028201546001600160a01b039081169116146131585760405162461bcd60e51b81526004016109ac906149d8565b610103548154106131a45760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064016109ac565b60006008820154600160d01b900460ff1660048111156131c6576131c661411c565b146132215760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b60648201526084016109ac565b818160040154101561326a5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b60448201526064016109ac565b6127108210158061328a57506127108210801561328a5750806004015482145b6114ce5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016109ac565b6132d182826139a9565b600082815260fc6020526040902060028101546003820154613300916001600160a01b039081169116846136ad565b611cf183600084613c57565b613314613d79565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61334761292a565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e19085906133c890600290600d880190600401614ed2565b60206040518083038185885af11580156133e6573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061340b919061465e565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156135175760008383600a015461348a9190614c20565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146134e1576040519150601f19603f3d011682016040523d82523d6000602084013e6134e6565b606091505b50505084600080516020614f96833981519152600160003460405161350d93929190614d85565b60405180910390a2505b8282600b01541115612a455760008383600b01546135359190614c20565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461358c576040519150601f19603f3d011682016040523d82523d6000602084013e613591565b606091505b50505084600080516020614f9683398151915260018034604051612b5793929190614d85565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b613611612939565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861334761292a565b600082815260fc60205260408120600881015490919061367d90849061ffff62010000820481169164010000000090041661297f565b600183015460038401549192506136a1916001600160a01b039182169116836136ad565b612a4584600185613c57565b6001600160a01b038216600003613714576040516001600160a01b038416908290600081818185875af1925050503d8060008114613707576040519150601f19603f3d011682016040523d82523d6000602084013e61370c565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613763573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a459190614bb9565b600054610100900460ff166137ae5760405162461bcd60e51b81526004016109ac90614eee565b6118dc613dc2565b600054610100900460ff166118dc5760405162461bcd60e51b81526004016109ac90614eee565b6000601436108015906137ff57503360009081526065602052604090205460ff165b15613811575060131936013560601c90565b503390565b600061386b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613df99092919063ffffffff16565b805190915015611cf157808060200190518101906138899190614bb9565b611cf15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016109ac565b6001600160a01b0381163b6139555760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016109ac565b600080516020614f7683398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b61398d83613e08565b60008251118061399a5750805b15611cf157612a458383613e48565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613a16573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613a3e91908101906147a7565b60a0820151608082015160088701549395509193509160009061271090613a6a90899061ffff16614e0b565b613a749190614e22565b600887015490915060009061271090613a98908a9062010000900461ffff16614e0b565b613aa29190614e22565b600888015490915060009061271090613ac8908b90640100000000900461ffff16614e0b565b613ad29190614e22565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613b22908490614c33565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613b5d908490614c33565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613b98908490614c33565b90915550506003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc602052604090819020805460038201546006830154935192937f2ab2a30b19f7bc6e386d4ee60aa21ed23c127ce9fe26903da97edd54bad0375a93613cb4939288926001600160a01b0390911691889190614f39565b60405180910390a18060040154600003612a455760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b158015613d1e57600080fd5b505af1158015613d32573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b78160060154604051613d6b91815260200190565b60405180910390a150505050565b60665460ff166118dc5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016109ac565b600054610100900460ff16613de95760405162461bcd60e51b81526004016109ac90614eee565b6118dc613df461292a565b6135b7565b60606129e18484600085613f3e565b613e11816138e8565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b613eb05760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016109ac565b600080846001600160a01b031684604051613ecb91906149ff565b600060405180830381855af49150503d8060008114613f06576040519150601f19603f3d011682016040523d82523d6000602084013e613f0b565b606091505b5091509150613f338282604051806060016040528060278152602001614fb660279139614019565b925050505b92915050565b606082471015613f9f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016109ac565b600080866001600160a01b03168587604051613fbb91906149ff565b60006040518083038185875af1925050503d8060008114613ff8576040519150601f19603f3d011682016040523d82523d6000602084013e613ffd565b606091505b509150915061400e87838387614032565b979650505050505050565b606083156140285750816129e4565b6129e483836140a7565b606083156140a157825160000361409a576001600160a01b0385163b61409a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016109ac565b50816112fb565b6112fb83835b8151156140b75781518083602001fd5b8060405162461bcd60e51b81526004016109ac9190614df8565b6001600160a01b03811681146115b157600080fd5b6000602082840312156140f857600080fd5b81356129e4816140d1565b60006020828403121561411557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b600581106141425761414261411c565b9052565b60005b83811015614161578181015183820152602001614149565b50506000910152565b60008151808452614182816020860160208601614146565b601f01601f19169290920160200192915050565b6020815281516020820152600060208301516141bd60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061422c8185018361ffff169052565b84015190506101406142438482018361ffff169052565b840151905061016061425a8482018361ffff169052565b8401519050610180614276848201836001600160a01b03169052565b84015190506101a061428a84820183614132565b8401516101c0848101919091528401516101e0808501919091528401516102008085019190915284015161022080850191909152840151610260610240808601829052919250906142df61028086018461416a565b9501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b60405160e0810167ffffffffffffffff81118282101715614328576143286142ef565b60405290565b60405160c0810167ffffffffffffffff81118282101715614328576143286142ef565b604051610160810167ffffffffffffffff81118282101715614328576143286142ef565b604051601f8201601f1916810167ffffffffffffffff8111828210171561439e5761439e6142ef565b604052919050565b600067ffffffffffffffff8211156143c0576143c06142ef565b50601f01601f191660200190565b60006143e16143dc846143a6565b614375565b90508281528383830111156143f557600080fd5b828260208301376000602084830101529392505050565b600082601f83011261441d57600080fd5b6129e4838335602085016143ce565b6000806000806080858703121561444257600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561446857600080fd5b6144748883890161440c565b9350606087013591508082111561448a57600080fd5b506144978782880161440c565b91505092959194509250565b600080604083850312156144b657600080fd5b50508035926020909101359150565b6000806000606084860312156144da57600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561450457600080fd5b823561450f816140d1565b9150602083013567ffffffffffffffff81111561452b57600080fd5b8301601f8101851361453c57600080fd5b61454b858235602084016143ce565b9150509250929050565b60008060006060848603121561456a57600080fd5b8335925060208401359150604084013567ffffffffffffffff81111561458f57600080fd5b61459b8682870161440c565b9150509250925092565b600080604083850312156145b857600080fd5b8235915060208301356145ca816140d1565b809150509250929050565b61ffff811681146115b157600080fd5b6000602082840312156145f757600080fd5b81356129e4816145d5565b6000806000806080858703121561461857600080fd5b8435614623816140d1565b93506020850135614633816140d1565b92506040850135614643816140d1565b91506060850135614653816140d1565b939692955090935050565b60006020828403121561467057600080fd5b5051919050565b600181811c9082168061468b57607f821691505b6020821081036146ab57634e487b7160e01b600052602260045260246000fd5b50919050565b600082601f8301126146c257600080fd5b81516146d06143dc826143a6565b8181528460208386010111156146e557600080fd5b6112fb826020830160208701614146565b80516002811061470557600080fd5b919050565b8051614705816140d1565b600060e0828403121561472757600080fd5b61472f614305565b905061473a826146f6565b8152602082015160208201526147526040830161470a565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff81111561478557600080fd5b614791848285016146b1565b60a08301525060c082015160c082015292915050565b600080604083850312156147ba57600080fd5b825167ffffffffffffffff808211156147d257600080fd5b9084019060c082870312156147e657600080fd5b6147ee61432e565b8251600581106147fd57600080fd5b80825250602083015160208201526040830151604082015260608301518281111561482757600080fd5b614833888286016146b1565b6060830152506080830151608082015260a083015160a082015280945050602085015191508082111561486557600080fd5b5061454b85828601614715565b6000806040838503121561488557600080fd5b8251614890816140d1565b60208401519092506145ca816140d1565b8051614705816145d5565b6000602082840312156148be57600080fd5b815167ffffffffffffffff808211156148d657600080fd5b9083019061016082860312156148eb57600080fd5b6148f3614351565b8251815260208301518281111561490957600080fd5b614915878286016146b1565b60208301525060408301518281111561492d57600080fd5b614939878286016146b1565b60408301525061494b606084016148a1565b606082015261495c608084016148a1565b608082015260a083015160a082015260c083015160c082015261498160e0840161470a565b60e0820152610100808401518381111561499a57600080fd5b6149a6888287016146b1565b8284015250506101209150818301518282015261014091506149c982840161470a565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614a11818460208701614146565b9190910192915050565b601f821115611cf157600081815260208120601f850160051c81016020861015614a425750805b601f850160051c820191505b8181101561370c57828155600101614a4e565b815167ffffffffffffffff811115614a7b57614a7b6142ef565b614a8f81614a898454614677565b84614a1b565b602080601f831160018114614ac45760008415614aac5750858301515b600019600386901b1c1916600185901b17855561370c565b600085815260208120601f198616915b82811015614af357888601518255948401946001909101908401614ad4565b5085821015614b115787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b600060208284031215614bcb57600080fd5b815180151581146129e457600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b81810381811115613f3857613f38614c0a565b80820180821115613f3857613f38614c0a565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b60008154614cf281614677565b808552602060018381168015614d0f5760018114614d2957614d57565b60ff1985168884015283151560051b880183019550614d57565b866000528260002060005b85811015614d4f5781548a8201860152908301908401614d34565b890184019650505b505050505092915050565b6020815260006129e46020830184614ce5565b600281106115b1576115b161411c565b60608101614d9285614d75565b848252614d9e84614d75565b602082019390935260400152919050565b60208101614dbc83614d75565b91905290565b8281526040602082015260006129e16040830184614ce5565b600060208284031215614ded57600080fd5b81516129e4816140d1565b6020815260006129e4602083018461416a565b8082028115828204841417613f3857613f38614c0a565b600082614e3f57634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a080610160840152614eb681840186614ce5565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006129e16040830184614ce5565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b85815260a08101614f4986614d75565b60208201959095526001600160a01b03939093166040840152606083019190915260809091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b69c2c919d42e5c2c9dd12ae4177551a44b8a442d59efd6afb644fcd58deae8d64736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161552c62000120600039600081816116390152818161167901528181611a4201528181611a820152611b11015261552c6000f3fe6080604052600436106101e35760003560e01c80635c0cd1e2116101025780638da5cb5b11610095578063e308a09911610064578063e308a09914610579578063eb63612d14610599578063f2fde38b146105b9578063f8c8765e146105d957600080fd5b80638da5cb5b146104fb5780639dcc5daf14610519578063d299630f14610539578063ddd5e1b21461055957600080fd5b80637b44cdb5116100d15780637b44cdb5146104a05780637e69b7b0146104b35780638456cb59146104c65780638b69fa0a146104db57600080fd5b80635c0cd1e2146104405780635c975abb146104605780636e72b45214610478578063715018a61461048b57600080fd5b80633751d89c1161017a5780634f1ef286116101495780634f1ef2861461039957806352d1902d146103ac578063572b6c05146103c15780635a34257a1461040a57600080fd5b80633751d89c146103245780633a1121cd146103445780633ab4a6a4146103645780633f4ba83a1461038457600080fd5b806326d00668116101b657806326d00668146102945780632fbe3b03146102b6578063311a6c56146102e45780633659cfe61461030457600080fd5b806306d6e63f146101e85780630a1a47d6146102265780630fa683d31461025457806315734fe714610281575b600080fd5b3480156101f457600080fd5b5061010154610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b506102466102413660046145c6565b6105f9565b60405190815260200161021d565b34801561026057600080fd5b5061027461026f3660046145e3565b610765565b60405161021d9190614676565b61024661028f366004614913565b610ae6565b3480156102a057600080fd5b506102b46102af3660046145c6565b61145d565b005b3480156102c257600080fd5b506102466102d13660046145e3565b6101026020526000908152604090205481565b3480156102f057600080fd5b506102b46102ff36600461498a565b6114c0565b34801561031057600080fd5b506102b461031f3660046145c6565b61162f565b34801561033057600080fd5b506102b461033f3660046145c6565b61170e565b34801561035057600080fd5b506102b461035f3660046149ac565b611767565b34801561037057600080fd5b506102b461037f3660046145e3565b611870565b34801561039057600080fd5b506102b4611a26565b6102b46103a73660046149d8565b611a38565b3480156103b857600080fd5b50610246611b04565b3480156103cd57600080fd5b506103fa6103dc3660046145c6565b6001600160a01b031660009081526065602052604090205460ff1690565b604051901515815260200161021d565b34801561041657600080fd5b506101015461042d90600160a01b900461ffff1681565b60405161ffff909116815260200161021d565b34801561044c57600080fd5b5061024661045b3660046145c6565b611bb7565b34801561046c57600080fd5b5060665460ff166103fa565b6102b46104863660046145e3565b611c6a565b34801561049757600080fd5b506102b4611f03565b6102b46104ae3660046145e3565b611f15565b6102b46104c13660046145e3565b61218f565b3480156104d257600080fd5b506102b4612247565b3480156104e757600080fd5b506102b46104f6366004614a3c565b612257565b34801561050757600080fd5b506033546001600160a01b0316610209565b34801561052557600080fd5b506102b46105343660046149ac565b6125ba565b34801561054557600080fd5b506102b4610554366004614a8c565b6126a8565b34801561056557600080fd5b506102b4610574366004614a8c565b61285a565b34801561058557600080fd5b506102b46105943660046145c6565b612a65565b3480156105a557600080fd5b506102b46105b4366004614acc565b612a90565b3480156105c557600080fd5b506102b46105d43660046145c6565b612ae9565b3480156105e557600080fd5b506102b46105f4366004614ae9565b612b5f565b600080610604612ce0565b9050806001600160a01b03166106226033546001600160a01b031690565b6001600160a01b03160361066c5750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa1580156106b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106dc9190614b45565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b15801561072157600080fd5b505afa158015610735573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b610814604080516102c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081526020016000815260200160008152602001600081525090565b600082815260fc6020908152604080832081516102c0810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108ee576108ee6145fc565b60048111156108ff576108ff6145fc565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201805461093b90614b5e565b80601f016020809104026020016040519081016040528092919081815260200182805461096790614b5e565b80156109b45780601f10610989576101008083540402835291602001916109b4565b820191906000526020600020905b81548152906001019060200180831161099757829003601f168201915b50505050508152602001600e8201548152602001600f82015481526020016010820154815260200160118201548152505090506109f16101035490565b815110610a3e5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b6000610a48612ce0565b905081602001516001600160a01b0316816001600160a01b03161480610a83575081604001516001600160a01b0316816001600160a01b0316145b610adf5760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b6064820152608401610a35565b5092915050565b6000610af0612cef565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b6d9190810190614ca8565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190614d87565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610c4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c739190810190614dc1565b9050600084608001518660a0015103610c8c5781610d09565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610cc49160040190815260200190565b600060405180830381865afa158015610ce1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d099190810190614dc1565b905060008560e00151600014610d23578660e00151610d26565b60005b90506000610d4287606001518560600151856080015185612d35565b60c08901519091506001600160a01b0316610da057803414610d9b5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b610de3565b3415610de35760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b856001600160a01b0316610df5612ce0565b6001600160a01b031614610e1b5760405162461bcd60e51b8152600401610a3590614eed565b8b876020015114610e665760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b6044820152606401610a35565b428760c001511015610ead5760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b6044820152606401610a35565b600088516004811115610ec257610ec26145fc565b14610f0f5760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e0000000000000000006044820152606401610a35565b600087516001811115610f2457610f246145fc565b14610f715760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e6700000000006044820152606401610a35565b8a51602e14610fb05760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b89604051602001610fc19190614f14565b604051602081830303815290604052805190602001208760a00151604051602001610fec9190614f14565b604051602081830303815290604052805190602001201461104f5760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e676564000000006044820152606401610a35565b600061105b6101035490565b9050604051806102c00160405280828152602001886001600160a01b03168152602001876001600160a01b031681526020018a60c001516001600160a01b0316815260200189606001518152602001600081526020018f81526020018e815260200161010160149054906101000a900461ffff1661ffff168152602001866060015161ffff168152602001856080015161ffff1681526020018660e001516001600160a01b031681526020016000600481111561111a5761111a6145fc565b8152602001600081526020016000815260200160008152602001428152602001866101000151815260200186610120015181526020018960e0015181526020018a60e001518152602001896060015181525060fc60008381526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080160006101000a81548161ffff021916908361ffff1602179055506101208201518160080160026101000a81548161ffff021916908361ffff1602179055506101408201518160080160046101000a81548161ffff021916908361ffff1602179055506101608201518160080160066101000a8154816001600160a01b0302191690836001600160a01b0316021790555061018082015181600801601a6101000a81548160ff021916908360048111156112fd576112fd6145fc565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906113439082614f76565b50610240820151600e820155610260820151600f82015561028082015160108201556102a09091015160119091015561138161010380546001019055565b60fe60009054906101000a90046001600160a01b03166001600160a01b031663a7d5eaea8f8f846040518463ffffffff1660e01b81526004016113d7939291909283526020830191909152604082015260600190565b600060405180830381600087803b1580156113f157600080fd5b505af1158015611405573d6000803e3d6000fd5b5050505060c08901516001600160a01b0316156114365760c0890151611436906001600160a01b0316883085612dae565b61144a89602001518960200151838f612e0e565b985050505050505050505b949350505050565b611465612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b60006114ca612ce0565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b909204161461155d5760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b6064820152608401610a35565b60036008820154600160d01b900460ff16600481111561157f5761157f6145fc565b146115da5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b6064820152608401610a35565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222768660405161161691815260200190565b60405180910390a36116288285612fa2565b5050505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116775760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116c0600080516020615490833981519152546001600160a01b031690565b6001600160a01b0316146116e65760405162461bcd60e51b8152600401610a3590615082565b6116ef8161322c565b6040805160008082526020820190925261170b91839190613234565b50565b611716612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee691016114b5565b61176f612cef565b60ff5483906001600160a01b0316632fa117e58261178b612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156117d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f991906150ce565b6118155760405162461bcd60e51b8152600401610a35906150f0565b611822836000868561339f565b600083815260fc6020526040812060048101805491928592611845908490615135565b92505081905550828160050160008282546118609190615148565b909155506116289050848461368a565b600081815260fc60205260409020600e810154600c8201546118929042615135565b10156118e05760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f742070617373656420796574006044820152606401610a35565b60016008820154600160d01b900460ff166004811115611902576119026145fc565b0361198557600a8101541561197657600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d806000811461196c576040519150601f19603f3d011682016040523d82523d6000602084013e611971565b606091505b505050505b611981826002612fa2565b5050565b60026008820154600160d01b900460ff1660048111156119a7576119a76145fc565b0361198157600b81015415611a1b57600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611a11576040519150601f19603f3d011682016040523d82523d6000602084013e611a16565b606091505b505050505b611981826001612fa2565b611a2e612f29565b611a366136cf565b565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003611a805760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611ac9600080516020615490833981519152546001600160a01b031690565b6001600160a01b031614611aef5760405162461bcd60e51b8152600401610a3590615082565b611af88261322c565b61198182826001613234565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ba45760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610a35565b5060008051602061549083398151915290565b60ff5460009081906001600160a01b0316631847c06b611bd5612ce0565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3d9190614b45565b6000908152610104602090815260408083206001600160a01b039096168352949052929092205492915050565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611ca95760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611ccb57611ccb6145fc565b10611ce85760405162461bcd60e51b8152600401610a3590615187565b60028101546001600160a01b0316611cfe612ce0565b6001600160a01b031614611d545760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d75737420626520746865207265636569766572006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611d9190600d860190600401615277565b602060405180830381865afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd29190614b45565b90503482600b016000828254611de89190615148565b9091555050600b8201548114611e5f5760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290611e8b90600090600190349061529a565b60405180910390a28082600a01541015611ef45760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906000906152c4565b60405180910390a2505050565b611efe8382613727565b505050565b611f0b612f29565b611a36600061397a565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611f545760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611f7657611f766145fc565b10611f935760405162461bcd60e51b8152600401610a3590615187565b60018101546001600160a01b0316611fa9612ce0565b6001600160a01b031614611fff5760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e6465720000006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea99061203c90600d860190600401615277565b602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190614b45565b90503482600a0160008282546120939190615148565b9091555050600a82015481146121085760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290612133906000908190349061529a565b60405180910390a28082600b01541015611ef45760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906001906152c4565b600081815260fc602052604090206008810154600160301b90046001600160a01b03166121ce5760405162461bcd60e51b8152600401610a359061515b565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916122119190600d8701906004016152d7565b6000604051808303818588803b15801561222a57600080fd5b505af115801561223e573d6000803e3d6000fd5b50505050505050565b61224f612f29565b611a366139cc565b60ff5483906001600160a01b0316632fa117e582612273612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e191906150ce565b6122fd5760405162461bcd60e51b8152600401610a35906150f0565b8151602e1461233c5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661237b5760405162461bcd60e51b8152600401610a359061515b565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156123c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e991906152f0565b60018301549091506001600160a01b0380831691161480612419575060028201546001600160a01b038281169116145b61248d576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c6567617465736064820152608401610a35565b60046008830154600160d01b900460ff1660048111156124af576124af6145fc565b106125165760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b6064820152608401610a35565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c87604051612571919061530d565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd62866040516125aa919061530d565b60405180910390a3505050505050565b6125c2612cef565b60ff5483906001600160a01b0316632fa117e5826125de612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015612628573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264c91906150ce565b6126685760405162461bcd60e51b8152600401610a35906150f0565b612675836001868561339f565b600083815260fc6020526040812060048101805491928592612698908490615135565b9091555061162890508484613a0a565b6126b0612cef565b60ff5460405162f577a560e81b8152600481018490526000916001600160a01b03169063f577a5009060240160006040518083038186803b1580156126f457600080fd5b505afa158015612708573d6000803e3d6000fd5b505060ff546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa158015612755573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277991906152f0565b6000848152610104602090815260408083206001600160a01b0387168452909152902054909150806127e05760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b6000848152610104602090815260408083206001600160a01b038716845290915281205561280f828483613aa7565b60408051858152602081018390526001600160a01b038516917ff7c8cc6f18f75645957886fe11026a08ce70f199ba95cbb33ddd4064aa85203991015b60405180910390a250505050565b612862612cef565b600061286c612ce0565b6001600160a01b03166128876033546001600160a01b031690565b6001600160a01b0316036128c65782156128b35760405162461bcd60e51b8152600401610a3590614eed565b50610101546001600160a01b0316612993565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561290a57600080fd5b505afa15801561291e573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa15801561296c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299091906152f0565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806129f65760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b600084815260fd602090815260408083206001600160a01b0387168452909152812055612a24828483613aa7565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910161284c565b612a6d612f29565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b612a98612f29565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd7130906020016114b5565b612af1612f29565b6001600160a01b038116612b565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a35565b61170b8161397a565b600054610100900460ff1615808015612b7f5750600054600160ff909116105b80612b995750303b158015612b99575060005460ff166001145b612bfc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a35565b6000805460ff191660011790558015612c1f576000805461ff0019166101001790555b612c27613b81565b612c2f613bb0565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff80548784169083161790556101008054868416908316179055610101805492851692909116919091179055612c8a61010380546001019055565b612c946064612a90565b8015611628576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000612cea613bd7565b905090565b60665460ff1615611a365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a35565b600080612d428387615148565b9050612710612d5561ffff861683615320565b612d6361ffff881684615320565b61010154612d7c90600160a01b900461ffff1685615320565b612d869190615148565b612d909190615148565b612d9a9190615337565b612da49082615148565b9695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612e08908590613c10565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612ee29d9c9b9a99989796959493929190615359565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612f1a919061530d565b60405180910390a25050505050565b612f31612ce0565b6001600160a01b0316612f4c6033546001600160a01b031690565b6001600160a01b031614611a365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a35565b600082815260fc602052604090206002821115612ff25760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b6044820152606401610a35565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b03948516949093169290919060001987016130ad576040516001600160a01b038616908390600081818185875af1925050503d8060008114613096576040519150601f19603f3d011682016040523d82523d6000602084013e61309b565b606091505b5050506130a88884613a0a565b6131e8565b6001198701613111576040516001600160a01b038516908290600081818185875af1925050503d80600081146130ff576040519150601f19603f3d011682016040523d82523d6000602084013e613104565b606091505b5050506130a8888461368a565b600061311e600284615337565b9050600061312d600286615337565b90506131398a82613a0a565b6131438a8261368a565b6040516001600160a01b038816908390600081818185875af1925050503d806000811461318c576040519150601f19603f3d011682016040523d82523d6000602084013e613191565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d80600081146131dd576040519150601f19603f3d011682016040523d82523d6000602084013e6131e2565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f38860405161321a91815260200190565b60405180910390a25050505050505050565b61170b612f29565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561326757611efe83613ce2565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156132c1575060408051601f3d908101601f191682019092526132be91810190614b45565b60015b6133245760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610a35565b60008051602061549083398151915281146133935760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610a35565b50611efe838383613d7e565b600084815260fc60205260408120908460018111156133c0576133c06145fc565b036134665760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906152f0565b60018201546001600160a01b039081169116146134615760405162461bcd60e51b8152600401610a3590614eed565b61351b565b600184600181111561347a5761347a6145fc565b0361351b5760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec91906152f0565b60028201546001600160a01b0390811691161461351b5760405162461bcd60e51b8152600401610a3590614eed565b610103548154106135675760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b6044820152606401610a35565b60006008820154600160d01b900460ff166004811115613589576135896145fc565b146135e45760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b6064820152608401610a35565b818160040154101561362d5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401610a35565b6127108210158061364d57506127108210801561364d5750806004015482145b6116285760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610a35565b6136948282613da3565b600082815260fc60205260409020600281015460038201546136c3916001600160a01b03908116911684613aa7565b611efe83600084614129565b6136d761424f565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61370a612ce0565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e190859061378b90600290600d8801906004016153e7565b60206040518083038185885af11580156137a9573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906137ce9190614b45565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156138da5760008383600a015461384d9190615135565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146138a4576040519150601f19603f3d011682016040523d82523d6000602084013e6138a9565b606091505b505050846000805160206154b083398151915260016000346040516138d09392919061529a565b60405180910390a2505b8282600b01541115612e085760008383600b01546138f89190615135565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461394f576040519150601f19603f3d011682016040523d82523d6000602084013e613954565b606091505b505050846000805160206154b083398151915260018034604051612f1a9392919061529a565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6139d4612cef565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861370a612ce0565b600082815260fc6020526040812060118101549091908103613a2d576000613a4b565b60118201546010830154613a419085615320565b613a4b9190615337565b6008830154909150600090613a7790859061ffff62010000820481169164010000000090041685612d35565b60018401546003850154919250613a9b916001600160a01b03918216911683613aa7565b61162885600186614129565b6001600160a01b038216600003613b0e576040516001600160a01b038416908290600081818185875af1925050503d8060008114613b01576040519150601f19603f3d011682016040523d82523d6000602084013e613b06565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0891906150ce565b600054610100900460ff16613ba85760405162461bcd60e51b8152600401610a3590615403565b611a36614298565b600054610100900460ff16611a365760405162461bcd60e51b8152600401610a3590615403565b600060143610801590613bf957503360009081526065602052604090205460ff165b15613c0b575060131936013560601c90565b503390565b6000613c65826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166142cf9092919063ffffffff16565b805190915015611efe5780806020019051810190613c8391906150ce565b611efe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a35565b6001600160a01b0381163b613d4f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610a35565b60008051602061549083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613d87836142e8565b600082511180613d945750805b15611efe57612e088383614328565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e389190810190614ca8565b60a0820151608082015160088701549395509193509160009061271090613e6490899061ffff16615320565b613e6e9190615337565b600887015490915060009061271090613e92908a9062010000900461ffff16615320565b613e9c9190615337565b600888015490915060009061271090613ec2908b90640100000000900461ffff16615320565b613ecc9190615337565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613f1c908490615148565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613f57908490615148565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613f92908490615148565b9091555050600f88015415801590613fad5750601088015415155b1561406f576000886011015489601001548b613fc99190615320565b613fd39190615337565b600f8a015460009081526101046020908152604080832060038e01546001600160a01b03168452909152812080549293508392909190614014908490615148565b90915550506003890154600f8a015460068b015460408051918252602082018590526001600160a01b03909316927f7be8d1d5def43ba21be043f0d166965a1c479d40c0fac41f9a9fe18f1a9a2863910160405180910390a3505b6003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f2279461418a949389936001600160a01b0390911692899261544e565b60405180910390a18060040154600003612e085760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b1580156141f457600080fd5b505af1158015614208573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b7816006015460405161424191815260200190565b60405180910390a150505050565b60665460ff16611a365760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a35565b600054610100900460ff166142bf5760405162461bcd60e51b8152600401610a3590615403565b611a366142ca612ce0565b61397a565b60606142de848460008561441e565b90505b9392505050565b6142f181613ce2565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6143905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610a35565b600080846001600160a01b0316846040516143ab9190614f14565b600060405180830381855af49150503d80600081146143e6576040519150601f19603f3d011682016040523d82523d6000602084013e6143eb565b606091505b509150915061441382826040518060600160405280602781526020016154d0602791396144f9565b925050505b92915050565b60608247101561447f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a35565b600080866001600160a01b0316858760405161449b9190614f14565b60006040518083038185875af1925050503d80600081146144d8576040519150601f19603f3d011682016040523d82523d6000602084013e6144dd565b606091505b50915091506144ee87838387614512565b979650505050505050565b606083156145085750816142e1565b6142e18383614587565b6060831561458157825160000361457a576001600160a01b0385163b61457a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a35565b5081611455565b61145583835b8151156145975781518083602001fd5b8060405162461bcd60e51b8152600401610a35919061530d565b6001600160a01b038116811461170b57600080fd5b6000602082840312156145d857600080fd5b81356142e1816145b1565b6000602082840312156145f557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60058110614622576146226145fc565b9052565b60005b83811015614641578181015183820152602001614629565b50506000910152565b60008151808452614662816020860160208601614626565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015161469d60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061470c8185018361ffff169052565b84015190506101406147238482018361ffff169052565b840151905061016061473a8482018361ffff169052565b8401519050610180614756848201836001600160a01b03169052565b84015190506101a061476a84820183614612565b8401516101c0848101919091528401516101e08085019190915284015161020080850191909152840151610220808501919091528401516102c0610240808601829052919250906147bf6102e086018461464a565b9086015161026086810191909152860151610280808701919091528601516102a080870191909152909501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715614832576148326147f8565b60405290565b604051610160810167ffffffffffffffff81118282101715614832576148326147f8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614885576148856147f8565b604052919050565b600067ffffffffffffffff8211156148a7576148a76147f8565b50601f01601f191660200190565b60006148c86148c38461488d565b61485c565b90508281528383830111156148dc57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261490457600080fd5b6142e1838335602085016148b5565b6000806000806080858703121561492957600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561494f57600080fd5b61495b888389016148f3565b9350606087013591508082111561497157600080fd5b5061497e878288016148f3565b91505092959194509250565b6000806040838503121561499d57600080fd5b50508035926020909101359150565b6000806000606084860312156149c157600080fd5b505081359360208301359350604090920135919050565b600080604083850312156149eb57600080fd5b82356149f6816145b1565b9150602083013567ffffffffffffffff811115614a1257600080fd5b8301601f81018513614a2357600080fd5b614a32858235602084016148b5565b9150509250929050565b600080600060608486031215614a5157600080fd5b8335925060208401359150604084013567ffffffffffffffff811115614a7657600080fd5b614a82868287016148f3565b9150509250925092565b60008060408385031215614a9f57600080fd5b823591506020830135614ab1816145b1565b809150509250929050565b61ffff8116811461170b57600080fd5b600060208284031215614ade57600080fd5b81356142e181614abc565b60008060008060808587031215614aff57600080fd5b8435614b0a816145b1565b93506020850135614b1a816145b1565b92506040850135614b2a816145b1565b91506060850135614b3a816145b1565b939692955090935050565b600060208284031215614b5757600080fd5b5051919050565b600181811c90821680614b7257607f821691505b602082108103614b9257634e487b7160e01b600052602260045260246000fd5b50919050565b805160058110614ba757600080fd5b919050565b600082601f830112614bbd57600080fd5b8151614bcb6148c38261488d565b818152846020838601011115614be057600080fd5b611455826020830160208701614626565b8051614ba7816145b1565b805160028110614ba757600080fd5b60006101008284031215614c1e57600080fd5b614c2661480e565b9050614c3182614bfc565b815260208201516020820152614c4960408301614bf1565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff811115614c7c57600080fd5b614c8884828501614bac565b60a08301525060c082015160c082015260e082015160e082015292915050565b60008060408385031215614cbb57600080fd5b825167ffffffffffffffff80821115614cd357600080fd5b908401906101008287031215614ce857600080fd5b614cf061480e565b614cf983614b98565b81526020830151602082015260408301516040820152606083015182811115614d2157600080fd5b614d2d88828601614bac565b6060830152506080830151608082015260a083015160a0820152614d5360c08401614bf1565b60c082015260e083015160e0820152809450506020850151915080821115614d7a57600080fd5b50614a3285828601614c0b565b60008060408385031215614d9a57600080fd5b8251614da5816145b1565b6020840151909250614ab1816145b1565b8051614ba781614abc565b600060208284031215614dd357600080fd5b815167ffffffffffffffff80821115614deb57600080fd5b908301906101608286031215614e0057600080fd5b614e08614838565b82518152602083015182811115614e1e57600080fd5b614e2a87828601614bac565b602083015250604083015182811115614e4257600080fd5b614e4e87828601614bac565b604083015250614e6060608401614db6565b6060820152614e7160808401614db6565b608082015260a083015160a082015260c083015160c0820152614e9660e08401614bf1565b60e08201526101008084015183811115614eaf57600080fd5b614ebb88828701614bac565b828401525050610120915081830151828201526101409150614ede828401614bf1565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614f26818460208701614626565b9190910192915050565b601f821115611efe57600081815260208120601f850160051c81016020861015614f575750805b601f850160051c820191505b81811015613b0657828155600101614f63565b815167ffffffffffffffff811115614f9057614f906147f8565b614fa481614f9e8454614b5e565b84614f30565b602080601f831160018114614fd95760008415614fc15750858301515b600019600386901b1c1916600185901b178555613b06565b600085815260208120601f198616915b8281101561500857888601518255948401946001909101908401614fe9565b50858210156150265787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6000602082840312156150e057600080fd5b815180151581146142e157600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156144185761441861511f565b808201808211156144185761441861511f565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b6000815461520781614b5e565b808552602060018381168015615224576001811461523e5761526c565b60ff1985168884015283151560051b88018301955061526c565b866000528260002060005b858110156152645781548a8201860152908301908401615249565b890184019650505b505050505092915050565b6020815260006142e160208301846151fa565b6002811061170b5761170b6145fc565b606081016152a78561528a565b8482526152b38461528a565b602082019390935260400152919050565b602081016152d18361528a565b91905290565b8281526040602082015260006142de60408301846151fa565b60006020828403121561530257600080fd5b81516142e1816145b1565b6020815260006142e1602083018461464a565b80820281158282048414176144185761441861511f565b60008261535457634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a0806101608401526153cb818401866151fa565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006142de60408301846151fa565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c0810161545e8761528a565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220ebf0fdcd633b2aa3cc45cd6844284d1b24a3cd790fcd8ef9ad87dff0726b7fe764736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106101e35760003560e01c80635c0cd1e2116101025780638da5cb5b11610095578063e308a09911610064578063e308a09914610579578063eb63612d14610599578063f2fde38b146105b9578063f8c8765e146105d957600080fd5b80638da5cb5b146104fb5780639dcc5daf14610519578063d299630f14610539578063ddd5e1b21461055957600080fd5b80637b44cdb5116100d15780637b44cdb5146104a05780637e69b7b0146104b35780638456cb59146104c65780638b69fa0a146104db57600080fd5b80635c0cd1e2146104405780635c975abb146104605780636e72b45214610478578063715018a61461048b57600080fd5b80633751d89c1161017a5780634f1ef286116101495780634f1ef2861461039957806352d1902d146103ac578063572b6c05146103c15780635a34257a1461040a57600080fd5b80633751d89c146103245780633a1121cd146103445780633ab4a6a4146103645780633f4ba83a1461038457600080fd5b806326d00668116101b657806326d00668146102945780632fbe3b03146102b6578063311a6c56146102e45780633659cfe61461030457600080fd5b806306d6e63f146101e85780630a1a47d6146102265780630fa683d31461025457806315734fe714610281575b600080fd5b3480156101f457600080fd5b5061010154610209906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561023257600080fd5b506102466102413660046145c6565b6105f9565b60405190815260200161021d565b34801561026057600080fd5b5061027461026f3660046145e3565b610765565b60405161021d9190614676565b61024661028f366004614913565b610ae6565b3480156102a057600080fd5b506102b46102af3660046145c6565b61145d565b005b3480156102c257600080fd5b506102466102d13660046145e3565b6101026020526000908152604090205481565b3480156102f057600080fd5b506102b46102ff36600461498a565b6114c0565b34801561031057600080fd5b506102b461031f3660046145c6565b61162f565b34801561033057600080fd5b506102b461033f3660046145c6565b61170e565b34801561035057600080fd5b506102b461035f3660046149ac565b611767565b34801561037057600080fd5b506102b461037f3660046145e3565b611870565b34801561039057600080fd5b506102b4611a26565b6102b46103a73660046149d8565b611a38565b3480156103b857600080fd5b50610246611b04565b3480156103cd57600080fd5b506103fa6103dc3660046145c6565b6001600160a01b031660009081526065602052604090205460ff1690565b604051901515815260200161021d565b34801561041657600080fd5b506101015461042d90600160a01b900461ffff1681565b60405161ffff909116815260200161021d565b34801561044c57600080fd5b5061024661045b3660046145c6565b611bb7565b34801561046c57600080fd5b5060665460ff166103fa565b6102b46104863660046145e3565b611c6a565b34801561049757600080fd5b506102b4611f03565b6102b46104ae3660046145e3565b611f15565b6102b46104c13660046145e3565b61218f565b3480156104d257600080fd5b506102b4612247565b3480156104e757600080fd5b506102b46104f6366004614a3c565b612257565b34801561050757600080fd5b506033546001600160a01b0316610209565b34801561052557600080fd5b506102b46105343660046149ac565b6125ba565b34801561054557600080fd5b506102b4610554366004614a8c565b6126a8565b34801561056557600080fd5b506102b4610574366004614a8c565b61285a565b34801561058557600080fd5b506102b46105943660046145c6565b612a65565b3480156105a557600080fd5b506102b46105b4366004614acc565b612a90565b3480156105c557600080fd5b506102b46105d43660046145c6565b612ae9565b3480156105e557600080fd5b506102b46105f4366004614ae9565b612b5f565b600080610604612ce0565b9050806001600160a01b03166106226033546001600160a01b031690565b6001600160a01b03160361066c5750506001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc602052604090205490565b61010054604051631847c06b60e01b81526001600160a01b0383811660048301526000921690631847c06b90602401602060405180830381865afa1580156106b8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106dc9190614b45565b6101005460405162f577a560e81b8152600481018390529192506001600160a01b03169063f577a5009060240160006040518083038186803b15801561072157600080fd5b505afa158015610735573d6000803e3d6000fd5b50505060009182525060fd602090815260408083206001600160a01b039096168352949052929092205492915050565b610814604080516102c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e0810182905261010081018290526101208101829052610140810182905261016081018290529061018082019081526020016000815260200160008152602001600081526020016000815260200160608152602001600081526020016000815260200160008152602001600081525090565b600082815260fc6020908152604080832081516102c0810183528154815260018201546001600160a01b039081169482019490945260028201548416928101929092526003810154831660608301526004808201546080840152600582015460a0840152600682015460c0840152600782015460e0840152600882015461ffff8082166101008601526201000082048116610120860152640100000000820416610140850152600160301b810490941661016084015291929091610180840191600160d01b900460ff16908111156108ee576108ee6145fc565b60048111156108ff576108ff6145fc565b815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201805461093b90614b5e565b80601f016020809104026020016040519081016040528092919081815260200182805461096790614b5e565b80156109b45780601f10610989576101008083540402835291602001916109b4565b820191906000526020600020905b81548152906001019060200180831161099757829003601f168201915b50505050508152602001600e8201548152602001600f82015481526020016010820154815260200160118201548152505090506109f16101035490565b815110610a3e5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b60448201526064015b60405180910390fd5b6000610a48612ce0565b905081602001516001600160a01b0316816001600160a01b03161480610a83575081604001516001600160a01b0316816001600160a01b0316145b610adf5760405162461bcd60e51b815260206004820152602760248201527f596f7520617265206e6f742072656c6174656420746f2074686973207472616e60448201526639b0b1ba34b7b760c91b6064820152608401610a35565b5092915050565b6000610af0612cef565b60fe5460405163353bb87f60e21b8152600481018790526024810186905260009182916001600160a01b039091169063d4eee1fc90604401600060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b6d9190810190614ca8565b60ff54602083810151908301516040516303ef723760e61b81526004810192909252602482015292945090925060009182916001600160a01b03169063fbdc8dc0906044016040805180830381865afa158015610bce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bf29190614d87565b6101005460a0870151604051630b7a459360e31b815260048101919091529294509092506000916001600160a01b0390911690635bd22c9890602401600060405180830381865afa158015610c4b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610c739190810190614dc1565b9050600084608001518660a0015103610c8c5781610d09565b610100546080860151604051630b7a459360e31b81526001600160a01b0390921691635bd22c9891610cc49160040190815260200190565b600060405180830381865afa158015610ce1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d099190810190614dc1565b905060008560e00151600014610d23578660e00151610d26565b60005b90506000610d4287606001518560600151856080015185612d35565b60c08901519091506001600160a01b0316610da057803414610d9b5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b610de3565b3415610de35760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b6044820152606401610a35565b856001600160a01b0316610df5612ce0565b6001600160a01b031614610e1b5760405162461bcd60e51b8152600401610a3590614eed565b8b876020015114610e665760405162461bcd60e51b8152602060048201526015602482015274125b98dbdc9c9958dd081c1c9bdc1bdcd85b081251605a1b6044820152606401610a35565b428760c001511015610ead5760405162461bcd60e51b815260206004820152601060248201526f141c9bdc1bdcd85b08195e1c1a5c995960821b6044820152606401610a35565b600088516004811115610ec257610ec26145fc565b14610f0f5760405162461bcd60e51b815260206004820152601760248201527f5365727669636520737461747573206e6f74206f70656e0000000000000000006044820152606401610a35565b600087516001811115610f2457610f246145fc565b14610f715760405162461bcd60e51b815260206004820152601b60248201527f50726f706f73616c20737461747573206e6f742070656e64696e6700000000006044820152606401610a35565b8a51602e14610fb05760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b89604051602001610fc19190614f14565b604051602081830303815290604052805190602001208760a00151604051602001610fec9190614f14565b604051602081830303815290604052805190602001201461104f5760405162461bcd60e51b815260206004820152601c60248201527f50726f706f73616c206461746155726920686173206368616e676564000000006044820152606401610a35565b600061105b6101035490565b9050604051806102c00160405280828152602001886001600160a01b03168152602001876001600160a01b031681526020018a60c001516001600160a01b0316815260200189606001518152602001600081526020018f81526020018e815260200161010160149054906101000a900461ffff1661ffff168152602001866060015161ffff168152602001856080015161ffff1681526020018660e001516001600160a01b031681526020016000600481111561111a5761111a6145fc565b8152602001600081526020016000815260200160008152602001428152602001866101000151815260200186610120015181526020018960e0015181526020018a60e001518152602001896060015181525060fc60008381526020019081526020016000206000820151816000015560208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060608201518160030160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506080820151816004015560a0820151816005015560c0820151816006015560e082015181600701556101008201518160080160006101000a81548161ffff021916908361ffff1602179055506101208201518160080160026101000a81548161ffff021916908361ffff1602179055506101408201518160080160046101000a81548161ffff021916908361ffff1602179055506101608201518160080160066101000a8154816001600160a01b0302191690836001600160a01b0316021790555061018082015181600801601a6101000a81548160ff021916908360048111156112fd576112fd6145fc565b02179055506101a082015160098201556101c0820151600a8201556101e0820151600b820155610200820151600c820155610220820151600d8201906113439082614f76565b50610240820151600e820155610260820151600f82015561028082015160108201556102a09091015160119091015561138161010380546001019055565b60fe60009054906101000a90046001600160a01b03166001600160a01b031663a7d5eaea8f8f846040518463ffffffff1660e01b81526004016113d7939291909283526020830191909152604082015260600190565b600060405180830381600087803b1580156113f157600080fd5b505af1158015611405573d6000803e3d6000fd5b5050505060c08901516001600160a01b0316156114365760c0890151611436906001600160a01b0316883085612dae565b61144a89602001518960200151838f612e0e565b985050505050505050505b949350505050565b611465612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b60006114ca612ce0565b6000848152610102602090815260408083205480845260fc909252909120600881015492935090916001600160a01b03808516600160301b909204161461155d5760405162461bcd60e51b815260206004820152602160248201527f5468652063616c6c6572206d757374206265207468652061726269747261746f6044820152603960f91b6064820152608401610a35565b60036008820154600160d01b900460ff16600481111561157f5761157f6145fc565b146115da5760405162461bcd60e51b815260206004820152602560248201527f54686520646973707574652068617320616c7265616479206265656e207265736044820152641bdb1d995960da1b6064820152608401610a35565b84836001600160a01b03167f394027a5fa6e098a1191094d1719d6929b9abc535fcc0c8f448d6a4e756222768660405161161691815260200190565b60405180910390a36116288285612fa2565b5050505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036116775760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166116c0600080516020615490833981519152546001600160a01b031690565b6001600160a01b0316146116e65760405162461bcd60e51b8152600401610a3590615082565b6116ef8161322c565b6040805160008082526020820190925261170b91839190613234565b50565b611716612f29565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee691016114b5565b61176f612cef565b60ff5483906001600160a01b0316632fa117e58261178b612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156117d5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117f991906150ce565b6118155760405162461bcd60e51b8152600401610a35906150f0565b611822836000868561339f565b600083815260fc6020526040812060048101805491928592611845908490615135565b92505081905550828160050160008282546118609190615148565b909155506116289050848461368a565b600081815260fc60205260409020600e810154600c8201546118929042615135565b10156118e05760405162461bcd60e51b815260206004820152601f60248201527f54696d656f75742074696d6520686173206e6f742070617373656420796574006044820152606401610a35565b60016008820154600160d01b900460ff166004811115611902576119026145fc565b0361198557600a8101541561197657600a81018054600091829055600183015460405191926001600160a01b0390911691839181818185875af1925050503d806000811461196c576040519150601f19603f3d011682016040523d82523d6000602084013e611971565b606091505b505050505b611981826002612fa2565b5050565b60026008820154600160d01b900460ff1660048111156119a7576119a76145fc565b0361198157600b81015415611a1b57600b81018054600091829055600283015460405191926001600160a01b0390911691839181818185875af1925050503d8060008114611a11576040519150601f19603f3d011682016040523d82523d6000602084013e611a16565b606091505b505050505b611981826001612fa2565b611a2e612f29565b611a366136cf565b565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003611a805760405162461bcd60e51b8152600401610a3590615036565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611ac9600080516020615490833981519152546001600160a01b031690565b6001600160a01b031614611aef5760405162461bcd60e51b8152600401610a3590615082565b611af88261322c565b61198182826001613234565b6000306001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ba45760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608401610a35565b5060008051602061549083398151915290565b60ff5460009081906001600160a01b0316631847c06b611bd5612ce0565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015611c19573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3d9190614b45565b6000908152610104602090815260408083206001600160a01b039096168352949052929092205492915050565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611ca95760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611ccb57611ccb6145fc565b10611ce85760405162461bcd60e51b8152600401610a3590615187565b60028101546001600160a01b0316611cfe612ce0565b6001600160a01b031614611d545760405162461bcd60e51b815260206004820152601f60248201527f5468652063616c6c6572206d75737420626520746865207265636569766572006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea990611d9190600d860190600401615277565b602060405180830381865afa158015611dae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd29190614b45565b90503482600b016000828254611de89190615148565b9091555050600b8201548114611e5f5760405162461bcd60e51b815260206004820152603660248201527f54686520726563656976657220666565206d75737420626520657175616c20746044820152751bc81d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60521b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290611e8b90600090600190349061529a565b60405180910390a28082600a01541015611ef45760088201805460ff60d01b1916600160d01b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906000906152c4565b60405180910390a2505050565b611efe8382613727565b505050565b611f0b612f29565b611a36600061397a565b600081815260fc602052604090206008810154600160301b90046001600160a01b0316611f545760405162461bcd60e51b8152600401610a359061515b565b60036008820154600160d01b900460ff166004811115611f7657611f766145fc565b10611f935760405162461bcd60e51b8152600401610a3590615187565b60018101546001600160a01b0316611fa9612ce0565b6001600160a01b031614611fff5760405162461bcd60e51b815260206004820152601d60248201527f5468652063616c6c6572206d757374206265207468652073656e6465720000006044820152606401610a35565b600881015460405163f7434ea960e01b8152600091600160301b90046001600160a01b03169063f7434ea99061203c90600d860190600401615277565b602060405180830381865afa158015612059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207d9190614b45565b90503482600a0160008282546120939190615148565b9091555050600a82015481146121085760405162461bcd60e51b815260206004820152603460248201527f5468652073656e64657220666565206d75737420626520657175616c20746f206044820152731d1a1948185c989a5d1c985d1a5bdb8818dbdcdd60621b6064820152608401610a35565b42600c83015560405183906000805160206154b083398151915290612133906000908190349061529a565b60405180910390a28082600b01541015611ef45760088201805460ff60d01b1916600160d11b17905560405183907fc74b9f7dedf2887cd3c113b6d8da9cea19e55c1116e25f1f0e1b72d7543179b590611ee7906001906152c4565b600081815260fc602052604090206008810154600160301b90046001600160a01b03166121ce5760405162461bcd60e51b8152600401610a359061515b565b6008810154600982015460405163093225f160e31b8152600160301b9092046001600160a01b0316916349912f889134916122119190600d8701906004016152d7565b6000604051808303818588803b15801561222a57600080fd5b505af115801561223e573d6000803e3d6000fd5b50505050505050565b61224f612f29565b611a366139cc565b60ff5483906001600160a01b0316632fa117e582612273612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e191906150ce565b6122fd5760405162461bcd60e51b8152600401610a35906150f0565b8151602e1461233c5760405162461bcd60e51b815260206004820152600b60248201526a125b9d985b1a590818da5960aa1b6044820152606401610a35565b600083815260fc602052604090206008810154600160301b90046001600160a01b031661237b5760405162461bcd60e51b8152600401610a359061515b565b60ff546040516331a9108f60e11b8152600481018790526000916001600160a01b031690636352211e90602401602060405180830381865afa1580156123c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e991906152f0565b60018301549091506001600160a01b0380831691161480612419575060028201546001600160a01b038281169116145b61248d576040805162461bcd60e51b81526020600482015260248101919091527f5468652063616c6c6572206d757374206265207468652073656e646572206f7260448201527f20746865207265636569766572206f722074686569722064656c6567617465736064820152608401610a35565b60046008830154600160d01b900460ff1660048111156124af576124af6145fc565b106125165760405162461bcd60e51b815260206004820152603160248201527f4d757374206e6f742073656e642065766964656e6365206966207468652064696044820152701cdc1d5d19481a5cc81c995cdbdb1d9959607a1b6064820152608401610a35565b806001600160a01b0316858360080160069054906101000a90046001600160a01b03166001600160a01b03167fdccf2f8b2cc26eafcd61905cba744cff4b81d14740725f6376390dc6298a6a3c87604051612571919061530d565b60405180910390a485857fd998ce0f89c38b0f93256f0b843a404a3a3c5055b75265623f7cb9c369a1dd62866040516125aa919061530d565b60405180910390a3505050505050565b6125c2612cef565b60ff5483906001600160a01b0316632fa117e5826125de612ce0565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015612628573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264c91906150ce565b6126685760405162461bcd60e51b8152600401610a35906150f0565b612675836001868561339f565b600083815260fc6020526040812060048101805491928592612698908490615135565b9091555061162890508484613a0a565b6126b0612cef565b60ff5460405162f577a560e81b8152600481018490526000916001600160a01b03169063f577a5009060240160006040518083038186803b1580156126f457600080fd5b505afa158015612708573d6000803e3d6000fd5b505060ff546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa158015612755573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277991906152f0565b6000848152610104602090815260408083206001600160a01b0387168452909152902054909150806127e05760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b6000848152610104602090815260408083206001600160a01b038716845290915281205561280f828483613aa7565b60408051858152602081018390526001600160a01b038516917ff7c8cc6f18f75645957886fe11026a08ce70f199ba95cbb33ddd4064aa85203991015b60405180910390a250505050565b612862612cef565b600061286c612ce0565b6001600160a01b03166128876033546001600160a01b031690565b6001600160a01b0316036128c65782156128b35760405162461bcd60e51b8152600401610a3590614eed565b50610101546001600160a01b0316612993565b6101005460405162f577a560e81b8152600481018590526001600160a01b039091169063f577a5009060240160006040518083038186803b15801561290a57600080fd5b505afa15801561291e573d6000803e3d6000fd5b5050610100546040516331a9108f60e11b8152600481018790526001600160a01b039091169250636352211e9150602401602060405180830381865afa15801561296c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299091906152f0565b90505b600083815260fd602090815260408083206001600160a01b0386168452909152902054806129f65760405162461bcd60e51b815260206004820152601060248201526f6e6f7468696e6720746f20636c61696d60801b6044820152606401610a35565b600084815260fd602090815260408083206001600160a01b0387168452909152812055612a24828483613aa7565b60408051858152602081018390526001600160a01b038516917f2227733fc4c8a9034cb58087dcf6995128b9c0233b038b03366aaf30c92b92d6910161284c565b612a6d612f29565b61010180546001600160a01b0319166001600160a01b0392909216919091179055565b612a98612f29565b610101805461ffff60a01b1916600160a01b61ffff8416908102919091179091556040519081527f8339189e972f7fba792126e752aa8485af08710bce4a041c5bc3f9858acd7130906020016114b5565b612af1612f29565b6001600160a01b038116612b565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a35565b61170b8161397a565b600054610100900460ff1615808015612b7f5750600054600160ff909116105b80612b995750303b158015612b99575060005460ff166001145b612bfc5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610a35565b6000805460ff191660011790558015612c1f576000805461ff0019166101001790555b612c27613b81565b612c2f613bb0565b60fe80546001600160a01b038088166001600160a01b03199283161790925560ff80548784169083161790556101008054868416908316179055610101805492851692909116919091179055612c8a61010380546001019055565b612c946064612a90565b8015611628576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050505050565b6000612cea613bd7565b905090565b60665460ff1615611a365760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a35565b600080612d428387615148565b9050612710612d5561ffff861683615320565b612d6361ffff881684615320565b61010154612d7c90600160a01b900461ffff1685615320565b612d869190615148565b612d909190615148565b612d9a9190615337565b612da49082615148565b9695505050505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052612e08908590613c10565b50505050565b600060fc600084815260200190815260200160002090507f8b4f0e94aa0aee74c276abd2d92a5e2737a493b055e19d5b2d4c0ac573242a158386868460030160009054906101000a90046001600160a01b031685600401548660060154876007015461010160149054906101000a900461ffff168960080160029054906101000a900461ffff168a60080160049054906101000a900461ffff168b60080160069054906101000a90046001600160a01b03168c600d018d600e0154604051612ee29d9c9b9a99989796959493929190615359565b60405180910390a1827f61606860eb6c87306811e2695215385101daab53bd6ab4e9f9049aead9363c7d83604051612f1a919061530d565b60405180910390a25050505050565b612f31612ce0565b6001600160a01b0316612f4c6033546001600160a01b031690565b6001600160a01b031614611a365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a35565b600082815260fc602052604090206002821115612ff25760405162461bcd60e51b815260206004820152600e60248201526d496e76616c69642072756c696e6760901b6044820152606401610a35565b60018101546002820154600483018054600a85018054600b87018054600095869055928590559390935560088601805460ff60d01b1916600160d21b1790556001600160a01b03948516949093169290919060001987016130ad576040516001600160a01b038616908390600081818185875af1925050503d8060008114613096576040519150601f19603f3d011682016040523d82523d6000602084013e61309b565b606091505b5050506130a88884613a0a565b6131e8565b6001198701613111576040516001600160a01b038516908290600081818185875af1925050503d80600081146130ff576040519150601f19603f3d011682016040523d82523d6000602084013e613104565b606091505b5050506130a8888461368a565b600061311e600284615337565b9050600061312d600286615337565b90506131398a82613a0a565b6131438a8261368a565b6040516001600160a01b038816908390600081818185875af1925050503d806000811461318c576040519150601f19603f3d011682016040523d82523d6000602084013e613191565b606091505b50506040516001600160a01b03881691508390600081818185875af1925050503d80600081146131dd576040519150601f19603f3d011682016040523d82523d6000602084013e6131e2565b606091505b50505050505b877f76b363d70472d47d20e4119f3625c05ed37ca51b1d9e1cd8b87d8c20530640f38860405161321a91815260200190565b60405180910390a25050505050505050565b61170b612f29565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561326757611efe83613ce2565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156132c1575060408051601f3d908101601f191682019092526132be91810190614b45565b60015b6133245760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608401610a35565b60008051602061549083398151915281146133935760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608401610a35565b50611efe838383613d7e565b600084815260fc60205260408120908460018111156133c0576133c06145fc565b036134665760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa15801561340e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061343291906152f0565b60018201546001600160a01b039081169116146134615760405162461bcd60e51b8152600401610a3590614eed565b61351b565b600184600181111561347a5761347a6145fc565b0361351b5760ff546040516331a9108f60e11b8152600481018590526001600160a01b0390911690636352211e90602401602060405180830381865afa1580156134c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ec91906152f0565b60028201546001600160a01b0390811691161461351b5760405162461bcd60e51b8152600401610a3590614eed565b610103548154106135675760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081d1c985b9cd858dd1a5bdb881a5960521b6044820152606401610a35565b60006008820154600160d01b900460ff166004811115613589576135896145fc565b146135e45760405162461bcd60e51b815260206004820152602560248201527f546865207472616e73616374696f6e2073686f756c646e2774206265206469736044820152641c1d5d195960da1b6064820152608401610a35565b818160040154101561362d5760405162461bcd60e51b8152602060048201526012602482015271496e73756666696369656e742066756e647360701b6044820152606401610a35565b6127108210158061364d57506127108210801561364d5750806004015482145b6116285760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b6044820152606401610a35565b6136948282613da3565b600082815260fc60205260409020600281015460038201546136c3916001600160a01b03908116911684613aa7565b611efe83600084614129565b6136d761424f565b6066805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61370a612ce0565b6040516001600160a01b03909116815260200160405180910390a1565b600082815260fc60205260409081902060088101805460ff60d01b1916600360d01b1790819055915163c13517e160e01b81529091600160301b90046001600160a01b031690819063c13517e190859061378b90600290600d8801906004016153e7565b60206040518083038185885af11580156137a9573d6000803e3d6000fd5b50505050506040513d601f19601f820116820180604052508101906137ce9190614b45565b600983018181556000918252610102602090815260409283902087905590548251878152918201879052916001600160a01b038416917f74baab670a4015ab2f1b467c5252a96141a2573f2908e58a92081e80d3cfde3d910160405180910390a38282600a015411156138da5760008383600a015461384d9190615135565b600a840185905560018401546040519192506001600160a01b0316908290600081818185875af1925050503d80600081146138a4576040519150601f19603f3d011682016040523d82523d6000602084013e6138a9565b606091505b505050846000805160206154b083398151915260016000346040516138d09392919061529a565b60405180910390a2505b8282600b01541115612e085760008383600b01546138f89190615135565b600b840185905560028401546040519192506001600160a01b0316908290600081818185875af1925050503d806000811461394f576040519150601f19603f3d011682016040523d82523d6000602084013e613954565b606091505b505050846000805160206154b083398151915260018034604051612f1a9392919061529a565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6139d4612cef565b6066805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861370a612ce0565b600082815260fc6020526040812060118101549091908103613a2d576000613a4b565b60118201546010830154613a419085615320565b613a4b9190615337565b6008830154909150600090613a7790859061ffff62010000820481169164010000000090041685612d35565b60018401546003850154919250613a9b916001600160a01b03918216911683613aa7565b61162885600186614129565b6001600160a01b038216600003613b0e576040516001600160a01b038416908290600081818185875af1925050503d8060008114613b01576040519150601f19603f3d011682016040523d82523d6000602084013e613b06565b606091505b505050505050565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820183905283169063a9059cbb906044016020604051808303816000875af1158015613b5d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0891906150ce565b600054610100900460ff16613ba85760405162461bcd60e51b8152600401610a3590615403565b611a36614298565b600054610100900460ff16611a365760405162461bcd60e51b8152600401610a3590615403565b600060143610801590613bf957503360009081526065602052604090205460ff165b15613c0b575060131936013560601c90565b503390565b6000613c65826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166142cf9092919063ffffffff16565b805190915015611efe5780806020019051810190613c8391906150ce565b611efe5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a35565b6001600160a01b0381163b613d4f5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608401610a35565b60008051602061549083398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b613d87836142e8565b600082511180613d945750805b15611efe57612e088383614328565b600082815260fc602052604080822060fe5460068201546007830154935163353bb87f60e21b81526004810191909152602481019390935290929182916001600160a01b03169063d4eee1fc90604401600060405180830381865afa158015613e10573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613e389190810190614ca8565b60a0820151608082015160088701549395509193509160009061271090613e6490899061ffff16615320565b613e6e9190615337565b600887015490915060009061271090613e92908a9062010000900461ffff16615320565b613e9c9190615337565b600888015490915060009061271090613ec2908b90640100000000900461ffff16615320565b613ecc9190615337565b60038901546001600160a01b031660009081527fc34a738ec333e394a3927794cadc6dd0eb7d9eed0999d1e55021ea223ac362cc6020526040812080549293508592909190613f1c908490615148565b9091555050600085815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054849290613f57908490615148565b9091555050600084815260fd6020908152604080832060038c01546001600160a01b0316845290915281208054839290613f92908490615148565b9091555050600f88015415801590613fad5750601088015415155b1561406f576000886011015489601001548b613fc99190615320565b613fd39190615337565b600f8a015460009081526101046020908152604080832060038e01546001600160a01b03168452909152812080549293508392909190614014908490615148565b90915550506003890154600f8a015460068b015460408051918252602082018590526001600160a01b03909316927f7be8d1d5def43ba21be043f0d166965a1c479d40c0fac41f9a9fe18f1a9a2863910160405180910390a3505b6003880154600689015460408051888152602081019290925281018490526001600160a01b03909116907f17c48ab8e1617182f35ae77fd7da7f4e15dedf7018aa371a4481c20c790b65469060600160405180910390a26003880154600689015460408051878152602081019290925281018490526001600160a01b03909116907f3476ed3eea2cdac584273bc8830824c8ca42ca2a99e9f144a87a1cdbbf9dd15a9060600160405180910390a250505050505050505050565b600083815260fc6020526040908190208054600382015460068301546007840154945193947ff3afebb51c3c2b45151cf0572b3d287505cf6ecea01df5f222c1d8cf0159f2279461418a949389936001600160a01b0390911692899261544e565b60405180910390a18060040154600003612e085760fe5460068201546005830154604051635ab9ae0f60e11b8152600481019290925260248201526001600160a01b039091169063b5735c1e90604401600060405180830381600087803b1580156141f457600080fd5b505af1158015614208573d6000803e3d6000fd5b505050507f6bef1b5e95b741d6e665eb9b5c2d3e1203c46a771451055a9d41e0b8ff4510b7816006015460405161424191815260200190565b60405180910390a150505050565b60665460ff16611a365760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a35565b600054610100900460ff166142bf5760405162461bcd60e51b8152600401610a3590615403565b611a366142ca612ce0565b61397a565b60606142de848460008561441e565b90505b9392505050565b6142f181613ce2565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6143905760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b6064820152608401610a35565b600080846001600160a01b0316846040516143ab9190614f14565b600060405180830381855af49150503d80600081146143e6576040519150601f19603f3d011682016040523d82523d6000602084013e6143eb565b606091505b509150915061441382826040518060600160405280602781526020016154d0602791396144f9565b925050505b92915050565b60608247101561447f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610a35565b600080866001600160a01b0316858760405161449b9190614f14565b60006040518083038185875af1925050503d80600081146144d8576040519150601f19603f3d011682016040523d82523d6000602084013e6144dd565b606091505b50915091506144ee87838387614512565b979650505050505050565b606083156145085750816142e1565b6142e18383614587565b6060831561458157825160000361457a576001600160a01b0385163b61457a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a35565b5081611455565b61145583835b8151156145975781518083602001fd5b8060405162461bcd60e51b8152600401610a35919061530d565b6001600160a01b038116811461170b57600080fd5b6000602082840312156145d857600080fd5b81356142e1816145b1565b6000602082840312156145f557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60058110614622576146226145fc565b9052565b60005b83811015614641578181015183820152602001614629565b50506000910152565b60008151808452614662816020860160208601614626565b601f01601f19169290920160200192915050565b60208152815160208201526000602083015161469d60408401826001600160a01b03169052565b5060408301516001600160a01b03811660608401525060608301516001600160a01b038116608084015250608083015160a083015260a083015160c083015260c083015160e083015260e083015161010081818501528085015191505061012061470c8185018361ffff169052565b84015190506101406147238482018361ffff169052565b840151905061016061473a8482018361ffff169052565b8401519050610180614756848201836001600160a01b03169052565b84015190506101a061476a84820183614612565b8401516101c0848101919091528401516101e08085019190915284015161020080850191909152840151610220808501919091528401516102c0610240808601829052919250906147bf6102e086018461464a565b9086015161026086810191909152860151610280808701919091528601516102a080870191909152909501519301929092525090919050565b634e487b7160e01b600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715614832576148326147f8565b60405290565b604051610160810167ffffffffffffffff81118282101715614832576148326147f8565b604051601f8201601f1916810167ffffffffffffffff81118282101715614885576148856147f8565b604052919050565b600067ffffffffffffffff8211156148a7576148a76147f8565b50601f01601f191660200190565b60006148c86148c38461488d565b61485c565b90508281528383830111156148dc57600080fd5b828260208301376000602084830101529392505050565b600082601f83011261490457600080fd5b6142e1838335602085016148b5565b6000806000806080858703121561492957600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561494f57600080fd5b61495b888389016148f3565b9350606087013591508082111561497157600080fd5b5061497e878288016148f3565b91505092959194509250565b6000806040838503121561499d57600080fd5b50508035926020909101359150565b6000806000606084860312156149c157600080fd5b505081359360208301359350604090920135919050565b600080604083850312156149eb57600080fd5b82356149f6816145b1565b9150602083013567ffffffffffffffff811115614a1257600080fd5b8301601f81018513614a2357600080fd5b614a32858235602084016148b5565b9150509250929050565b600080600060608486031215614a5157600080fd5b8335925060208401359150604084013567ffffffffffffffff811115614a7657600080fd5b614a82868287016148f3565b9150509250925092565b60008060408385031215614a9f57600080fd5b823591506020830135614ab1816145b1565b809150509250929050565b61ffff8116811461170b57600080fd5b600060208284031215614ade57600080fd5b81356142e181614abc565b60008060008060808587031215614aff57600080fd5b8435614b0a816145b1565b93506020850135614b1a816145b1565b92506040850135614b2a816145b1565b91506060850135614b3a816145b1565b939692955090935050565b600060208284031215614b5757600080fd5b5051919050565b600181811c90821680614b7257607f821691505b602082108103614b9257634e487b7160e01b600052602260045260246000fd5b50919050565b805160058110614ba757600080fd5b919050565b600082601f830112614bbd57600080fd5b8151614bcb6148c38261488d565b818152846020838601011115614be057600080fd5b611455826020830160208701614626565b8051614ba7816145b1565b805160028110614ba757600080fd5b60006101008284031215614c1e57600080fd5b614c2661480e565b9050614c3182614bfc565b815260208201516020820152614c4960408301614bf1565b6040820152606082015160608201526080820151608082015260a082015167ffffffffffffffff811115614c7c57600080fd5b614c8884828501614bac565b60a08301525060c082015160c082015260e082015160e082015292915050565b60008060408385031215614cbb57600080fd5b825167ffffffffffffffff80821115614cd357600080fd5b908401906101008287031215614ce857600080fd5b614cf061480e565b614cf983614b98565b81526020830151602082015260408301516040820152606083015182811115614d2157600080fd5b614d2d88828601614bac565b6060830152506080830151608082015260a083015160a0820152614d5360c08401614bf1565b60c082015260e083015160e0820152809450506020850151915080821115614d7a57600080fd5b50614a3285828601614c0b565b60008060408385031215614d9a57600080fd5b8251614da5816145b1565b6020840151909250614ab1816145b1565b8051614ba781614abc565b600060208284031215614dd357600080fd5b815167ffffffffffffffff80821115614deb57600080fd5b908301906101608286031215614e0057600080fd5b614e08614838565b82518152602083015182811115614e1e57600080fd5b614e2a87828601614bac565b602083015250604083015182811115614e4257600080fd5b614e4e87828601614bac565b604083015250614e6060608401614db6565b6060820152614e7160808401614db6565b608082015260a083015160a082015260c083015160c0820152614e9660e08401614bf1565b60e08201526101008084015183811115614eaf57600080fd5b614ebb88828701614bac565b828401525050610120915081830151828201526101409150614ede828401614bf1565b91810191909152949350505050565b6020808252600d908201526c1058d8d95cdcc819195b9a5959609a1b604082015260600190565b60008251614f26818460208701614626565b9190910192915050565b601f821115611efe57600081815260208120601f850160051c81016020861015614f575750805b601f850160051c820191505b81811015613b0657828155600101614f63565b815167ffffffffffffffff811115614f9057614f906147f8565b614fa481614f9e8454614b5e565b84614f30565b602080601f831160018114614fd95760008415614fc15750858301515b600019600386901b1c1916600185901b178555613b06565b600085815260208120601f198616915b8281101561500857888601518255948401946001909101908401614fe9565b50858210156150265787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b6000602082840312156150e057600080fd5b815180151581146142e157600080fd5b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b818103818111156144185761441861511f565b808201808211156144185761441861511f565b602080825260129082015271105c989a5d1c985d1bdc881b9bdd081cd95d60721b604082015260600190565b6020808252604d908201527f446973707574652068617320616c7265616479206265656e206372656174656460408201527f206f72206265636175736520746865207472616e73616374696f6e206861732060608201526c1899595b88195e1958dd5d1959609a1b608082015260a00190565b6000815461520781614b5e565b808552602060018381168015615224576001811461523e5761526c565b60ff1985168884015283151560051b88018301955061526c565b866000528260002060005b858110156152645781548a8201860152908301908401615249565b890184019650505b505050505092915050565b6020815260006142e160208301846151fa565b6002811061170b5761170b6145fc565b606081016152a78561528a565b8482526152b38461528a565b602082019390935260400152919050565b602081016152d18361528a565b91905290565b8281526040602082015260006142de60408301846151fa565b60006020828403121561530257600080fd5b81516142e1816145b1565b6020815260006142e1602083018461464a565b80820281158282048414176144185761441861511f565b60008261535457634e487b7160e01b600052601260045260246000fd5b500490565b8d8152602081018d9052604081018c90526001600160a01b038b81166060830152608082018b905260a082018a905260c0820189905261ffff88811660e08401528781166101008401528616610120830152841661014082015260006101a0806101608401526153cb818401866151fa565b915050826101808301529e9d5050505050505050505050505050565b60ff831681526040602082015260006142de60408301846151fa565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b86815260c0810161545e8761528a565b60208201969096526001600160a01b039490941660408501526060840192909252608083015260a09091015291905056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc73e533bc8a993eccbc1023beebad0020f6b6c3639f83062f00fc194b4d1172ba416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220ebf0fdcd633b2aa3cc45cd6844284d1b24a3cd790fcd8ef9ad87dff0726b7fe764736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/packages/client/src/contracts/ABI/TalentLayerService.json b/packages/client/src/contracts/ABI/TalentLayerService.json index f5046a0..9fcc20d 100644 --- a/packages/client/src/contracts/ABI/TalentLayerService.json +++ b/packages/client/src/contracts/ABI/TalentLayerService.json @@ -137,12 +137,6 @@ "name": "status", "type": "uint8" }, - { - "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" - }, { "indexed": false, "internalType": "uint256", @@ -160,6 +154,12 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "name": "ProposalCreated", @@ -188,20 +188,20 @@ }, { "indexed": false, - "internalType": "address", - "name": "rateToken", - "type": "address" + "internalType": "uint256", + "name": "rateAmount", + "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "rateAmount", + "name": "expirationDate", "type": "uint256" }, { "indexed": false, "internalType": "uint256", - "name": "expirationDate", + "name": "referrerId", "type": "uint256" } ], @@ -322,6 +322,18 @@ "internalType": "string", "name": "dataUri", "type": "string" + }, + { + "indexed": false, + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "name": "ServiceCreated", @@ -331,7 +343,7 @@ "anonymous": false, "inputs": [ { - "indexed": true, + "indexed": false, "internalType": "uint256", "name": "id", "type": "uint256" @@ -341,9 +353,15 @@ "internalType": "string", "name": "dataUri", "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], - "name": "ServiceDetailedUpdated", + "name": "ServiceUpdated", "type": "event" }, { @@ -519,11 +537,6 @@ "name": "_serviceId", "type": "uint256" }, - { - "internalType": "address", - "name": "_rateToken", - "type": "address" - }, { "internalType": "uint256", "name": "_rateAmount", @@ -548,6 +561,11 @@ "internalType": "bytes", "name": "_signature", "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" } ], "name": "createProposal", @@ -576,6 +594,16 @@ "internalType": "bytes", "name": "_signature", "type": "bytes" + }, + { + "internalType": "address", + "name": "_rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_referralAmount", + "type": "uint256" } ], "name": "createService", @@ -640,6 +668,11 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Proposal", @@ -710,6 +743,16 @@ "internalType": "uint256", "name": "platformId", "type": "uint256" + }, + { + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Service", @@ -766,6 +809,16 @@ "internalType": "uint256", "name": "platformId", "type": "uint256" + }, + { + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Service", @@ -808,6 +861,11 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "internalType": "struct TalentLayerService.Proposal", @@ -1023,6 +1081,11 @@ "internalType": "uint256", "name": "expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "referrerId", + "type": "uint256" } ], "stateMutability": "view", @@ -1155,6 +1218,16 @@ "internalType": "uint256", "name": "platformId", "type": "uint256" + }, + { + "internalType": "address", + "name": "rateToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "referralAmount", + "type": "uint256" } ], "stateMutability": "view", @@ -1253,11 +1326,6 @@ "name": "_serviceId", "type": "uint256" }, - { - "internalType": "address", - "name": "_rateToken", - "type": "address" - }, { "internalType": "uint256", "name": "_rateAmount", @@ -1272,6 +1340,11 @@ "internalType": "uint256", "name": "_expirationDate", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_referrerId", + "type": "uint256" } ], "name": "updateProposal", @@ -1291,13 +1364,18 @@ "name": "_serviceId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_referralAmount", + "type": "uint256" + }, { "internalType": "string", "name": "_dataUri", "type": "string" } ], - "name": "updateServiceData", + "name": "updateService", "outputs": [], "stateMutability": "nonpayable", "type": "function" @@ -1334,8 +1412,8 @@ "type": "function" } ], - "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6080516142306200012060003960008181610f7c01528181610fbc01528181611273015281816112b3015261134201526142306000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063c2cfee27116100ab578063d547741f1161006f578063d547741f1461072b578063ef0e239b1461074b578063f2fde38b14610778578063f6c53d9b14610798578063f9eaee0d146107af57600080fd5b8063c2cfee2714610669578063c75858d51461069c578063ccaa7d2a146106bc578063d338ec9a146106ea578063d4eee1fc146106fd57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a7d5eaea146105ca578063aba21009146105ea578063b5735c1e14610617578063c22c4f431461063757600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b80631499f9e6116102035780631499f9e6146102bf578063156b39aa146102f85780631db087ff1461031d578063248a9ca31461034b57806326d006681461037b57600080fd5b806301ffc9a714610235578063089b7c731461026a5780630e0660251461028c57806313ca98db146102ac575b600080fd5b34801561024157600080fd5b50610255610250366004613478565b6107e9565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046134a2565b610820565b005b34801561029857600080fd5b5061028a6102a7366004613506565b6109c3565b61028a6102ba36600461356e565b610b8b565b3480156102cb57600080fd5b50610130546102e0906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561030457600080fd5b5061030f6101365481565b604051908152602001610261565b34801561032957600080fd5b5061030f610338366004613624565b6101336020526000908152604090205481565b34801561035757600080fd5b5061030f610366366004613624565b600090815260fc602052604090206001015490565b34801561038757600080fd5b5061028a61039636600461363d565b610e57565b3480156103a757600080fd5b5061028a6103b636600461365a565b610eba565b3480156103c757600080fd5b5061028a6103d636600461365a565b610ee4565b3480156103e757600080fd5b5061028a6103f636600461363d565b610f72565b34801561040757600080fd5b5061028a61041636600461363d565b611051565b34801561042757600080fd5b5061028a610436366004613624565b6110aa565b34801561044757600080fd5b5061028a61045636600461368a565b6110f2565b61028a6104693660046136ce565b611269565b34801561047a57600080fd5b5061030f611335565b34801561048f57600080fd5b5061025561049e36600461363d565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b5061030f7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a6113e8565b34801561051157600080fd5b5061054061052036600461363d565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046137a0565b6113fc565b34801561058357600080fd5b506033546001600160a01b03166102e0565b3480156105a157600080fd5b506102556105b036600461365a565b6114d1565b3480156105c157600080fd5b5061030f600081565b3480156105d657600080fd5b5061028a6105e53660046137e1565b6114fc565b3480156105f657600080fd5b5061060a6106053660046134a2565b61157e565b60405161026191906138f1565b34801561062357600080fd5b5061028a6106323660046134a2565b6116b0565b34801561064357600080fd5b50610657610652366004613624565b611755565b60405161026196959493929190613914565b34801561067557600080fd5b506106896106843660046134a2565b611819565b6040516102619796959493929190613955565b3480156106a857600080fd5b5061028a6106b73660046139a9565b6118fa565b3480156106c857600080fd5b5061030f6106d7366004613624565b6101346020526000908152604090205481565b61030f6106f8366004613a25565b611c1e565b34801561070957600080fd5b5061071d6107183660046134a2565b611e1e565b604051610261929190613b02565b34801561073757600080fd5b5061028a61074636600461365a565b61209a565b34801561075757600080fd5b5061076b610766366004613624565b6120bf565b6040516102619190613b27565b34801561078457600080fd5b5061028a61079336600461363d565b612253565b3480156107a457600080fd5b5061030f61012e5481565b3480156107bb57600080fd5b506102556107ca36600461363d565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e58261083d6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab9190613b3a565b6108d05760405162461bcd60e51b81526004016108c790613b57565b60405180910390fd5b600082815261013160205260409020600181015484146109225760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff16600481111561093a5761093a61380d565b1461097f5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5484906001600160a01b0316632fa117e5826109e06122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4e9190613b3a565b610a6a5760405162461bcd60e51b81526004016108c790613b57565b60008481526101316020526040902060018101548614610abc5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff166004811115610ad457610ad461380d565b14610b195760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b602e8314610b395760405162461bcd60e51b81526004016108c790613b86565b60038101610b48848683613c2b565b50847f1cae99404f615a4039d85b1009cb70622aae6d64f671e8b1b191d9269847d43e8585604051610b7b929190613d15565b60405180910390a2505050505050565b61012f548a906001600160a01b0316632fa117e582610ba86122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c169190613b3a565b610c325760405162461bcd60e51b81526004016108c790613b57565b610c438b8b8b8b8b8b8b8a8a6122d8565b6040805160e0810190915280600081526020018c81526020018a6001600160a01b0316815260200189815260200188815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060209182018790528c8152610132825260408082208f83529092522081518154829060ff191660018381811115610ce857610ce861380d565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190610d459082613d31565b5060c0919091015160069091015560008b81526101336020526040902054158015610d7d575060008b81526101346020526040902054155b15610de25761012f546040516383ce205b60e01b8152600481018d90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610dc957600080fd5b505af1158015610ddd573d6000803e3d6000fd5b505050505b60008b815261013460205260408120805491610dfd83613e07565b91905055507f11a8bc6241aa94a07af6c545ce8ed2dca2aaede88d02fd2b7e2d7ed28ccf1d4a8a8c888860008e8e8e8c604051610e4299989796959493929190613e20565b60405180910390a15050505050505050505050565b610e5f6126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600082815260fc6020526040902060010154610ed581612720565b610edf8383612731565b505050565b610eec6122c9565b6001600160a01b0316816001600160a01b031614610f645760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108c7565b610f6e82826127b8565b5050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fba5760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110036000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146110295760405162461bcd60e51b81526004016108c790613ecd565b6110328161283d565b6040805160008082526020820190925261104e91839190612845565b50565b6110596126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610eaf565b60006110b581612720565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111125750600054600160ff909116105b8061112c5750303b15801561112c575060005460ff166001145b61118f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108c7565b6000805460ff1916600117905580156111b2576000805461ff0019166101001790555b6111ba6129b0565b6111c26129df565b6111ca6129df565b6111dc60006111d76122c9565b612a06565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e5561121e601e6110aa565b8015610edf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036112b15760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166112fa6000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146113205760405162461bcd60e51b81526004016108c790613ecd565b6113298261283d565b610f6e82826001612845565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113d55760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108c7565b506000805160206141b483398151915290565b6113f06126a7565b6113fa6000612a10565b565b6114046126a7565b6001600160a01b038316158015611419575081155b156114665760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108c7565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161125c565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f61152681612720565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611586613431565b60008381526101326020908152604080832085845290915290819020815160e081019092528054829060ff1660018111156115c3576115c361380d565b60018111156115d4576115d461380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161161c90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461164890613bab565b80156116955780601f1061166a57610100808354040283529160200191611695565b820191906000526020600020905b81548152906001019060200180831161167857829003601f168201915b50505050508152602001600682015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6116da81612720565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611714866064613f19565b61171e9190613f30565b905061013654811061173a57825460ff1916600217835561174d565b8254600490849060ff1916600183611571565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff90941694929391929161178a90613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546117b690613bab565b80156118035780601f106117d857610100808354040283529160200191611803565b820191906000526020600020905b8154815290600101906020018083116117e657829003601f168201915b5050505050908060040154908060050154905086565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b0390941694929391929161187190613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461189d90613bab565b80156118ea5780601f106118bf576101008083540402835291602001916118ea565b820191906000526020600020905b8154815290600101906020018083116118cd57829003601f168201915b5050505050908060060154905087565b61012f5487906001600160a01b0316632fa117e5826119176122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611961573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119859190613b3a565b6119a15760405162461bcd60e51b81526004016108c790613b57565b6001600160a01b0386166000908152610135602052604090205460ff166119fe5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115611a3857611a3861380d565b14611a7a5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b89816001015414611abd5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b602e8514611add5760405162461bcd60e51b81526004016108c790613b86565b6001815460ff166001811115611af557611af561380d565b03611b365760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108c7565b6001600160a01b03881660009081526101356020526040902060010154871015611b935760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b6002810180546001600160a01b0319166001600160a01b038a161790556003810187905560058101611bc6868883613c2b565b50600681018490556040517f0f68ab04ab4935c8598d30f2c12ec34265575059bb4cae481b4d632cc43db81e90611c0a908b908d908a908a908e908e908c90613f52565b60405180910390a150505050505050505050565b61012f5460009087906001600160a01b0316632fa117e582611c3e6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cac9190613b3a565b611cc85760405162461bcd60e51b81526004016108c790613b57565b611cd6888888888888612a62565b61012e80549081906000611ce983613e07565b9091555050600081815261013160205260409020805460ff19168155600181018a905560038101611d1b888a83613c2b565b506005810189905560008a81526101336020526040902054158015611d4d575060008a81526101346020526040902054155b15611db25761012f546040516383ce205b60e01b8152600481018c90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b505050505b60008a815261013360205260408120805491611dcd83613e07565b91905055507f8f3fc1086abc1020f602edd700a9ae5801b250c9d110af9e54022d7cc5df7bee828b8b8b8b604051611e09959493929190613f9a565b60405180910390a15098975050505050505050565b611e586040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b611e60613431565b60008481526101316020526040808220815160c081019092528054829060ff166004811115611e9157611e9161380d565b6004811115611ea257611ea261380d565b81526020016001820154815260200160028201548152602001600382018054611eca90613bab565b80601f0160208091040260200160405190810160405280929190818152602001828054611ef690613bab565b8015611f435780601f10611f1857610100808354040283529160200191611f43565b820191906000526020600020905b815481529060010190602001808311611f2657829003601f168201915b5050509183525050600482015460208083019190915260059092015460409182015260008881526101328352818120888252909252808220815160e0810190925280549394509192909190829060ff166001811115611fa457611fa461380d565b6001811115611fb557611fb561380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ffd90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461202990613bab565b80156120765780601f1061204b57610100808354040283529160200191612076565b820191906000526020600020905b81548152906001019060200180831161205957829003601f168201915b505050918352505060069190910154602090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120b581612720565b610edf83836127b8565b6120f96040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b61012e54821061214b5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108c7565b6000828152610131602052604090819020815160c081019092528054829060ff16600481111561217d5761217d61380d565b600481111561218e5761218e61380d565b815260200160018201548152602001600282015481526020016003820180546121b690613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546121e290613bab565b801561222f5780601f106122045761010080835404028352916020019161222f565b820191906000526020600020905b81548152906001019060200180831161221257829003601f168201915b50505050508152602001600482015481526020016005820154815250509050919050565b61225b6126a7565b6001600160a01b0381166122c05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c7565b61104e81612a10565b60006122d3612c0d565b905090565b6001600160a01b0387166000908152610135602052604090205460ff166123355760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b61013054604051634a7ab1d560e01b8152600481018790526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a49190613fcb565b90508034146123ea5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b6001600160a01b038816600090815261013560205260409020600101548710156124475760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b60008981526101316020526040812090815460ff16600481111561246d5761246d61380d565b146124af5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b80600101546000036124f75760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108c7565b60008a8152610132602090815260408083208e84529091529020600101548b900361255d5760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108c7565b8a8160010154036125ba5760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108c7565b602e85146125da5760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126499190613fe4565b90506001600160a01b038116156126995760008c8c89896040516020016126739493929190614001565b60405160208183030381529060405280519060200120905061269786868385612c46565b505b505050505050505050505050565b6126af6122c9565b6001600160a01b03166126ca6033546001600160a01b031690565b6001600160a01b0316146113fa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c7565b61104e8161272c6122c9565b612d3a565b61273b82826114d1565b610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127746122c9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127c282826114d1565b15610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127f96122c9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61104e6126a7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561287857610edf83612d93565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128d2575060408051601f3d908101601f191682019092526128cf91810190613fcb565b60015b6129355760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108c7565b6000805160206141b483398151915281146129a45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108c7565b50610edf838383612e2f565b600054610100900460ff166129d75760405162461bcd60e51b81526004016108c790614043565b6113fa612e5a565b600054610100900460ff166113fa5760405162461bcd60e51b81526004016108c790614043565b610f6e8282612731565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051638a98636360e01b8152600481018790526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613fcb565b9050803414612b175760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b602e8414612b375760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018890526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba69190613fe4565b90506001600160a01b03811615612c0357600088815261013360209081526040808320549051612bdd928c92918b918b910161408e565b604051602081830303815290604052805190602001209050612c0185858385612c46565b505b5050505050505050565b600060143610801590612c2f57503360009081526065602052604090205460ff165b15612c41575060131936013560601c90565b503390565b6000612c9f836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612ce38287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9192505050565b9050806001600160a01b0316836001600160a01b03161461174d5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108c7565b612d4482826114d1565b610f6e57612d5181612eb5565b612d5c836020612ec7565b604051602001612d6d9291906140cf565b60408051601f198184030181529082905262461bcd60e51b82526108c791600401614144565b6001600160a01b0381163b612e005760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108c7565b6000805160206141b483398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612e388361306a565b600082511180612e455750805b15610edf57612e5483836130aa565b50505050565b600054610100900460ff16612e815760405162461bcd60e51b81526004016108c790614043565b6113fa612e8c6122c9565b612a10565b6000806000612ea0858561319e565b91509150612ead816131e0565b509392505050565b606061081a6001600160a01b03831660145b60606000612ed6836002613f19565b612ee1906002614157565b67ffffffffffffffff811115612ef957612ef96136b8565b6040519080825280601f01601f191660200182016040528015612f23576020820181803683370190505b509050600360fc1b81600081518110612f3e57612f3e61416a565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f6d57612f6d61416a565b60200101906001600160f81b031916908160001a9053506000612f91846002613f19565b612f9c906001614157565b90505b6001811115613014576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fd057612fd061416a565b1a60f81b828281518110612fe657612fe661416a565b60200101906001600160f81b031916908160001a90535060049490941c9361300d81614180565b9050612f9f565b5083156130635760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108c7565b9392505050565b61307381612d93565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6131125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108c7565b600080846001600160a01b03168460405161312d9190614197565b600060405180830381855af49150503d8060008114613168576040519150601f19603f3d011682016040523d82523d6000602084013e61316d565b606091505b509150915061319582826040518060600160405280602781526020016141d46027913961332a565b95945050505050565b60008082516041036131d45760208301516040840151606085015160001a6131c887828585613343565b94509450505050612093565b50600090506002612093565b60008160048111156131f4576131f461380d565b036131fc5750565b60018160048111156132105761321061380d565b0361325d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108c7565b60028160048111156132715761327161380d565b036132be5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108c7565b60038160048111156132d2576132d261380d565b0361104e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108c7565b60608315613339575081613063565b6130638383613407565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561337a57506000905060036133fe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156133ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166133f7576000600192509250506133fe565b9150600090505b94509492505050565b8151156134175781518083602001fd5b8060405162461bcd60e51b81526004016108c79190614144565b6040805160e0810190915280600081526020016000815260200160006001600160a01b03168152602001600081526020016000815260200160608152602001600081525090565b60006020828403121561348a57600080fd5b81356001600160e01b03198116811461306357600080fd5b600080604083850312156134b557600080fd5b50508035926020909101359150565b60008083601f8401126134d657600080fd5b50813567ffffffffffffffff8111156134ee57600080fd5b60208301915083602082850101111561209357600080fd5b6000806000806060858703121561351c57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561354157600080fd5b61354d878288016134c4565b95989497509550505050565b6001600160a01b038116811461104e57600080fd5b6000806000806000806000806000806101008b8d03121561358e57600080fd5b8a35995060208b0135985060408b01356135a781613559565b975060608b0135965060808b0135955060a08b013567ffffffffffffffff808211156135d257600080fd5b6135de8e838f016134c4565b909750955060c08d0135945060e08d01359150808211156135fe57600080fd5b5061360b8d828e016134c4565b915080935050809150509295989b9194979a5092959850565b60006020828403121561363657600080fd5b5035919050565b60006020828403121561364f57600080fd5b813561306381613559565b6000806040838503121561366d57600080fd5b82359150602083013561367f81613559565b809150509250929050565b6000806040838503121561369d57600080fd5b82356136a881613559565b9150602083013561367f81613559565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156136e157600080fd5b82356136ec81613559565b9150602083013567ffffffffffffffff8082111561370957600080fd5b818501915085601f83011261371d57600080fd5b81358181111561372f5761372f6136b8565b604051601f8201601f19908116603f01168101908382118183101715613757576137576136b8565b8160405282815288602084870101111561377057600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461104e57600080fd5b6000806000606084860312156137b557600080fd5b83356137c081613559565b925060208401356137d081613792565b929592945050506040919091013590565b6000806000606084860312156137f657600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b600281106138335761383361380d565b9052565b60005b8381101561385257818101518382015260200161383a565b50506000910152565b60008151808452613873816020860160208601613837565b601f01601f19169290920160200192915050565b613892828251613823565b6020810151602083015260018060a01b0360408201511660408301526060810151606083015260808101516080830152600060a082015160e060a08501526138dd60e085018261385b565b60c093840151949093019390935250919050565b6020815260006130636020830184613887565b600581106138335761383361380d565b61391e8188613904565b85602082015284604082015260c06060820152600061394060c083018661385b565b60808301949094525060a00152949350505050565b61395f8189613823565b86602082015260018060a01b038616604082015284606082015283608082015260e060a0820152600061399560e083018561385b565b90508260c083015298975050505050505050565b600080600080600080600060c0888a0312156139c457600080fd5b873596506020880135955060408801356139dd81613559565b945060608801359350608088013567ffffffffffffffff811115613a0057600080fd5b613a0c8a828b016134c4565b989b979a5095989497959660a090950135949350505050565b60008060008060008060808789031215613a3e57600080fd5b8635955060208701359450604087013567ffffffffffffffff80821115613a6457600080fd5b613a708a838b016134c4565b90965094506060890135915080821115613a8957600080fd5b50613a9689828a016134c4565b979a9699509497509295939492505050565b613ab3828251613904565b60208101516020830152604081015160408301526000606082015160c06060850152613ae260c085018261385b565b90506080830151608085015260a083015160a08501528091505092915050565b604081526000613b156040830185613aa8565b82810360208401526131958185613887565b6020815260006130636020830184613aa8565b600060208284031215613b4c57600080fd5b815161306381613792565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613bbf57607f821691505b602082108103613bdf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610edf57600081815260208120601f850160051c81016020861015613c0c5750805b601f850160051c820191505b8181101561174d57828155600101613c18565b67ffffffffffffffff831115613c4357613c436136b8565b613c5783613c518354613bab565b83613be5565b6000601f841160018114613c8b5760008515613c735750838201355b600019600387901b1c1916600186901b178355613ce5565b600083815260209020601f19861690835b82811015613cbc5786850135825560209485019460019092019101613c9c565b5086821015613cd95760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000613d29602083018486613cec565b949350505050565b815167ffffffffffffffff811115613d4b57613d4b6136b8565b613d5f81613d598454613bab565b84613be5565b602080601f831160018114613d945760008415613d7c5750858301515b600019600386901b1c1916600185901b17855561174d565b600085815260208120601f198616915b82811015613dc357888601518255948401946001909101908401613da4565b5085821015613de15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600060018201613e1957613e19613df1565b5060010190565b60006101008b83528a6020840152806040840152613e418184018a8c613cec565b915050613e516060830188613823565b6001600160a01b0395909516608082015260a081019390935260c083019190915260e09091015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b808202811582820484141761081a5761081a613df1565b600082613f4d57634e487b7160e01b600052601260045260246000fd5b500490565b87815286602082015260c060408201526000613f7260c083018789613cec565b6001600160a01b0395909516606083015250608081019290925260a090910152949350505050565b858152846020820152836040820152608060608201526000613fc0608083018486613cec565b979650505050505050565b600060208284031215613fdd57600080fd5b5051919050565b600060208284031215613ff657600080fd5b815161306381613559565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614107816017850160208801613837565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614138816028840160208801613837565b01602801949350505050565b602081526000613063602083018461385b565b8082018082111561081a5761081a613df1565b634e487b7160e01b600052603260045260246000fd5b60008161418f5761418f613df1565b506000190190565b600082516141a9818460208701613837565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220810e0f3326770d5cbf2063fa706b979e196534c448759006348f0d89ef76705a64736f6c63430008110033", - "deployedBytecode": "0x6080604052600436106102305760003560e01c8063715018a61161012e578063c2cfee27116100ab578063d547741f1161006f578063d547741f1461072b578063ef0e239b1461074b578063f2fde38b14610778578063f6c53d9b14610798578063f9eaee0d146107af57600080fd5b8063c2cfee2714610669578063c75858d51461069c578063ccaa7d2a146106bc578063d338ec9a146106ea578063d4eee1fc146106fd57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a7d5eaea146105ca578063aba21009146105ea578063b5735c1e14610617578063c22c4f431461063757600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b80631499f9e6116102035780631499f9e6146102bf578063156b39aa146102f85780631db087ff1461031d578063248a9ca31461034b57806326d006681461037b57600080fd5b806301ffc9a714610235578063089b7c731461026a5780630e0660251461028c57806313ca98db146102ac575b600080fd5b34801561024157600080fd5b50610255610250366004613478565b6107e9565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a6102853660046134a2565b610820565b005b34801561029857600080fd5b5061028a6102a7366004613506565b6109c3565b61028a6102ba36600461356e565b610b8b565b3480156102cb57600080fd5b50610130546102e0906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561030457600080fd5b5061030f6101365481565b604051908152602001610261565b34801561032957600080fd5b5061030f610338366004613624565b6101336020526000908152604090205481565b34801561035757600080fd5b5061030f610366366004613624565b600090815260fc602052604090206001015490565b34801561038757600080fd5b5061028a61039636600461363d565b610e57565b3480156103a757600080fd5b5061028a6103b636600461365a565b610eba565b3480156103c757600080fd5b5061028a6103d636600461365a565b610ee4565b3480156103e757600080fd5b5061028a6103f636600461363d565b610f72565b34801561040757600080fd5b5061028a61041636600461363d565b611051565b34801561042757600080fd5b5061028a610436366004613624565b6110aa565b34801561044757600080fd5b5061028a61045636600461368a565b6110f2565b61028a6104693660046136ce565b611269565b34801561047a57600080fd5b5061030f611335565b34801561048f57600080fd5b5061025561049e36600461363d565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b5061030f7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a6113e8565b34801561051157600080fd5b5061054061052036600461363d565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a6105723660046137a0565b6113fc565b34801561058357600080fd5b506033546001600160a01b03166102e0565b3480156105a157600080fd5b506102556105b036600461365a565b6114d1565b3480156105c157600080fd5b5061030f600081565b3480156105d657600080fd5b5061028a6105e53660046137e1565b6114fc565b3480156105f657600080fd5b5061060a6106053660046134a2565b61157e565b60405161026191906138f1565b34801561062357600080fd5b5061028a6106323660046134a2565b6116b0565b34801561064357600080fd5b50610657610652366004613624565b611755565b60405161026196959493929190613914565b34801561067557600080fd5b506106896106843660046134a2565b611819565b6040516102619796959493929190613955565b3480156106a857600080fd5b5061028a6106b73660046139a9565b6118fa565b3480156106c857600080fd5b5061030f6106d7366004613624565b6101346020526000908152604090205481565b61030f6106f8366004613a25565b611c1e565b34801561070957600080fd5b5061071d6107183660046134a2565b611e1e565b604051610261929190613b02565b34801561073757600080fd5b5061028a61074636600461365a565b61209a565b34801561075757600080fd5b5061076b610766366004613624565b6120bf565b6040516102619190613b27565b34801561078457600080fd5b5061028a61079336600461363d565b612253565b3480156107a457600080fd5b5061030f61012e5481565b3480156107bb57600080fd5b506102556107ca36600461363d565b6001600160a01b03166000908152610135602052604090205460ff1690565b60006001600160e01b03198216637965db0b60e01b148061081a57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e58261083d6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610887573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ab9190613b3a565b6108d05760405162461bcd60e51b81526004016108c790613b57565b60405180910390fd5b600082815261013160205260409020600181015484146109225760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff16600481111561093a5761093a61380d565b1461097f5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5484906001600160a01b0316632fa117e5826109e06122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4e9190613b3a565b610a6a5760405162461bcd60e51b81526004016108c790613b57565b60008481526101316020526040902060018101548614610abc5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b6000815460ff166004811115610ad457610ad461380d565b14610b195760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108c7565b602e8314610b395760405162461bcd60e51b81526004016108c790613b86565b60038101610b48848683613c2b565b50847f1cae99404f615a4039d85b1009cb70622aae6d64f671e8b1b191d9269847d43e8585604051610b7b929190613d15565b60405180910390a2505050505050565b61012f548a906001600160a01b0316632fa117e582610ba86122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610bf2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c169190613b3a565b610c325760405162461bcd60e51b81526004016108c790613b57565b610c438b8b8b8b8b8b8b8a8a6122d8565b6040805160e0810190915280600081526020018c81526020018a6001600160a01b0316815260200189815260200188815260200187878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092018290525093855250505060209182018790528c8152610132825260408082208f83529092522081518154829060ff191660018381811115610ce857610ce861380d565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a08201516005820190610d459082613d31565b5060c0919091015160069091015560008b81526101336020526040902054158015610d7d575060008b81526101346020526040902054155b15610de25761012f546040516383ce205b60e01b8152600481018d90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610dc957600080fd5b505af1158015610ddd573d6000803e3d6000fd5b505050505b60008b815261013460205260408120805491610dfd83613e07565b91905055507f11a8bc6241aa94a07af6c545ce8ed2dca2aaede88d02fd2b7e2d7ed28ccf1d4a8a8c888860008e8e8e8c604051610e4299989796959493929190613e20565b60405180910390a15050505050505050505050565b610e5f6126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b600082815260fc6020526040902060010154610ed581612720565b610edf8383612731565b505050565b610eec6122c9565b6001600160a01b0316816001600160a01b031614610f645760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108c7565b610f6e82826127b8565b5050565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000163003610fba5760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110036000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146110295760405162461bcd60e51b81526004016108c790613ecd565b6110328161283d565b6040805160008082526020820190925261104e91839190612845565b50565b6110596126a7565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610eaf565b60006110b581612720565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111125750600054600160ff909116105b8061112c5750303b15801561112c575060005460ff166001145b61118f5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108c7565b6000805460ff1916600117905580156111b2576000805461ff0019166101001790555b6111ba6129b0565b6111c26129df565b6111ca6129df565b6111dc60006111d76122c9565b612a06565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e5561121e601e6110aa565b8015610edf576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036112b15760405162461bcd60e51b81526004016108c790613e81565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166112fa6000805160206141b4833981519152546001600160a01b031690565b6001600160a01b0316146113205760405162461bcd60e51b81526004016108c790613ecd565b6113298261283d565b610f6e82826001612845565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113d55760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108c7565b506000805160206141b483398151915290565b6113f06126a7565b6113fa6000612a10565b565b6114046126a7565b6001600160a01b038316158015611419575081155b156114665760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108c7565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161125c565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f61152681612720565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611586613431565b60008381526101326020908152604080832085845290915290819020815160e081019092528054829060ff1660018111156115c3576115c361380d565b60018111156115d4576115d461380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a09092019161161c90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461164890613bab565b80156116955780601f1061166a57610100808354040283529160200191611695565b820191906000526020600020905b81548152906001019060200180831161167857829003601f168201915b50505050508152602001600682015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f6116da81612720565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611714866064613f19565b61171e9190613f30565b905061013654811061173a57825460ff1916600217835561174d565b8254600490849060ff1916600183611571565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff90941694929391929161178a90613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546117b690613bab565b80156118035780601f106117d857610100808354040283529160200191611803565b820191906000526020600020905b8154815290600101906020018083116117e657829003601f168201915b5050505050908060040154908060050154905086565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b0390941694929391929161187190613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461189d90613bab565b80156118ea5780601f106118bf576101008083540402835291602001916118ea565b820191906000526020600020905b8154815290600101906020018083116118cd57829003601f168201915b5050505050908060060154905087565b61012f5487906001600160a01b0316632fa117e5826119176122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611961573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119859190613b3a565b6119a15760405162461bcd60e51b81526004016108c790613b57565b6001600160a01b0386166000908152610135602052604090205460ff166119fe5760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115611a3857611a3861380d565b14611a7a5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b89816001015414611abd5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108c7565b602e8514611add5760405162461bcd60e51b81526004016108c790613b86565b6001815460ff166001811115611af557611af561380d565b03611b365760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108c7565b6001600160a01b03881660009081526101356020526040902060010154871015611b935760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b6002810180546001600160a01b0319166001600160a01b038a161790556003810187905560058101611bc6868883613c2b565b50600681018490556040517f0f68ab04ab4935c8598d30f2c12ec34265575059bb4cae481b4d632cc43db81e90611c0a908b908d908a908a908e908e908c90613f52565b60405180910390a150505050505050505050565b61012f5460009087906001600160a01b0316632fa117e582611c3e6122c9565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cac9190613b3a565b611cc85760405162461bcd60e51b81526004016108c790613b57565b611cd6888888888888612a62565b61012e80549081906000611ce983613e07565b9091555050600081815261013160205260409020805460ff19168155600181018a905560038101611d1b888a83613c2b565b506005810189905560008a81526101336020526040902054158015611d4d575060008a81526101346020526040902054155b15611db25761012f546040516383ce205b60e01b8152600481018c90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b505050505b60008a815261013360205260408120805491611dcd83613e07565b91905055507f8f3fc1086abc1020f602edd700a9ae5801b250c9d110af9e54022d7cc5df7bee828b8b8b8b604051611e09959493929190613f9a565b60405180910390a15098975050505050505050565b611e586040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b611e60613431565b60008481526101316020526040808220815160c081019092528054829060ff166004811115611e9157611e9161380d565b6004811115611ea257611ea261380d565b81526020016001820154815260200160028201548152602001600382018054611eca90613bab565b80601f0160208091040260200160405190810160405280929190818152602001828054611ef690613bab565b8015611f435780601f10611f1857610100808354040283529160200191611f43565b820191906000526020600020905b815481529060010190602001808311611f2657829003601f168201915b5050509183525050600482015460208083019190915260059092015460409182015260008881526101328352818120888252909252808220815160e0810190925280549394509192909190829060ff166001811115611fa457611fa461380d565b6001811115611fb557611fb561380d565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611ffd90613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461202990613bab565b80156120765780601f1061204b57610100808354040283529160200191612076565b820191906000526020600020905b81548152906001019060200180831161205957829003601f168201915b505050918352505060069190910154602090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120b581612720565b610edf83836127b8565b6120f96040805160c08101909152806000815260200160008152602001600081526020016060815260200160008152602001600081525090565b61012e54821061214b5760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108c7565b6000828152610131602052604090819020815160c081019092528054829060ff16600481111561217d5761217d61380d565b600481111561218e5761218e61380d565b815260200160018201548152602001600282015481526020016003820180546121b690613bab565b80601f01602080910402602001604051908101604052809291908181526020018280546121e290613bab565b801561222f5780601f106122045761010080835404028352916020019161222f565b820191906000526020600020905b81548152906001019060200180831161221257829003601f168201915b50505050508152602001600482015481526020016005820154815250509050919050565b61225b6126a7565b6001600160a01b0381166122c05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108c7565b61104e81612a10565b60006122d3612c0d565b905090565b6001600160a01b0387166000908152610135602052604090205460ff166123355760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108c7565b61013054604051634a7ab1d560e01b8152600481018790526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612380573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123a49190613fcb565b90508034146123ea5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b6001600160a01b038816600090815261013560205260409020600101548710156124475760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108c7565b60008981526101316020526040812090815460ff16600481111561246d5761246d61380d565b146124af5760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108c7565b80600101546000036124f75760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108c7565b60008a8152610132602090815260408083208e84529091529020600101548b900361255d5760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108c7565b8a8160010154036125ba5760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108c7565b602e85146125da5760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612625573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126499190613fe4565b90506001600160a01b038116156126995760008c8c89896040516020016126739493929190614001565b60405160208183030381529060405280519060200120905061269786868385612c46565b505b505050505050505050505050565b6126af6122c9565b6001600160a01b03166126ca6033546001600160a01b031690565b6001600160a01b0316146113fa5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108c7565b61104e8161272c6122c9565b612d3a565b61273b82826114d1565b610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127746122c9565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127c282826114d1565b15610f6e57600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556127f96122c9565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b61104e6126a7565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561287857610edf83612d93565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa9250505080156128d2575060408051601f3d908101601f191682019092526128cf91810190613fcb565b60015b6129355760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108c7565b6000805160206141b483398151915281146129a45760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108c7565b50610edf838383612e2f565b600054610100900460ff166129d75760405162461bcd60e51b81526004016108c790614043565b6113fa612e5a565b600054610100900460ff166113fa5760405162461bcd60e51b81526004016108c790614043565b610f6e8282612731565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051638a98636360e01b8152600481018790526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612aad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ad19190613fcb565b9050803414612b175760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108c7565b602e8414612b375760405162461bcd60e51b81526004016108c790613b86565b61013054604051631fff7f2760e11b8152600481018890526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ba69190613fe4565b90506001600160a01b03811615612c0357600088815261013360209081526040808320549051612bdd928c92918b918b910161408e565b604051602081830303815290604052805190602001209050612c0185858385612c46565b505b5050505050505050565b600060143610801590612c2f57503360009081526065602052604090205460ff165b15612c41575060131936013560601c90565b503390565b6000612c9f836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90506000612ce38287878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612e9192505050565b9050806001600160a01b0316836001600160a01b03161461174d5760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108c7565b612d4482826114d1565b610f6e57612d5181612eb5565b612d5c836020612ec7565b604051602001612d6d9291906140cf565b60408051601f198184030181529082905262461bcd60e51b82526108c791600401614144565b6001600160a01b0381163b612e005760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108c7565b6000805160206141b483398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b612e388361306a565b600082511180612e455750805b15610edf57612e5483836130aa565b50505050565b600054610100900460ff16612e815760405162461bcd60e51b81526004016108c790614043565b6113fa612e8c6122c9565b612a10565b6000806000612ea0858561319e565b91509150612ead816131e0565b509392505050565b606061081a6001600160a01b03831660145b60606000612ed6836002613f19565b612ee1906002614157565b67ffffffffffffffff811115612ef957612ef96136b8565b6040519080825280601f01601f191660200182016040528015612f23576020820181803683370190505b509050600360fc1b81600081518110612f3e57612f3e61416a565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110612f6d57612f6d61416a565b60200101906001600160f81b031916908160001a9053506000612f91846002613f19565b612f9c906001614157565b90505b6001811115613014576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110612fd057612fd061416a565b1a60f81b828281518110612fe657612fe661416a565b60200101906001600160f81b031916908160001a90535060049490941c9361300d81614180565b9050612f9f565b5083156130635760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108c7565b9392505050565b61307381612d93565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6131125760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108c7565b600080846001600160a01b03168460405161312d9190614197565b600060405180830381855af49150503d8060008114613168576040519150601f19603f3d011682016040523d82523d6000602084013e61316d565b606091505b509150915061319582826040518060600160405280602781526020016141d46027913961332a565b95945050505050565b60008082516041036131d45760208301516040840151606085015160001a6131c887828585613343565b94509450505050612093565b50600090506002612093565b60008160048111156131f4576131f461380d565b036131fc5750565b60018160048111156132105761321061380d565b0361325d5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108c7565b60028160048111156132715761327161380d565b036132be5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108c7565b60038160048111156132d2576132d261380d565b0361104e5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108c7565b60608315613339575081613063565b6130638383613407565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561337a57506000905060036133fe565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156133ce573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166133f7576000600192509250506133fe565b9150600090505b94509492505050565b8151156134175781518083602001fd5b8060405162461bcd60e51b81526004016108c79190614144565b6040805160e0810190915280600081526020016000815260200160006001600160a01b03168152602001600081526020016000815260200160608152602001600081525090565b60006020828403121561348a57600080fd5b81356001600160e01b03198116811461306357600080fd5b600080604083850312156134b557600080fd5b50508035926020909101359150565b60008083601f8401126134d657600080fd5b50813567ffffffffffffffff8111156134ee57600080fd5b60208301915083602082850101111561209357600080fd5b6000806000806060858703121561351c57600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561354157600080fd5b61354d878288016134c4565b95989497509550505050565b6001600160a01b038116811461104e57600080fd5b6000806000806000806000806000806101008b8d03121561358e57600080fd5b8a35995060208b0135985060408b01356135a781613559565b975060608b0135965060808b0135955060a08b013567ffffffffffffffff808211156135d257600080fd5b6135de8e838f016134c4565b909750955060c08d0135945060e08d01359150808211156135fe57600080fd5b5061360b8d828e016134c4565b915080935050809150509295989b9194979a5092959850565b60006020828403121561363657600080fd5b5035919050565b60006020828403121561364f57600080fd5b813561306381613559565b6000806040838503121561366d57600080fd5b82359150602083013561367f81613559565b809150509250929050565b6000806040838503121561369d57600080fd5b82356136a881613559565b9150602083013561367f81613559565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156136e157600080fd5b82356136ec81613559565b9150602083013567ffffffffffffffff8082111561370957600080fd5b818501915085601f83011261371d57600080fd5b81358181111561372f5761372f6136b8565b604051601f8201601f19908116603f01168101908382118183101715613757576137576136b8565b8160405282815288602084870101111561377057600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461104e57600080fd5b6000806000606084860312156137b557600080fd5b83356137c081613559565b925060208401356137d081613792565b929592945050506040919091013590565b6000806000606084860312156137f657600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b600281106138335761383361380d565b9052565b60005b8381101561385257818101518382015260200161383a565b50506000910152565b60008151808452613873816020860160208601613837565b601f01601f19169290920160200192915050565b613892828251613823565b6020810151602083015260018060a01b0360408201511660408301526060810151606083015260808101516080830152600060a082015160e060a08501526138dd60e085018261385b565b60c093840151949093019390935250919050565b6020815260006130636020830184613887565b600581106138335761383361380d565b61391e8188613904565b85602082015284604082015260c06060820152600061394060c083018661385b565b60808301949094525060a00152949350505050565b61395f8189613823565b86602082015260018060a01b038616604082015284606082015283608082015260e060a0820152600061399560e083018561385b565b90508260c083015298975050505050505050565b600080600080600080600060c0888a0312156139c457600080fd5b873596506020880135955060408801356139dd81613559565b945060608801359350608088013567ffffffffffffffff811115613a0057600080fd5b613a0c8a828b016134c4565b989b979a5095989497959660a090950135949350505050565b60008060008060008060808789031215613a3e57600080fd5b8635955060208701359450604087013567ffffffffffffffff80821115613a6457600080fd5b613a708a838b016134c4565b90965094506060890135915080821115613a8957600080fd5b50613a9689828a016134c4565b979a9699509497509295939492505050565b613ab3828251613904565b60208101516020830152604081015160408301526000606082015160c06060850152613ae260c085018261385b565b90506080830151608085015260a083015160a08501528091505092915050565b604081526000613b156040830185613aa8565b82810360208401526131958185613887565b6020815260006130636020830184613aa8565b600060208284031215613b4c57600080fd5b815161306381613792565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c90821680613bbf57607f821691505b602082108103613bdf57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610edf57600081815260208120601f850160051c81016020861015613c0c5750805b601f850160051c820191505b8181101561174d57828155600101613c18565b67ffffffffffffffff831115613c4357613c436136b8565b613c5783613c518354613bab565b83613be5565b6000601f841160018114613c8b5760008515613c735750838201355b600019600387901b1c1916600186901b178355613ce5565b600083815260209020601f19861690835b82811015613cbc5786850135825560209485019460019092019101613c9c565b5086821015613cd95760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b602081526000613d29602083018486613cec565b949350505050565b815167ffffffffffffffff811115613d4b57613d4b6136b8565b613d5f81613d598454613bab565b84613be5565b602080601f831160018114613d945760008415613d7c5750858301515b600019600386901b1c1916600185901b17855561174d565b600085815260208120601f198616915b82811015613dc357888601518255948401946001909101908401613da4565b5085821015613de15787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600060018201613e1957613e19613df1565b5060010190565b60006101008b83528a6020840152806040840152613e418184018a8c613cec565b915050613e516060830188613823565b6001600160a01b0395909516608082015260a081019390935260c083019190915260e09091015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b808202811582820484141761081a5761081a613df1565b600082613f4d57634e487b7160e01b600052601260045260246000fd5b500490565b87815286602082015260c060408201526000613f7260c083018789613cec565b6001600160a01b0395909516606083015250608081019290925260a090910152949350505050565b858152846020820152836040820152608060608201526000613fc0608083018486613cec565b979650505050505050565b600060208284031215613fdd57600080fd5b5051919050565b600060208284031215613ff657600080fd5b815161306381613559565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614107816017850160208801613837565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351614138816028840160208801613837565b01602801949350505050565b602081526000613063602083018461385b565b8082018082111561081a5761081a613df1565b634e487b7160e01b600052603260045260246000fd5b60008161418f5761418f613df1565b506000190190565b600082516141a9818460208701613837565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220810e0f3326770d5cbf2063fa706b979e196534c448759006348f0d89ef76705a64736f6c63430008110033", + "bytecode": "0x60a0604052306080523480156200001557600080fd5b506200002062000026565b620000e8565b600054610100900460ff1615620000935760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff9081161015620000e6576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b60805161469e620001206000396000818161102e0152818161106e015281816113250152818161136501526113f4015261469e6000f3fe6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b50610255610250366004613872565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a61028536600461389c565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613900565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613970565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613970565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a61038336600461399e565b610cde565b6102fc6103963660046139bb565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613a5b565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613a5b565b610f96565b3480156103e757600080fd5b5061028a6103f636600461399e565b611024565b34801561040757600080fd5b5061028a61041636600461399e565b611103565b34801561042757600080fd5b5061028a610436366004613970565b61115c565b34801561044757600080fd5b5061028a610456366004613a8b565b6111a4565b61028a610469366004613acf565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e36600461399e565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b5061054061052036600461399e565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a610572366004613ba1565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613a5b565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d8366004613be2565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613c8f565b6119dc565b34801561060957600080fd5b5061061d61061836600461389c565b611a5e565b6040516102619190613dad565b34801561063657600080fd5b5061028a61064536600461389c565b611b9b565b34801561065657600080fd5b5061066a610665366004613970565b611c40565b604051610261989796959493929190613dd0565b34801561068a57600080fd5b5061069e61069936600461389c565b611d1d565b604051610261989796959493929190613e2e565b3480156106be57600080fd5b506102fc6106cd366004613970565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb36600461389c565b611e04565b604051610261929190613eff565b34801561071a57600080fd5b5061028a610729366004613a5b565b61207a565b34801561073a57600080fd5b5061074e610749366004613970565b61209f565b6040516102619190613f24565b34801561076757600080fd5b5061028a61077636600461399e565b61221f565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad36600461399e565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613f37565b612295565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613f98565b6108d35760405162461bcd60e51b81526004016108ca90613fb5565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613cbb565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613f98565b610a6d5760405162461bcd60e51b81526004016108ca90613fb5565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613cbb565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613fe4565b6001815460ff166001811115610b6457610b64613cbb565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983614089565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90614173565b60405180910390a150505050505050505050565b610ce66124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613f98565b610deb5760405162461bcd60e51b81526004016108ca90613fb5565b610dfa8a8a8a8a8a8a8a612545565b61012e80549081906000610e0d836141c8565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83614089565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f15836141c8565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f5597969594939291906141e1565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161274e565b610f91838361275f565b505050565b610f9e6124bd565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826127e6565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b5600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca90614272565b6110e48161286b565b6040805160008082526020820190925261110091839190612873565b50565b61110b6124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161274e565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6129de565b611274612a0d565b61127c612a0d565b61128e60006112896124bd565b612a34565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca90614272565b6113db8261286b565b61102082826001612873565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061462283398151915290565b6114a26124cc565b6114ac6000612a3e565b565b6114b66124cc565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613f98565b6116555760405162461bcd60e51b81526004016108ca90613fb5565b60008a81526101316020526040808220815161010081019092528054829060ff16600481111561168757611687613cbb565b600481111561169857611698613cbb565b815260200160018201548152602001600282015481526020016003820180546116c090614009565b80601f01602080910402602001604051908101604052809291908181526020018280546116ec90614009565b80156117395780601f1061170e57610100808354040283529160200191611739565b820191906000526020600020905b81548152906001019060200180831161171c57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015290506117878c8c8c8c8c8c8b8b8b612a90565b60408051610100810190915280600081526020018d81526020018260c001516001600160a01b031681526020018b81526020018a815260200189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561186357611863613cbb565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906118c090826142be565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611901575060008c81526101346020526040902054155b156119665761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611981836141c8565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516119c69998979695949392919061437e565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611a068161274e565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611a666137d4565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611aa457611aa4613cbb565b6001811115611ab557611ab5613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611afd90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611b2990614009565b8015611b765780601f10611b4b57610100808354040283529160200191611b76565b820191906000526020600020905b815481529060010190602001808311611b5957829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611bc58161274e565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611bff8660646143d5565b611c0991906143ec565b9050610136548110611c2557825460ff19166002178355611c38565b8254600490849060ff1916600183611a51565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611c7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614009565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611d7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611da190614009565b8015611dee5780601f10611dc357610100808354040283529160200191611dee565b820191906000526020600020905b815481529060010190602001808311611dd157829003601f168201915b5050505050908060060154908060070154905088565b611e0c613823565b611e146137d4565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611e4657611e46613cbb565b6004811115611e5757611e57613cbb565b81526020016001820154815260200160028201548152602001600382018054611e7f90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611eab90614009565b8015611ef85780601f10611ecd57610100808354040283529160200191611ef8565b820191906000526020600020905b815481529060010190602001808311611edb57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611f7b57611f7b613cbb565b6001811115611f8c57611f8c613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611fd490614009565b80601f016020809104026020016040519081016040528092919081815260200182805461200090614009565b801561204d5780601f106120225761010080835404028352916020019161204d565b820191906000526020600020905b81548152906001019060200180831161203057829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120958161274e565b610f9183836127e6565b6120a7613823565b61012e5482106120f95760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561212c5761212c613cbb565b600481111561213d5761213d613cbb565b8152602001600182015481526020016002820154815260200160038201805461216590614009565b80601f016020809104026020016040519081016040528092919081815260200182805461219190614009565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6122276124cc565b6001600160a01b03811661228c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b61110081612a3e565b61012f5485906001600160a01b0316632fa117e5826122b26124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123209190613f98565b61233c5760405162461bcd60e51b81526004016108ca90613fb5565b6000858152610131602052604090206001810154871461238e5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff1660048111156123a6576123a6613cbb565b146123eb5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e831461240b5760405162461bcd60e51b81526004016108ca90613fe4565b806007015485101561245f5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161246e848683614089565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d035880916906124ac908890879087908a9061440e565b60405180910390a150505050505050565b60006124c7612fb0565b905090565b6124d46124bd565b6001600160a01b03166124ef6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b49190614439565b90508034146125fa5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e851461261a5760405162461bcd60e51b81526004016108ca90613fe4565b6001600160a01b0382166000908152610135602052604090205460ff166126775760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156126c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e69190614452565b90506001600160a01b038116156127435760008981526101336020908152604080832054905161271d928d92918c918c910161446f565b60405160208183030381529060405280519060200120905061274186868385612fe9565b505b505050505050505050565b6111008161275a6124bd565b6130dd565b6127698282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127a26124bd565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127f08282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556128276124bd565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006124cc565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156128a657610f9183613136565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612900575060408051601f3d908101601f191682019092526128fd91810190614439565b60015b6129635760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061462283398151915281146129d25760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f918383836131d2565b600054610100900460ff16612a055760405162461bcd60e51b81526004016108ca906144b0565b6114ac6131fd565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906144b0565b611020828261275f565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff9190614439565b9050803414612b455760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020526040808220815161010081019092528054829060ff166004811115612b7757612b77613cbb565b6004811115612b8857612b88613cbb565b81526020016001820154815260200160028201548152602001600382018054612bb090614009565b80601f0160208091040260200160405190810160405280929190818152602001828054612bdc90614009565b8015612c295780601f10612bfe57610100808354040283529160200191612c29565b820191906000526020600020905b815481529060010190602001808311612c0c57829003601f168201915b5050505050815260200160048201548152602001600582015481526020016006820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600782015481525050905061013560008260c001516001600160a01b03166001600160a01b03168152602001908152602001600020600101548160e001518a612cbf91906144fb565b1015612cfe5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b600081516004811115612d1357612d13613cbb565b14612d555760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060200151600003612d9d5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612e035760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816020015103612e605760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612e805760405162461bcd60e51b81526004016108ca90613fe4565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eef9190614452565b90506001600160a01b03811615612f3f5760008c8c8a8a604051602001612f19949392919061450e565b604051602081830303815290604052805190602001209050612f3d87878385612fe9565b505b8315612fa25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612f8957600080fd5b505afa158015612f9d573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612fd257503360009081526065602052604090205460ff165b15612fe4575060131936013560601c90565b503390565b6000613042836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006130868287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061323492505050565b9050806001600160a01b0316836001600160a01b031614611c385760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b6130e78282611583565b611020576130f481613258565b6130ff83602061326a565b604051602001613110929190614550565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016145c5565b6001600160a01b0381163b6131a35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061462283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6131db8361340d565b6000825111806131e85750805b15610f91576131f7838361344d565b50505050565b600054610100900460ff166132245760405162461bcd60e51b81526004016108ca906144b0565b6114ac61322f6124bd565b612a3e565b60008060006132438585613541565b9150915061325081613583565b509392505050565b606061081d6001600160a01b03831660145b606060006132798360026143d5565b6132849060026144fb565b67ffffffffffffffff81111561329c5761329c613ab9565b6040519080825280601f01601f1916602001820160405280156132c6576020820181803683370190505b509050600360fc1b816000815181106132e1576132e16145d8565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613310576133106145d8565b60200101906001600160f81b031916908160001a90535060006133348460026143d5565b61333f9060016144fb565b90505b60018111156133b7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613373576133736145d8565b1a60f81b828281518110613389576133896145d8565b60200101906001600160f81b031916908160001a90535060049490941c936133b0816145ee565b9050613342565b5083156134065760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61341681613136565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6134b55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516134d09190614605565b600060405180830381855af49150503d806000811461350b576040519150601f19603f3d011682016040523d82523d6000602084013e613510565b606091505b50915091506135388282604051806060016040528060278152602001614642602791396136cd565b95945050505050565b60008082516041036135775760208301516040840151606085015160001a61356b878285856136e6565b94509450505050612073565b50600090506002612073565b600081600481111561359757613597613cbb565b0361359f5750565b60018160048111156135b3576135b3613cbb565b036136005760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561361457613614613cbb565b036136615760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561367557613675613cbb565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156136dc575081613406565b61340683836137aa565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561371d57506000905060036137a1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613771573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661379a576000600192509250506137a1565b9150600090505b94509492505050565b8151156137ba5781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906145c5565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561388457600080fd5b81356001600160e01b03198116811461340657600080fd5b600080604083850312156138af57600080fd5b50508035926020909101359150565b60008083601f8401126138d057600080fd5b50813567ffffffffffffffff8111156138e857600080fd5b60208301915083602082850101111561207357600080fd5b600080600080600080600060c0888a03121561391b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561394757600080fd5b6139538a828b016138be565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561398257600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156139b057600080fd5b813561340681613989565b60008060008060008060008060c0898b0312156139d757600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156139fd57600080fd5b613a098c838d016138be565b909850965060608b0135915080821115613a2257600080fd5b50613a2f8b828c016138be565b9095509350506080890135613a4381613989565b8092505060a089013590509295985092959890939650565b60008060408385031215613a6e57600080fd5b823591506020830135613a8081613989565b809150509250929050565b60008060408385031215613a9e57600080fd5b8235613aa981613989565b91506020830135613a8081613989565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613ae257600080fd5b8235613aed81613989565b9150602083013567ffffffffffffffff80821115613b0a57600080fd5b818501915085601f830112613b1e57600080fd5b813581811115613b3057613b30613ab9565b604051601f8201601f19908116603f01168101908382118183101715613b5857613b58613ab9565b81604052828152886020848701011115613b7157600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b600080600060608486031215613bb657600080fd5b8335613bc181613989565b92506020840135613bd181613b93565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613c0257600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613c3657600080fd5b613c428e838f016138be565b909850965060a08d0135955060c08d0135915080821115613c6257600080fd5b50613c6f8d828e016138be565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613ca457600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613ce157613ce1613cbb565b9052565b60005b83811015613d00578181015183820152602001613ce8565b50506000910152565b60008151808452613d21816020860160208601613ce5565b601f01601f19169290920160200192915050565b6000610100613d45848451613cd1565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613d8c82860182613d09565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006134066020830184613d35565b60058110613ce157613ce1613cbb565b6000610100613ddf838c613dc0565b896020840152886040840152806060840152613dfd81840189613d09565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613e3d838c613cd1565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613e6f81840187613d09565b60c0840195909552505060e001529695505050505050565b6000610100613e97848451613dc0565b60208301516020850152604083015160408501526060830151816060860152613ec282860182613d09565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613f126040830185613e87565b82810360208401526135388185613d35565b6020815260006134066020830184613e87565b600080600080600060808688031215613f4f57600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613f7b57600080fd5b613f87888289016138be565b969995985093965092949392505050565b600060208284031215613faa57600080fd5b815161340681613b93565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c9082168061401d57607f821691505b60208210810361403d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c8101602086101561406a5750805b601f850160051c820191505b81811015611c3857828155600101614076565b67ffffffffffffffff8311156140a1576140a1613ab9565b6140b5836140af8354614009565b83614043565b6000601f8411600181146140e957600085156140d15750838201355b600019600387901b1c1916600186901b178355614143565b600083815260209020601f19861690835b8281101561411a57868501358255602094850194600190920191016140fa565b50868210156141375760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c06040820152600061419360c08301878961414a565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016141da576141da6141b2565b5060010190565b87815286602082015285604082015260c06060820152600061420760c08301868861414a565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156142d8576142d8613ab9565b6142ec816142e68454614009565b84614043565b602080601f83116001811461432157600084156143095750858301515b600019600386901b1c1916600185901b178555611c38565b600085815260208120601f198616915b8281101561435057888601518255948401946001909101908401614331565b508582101561436e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a602084015280604084015261439f8184018a8c61414a565b9150506143af6060830188613cd1565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d6141b2565b60008261440957634e487b7160e01b600052601260045260246000fd5b500490565b84815260606020820152600061442860608301858761414a565b905082604083015295945050505050565b60006020828403121561444b57600080fd5b5051919050565b60006020828403121561446457600080fd5b815161340681613989565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d6141b2565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614588816017850160208801613ce5565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516145b9816028840160208801613ce5565b01602801949350505050565b6020815260006134066020830184613d09565b634e487b7160e01b600052603260045260246000fd5b6000816145fd576145fd6141b2565b506000190190565b60008251614617818460208701613ce5565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204101a0ea1f12070439ff1321a6a5682dbe115cfb89975139083fc58ba5f80b4864736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106102305760003560e01c8063715018a61161012e578063c22c4f43116100ab578063ef0e239b1161006f578063ef0e239b1461072e578063f2fde38b1461075b578063f6c53d9b1461077b578063f9eaee0d14610792578063ff420375146107cc57600080fd5b8063c22c4f431461064a578063c2cfee271461067e578063ccaa7d2a146106b2578063d4eee1fc146106e0578063d547741f1461070e57600080fd5b8063a217fddf116100f2578063a217fddf146105b5578063a24bd889146105ca578063a7d5eaea146105dd578063aba21009146105fd578063b5735c1e1461062a57600080fd5b8063715018a6146104f057806371da85f9146105055780637c5a72cd146105575780638da5cb5b1461057757806391d148541461059557600080fd5b80632f2ff15d116101bc578063485cc95511610180578063485cc9551461043b5780634f1ef2861461045b57806352d1902d1461046e578063572b6c05146104835780636ce76f30146104bc57600080fd5b80632f2ff15d1461039b57806336568abe146103bb5780633659cfe6146103db5780633751d89c146103fb5780633ca2ad6f1461041b57600080fd5b8063156b39aa11610203578063156b39aa146102e55780631db087ff1461030a578063248a9ca31461033857806326d00668146103685780632afaf2201461038857600080fd5b806301ffc9a714610235578063089b7c731461026a5780631499f9e61461028c578063154664ed146102c5575b600080fd5b34801561024157600080fd5b50610255610250366004613872565b6107ec565b60405190151581526020015b60405180910390f35b34801561027657600080fd5b5061028a61028536600461389c565b610823565b005b34801561029857600080fd5b50610130546102ad906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b3480156102d157600080fd5b5061028a6102e0366004613900565b6109c6565b3480156102f157600080fd5b506102fc6101365481565b604051908152602001610261565b34801561031657600080fd5b506102fc610325366004613970565b6101336020526000908152604090205481565b34801561034457600080fd5b506102fc610353366004613970565b600090815260fc602052604090206001015490565b34801561037457600080fd5b5061028a61038336600461399e565b610cde565b6102fc6103963660046139bb565b610d41565b3480156103a757600080fd5b5061028a6103b6366004613a5b565b610f6c565b3480156103c757600080fd5b5061028a6103d6366004613a5b565b610f96565b3480156103e757600080fd5b5061028a6103f636600461399e565b611024565b34801561040757600080fd5b5061028a61041636600461399e565b611103565b34801561042757600080fd5b5061028a610436366004613970565b61115c565b34801561044757600080fd5b5061028a610456366004613a8b565b6111a4565b61028a610469366004613acf565b61131b565b34801561047a57600080fd5b506102fc6113e7565b34801561048f57600080fd5b5061025561049e36600461399e565b6001600160a01b031660009081526065602052604090205460ff1690565b3480156104c857600080fd5b506102fc7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f81565b3480156104fc57600080fd5b5061028a61149a565b34801561051157600080fd5b5061054061052036600461399e565b610135602052600090815260409020805460019091015460ff9091169082565b604080519215158352602083019190915201610261565b34801561056357600080fd5b5061028a610572366004613ba1565b6114ae565b34801561058357600080fd5b506033546001600160a01b03166102ad565b3480156105a157600080fd5b506102556105b0366004613a5b565b611583565b3480156105c157600080fd5b506102fc600081565b61028a6105d8366004613be2565b6115ae565b3480156105e957600080fd5b5061028a6105f8366004613c8f565b6119dc565b34801561060957600080fd5b5061061d61061836600461389c565b611a5e565b6040516102619190613dad565b34801561063657600080fd5b5061028a61064536600461389c565b611b9b565b34801561065657600080fd5b5061066a610665366004613970565b611c40565b604051610261989796959493929190613dd0565b34801561068a57600080fd5b5061069e61069936600461389c565b611d1d565b604051610261989796959493929190613e2e565b3480156106be57600080fd5b506102fc6106cd366004613970565b6101346020526000908152604090205481565b3480156106ec57600080fd5b506107006106fb36600461389c565b611e04565b604051610261929190613eff565b34801561071a57600080fd5b5061028a610729366004613a5b565b61207a565b34801561073a57600080fd5b5061074e610749366004613970565b61209f565b6040516102619190613f24565b34801561076757600080fd5b5061028a61077636600461399e565b61221f565b34801561078757600080fd5b506102fc61012e5481565b34801561079e57600080fd5b506102556107ad36600461399e565b6001600160a01b03166000908152610135602052604090205460ff1690565b3480156107d857600080fd5b5061028a6107e7366004613f37565b612295565b60006001600160e01b03198216637965db0b60e01b148061081d57506301ffc9a760e01b6001600160e01b03198316145b92915050565b61012f5482906001600160a01b0316632fa117e5826108406124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa15801561088a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ae9190613f98565b6108d35760405162461bcd60e51b81526004016108ca90613fb5565b60405180910390fd5b600082815261013160205260409020600181015484146109255760405162461bcd60e51b815260206004820152600d60248201526c3737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff16600481111561093d5761093d613cbb565b146109825760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b805460ff191660031781556040518381527f853aa4be1ac86f37acfc91d42b57f1fe895205aa6f8f9b7caa77ca257049ab1a9060200160405180910390a150505050565b61012f5487906001600160a01b0316632fa117e5826109e36124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a519190613f98565b610a6d5760405162461bcd60e51b81526004016108ca90613fb5565b60008781526101316020908152604080832061013283528184208c855290925282209091825460ff166004811115610aa757610aa7613cbb565b14610ae95760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b89816001015414610b2c5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b602e8614610b4c5760405162461bcd60e51b81526004016108ca90613fe4565b6001815460ff166001811115610b6457610b64613cbb565b03610ba55760405162461bcd60e51b8152602060048201526011602482015270105b1c9958591e481d985b1a59185d1959607a1b60448201526064016108ca565b60068201546001600160a01b031660009081526101356020526040902060010154881015610c065760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b8315610c695761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015610c5057600080fd5b505afa158015610c64573d6000803e3d6000fd5b505050505b6003810188905560058101610c7f878983614089565b5060068101859055600781018490556040517ffbfaa6f4e508bec40137ac265a7424e16a2d209355b2f4a35de5a80ba8fec1db90610cca908b908d908b908b908e908c908c90614173565b60405180910390a150505050505050505050565b610ce66124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916600117905590519182527f3ef8564460ada92419608d823c014975d98f8104d7d1e68c222967ac6814cd9791015b60405180910390a150565b61012f5460009089906001600160a01b0316632fa117e582610d616124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015610dab573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcf9190613f98565b610deb5760405162461bcd60e51b81526004016108ca90613fb5565b610dfa8a8a8a8a8a8a8a612545565b61012e80549081906000610e0d836141c8565b9091555050600081815261013160205260409020805460ff19168155600181018c905560038101610e3f8a8c83614089565b50600581018b90556006810180546001600160a01b0319166001600160a01b0388161790556007810185905560008c81526101336020526040902054158015610e95575060008c81526101346020526040902054155b15610efa5761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b158015610ee157600080fd5b505af1158015610ef5573d6000803e3d6000fd5b505050505b60008c815261013360205260408120805491610f15836141c8565b91905055507fe7f6435fc92b0ccd6f56395ae67b06f2cdb9680c0179f87f5821431304ad3f3e828d8d8d8d8b8b604051610f5597969594939291906141e1565b60405180910390a1509a9950505050505050505050565b600082815260fc6020526040902060010154610f878161274e565b610f91838361275f565b505050565b610f9e6124bd565b6001600160a01b0316816001600160a01b0316146110165760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016108ca565b61102082826127e6565b5050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016300361106c5760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166110b5600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146110db5760405162461bcd60e51b81526004016108ca90614272565b6110e48161286b565b6040805160008082526020820190925261110091839190612873565b50565b61110b6124cc565b6001600160a01b038116600081815260656020908152604091829020805460ff1916905590519182527fd2d636efcad0cea42e170256f4c5d8b1cd81e47b855557edaf44014e6cc4cee69101610d36565b60006111678161274e565b6101368290556040518281527f577d7afcf67637a2f602cba220bbb292c1d715380dd011bfec748c3f641b2fd29060200160405180910390a15050565b600054610100900460ff16158080156111c45750600054600160ff909116105b806111de5750303b1580156111de575060005460ff166001145b6112415760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016108ca565b6000805460ff191660011790558015611264576000805461ff0019166101001790555b61126c6129de565b611274612a0d565b61127c612a0d565b61128e60006112896124bd565b612a34565b61012f80546001600160a01b038086166001600160a01b031992831617909255610130805492851692909116919091179055600161012e556112d0601e61115c565b8015610f91576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020015b60405180910390a1505050565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036113635760405162461bcd60e51b81526004016108ca90614226565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166113ac600080516020614622833981519152546001600160a01b031690565b6001600160a01b0316146113d25760405162461bcd60e51b81526004016108ca90614272565b6113db8261286b565b61102082826001612873565b6000306001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146114875760405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c000000000000000060648201526084016108ca565b5060008051602061462283398151915290565b6114a26124cc565b6114ac6000612a3e565b565b6114b66124cc565b6001600160a01b0383161580156114cb575081155b156115185760405162461bcd60e51b815260206004820152601d60248201527f4f776e65722063616e27742072656d6f7665204f78206164647265737300000060448201526064016108ca565b6001600160a01b03831660008181526101356020908152604091829020805460ff19168615159081178255600190910185905582519384529083015281018290527f42b585a1da1cff4b571e7a78aea1b4601b1d128de41a0feebd8a77aaf48b9d889060600161130e565b600091825260fc602090815260408084206001600160a01b0393909316845291905290205460ff1690565b61012f548a906001600160a01b0316632fa117e5826115cb6124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa158015611615573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116399190613f98565b6116555760405162461bcd60e51b81526004016108ca90613fb5565b60008a81526101316020526040808220815161010081019092528054829060ff16600481111561168757611687613cbb565b600481111561169857611698613cbb565b815260200160018201548152602001600282015481526020016003820180546116c090614009565b80601f01602080910402602001604051908101604052809291908181526020018280546116ec90614009565b80156117395780601f1061170e57610100808354040283529160200191611739565b820191906000526020600020905b81548152906001019060200180831161171c57829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015290506117878c8c8c8c8c8c8b8b8b612a90565b60408051610100810190915280600081526020018d81526020018260c001516001600160a01b031681526020018b81526020018a815260200189898080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020018781526020018481525061013260008d815260200190815260200160002060008e815260200190815260200160002060008201518160000160006101000a81548160ff0219169083600181111561186357611863613cbb565b02179055506020820151600182015560408201516002820180546001600160a01b0319166001600160a01b03909216919091179055606082015160038201556080820151600482015560a082015160058201906118c090826142be565b5060c0820151600682015560e09091015160079091015560008c81526101336020526040902054158015611901575060008c81526101346020526040902054155b156119665761012f546040516383ce205b60e01b8152600481018e90526001600160a01b03909116906383ce205b90602401600060405180830381600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b505050505b60008c815261013460205260408120805491611981836141c8565b91905055507fabd26455c3256ad90125661f4c1a4c16fecf585ccade21e749c56d8fd44bb1dd8b8d8a8a60008f8f8d8b6040516119c69998979695949392919061437e565b60405180910390a1505050505050505050505050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611a068161274e565b60008481526101316020908152604080832061013283528184208785529092529091208154600160ff1991821681178455808301546002850155600484018690558254909183911682805b0217905550505050505050565b611a666137d4565b60008381526101326020908152604080832085845290915290819020815161010081019092528054829060ff166001811115611aa457611aa4613cbb565b6001811115611ab557611ab5613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611afd90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611b2990614009565b8015611b765780601f10611b4b57610100808354040283529160200191611b76565b820191906000526020600020905b815481529060010190602001808311611b5957829003601f168201915b5050505050815260200160068201548152602001600782015481525050905092915050565b7f2fdac322ee704ce09f0773f7f3f92eb98d5e7c836ee9c056cccd5f61041e5e3f611bc58161274e565b6000838152610131602090815260408083206101328352818420600282015485529092528220600381015491929091611bff8660646143d5565b611c0991906143ec565b9050610136548110611c2557825460ff19166002178355611c38565b8254600490849060ff1916600183611a51565b505050505050565b61013160205260009081526040902080546001820154600283015460038401805460ff909416949293919291611c7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611ca190614009565b8015611cee5780601f10611cc357610100808354040283529160200191611cee565b820191906000526020600020905b815481529060010190602001808311611cd157829003601f168201915b505050600484015460058501546006860154600790960154949591949093506001600160a01b03909116915088565b61013260209081526000928352604080842090915290825290208054600182015460028301546003840154600485015460058601805460ff9096169694956001600160a01b03909416949293919291611d7590614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611da190614009565b8015611dee5780601f10611dc357610100808354040283529160200191611dee565b820191906000526020600020905b815481529060010190602001808311611dd157829003601f168201915b5050505050908060060154908060070154905088565b611e0c613823565b611e146137d4565b60008481526101316020526040808220815161010081019092528054829060ff166004811115611e4657611e46613cbb565b6004811115611e5757611e57613cbb565b81526020016001820154815260200160028201548152602001600382018054611e7f90614009565b80601f0160208091040260200160405190810160405280929190818152602001828054611eab90614009565b8015611ef85780601f10611ecd57610100808354040283529160200191611ef8565b820191906000526020600020905b815481529060010190602001808311611edb57829003601f168201915b50505091835250506004820154602080830191909152600583015460408084019190915260068401546001600160a01b03166060840152600790930154608090920191909152600088815261013282528281208882529091528181208251610100810190935280549394509092829060ff166001811115611f7b57611f7b613cbb565b6001811115611f8c57611f8c613cbb565b81526001820154602082015260028201546001600160a01b03166040820152600382015460608201526004820154608082015260058201805460a090920191611fd490614009565b80601f016020809104026020016040519081016040528092919081815260200182805461200090614009565b801561204d5780601f106120225761010080835404028352916020019161204d565b820191906000526020600020905b81548152906001019060200180831161203057829003601f168201915b505050918352505060068201546020820152600790910154604090910152919350909150505b9250929050565b600082815260fc60205260409020600101546120958161274e565b610f9183836127e6565b6120a7613823565b61012e5482106120f95760405162461bcd60e51b815260206004820152601a60248201527f54686973207365727669636520646f65736e277420657869737400000000000060448201526064016108ca565b6000828152610131602052604090819020815161010081019092528054829060ff16600481111561212c5761212c613cbb565b600481111561213d5761213d613cbb565b8152602001600182015481526020016002820154815260200160038201805461216590614009565b80601f016020809104026020016040519081016040528092919081815260200182805461219190614009565b80156121de5780601f106121b3576101008083540402835291602001916121de565b820191906000526020600020905b8154815290600101906020018083116121c157829003601f168201915b5050509183525050600482015460208201526005820154604082015260068201546001600160a01b0316606082015260079091015460809091015292915050565b6122276124cc565b6001600160a01b03811661228c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016108ca565b61110081612a3e565b61012f5485906001600160a01b0316632fa117e5826122b26124bd565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b03166024820152604401602060405180830381865afa1580156122fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123209190613f98565b61233c5760405162461bcd60e51b81526004016108ca90613fb5565b6000858152610131602052604090206001810154871461238e5760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b60448201526064016108ca565b6000815460ff1660048111156123a6576123a6613cbb565b146123eb5760405162461bcd60e51b81526020600482015260156024820152741cdd185d1d5cc81b5d5cdd081899481bdc195b9959605a1b60448201526064016108ca565b602e831461240b5760405162461bcd60e51b81526004016108ca90613fe4565b806007015485101561245f5760405162461bcd60e51b815260206004820152601c60248201527f43616e27742072656475636520726566657272616c20616d6f756e740000000060448201526064016108ca565b6003810161246e848683614089565b50600781018590556040517fae55ce3c351e2400a1a143e7ed66668e581e1656ad1797a317e415d035880916906124ac908890879087908a9061440e565b60405180910390a150505050505050565b60006124c7612fb0565b905090565b6124d46124bd565b6001600160a01b03166124ef6033546001600160a01b031690565b6001600160a01b0316146114ac5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108ca565b61013054604051638a98636360e01b8152600481018890526000916001600160a01b031690638a98636390602401602060405180830381865afa158015612590573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125b49190614439565b90508034146125fa5760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b602e851461261a5760405162461bcd60e51b81526004016108ca90613fe4565b6001600160a01b0382166000908152610135602052604090205460ff166126775760405162461bcd60e51b8152602060048201526011602482015270151bdad95b881b9bdd08185b1b1bddd959607a1b60448201526064016108ca565b61013054604051631fff7f2760e11b8152600481018990526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa1580156126c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e69190614452565b90506001600160a01b038116156127435760008981526101336020908152604080832054905161271d928d92918c918c910161446f565b60405160208183030381529060405280519060200120905061274186868385612fe9565b505b505050505050505050565b6111008161275a6124bd565b6130dd565b6127698282611583565b61102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191660011790556127a26124bd565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6127f08282611583565b1561102057600082815260fc602090815260408083206001600160a01b03851684529091529020805460ff191690556128276124bd565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6111006124cc565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156128a657610f9183613136565b826001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa925050508015612900575060408051601f3d908101601f191682019092526128fd91810190614439565b60015b6129635760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b60648201526084016108ca565b60008051602061462283398151915281146129d25760405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b60648201526084016108ca565b50610f918383836131d2565b600054610100900460ff16612a055760405162461bcd60e51b81526004016108ca906144b0565b6114ac6131fd565b600054610100900460ff166114ac5760405162461bcd60e51b81526004016108ca906144b0565b611020828261275f565b603380546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61013054604051634a7ab1d560e01b8152600481018890526000916001600160a01b031690634a7ab1d590602401602060405180830381865afa158015612adb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aff9190614439565b9050803414612b455760405162461bcd60e51b81526020600482015260126024820152714e6f6e2d6d61746368696e672066756e647360701b60448201526064016108ca565b60008981526101316020526040808220815161010081019092528054829060ff166004811115612b7757612b77613cbb565b6004811115612b8857612b88613cbb565b81526020016001820154815260200160028201548152602001600382018054612bb090614009565b80601f0160208091040260200160405190810160405280929190818152602001828054612bdc90614009565b8015612c295780601f10612bfe57610100808354040283529160200191612c29565b820191906000526020600020905b815481529060010190602001808311612c0c57829003601f168201915b5050505050815260200160048201548152602001600582015481526020016006820160009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b03168152602001600782015481525050905061013560008260c001516001600160a01b03166001600160a01b03168152602001908152602001600020600101548160e001518a612cbf91906144fb565b1015612cfe5760405162461bcd60e51b815260206004820152600e60248201526d416d6f756e7420746f6f206c6f7760901b60448201526064016108ca565b600081516004811115612d1357612d13613cbb565b14612d555760405162461bcd60e51b815260206004820152601260248201527114d95c9d9a58d9481b9bdd081bdc195b995960721b60448201526064016108ca565b8060200151600003612d9d5760405162461bcd60e51b815260206004820152601160248201527014d95c9d9a58d9481b9bdd08195e1a5cdd607a1b60448201526064016108ca565b60008a8152610132602090815260408083208e84529091529020600101548b9003612e035760405162461bcd60e51b81526020600482015260166024820152751c1c9bdc1bdcd85b08185b1c9958591e48195e1a5cdd60521b60448201526064016108ca565b8a816020015103612e605760405162461bcd60e51b815260206004820152602160248201527f63616e27742063726561746520666f7220796f7572206f776e207365727669636044820152606560f81b60648201526084016108ca565b602e8614612e805760405162461bcd60e51b81526004016108ca90613fe4565b61013054604051631fff7f2760e11b8152600481018a90526000916001600160a01b031690633ffefe4e90602401602060405180830381865afa158015612ecb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eef9190614452565b90506001600160a01b03811615612f3f5760008c8c8a8a604051602001612f19949392919061450e565b604051602081830303815290604052805190602001209050612f3d87878385612fe9565b505b8315612fa25761012f5460405162f577a560e81b8152600481018690526001600160a01b039091169063f577a5009060240160006040518083038186803b158015612f8957600080fd5b505afa158015612f9d573d6000803e3d6000fd5b505050505b505050505050505050505050565b600060143610801590612fd257503360009081526065602052604090205460ff165b15612fe4575060131936013560601c90565b503390565b6000613042836040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b905060006130868287878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061323492505050565b9050806001600160a01b0316836001600160a01b031614611c385760405162461bcd60e51b8152602060048201526011602482015270696e76616c6964207369676e617475726560781b60448201526064016108ca565b6130e78282611583565b611020576130f481613258565b6130ff83602061326a565b604051602001613110929190614550565b60408051601f198184030181529082905262461bcd60e51b82526108ca916004016145c5565b6001600160a01b0381163b6131a35760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b60648201526084016108ca565b60008051602061462283398151915280546001600160a01b0319166001600160a01b0392909216919091179055565b6131db8361340d565b6000825111806131e85750805b15610f91576131f7838361344d565b50505050565b600054610100900460ff166132245760405162461bcd60e51b81526004016108ca906144b0565b6114ac61322f6124bd565b612a3e565b60008060006132438585613541565b9150915061325081613583565b509392505050565b606061081d6001600160a01b03831660145b606060006132798360026143d5565b6132849060026144fb565b67ffffffffffffffff81111561329c5761329c613ab9565b6040519080825280601f01601f1916602001820160405280156132c6576020820181803683370190505b509050600360fc1b816000815181106132e1576132e16145d8565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613310576133106145d8565b60200101906001600160f81b031916908160001a90535060006133348460026143d5565b61333f9060016144fb565b90505b60018111156133b7576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613373576133736145d8565b1a60f81b828281518110613389576133896145d8565b60200101906001600160f81b031916908160001a90535060049490941c936133b0816145ee565b9050613342565b5083156134065760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016108ca565b9392505050565b61341681613136565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606001600160a01b0383163b6134b55760405162461bcd60e51b815260206004820152602660248201527f416464726573733a2064656c65676174652063616c6c20746f206e6f6e2d636f6044820152651b9d1c9858dd60d21b60648201526084016108ca565b600080846001600160a01b0316846040516134d09190614605565b600060405180830381855af49150503d806000811461350b576040519150601f19603f3d011682016040523d82523d6000602084013e613510565b606091505b50915091506135388282604051806060016040528060278152602001614642602791396136cd565b95945050505050565b60008082516041036135775760208301516040840151606085015160001a61356b878285856136e6565b94509450505050612073565b50600090506002612073565b600081600481111561359757613597613cbb565b0361359f5750565b60018160048111156135b3576135b3613cbb565b036136005760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016108ca565b600281600481111561361457613614613cbb565b036136615760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016108ca565b600381600481111561367557613675613cbb565b036111005760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016108ca565b606083156136dc575081613406565b61340683836137aa565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561371d57506000905060036137a1565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613771573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661379a576000600192509250506137a1565b9150600090505b94509492505050565b8151156137ba5781518083602001fd5b8060405162461bcd60e51b81526004016108ca91906145c5565b60408051610100810190915280600081526020016000815260200160006001600160a01b0316815260200160008152602001600081526020016060815260200160008152602001600081525090565b6040805161010081019091528060008152602001600081526020016000815260200160608152602001600081526020016000815260200160006001600160a01b03168152602001600081525090565b60006020828403121561388457600080fd5b81356001600160e01b03198116811461340657600080fd5b600080604083850312156138af57600080fd5b50508035926020909101359150565b60008083601f8401126138d057600080fd5b50813567ffffffffffffffff8111156138e857600080fd5b60208301915083602082850101111561207357600080fd5b600080600080600080600060c0888a03121561391b57600080fd5b873596506020880135955060408801359450606088013567ffffffffffffffff81111561394757600080fd5b6139538a828b016138be565b989b979a50959895979660808701359660a0013595509350505050565b60006020828403121561398257600080fd5b5035919050565b6001600160a01b038116811461110057600080fd5b6000602082840312156139b057600080fd5b813561340681613989565b60008060008060008060008060c0898b0312156139d757600080fd5b8835975060208901359650604089013567ffffffffffffffff808211156139fd57600080fd5b613a098c838d016138be565b909850965060608b0135915080821115613a2257600080fd5b50613a2f8b828c016138be565b9095509350506080890135613a4381613989565b8092505060a089013590509295985092959890939650565b60008060408385031215613a6e57600080fd5b823591506020830135613a8081613989565b809150509250929050565b60008060408385031215613a9e57600080fd5b8235613aa981613989565b91506020830135613a8081613989565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613ae257600080fd5b8235613aed81613989565b9150602083013567ffffffffffffffff80821115613b0a57600080fd5b818501915085601f830112613b1e57600080fd5b813581811115613b3057613b30613ab9565b604051601f8201601f19908116603f01168101908382118183101715613b5857613b58613ab9565b81604052828152886020848701011115613b7157600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b801515811461110057600080fd5b600080600060608486031215613bb657600080fd5b8335613bc181613989565b92506020840135613bd181613b93565b929592945050506040919091013590565b6000806000806000806000806000806101008b8d031215613c0257600080fd5b8a35995060208b0135985060408b0135975060608b0135965060808b013567ffffffffffffffff80821115613c3657600080fd5b613c428e838f016138be565b909850965060a08d0135955060c08d0135915080821115613c6257600080fd5b50613c6f8d828e016138be565b9150809450508092505060e08b013590509295989b9194979a5092959850565b600080600060608486031215613ca457600080fd5b505081359360208301359350604090920135919050565b634e487b7160e01b600052602160045260246000fd5b60028110613ce157613ce1613cbb565b9052565b60005b83811015613d00578181015183820152602001613ce8565b50506000910152565b60008151808452613d21816020860160208601613ce5565b601f01601f19169290920160200192915050565b6000610100613d45848451613cd1565b6020830151602085015260018060a01b036040840151166040850152606083015160608501526080830151608085015260a08301518160a0860152613d8c82860182613d09565b91505060c083015160c085015260e083015160e08501528091505092915050565b6020815260006134066020830184613d35565b60058110613ce157613ce1613cbb565b6000610100613ddf838c613dc0565b896020840152886040840152806060840152613dfd81840189613d09565b6080840197909752505060a08101939093526001600160a01b039190911660c083015260e090910152949350505050565b6000610100613e3d838c613cd1565b89602084015260018060a01b03891660408401528760608401528660808401528060a0840152613e6f81840187613d09565b60c0840195909552505060e001529695505050505050565b6000610100613e97848451613dc0565b60208301516020850152604083015160408501526060830151816060860152613ec282860182613d09565b6080858101519087015260a0808601519087015260c0808601516001600160a01b03169087015260e0948501519490950193909352509192915050565b604081526000613f126040830185613e87565b82810360208401526135388185613d35565b6020815260006134066020830184613e87565b600080600080600060808688031215613f4f57600080fd5b853594506020860135935060408601359250606086013567ffffffffffffffff811115613f7b57600080fd5b613f87888289016138be565b969995985093965092949392505050565b600060208284031215613faa57600080fd5b815161340681613b93565b6020808252601590820152744e6f74206f776e6572206f722064656c656761746560581b604082015260600190565b6020808252600b908201526a125b9d985b1a590818da5960aa1b604082015260600190565b600181811c9082168061401d57607f821691505b60208210810361403d57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115610f9157600081815260208120601f850160051c8101602086101561406a5750805b601f850160051c820191505b81811015611c3857828155600101614076565b67ffffffffffffffff8311156140a1576140a1613ab9565b6140b5836140af8354614009565b83614043565b6000601f8411600181146140e957600085156140d15750838201355b600019600387901b1c1916600186901b178355614143565b600083815260209020601f19861690835b8281101561411a57868501358255602094850194600190920191016140fa565b50868210156141375760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b87815286602082015260c06040820152600061419360c08301878961414a565b606083019590955250608081019290925260a090910152949350505050565b634e487b7160e01b600052601160045260246000fd5b6000600182016141da576141da6141b2565b5060010190565b87815286602082015285604082015260c06060820152600061420760c08301868861414a565b6001600160a01b039490941660808301525060a0015295945050505050565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b19195b1959d85d1958d85b1b60a21b606082015260800190565b6020808252602c908201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060408201526b6163746976652070726f787960a01b606082015260800190565b815167ffffffffffffffff8111156142d8576142d8613ab9565b6142ec816142e68454614009565b84614043565b602080601f83116001811461432157600084156143095750858301515b600019600386901b1c1916600185901b178555611c38565b600085815260208120601f198616915b8281101561435057888601518255948401946001909101908401614331565b508582101561436e5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60006101008b83528a602084015280604084015261439f8184018a8c61414a565b9150506143af6060830188613cd1565b8560808301528460a08301528360c08301528260e08301529a9950505050505050505050565b808202811582820484141761081d5761081d6141b2565b60008261440957634e487b7160e01b600052601260045260246000fd5b500490565b84815260606020820152600061442860608301858761414a565b905082604083015295945050505050565b60006020828403121561444b57600080fd5b5051919050565b60006020828403121561446457600080fd5b815161340681613989565b6c6372656174655365727669636560981b815284600d820152603b60f81b602d82015283602e8201528183604e83013760009101604e019081529392505050565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b8082018082111561081d5761081d6141b2565b6d18dc99585d19541c9bdc1bdcd85b60921b815284600e820152603b60f81b602e82015283602f8201528183604f83013760009101604f019081529392505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351614588816017850160208801613ce5565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516145b9816028840160208801613ce5565b01602801949350505050565b6020815260006134066020830184613d09565b634e487b7160e01b600052603260045260246000fd5b6000816145fd576145fd6141b2565b506000190190565b60008251614617818460208701613ce5565b919091019291505056fe360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a26469706673582212204101a0ea1f12070439ff1321a6a5682dbe115cfb89975139083fc58ba5f80b4864736f6c63430008110033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/packages/client/src/disputes/__tests__/disputes.spec.ts b/packages/client/src/disputes/__tests__/disputes.spec.ts index c1dc293..bebe17d 100644 --- a/packages/client/src/disputes/__tests__/disputes.spec.ts +++ b/packages/client/src/disputes/__tests__/disputes.spec.ts @@ -1,8 +1,8 @@ import { parseEther, toHex } from "viem"; import { Disputes } from ".."; import { getChainConfig, getGraphQLConfig } from "../../config"; -import GraphQLClient from "../../graphql"; import { getPlatformById } from "../../platform/graphql/queries"; +import { ChainConfig } from "../../types"; import { MockGraphQLClient, MockViemClient } from "../../__mocks__/clientMocks"; import { testPlatformId, testChainId, testPlatformResponseWithArbitrator, testAddress } from "../../__mocks__/fixtures"; @@ -11,13 +11,15 @@ describe('Disputes', () => { let mockGraphQLClient: any; let mockViemClient: any; let disputes: Disputes; + let mockChainConfig: ChainConfig; beforeEach(() => { mockGraphQLClient = new MockGraphQLClient(); // DO NOT remove this comments - they are needed for local testing // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) mockViemClient = new MockViemClient(); - disputes = new Disputes(mockViemClient, testPlatformId, mockGraphQLClient, testChainId); + mockChainConfig = getChainConfig(testChainId); + disputes = new Disputes(mockViemClient, testPlatformId, mockGraphQLClient, mockChainConfig); }); it('constructor initializes correctly', () => { @@ -41,8 +43,9 @@ describe('Disputes', () => { it('should read arbitration contract and return value if arbitrator address is not zero', async () => { // Arrange // set a new disputes instance with a different platform id - disputes = new Disputes(mockViemClient, 2, mockGraphQLClient, testChainId); - const chainConfig = getChainConfig(disputes.chainId); + mockChainConfig = getChainConfig(testChainId); + disputes = new Disputes(mockViemClient, 2, mockGraphQLClient, mockChainConfig); + const chainConfig = mockChainConfig const contract = chainConfig.contracts['talentLayerArbitrator']; //Act diff --git a/packages/client/src/disputes/index.ts b/packages/client/src/disputes/index.ts index 8e75e4f..aab0e72 100644 --- a/packages/client/src/disputes/index.ts +++ b/packages/client/src/disputes/index.ts @@ -1,27 +1,41 @@ -import { parseEther, toHex, zeroAddress } from 'viem'; -import { getChainConfig } from '../config'; +import { Hash, parseEther, toHex, zeroAddress } from 'viem'; import GraphQLClient from '../graphql'; import { getPlatformById } from '../platform/graphql/queries'; -import { NetworkEnum, TransactionHash } from '../types'; +import { ChainConfig, NetworkEnum } from '../types'; import { ViemClient } from '../viem'; +/** + * Get arbitration cost. Set price of arbitration + * + * @group TalentLayerClient Modules + */ export class Disputes { + /** @hidden */ wallet: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ subgraph: GraphQLClient; - chainId: NetworkEnum; + /** @hidden */ + chainConfig: ChainConfig; + + /** @hidden */ constructor( walletClient: ViemClient, platformId: number, graphQlClient: GraphQLClient, - chainId: number, + chainConfig: ChainConfig ) { this.wallet = walletClient; this.platformID = platformId; this.subgraph = graphQlClient; - this.chainId = chainId; + this.chainConfig = chainConfig; } + /** + * getArbitrationCost - Retrieves the current cost of arbitration. This function is useful for understanding the financial implications of initiating an arbitration process. + * @returns {Promise} - Returns a Promise that resolves to the arbitration cost, typically in a numerical or string format representing the cost value. + */ public async getArbitrationCost(): Promise { const platformResponse = await this.subgraph.get(getPlatformById(this.platformID.toString())); @@ -36,7 +50,7 @@ export class Disputes { return 0; } - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts['talentLayerArbitrator']; console.log('SDK: reading contract'); @@ -52,7 +66,12 @@ export class Disputes { }); } - public async setPrice(value: number | string): Promise { + /** + * setPrice - Sets the price of arbitration. This function allows for modifying the arbitration cost for the current platform + * @param {number | string} value - The new price value for arbitration, which can be specified as a number or a string representing the price. + * @returns {Promise} - A promise that resolves to the transaction hash of the set operation. + */ + public async setPrice(value: number | string): Promise { const transformedPrice = parseEther(value.toString()); console.log('SDK: setting arbitration price'); const tx = await this.wallet.writeContract('talentLayerArbitrator', 'setArbitrationPrice', [ diff --git a/packages/client/src/escrow/__tests__/escrow.spec.ts b/packages/client/src/escrow/__tests__/escrow.spec.ts index aa76a2c..38125be 100644 --- a/packages/client/src/escrow/__tests__/escrow.spec.ts +++ b/packages/client/src/escrow/__tests__/escrow.spec.ts @@ -1,5 +1,7 @@ import { Escrow } from '..'; +import { getChainConfig } from '../../config'; +import { ChainConfig } from '../../types'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; import { testAddress, testAmount, testChainId, testCid, testIpfsHash, testMetaEvidenceCid, testPlatformId, testProposalId, testProposalIdWithDifferentRateToken, testProposalResponse, testProtocolAndPlatformResponse, testServiceId, testServiceResponse, testUserId } from '../../__mocks__/fixtures'; // DO NOT remove this comments - they are needed for local testing @@ -12,6 +14,7 @@ describe('Escrow', () => { let mockGraphQLClient: any; let mockIPFSClient: any; let mockViemClient: any; + let mockChainConfig: ChainConfig; beforeEach(() => { mockGraphQLClient = new MockGraphQLClient(); @@ -19,7 +22,8 @@ describe('Escrow', () => { // mockGraphQLClient = new GraphQLClient(getGraphQLConfig(137)) mockIPFSClient = new MockIPFSClient(); mockViemClient = new MockViemClient(); - escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, testChainId); + mockChainConfig = getChainConfig(testChainId); + escrow = new Escrow(mockGraphQLClient, mockIPFSClient, mockViemClient, testPlatformId, mockChainConfig); }); describe('approve', () => { diff --git a/packages/client/src/escrow/index.ts b/packages/client/src/escrow/index.ts index d19d6e4..978d4eb 100644 --- a/packages/client/src/escrow/index.ts +++ b/packages/client/src/escrow/index.ts @@ -3,33 +3,48 @@ import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; import { Proposal } from '../proposals'; import { Service } from '../services'; -import { ClientTransactionResponse, NetworkEnum, RateToken } from '../types'; +import { ChainConfig, ClientTransactionResponse, RateToken } from '../types'; import { calculateApprovalAmount } from '../utils/fees'; import { ViemClient } from '../viem'; import { getPaymentsByService, getProtocolAndPlatformsFees } from './graphql/queries'; +import { IEscrow } from "./types"; -export class Escrow { +/** + * Release and reimburse payments using TalentLayer escrow + * + * @group TalentLayerClient Modules + */ +export class Escrow implements IEscrow { + + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; - chainId: NetworkEnum; + /** @hidden */ erc20: IERC20; + /** @hidden */ + chainConfig: ChainConfig; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, viemClient: ViemClient, platformId: number, - chainId: NetworkEnum, + chainConfig: ChainConfig + ) { - console.log('SDK: escrow initialising: '); + console.log('SDK: escrow initialising'); this.graphQlClient = graphQlClient; this.platformID = platformId; this.ipfsClient = ipfsClient; this.viemClient = viemClient; - this.chainId = chainId; - this.erc20 = new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainId); + this.chainConfig = chainConfig; + this.erc20 = new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainConfig); } public async approve( @@ -43,13 +58,26 @@ export class Escrow { this.viemClient, this.platformID, ); + + const serviceInstance = new Service( + this.graphQlClient, + this.ipfsClient, + this.viemClient, + this.platformID, + ); + const proposal = await proposalInstance.getOne(proposalId); + const service = await serviceInstance.getOne(serviceId); const erc20 = this.erc20; if (!proposal) { throw new Error('Proposal not found'); } + if (!service) { + throw new Error('Service not found'); + } + if (!proposal.cid) { throw new Error('Proposal cid not found'); } @@ -69,11 +97,14 @@ export class Escrow { throw Error('Unable to fetch fees'); } + console.log('SDK: referral amount', service.referralAmount); + const approvalAmount = calculateApprovalAmount( proposal.rateAmount, protocolAndPlatformsFees.servicePlatform.originServiceFeeRate, protocolAndPlatformsFees.proposalPlatform.originValidatedProposalFeeRate, protocolAndPlatformsFees.protocols[0].protocolEscrowFeeRate, + service.referralAmount, ); console.log('SDK: escrow seeking approval for amount: ', approvalAmount.toString()); @@ -151,13 +182,11 @@ export class Escrow { throw new Error('Transaction Id not found for service'); } - const tx = await this.viemClient.writeContract('talentLayerEscrow', 'release', [ + return await this.viemClient.writeContract('talentLayerEscrow', 'release', [ userId, parseInt(transactionId), amount.toString(), ]); - - return tx; } public async reimburse(serviceId: string, amount: bigint, userId: number): Promise { @@ -178,15 +207,20 @@ export class Escrow { throw new Error('Transaction Id not found for service'); } - const tx = await this.viemClient.writeContract('talentLayerEscrow', 'reimburse', [ + return await this.viemClient.writeContract('talentLayerEscrow', 'reimburse', [ userId, parseInt(transactionId), amount.toString(), ]); - - return tx; } + public async claimReferralBalance(referrerId: string, tokenAddress: string): Promise { + return await this.viemClient.writeContract('talentLayerEscrow', 'claimReferralBalance', [ + referrerId, + tokenAddress, + ]); + } + public async getProtocolAndPlatformsFees( originServicePlatformId: string, originValidatedProposalPlatformId: string, @@ -206,4 +240,10 @@ export class Escrow { return response?.data?.payments || null } + public async getClaimableReferralBalance(address: string): Promise { + return await this.viemClient.readContract('talentLayerEscrow', 'getClaimableReferralBalance', [ + address, + ]); + } + } diff --git a/packages/client/src/escrow/types/index.ts b/packages/client/src/escrow/types/index.ts index 9e74b15..52b6c98 100644 --- a/packages/client/src/escrow/types/index.ts +++ b/packages/client/src/escrow/types/index.ts @@ -8,9 +8,11 @@ export interface IEscrow { ): Promise; release(serviceId: string, amount: bigint, userId: number): Promise; reimburse(serviceId: string, amount: bigint, userId: number): Promise; + claimReferralBalance(referrerId: string, tokenAddress: string): Promise; getProtocolAndPlatformsFees( originServicePlatformId: string, originValidatedProposalPlatformId: string, ): Promise; getByService(serviceId: string, paymentType?: string): Promise; + getClaimableReferralBalance(address: string): Promise; } diff --git a/packages/client/src/graphql/queries.ts b/packages/client/src/graphql/queries.ts index 7044acf..e13a403 100644 --- a/packages/client/src/graphql/queries.ts +++ b/packages/client/src/graphql/queries.ts @@ -3,6 +3,18 @@ export const serviceQueryFields = ` status createdAt cid + referralAmount + referrer { + address + handle + id + } + rateToken { + address + decimals + name + symbol + } transaction { id } @@ -11,7 +23,7 @@ export const serviceQueryFields = ` handle address rating - userStats { + userStat { numReceivedReviews } } @@ -42,7 +54,6 @@ export const serviceDescriptionQueryFields = ` startDate expectedEndDate rateAmount - rateToken keywords_raw keywords { id @@ -59,7 +70,7 @@ export const getProposalsByService = (serviceId: string) => ` address cid rating - userStats { + userStat { numReceivedReviews } } @@ -75,6 +86,11 @@ export const getProposalsByService = (serviceId: string) => ` about video_url } + referrer { + address + handle + id + } status expirationDate } diff --git a/packages/client/src/index.ts b/packages/client/src/index.ts index 297ece0..2cfbcb0 100644 --- a/packages/client/src/index.ts +++ b/packages/client/src/index.ts @@ -1,6 +1,6 @@ import { getChainConfig, getGraphQLConfig } from './config'; import GraphQLClient from './graphql'; -import { Config, NetworkEnum, TalentLayerClientConfig } from './types'; +import { Config, CustomChainConfig, NetworkEnum, TalentLayerClientConfig } from './types'; import IPFSClient from './ipfs'; import { ViemClient } from './viem'; import { IERC20, ERC20 } from './blockchain-bindings/erc20'; @@ -14,37 +14,58 @@ import { Profile } from './profile'; import { IProfile } from './profile/types'; import { Escrow } from './escrow'; import { IEscrow } from './escrow/types'; -import { IService, Service } from './services'; +import { Service } from './services'; import { IReview } from './reviews/types'; import { Review } from './reviews'; +import { IService } from "./services/types"; +import { isNetworkEnum } from './utils/typeguard'; /** * Main client for interacting with the TalentLayer protocol. */ export class TalentLayerClient { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; - chainId: NetworkEnum; + /** @hidden */ signatureApiUrl?: string; + /** @hidden */ + chainConfig: Config | CustomChainConfig; - /** - * Initializes a new instance of the TalentLayerClient. - * @param {TalentLayerClientConfig} config - Configuration options for the client. - */ + /** @hidden */ constructor(config: TalentLayerClientConfig) { - console.log('SDK: client initialising', config); + console.log('SDK: client initialising with special Racoon versionzzzz', config); this.platformID = config.platformId; - this.graphQlClient = new GraphQLClient(getGraphQLConfig(config.chainId)); + this.ipfsClient = new IPFSClient({ baseUrl: config.ipfsConfig.baseUrl, clientId: config.ipfsConfig.clientId, clientSecret: config.ipfsConfig.clientSecret, }); - this.viemClient = new ViemClient(config.chainId, config.walletConfig || {}); - this.chainId = config.chainId; + this.signatureApiUrl = config?.signatureApiUrl; + + if (config?.chainId) { + this.chainConfig = getChainConfig(config.chainId); + } else if (config.customChainConfig) { + // if user has given custom chain config, that will take priority + this.chainConfig = config.customChainConfig + } else { + throw Error('At least one of chainId or customChainConfig need to be provided') + } + + if (isNetworkEnum(this.chainConfig.networkId)) { + this.graphQlClient = new GraphQLClient(getGraphQLConfig(this.chainConfig.networkId)); + } else { + this.graphQlClient = new GraphQLClient({ subgraphUrl: this.chainConfig.subgraphUrl, chainId: this.chainConfig.networkId }); + } + + this.viemClient = new ViemClient({ ...config.walletConfig, chainConfig: this.chainConfig }); } /** @@ -54,13 +75,21 @@ export class TalentLayerClient { return getChainConfig(networkId); } + + /** + * Returns chain config for current isntance of SDK + */ + public getCurrentChainConfig(): Config { + return this.chainConfig + } + /** * Provides access to ERC20 token functionalities. * @type {IERC20} */ // @ts-ignore get erc20(): IERC20 { - return new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainId); + return new ERC20(this.ipfsClient, this.viemClient, this.platformID, this.chainConfig); } /** @@ -94,7 +123,7 @@ export class TalentLayerClient { */ // @ts-ignore get disputes(): IDispute { - return new Disputes(this.viemClient, this.platformID, this.graphQlClient, this.chainId); + return new Disputes(this.viemClient, this.platformID, this.graphQlClient, this.chainConfig); } /** @@ -142,7 +171,7 @@ export class TalentLayerClient { this.ipfsClient, this.viemClient, this.platformID, - this.chainId, + this.chainConfig ); } } diff --git a/packages/client/src/platform/index.ts b/packages/client/src/platform/index.ts index 24c4e39..cfb7357 100644 --- a/packages/client/src/platform/index.ts +++ b/packages/client/src/platform/index.ts @@ -1,21 +1,27 @@ -import { parseEther, zeroAddress } from 'viem'; +import { Hash, parseEther, zeroAddress } from 'viem'; import { getChainConfig } from '../config'; import { FEE_RATE_DIVIDER } from '../constants'; import GraphQLClient from '../graphql'; import IPFSClient from '../ipfs'; -import { ClientTransactionResponse, NetworkEnum, TransactionHash } from '../types'; +import { ClientTransactionResponse, NetworkEnum } from '../types'; import { ViemClient } from '../viem'; import { getPlatformById, getPlatformsByOwner } from './graphql/queries'; import { Arbitrator, PlatformDetails } from './types'; export class Platform { + /** @hidden */ subgraph: GraphQLClient; + /** @hidden */ wallet: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ ipfs: IPFSClient; + /** @hidden */ static readonly UPDATE_ERROR = 'unable to update platform details'; + /** @hidden */ constructor( graphQlClient: GraphQLClient, walletClient: ViemClient, @@ -28,6 +34,13 @@ export class Platform { this.ipfs = ipfsClient; } + /** + * Retrieves the details of a specific platform based on the provided ID. + * This method queries the GraphQL client for the platform data and returns the platform details if found. + * + * @param {string} id - The unique identifier of the platform to retrieve. + * @returns {Promise} A promise that resolves to the platform details if found, otherwise null. + */ public async getOne(id: string): Promise { const response = await this.subgraph.get(getPlatformById(id)); @@ -38,10 +51,22 @@ export class Platform { return null; } + /** + * Uploads platform details to IPFS and returns the corresponding CID. + * + * @param {PlatformDetails} data - The platform details to be uploaded. + * @returns {Promise} A promise that resolves to the CID of the uploaded data. + */ public async upload(data: PlatformDetails): Promise { return this.ipfs.post(JSON.stringify(data)); } + /** + * Fetches platforms owned by a specific address. + * + * @param {string} address - The wallet address of the platform owner. + * @returns {Promise} A promise that resolves to an array of platforms owned by the address, or an empty array if none. + */ public async getByOwner(address: `0x${string}`): Promise { const response = await this.subgraph.get(getPlatformsByOwner(address)); @@ -52,6 +77,12 @@ export class Platform { return []; } + /** + * Updates the platform details on the blockchain using the provided data. + * + * @param {PlatformDetails} data - The new platform details to be updated. + * @returns {Promise} A promise that resolves to the transaction response of the update operation. + */ public async update(data: PlatformDetails): Promise { console.log('SDK: update platform details'); const cid = await this.upload(data); @@ -68,7 +99,13 @@ export class Platform { return { cid, tx }; } - public async setFeeTimeout(timeout: number): Promise { + /** + * Sets the fee timeout for the platform. + * + * @param {number} timeout - The timeout value in seconds. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async setFeeTimeout(timeout: number): Promise { const tx = await this.wallet.writeContract( 'talentLayerPlatformId', 'updateArbitrationFeeTimeout', @@ -78,6 +115,12 @@ export class Platform { return tx; } + /** + * Retrieves a list of available arbitrators for a given chain ID. + * + * @param {NetworkEnum} chainId - The blockchain network chain ID. + * @returns {Arbitrator[]} An array of arbitrator objects available for the specified chain. + */ public getArbitrators(chainId: NetworkEnum): Arbitrator[] { const chainConfig = getChainConfig(chainId); const contract = chainConfig.contracts['talentLayerArbitrator']; @@ -89,15 +132,22 @@ export class Platform { return allowedArbitrators; } - public async updateArbitrator(address: `0x${string}`): Promise { - const allowedArbitrators: Arbitrator[] = this.getArbitrators(this.wallet.chainId); + /** + * Updates the arbitrator address for the platform. + * Throws an error if the provided address is not an allowed arbitrator. + * + * @param {Hash} address - The new arbitrator's address. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateArbitrator(address: Hash): Promise { + const allowedArbitrators: Arbitrator[] = this.getArbitrators(this.wallet.chain.id); const allowedArbitratorAddresses = allowedArbitrators.map((_arbitrator: Arbitrator) => _arbitrator.address.toLowerCase(), ); if (!allowedArbitratorAddresses.includes(address.toLowerCase())) { - throw new Error(`Invalid Arbitrator: ${address}`); + throw new Error(`Invalid Arbitrator: ${address} allowed arbitrators: ${JSON.stringify(allowedArbitratorAddresses)}`); } const tx = await this.wallet.writeContract('talentLayerPlatformId', 'updateArbitrator', [ @@ -110,7 +160,14 @@ export class Platform { } // Fee functions - public async updateOriginServiceFeeRate(value: number): Promise { + + /** + * Updates the service fee rate for origin services on the platform. + * + * @param {number} value - The new fee rate as a percentage ( if you want to set the fees to 5%, pass in 5). + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateOriginServiceFeeRate(value: number): Promise { const transformedFeeRate = Math.round((Number(value) * FEE_RATE_DIVIDER) / 100); console.log('SDK: transformedFeeRate', transformedFeeRate, this.platformID); @@ -123,7 +180,13 @@ export class Platform { return tx; } - public async updateOriginValidatedProposalFeeRate(value: number): Promise { + /** + * Updates the fee rate for validated proposals + * + * @param {number} value - The new fee rate as a percentage ( if you want to set the fees to 5%, pass in 5). + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateOriginValidatedProposalFeeRate(value: number): Promise { const transformedFeeRate = Math.round((Number(value) * FEE_RATE_DIVIDER) / 100); console.log('SDK: transformedFeeRate', transformedFeeRate, this.platformID); @@ -136,7 +199,13 @@ export class Platform { return tx; } - public async updateServicePostingFee(value: number): Promise { + /** + * Updates the posting fee for services on the platform. + * + * @param {number} value - The new fee rate. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateServicePostingFee(value: number): Promise { const transformedFeeRate = parseEther(value.toString()); console.log('SDK: transformedFeeRate', transformedFeeRate, this.platformID); @@ -148,7 +217,13 @@ export class Platform { return tx; } - public async updateProposalPostingFee(value: number): Promise { + /** + * Updates the posting fee for proposals on the platform. + * + * @param {number} value - The new fee rate. + * @returns {Promise} A promise that resolves to the transaction hash of the update operation. + */ + public async updateProposalPostingFee(value: number): Promise { const transformedFeeRate = parseEther(value.toString()); console.log('SDK: updateProposalPostingFee', transformedFeeRate); diff --git a/packages/client/src/profile/graphql/index.ts b/packages/client/src/profile/graphql/index.ts index e7b1b79..816c323 100644 --- a/packages/client/src/profile/graphql/index.ts +++ b/packages/client/src/profile/graphql/index.ts @@ -9,8 +9,16 @@ export const getProfileByAddress = (address: Hash) => handle rating delegates - userStats { + userStat { + averageReferredRating + numCreatedProposals + numCreatedServices + numFinishedServicesAsBuyer + numFinishedServicesAsSeller + numGivenReviews numReceivedReviews + numReferredUsers + numReferredUsersReviewsReceived } updatedAt createdAt @@ -43,8 +51,16 @@ export const getProfiles = (numberPerPage?: number, offset?: number, searchQuery id address handle - userStats { + userStat { + averageReferredRating + numCreatedProposals + numCreatedServices + numFinishedServicesAsBuyer + numFinishedServicesAsSeller + numGivenReviews numReceivedReviews + numReferredUsers + numReferredUsersReviewsReceived } rating } @@ -60,8 +76,16 @@ export const getProfileById = (id: string) => ` handle rating delegates - userStats { - numReceivedReviews + userStat { + averageReferredRating + numCreatedProposals + numCreatedServices + numFinishedServicesAsBuyer + numFinishedServicesAsSeller + numGivenReviews + numReceivedReviews + numReferredUsers + numReferredUsersReviewsReceived } updatedAt createdAt @@ -95,16 +119,26 @@ export const getUserTotalGains = (id: string) => ` { user(id: "${id}") { totalGains{ - id - totalGain - token { + id + totalGain + token { id name symbol decimals - } + } } + referralGains { + availableBalance + totalGain + token { + address + decimals + symbol + name + } } + } } `; diff --git a/packages/client/src/profile/index.ts b/packages/client/src/profile/index.ts index 672af93..7f9a7b0 100644 --- a/packages/client/src/profile/index.ts +++ b/packages/client/src/profile/index.ts @@ -8,14 +8,21 @@ import { getMintFees, getPaymentsForUser, getProfileByAddress, getProfileById, g import { TalentLayerProfile } from './types'; export class Profile { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformId: number; + /** @hidden */ static CREATE_ERROR = 'unable to create profile'; + /** @hidden */ static UPDATE_ERROR = 'unable to update profile'; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -28,6 +35,11 @@ export class Profile { this.viemClient = viemClient; } + /** + * getByAddress - Retrieves a user's profile based on their address. + * @param {Hash} address - The address of the user whose profile is being requested. + * @returns {Promise} - A promise that resolves to the user's profile data, or null if no profile is found. + */ public async getByAddress(address: Hash): Promise { const response = await this.graphQlClient.get(getProfileByAddress(address)); @@ -38,6 +50,11 @@ export class Profile { return null; } + /** + * getById - Fetches a user's profile using their user ID. This is useful for retrieving profile information when the user ID is known, instead of the address + * @param {string} userId - The id of the user whose profile is to be retrieved. + * @returns {Promise} - A promise that resolves to the user's profile data, or null if the profile does not exist. + */ public async getById(userId: string): Promise { const query = getProfileById(userId); @@ -46,10 +63,21 @@ export class Profile { return response?.data?.user || null; } + /** + * upload - Uploads profile data to IPFS and returns the resulting CID. + * @param {TalentLayerProfile} profileData - The profile data to be uploaded. + * @returns {Promise} - A promise that resolves to the Content Identifier (CID) of the uploaded data on IPFS. + */ public async upload(profileData: TalentLayerProfile): Promise { return this.ipfsClient.post(JSON.stringify(profileData)); } + /** + * update - Updates the profile data of a user. This involves uploading new profile data to IPFS and writing the update transaction to the contract. + * @param {TalentLayerProfile} profileData - The new profile data to be updated. + * @param {string} userId - The unique identifier of the user whose profile is being updated. + * @returns {Promise} - A promise that resolves to the transaction response, including the CID and transaction hash. + */ public async update( profileData: TalentLayerProfile, userId: string, @@ -69,10 +97,15 @@ export class Profile { throw new Error(Profile.UPDATE_ERROR); } + /** + * create - Creates a new user profile by minting it on the TalentLayerId contract. This function is typically called when a new user registers and a profile needs to be created in the system. + * @param {string} handle - The user handle or username for the new profile. + * @returns {Promise} - A promise that resolves to the transaction hash once the profile creation transaction is completed. + */ public async create(handle: string): Promise { - const proposolResponse = await this.graphQlClient.get(getProtocolById(1)); + const proposalResponse = await this.graphQlClient.get(getProtocolById(1)); - const protocol = proposolResponse?.data?.protocol; + const protocol = proposalResponse?.data?.protocol; console.log('SDK: protocol', protocol); @@ -93,6 +126,11 @@ export class Profile { ); } + /** + * getBy - Retrieves profiles based on specified search criteria. This function is useful for fetching multiple profiles, for instance, when implementing search functionality. + * @param {{ numberPerPage?: number; offset?: number; searchQuery?: string; }} params - The search parameters including pagination and search query. + * @returns {Promise} - A promise that resolves to the list of profiles matching the search criteria. + */ public async getBy(params: { numberPerPage?: number; offset?: number; @@ -103,6 +141,11 @@ export class Profile { return this.graphQlClient.get(query); } + /** + * getTotalGains - Retrieves the total earnings of the user + * @param {string} userId - The unique identifier of the user whose earnings are being queried. + * @returns {Promise} - A promise that resolves to the total earnings of the user. + */ public async getTotalGains(userId: string): Promise { const query = getUserTotalGains(userId); @@ -111,6 +154,14 @@ export class Profile { return response?.data?.user?.totalGains || null; } + /** + * getPayments - Fetches the payments received by the user + * @param {string} userId - The user's unique identifier. + * @param {number} [numberPerPage] - The number of payment records per page for pagination. + * @param {number} [offset] - The offset for pagination. + * @param {string} [startDate] - The start date for filtering the payment history. + * @returns {Promise} - A promise that resolves to the user's payment history. + */ public async getPayments( userId: string, numberPerPage?: number, @@ -125,6 +176,10 @@ export class Profile { return response?.data?.payments || null } + /** + * getMintFees - Retrieves the current profile minting fees for the TalentLayer protocol + * @returns {Promise} - A promise that resolves to the minting fees data. Returns null if no data is found or in case of an error. + */ public async getMintFees(): Promise { const query = getMintFees(); diff --git a/packages/client/src/proposals/__tests__/proposals.spec.ts b/packages/client/src/proposals/__tests__/proposals.spec.ts index 245f813..cb5f565 100644 --- a/packages/client/src/proposals/__tests__/proposals.spec.ts +++ b/packages/client/src/proposals/__tests__/proposals.spec.ts @@ -1,7 +1,22 @@ import { Proposal } from '..'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; -import { testAddress, testAmount, testChainId, testCid, testExpirationDate, testIpfsHash, testOwnerAddress, testPlatformDetails, testPlatformId, testPlatformResponse, testPlatformsByOwnerResponse, testProposalDetails, testProposalId, testProposalResponse, testProposalsByServiceId, testProposalsByUser, testProtocolAndPlatformResponse, testServiceId, testSignature, testUserId } from '../../__mocks__/fixtures'; +import { + testAmount, + testExpirationDate, + testIpfsHash, + testPlatformId, + testPlatformResponse, + testProposalDetails, + testProposalId, + testProposalResponse, + testProposalsByServiceId, + testProposalsByUser, + testReferrerUserId, + testServiceId, + testSignature, + testUserId +} from '../../__mocks__/fixtures'; // Additional imports... describe('Platform', () => { @@ -62,19 +77,19 @@ describe('Platform', () => { const proposalDetails = testProposalDetails; const userId = testUserId; const serviceId = testServiceId; - const rateToken = testAddress; const rateAmount = testAmount; const expirationDate = testExpirationDate; + const referrerId = testReferrerUserId; // Act - const resposne = await proposal.update(proposalDetails, userId, serviceId, rateToken, rateAmount.toString(), expirationDate) + const response = await proposal.update(proposalDetails, userId, serviceId, rateAmount.toString(), expirationDate, referrerId) // Assert expect(mockIPFSClient.post).toHaveBeenCalledWith(JSON.stringify(proposalDetails)); expect(mockViemClient.writeContract).toHaveBeenLastCalledWith( 'talentLayerService', 'updateProposal', - [userId, serviceId, rateToken, rateAmount.toString(), testIpfsHash, expirationDate] + [userId, serviceId, rateAmount.toString(), testIpfsHash, expirationDate, referrerId] ) }) }) @@ -85,20 +100,21 @@ describe('Platform', () => { const proposalDetails = testProposalDetails; const userId = testUserId; const serviceId = testServiceId; - const rateToken = testAddress; const rateAmount = testAmount; const expirationDate = testExpirationDate; const signatureResponse = testSignature; + const referrerId = testReferrerUserId; + jest.spyOn(proposal, 'getSignature').mockResolvedValueOnce(signatureResponse); // Act - const resposne = await proposal.create(proposalDetails, userId, serviceId, rateToken, rateAmount.toString(), expirationDate) + const response = await proposal.create(proposalDetails, userId, serviceId, rateAmount.toString(), expirationDate, referrerId) // Assert expect(mockViemClient.writeContract).toHaveBeenCalledWith( 'talentLayerService', 'createProposal', - [userId, serviceId, rateToken, rateAmount.toString(), testPlatformId, testIpfsHash, expirationDate, signatureResponse], + [userId, serviceId, rateAmount.toString(), testPlatformId, testIpfsHash, expirationDate, signatureResponse, referrerId], BigInt(testPlatformResponse.data.platform.proposalPostingFee), ) diff --git a/packages/client/src/proposals/graphql/index.ts b/packages/client/src/proposals/graphql/index.ts index 0ad8e24..fcfde83 100644 --- a/packages/client/src/proposals/graphql/index.ts +++ b/packages/client/src/proposals/graphql/index.ts @@ -8,10 +8,14 @@ export const getProposalById = (id: string) => ` address cid rating - userStats { + userStat { numReceivedReviews } } + referrer { + address + handle + } platform { id } @@ -67,10 +71,14 @@ export const getAllProposalsByServiceId = (id: string) => ` address cid rating - userStats { + userStat { numReceivedReviews } } + referrer { + address + handle + } description { id about @@ -113,6 +121,10 @@ export const getAllProposalsByUser = (id: string) => ` handle } } + referrer { + address + handle + } description { id about diff --git a/packages/client/src/proposals/index.ts b/packages/client/src/proposals/index.ts index f028b72..ea16ff8 100644 --- a/packages/client/src/proposals/index.ts +++ b/packages/client/src/proposals/index.ts @@ -5,15 +5,24 @@ import { ClientTransactionResponse } from '../types'; import { getSignature } from '../utils/signature'; import { ViemClient } from '../viem'; import { getAllProposalsByServiceId, getAllProposalsByUser, getProposalById } from './graphql'; -import { CreateProposalArgs, ProposalDetails } from './types'; +import { CreateProposalArgs, IProposal, ProposalDetails } from './types'; -export class Proposal { +/** + * The sub module that deals with proposals associated to services on TalentLayer + */ +export class Proposal implements IProposal { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ signatureApiUrl?: string; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -29,6 +38,11 @@ export class Proposal { this.signatureApiUrl = signatureApiUrl; } + /** + * Retrieves a specific proposal by its ID. + * @param {string} proposalId - The unique identifier of the proposal. + * @returns {Promise} - A promise that resolves to the details of the proposal. + */ public async getOne(proposalId: string): Promise { const query = getProposalById(proposalId); @@ -40,6 +54,11 @@ export class Proposal { return null; } + /** + * Fetches all proposals associated with a specific service ID. + * @param {string} serviceId - The unique identifier of the service. + * @returns {Promise} - A promise that resolves to a list of proposals related to the service. + */ public async getByServiceId(serviceId: string): Promise { const query = getAllProposalsByServiceId(serviceId) @@ -48,6 +67,11 @@ export class Proposal { return response?.data?.proposals || null } + /** + * Retrieves all proposals created by a specific user ID. + * @param {string} userId - The unique identifier of the user. + * @returns {Promise} - A promise that resolves to a list of proposals related to the user. + */ public async getByUser(userId: string): Promise { const query = getAllProposalsByUser(userId) @@ -56,21 +80,42 @@ export class Proposal { return response?.data?.proposals || null } + /** + * Generates a signature for a proposal creation operation. + * @param {CreateProposalArgs} args - The arguments required for creating the proposal signature. + * @returns {Promise} - A promise that resolves to the generated signature string. + */ + public async getSignature(args: CreateProposalArgs): Promise { return getSignature('createProposal', args, this.signatureApiUrl); } + /** + * Uploads proposal details to IPFS and returns the CID. + * @param {ProposalDetails} proposalDetails - The details of the proposal to be uploaded. + * @returns {Promise} - A promise that resolves to the CID of the uploaded proposal data. + */ public async upload(proposalDetails: ProposalDetails): Promise { return this.ipfsClient.post(JSON.stringify(proposalDetails)); } + /** + * Creates a new proposal with the given details. + * @param {ProposalDetails} proposalDetails - The details of the proposal to be created. + * @param {string} userId - The user ID of the proposal creator. + * @param {string} serviceId - The ID of the service for which the proposal is being created + * @param {string} rateAmount - The amount/rate for which the proposal is being created + * @param {string} expirationDate - The expiration date of the proposal. + * @param {string} referrerId - The user ID of the referrer (default 0 if no referer). + * @returns {Promise} - A promise that resolves to the transaction response for the proposal creation {cid and txHash}. + */ public async create( - proposalDetails: ProposalDetails, + proposalDetails: ProposalDetails, userId: string, serviceId: string, - rateToken: string, rateAmount: string, expirationDate: string, + referrerId: string = '0', ): Promise { const cid = await this.upload(proposalDetails); const signature = await this.getSignature({ @@ -93,7 +138,7 @@ export class Proposal { const tx = await this.viemClient.writeContract( 'talentLayerService', 'createProposal', - [userId, serviceId, rateToken, rateAmount, this.platformID, cid, expirationDate, signature], + [userId, serviceId, rateAmount, this.platformID, cid, expirationDate, signature, referrerId], proposalPostingFees, ); @@ -101,31 +146,42 @@ export class Proposal { return { cid, tx }; } - throw new Error('Unable to update propsal service'); + throw new Error('Unable to create the proposal'); } + /** + * Updates an existing proposal with new details. + * This method is used to modify the attributes of a proposal, such as rate, expiration date, or other proposal-related details. + * @param {ProposalDetails} proposalDetails - The updated details of the proposal. + * @param {string} userId - The user ID of the individual updating the proposal. + * @param {string} serviceId - The service ID associated with the proposal. + * @param {string} rateAmount - The new amount/rate associated with the proposal. + * @param {string} expirationDate - The new expiration date of the proposal. + * @param {string} referrerId - The user ID of the referrer (default 0 if no referer). + * @returns {Promise} - A promise that resolves to the transaction response for the proposal update. Includes the CID of the updated proposal data and the transaction hash. + */ public async update( proposalDetails: ProposalDetails, userId: string, serviceId: string, - rateToken: string, rateAmount: string, expirationDate: string, + referrerId: string = '0', ): Promise { const cid = await this.upload(proposalDetails); const tx = await this.viemClient.writeContract('talentLayerService', 'updateProposal', [ userId, serviceId, - rateToken, rateAmount, cid, expirationDate, + referrerId, ]); if (cid && tx) { return { cid, tx }; } - throw new Error('Unable to update propsal service'); + throw new Error('Unable to update the proposal'); } } diff --git a/packages/client/src/proposals/types/index.ts b/packages/client/src/proposals/types/index.ts index d0f8519..23af277 100644 --- a/packages/client/src/proposals/types/index.ts +++ b/packages/client/src/proposals/types/index.ts @@ -13,31 +13,25 @@ export interface CreateProposalArgs { } export interface IProposal { + getOne(id: string): Promise; + getByServiceId(id: string): Promise; + getByUser(id: string): Promise; getSignature(args: CreateProposalArgs): Promise; - - getOne(proposalId: string): Promise; - - getByServiceId(serviceId: string): Promise; - - getByUser(userId: string): Promise; - + upload(proposalDetails: ProposalDetails): Promise; create( - proposalDetails: ProposalDetails, - userId: string, - serviceId: string, - rateToken: string, - rateAmount: string, - expirationDate: string + proposalDetails: ProposalDetails, + userId: string, + serviceId: string, + rateAmount: string, + expirationDate: string, + referrerId?: string, ): Promise; - update( - proposalDetails: ProposalDetails, - userId: string, - serviceId: string, - rateToken: string, - rateAmount: string, - expirationDate: string + proposalDetails: ProposalDetails, + userId: string, + serviceId: string, + rateAmount: string, + expirationDate: string, + referrerId?: string, ): Promise; - - upload(proposalDetails: ProposalDetails): Promise; } diff --git a/packages/client/src/reviews/index.ts b/packages/client/src/reviews/index.ts index 63bf240..1898b86 100644 --- a/packages/client/src/reviews/index.ts +++ b/packages/client/src/reviews/index.ts @@ -6,13 +6,19 @@ import { getReviewsByService } from './graphql'; import { ReviewDetails } from './types'; export class Review { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformId: number; + /** @hidden */ static CREATE_ERROR = 'unable to submit review'; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -27,6 +33,11 @@ export class Review { this.viemClient = viemClient; } + /** + * Uploads review data to IPFS and returns the CID. This function is called during review creation + * @param {ReviewDetails} data - The review data to be uploaded. + * @returns {Promise} - A promise that resolves to the CID of the uploaded review data. + */ public async uploadReviewDataToIpfs(data: ReviewDetails): Promise { if (this.ipfsClient) { return this.ipfsClient.post(JSON.stringify(data)); @@ -35,6 +46,14 @@ export class Review { throw new Error(IPFSClient.IPFS_CLIENT_ERROR); } + /** + * Creates a new review with the given details for a service. + * @param {ReviewDetails} data - The details of the review to be created. + * @param {string} serviceId - The service ID associated with the review. + * @param {string} userId - The user ID of the user creating the review. + * @returns {Promise} - A promise that resolves to the transaction response for the review creation. Includes the CID of the review data and the transaction hash. + * @throws {Error} - Throws an error if unable to submit the review. + */ public async create( data: ReviewDetails, serviceId: string, @@ -57,6 +76,11 @@ export class Review { throw new Error(Review.CREATE_ERROR); } + /** + * Retrieves all reviews associated with a specific service ID. + * @param {string} serviceId - The unique identifier of the service. + * @returns {Promise} - A promise that resolves to the reviews related to the specified service. + */ public async getByService(serviceId: string): Promise { const query = getReviewsByService(serviceId); diff --git a/packages/client/src/services/__tests__/services.spec.ts b/packages/client/src/services/__tests__/services.spec.ts index 08673ce..131add4 100644 --- a/packages/client/src/services/__tests__/services.spec.ts +++ b/packages/client/src/services/__tests__/services.spec.ts @@ -2,7 +2,20 @@ import { Service } from '..'; import { getPlatformById } from '../../platform/graphql/queries'; import { MockGraphQLClient, MockIPFSClient, MockViemClient } from '../../__mocks__/clientMocks'; -import { testAddress, testIpfsHash, testPlatformId, testPlatformResponse, testSearchServiceProps, testSearchServicesResponse, testServiceDetails, testServiceId, testServiceResponse, testSignature, testUserId } from '../../__mocks__/fixtures'; +import { + testAddress, + testIpfsHash, + testPlatformId, + testPlatformResponse, + testReferralAmount, + testSearchServiceProps, + testSearchServicesResponse, + testServiceDetails, + testServiceId, + testServiceResponse, + testSignature, + testUserId +} from '../../__mocks__/fixtures'; describe('Service', () => { let service: Service; @@ -41,7 +54,7 @@ describe('Service', () => { jest.spyOn(service, 'getServiceSignature').mockResolvedValue(testSignature) // Act - const response = await service.create(serviceDetails, userId, platformID); + const response = await service.create(serviceDetails, userId, platformID, testAddress, testReferralAmount); // Assert expect(response.cid).toEqual(testIpfsHash); @@ -50,7 +63,7 @@ describe('Service', () => { expect(mockViemClient.writeContract).toHaveBeenCalledWith( 'talentLayerService', 'createService', - [userId, platformID, testIpfsHash, testSignature], + [userId, platformID, testIpfsHash, testSignature, testAddress, testReferralAmount], BigInt(testPlatformResponse.data.platform.servicePostingFee), ); @@ -58,9 +71,32 @@ describe('Service', () => { }) }) + describe('update', () => { + it('should update a new service', async () => { + // Arrange + const serviceDetails = testServiceDetails; + const userId = testUserId; + const serviceId = 1; + jest.spyOn(service, 'getServiceSignature').mockResolvedValue(testSignature) + + // Act + const response = await service.update(serviceDetails, userId, serviceId,testReferralAmount); + + // Assert + expect(response.cid).toEqual(testIpfsHash); + expect(response.tx).toEqual(testAddress); + expect(mockViemClient.writeContract).toHaveBeenCalledWith( + 'talentLayerService', + 'updateService', + [userId, serviceId, testReferralAmount, testIpfsHash] + ); + + }) + }) + describe('search', () => { - it('should reaturn services based on criteria', async () => { - // Arranage + it('should return services based on criteria', async () => { + // Arrange const props = testSearchServiceProps; // Act @@ -74,7 +110,7 @@ describe('Service', () => { describe('getServices', () => { it('should return services based on criteria', async () => { - // Arranage + // Arrange const props = testSearchServiceProps; // Act diff --git a/packages/client/src/services/index.ts b/packages/client/src/services/index.ts index e4ff668..d68a30a 100644 --- a/packages/client/src/services/index.ts +++ b/packages/client/src/services/index.ts @@ -9,27 +9,29 @@ import { getServices, searchServices, } from './graphql/queries'; -import { ICreateServiceSignature, IProps, ServiceDetails } from './types'; - -export interface IService { - getOne(id: string): Promise; - create( - serviceDetails: ServiceDetails, - userId: string, - platformId: number, - ): Promise; - updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; - getServices(params: IProps): Promise; - search(params: IProps): Promise; -} - -export class Service { +import { + ICreateServiceSignature, + IProps, + IService, + ServiceDetails, +} from './types'; + +/** + * Class representing Services inside TalentLayer + */ +export class Service implements IService { + /** @hidden */ graphQlClient: GraphQLClient; + /** @hidden */ ipfsClient: IPFSClient; + /** @hidden */ viemClient: ViemClient; + /** @hidden */ platformID: number; + /** @hidden */ signatureApiUrl?: string; + /** @hidden */ constructor( graphQlClient: GraphQLClient, ipfsClient: IPFSClient, @@ -45,10 +47,20 @@ export class Service { this.signatureApiUrl = signatureApiUrl; } + /** + * Asynchronously gets the service signature. + * @param {ICreateServiceSignature} args - The arguments to get the service signature. + * @returns {Promise} - A promise that resolves to the service signature. + */ public async getServiceSignature(args: ICreateServiceSignature) { return getSignature('createService', args, this.signatureApiUrl); } + /** + * Asynchronously retrieves a single service by its ID. + * @param {string} id - The ID of the service to retrieve. + * @returns {Promise} - A promise that resolves to the retrieved service. + */ public async getOne(id: string): Promise { const query = getOne(id); @@ -57,6 +69,11 @@ export class Service { return response?.data?.service || {}; } + /** + * Asynchronously uploads service data to IPFS. + * @param {ServiceDetails} serviceData - The service data to upload. + * @returns {Promise} - A promise that resolves to the IPFS address of the uploaded data. + */ public async updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise { if (this.ipfsClient) { return this.ipfsClient.post(JSON.stringify(serviceData)); @@ -65,19 +82,40 @@ export class Service { throw new Error(IPFSClient.IPFS_CLIENT_ERROR); } + /** + * Asynchronously gets multiple services based on provided parameters. + * @param {IProps} params - The parameters to filter the services. + * @returns {Promise} - A promise that resolves to the list of services. + */ public async getServices(params: IProps): Promise { return this.graphQlClient.get(getServices(params)); } + /** + * Asynchronously searches for services based on provided parameters. + * @param {IProps} params - The search parameters. + * @returns {Promise} - A promise that resolves to the search results. + */ public async search(params: IProps): Promise { return this.graphQlClient.get(searchServices(params)); } + /** + * Asynchronously creates a new service. + * @param {ServiceDetails} serviceDetails - The details of the service to create. + * @param {string} userId - The user ID creating the service. + * @param {number} platformId - The platform ID where the service is created. + * @param {string} token - The address of the token used for this service. + * @param {string} referralAmount - The user ID of the referrer (default 0 if no referrer). + * @returns {Promise} - A promise that resolves to the transaction response of the service creation. + */ public async create( serviceDetails: ServiceDetails, userId: string, platformId: number, + token: string, + referralAmount: string = '0', ): Promise { const platformDetailsResponse = await this.graphQlClient.get( getPlatformById(this.platformID.toString()), @@ -95,7 +133,7 @@ export class Service { const tx = await this.viemClient.writeContract( 'talentLayerService', 'createService', - [userId, platformId, cid, signature], + [userId, platformId, cid, signature, token, referralAmount], servicePostingFee, ); @@ -105,4 +143,25 @@ export class Service { throw new Error('Unable to create service'); } + + public async update( + serviceDetails: ServiceDetails, + userId: string, + serviceId: number, + referralAmount: string = '0', + ): Promise { + const cid = await this.updloadServiceDataToIpfs(serviceDetails); + + const tx = await this.viemClient.writeContract( + 'talentLayerService', + 'updateService', + [userId, serviceId, referralAmount, cid] + ); + + if (cid && tx) { + return { cid, tx }; + } + + throw new Error('Unable to update service'); + } } diff --git a/packages/client/src/services/types/index.ts b/packages/client/src/services/types/index.ts index 3fa82b8..ce294cf 100644 --- a/packages/client/src/services/types/index.ts +++ b/packages/client/src/services/types/index.ts @@ -1,10 +1,30 @@ import { ServiceStatusEnum } from '../enums'; +import {ClientTransactionResponse} from "../../types"; + +export interface IService { + getOne(id: string): Promise; + create( + serviceDetails: ServiceDetails, + userId: string, + platformId: number, + token: string, + referralAmount?: string, + ): Promise; + update( + serviceDetails: ServiceDetails, + userId: string, + serviceId: number, + referralAmount?: string, + ): Promise; + updloadServiceDataToIpfs(serviceData: ServiceDetails): Promise; + getServices(params: IProps): Promise; + search(params: IProps): Promise; +} export type ServiceDetails = { title: string; about: string; keywords: string; - rateToken: string; rateAmount: string; [key: string]: any; }; diff --git a/packages/client/src/types/index.ts b/packages/client/src/types/index.ts index 53b546a..acb6bb2 100644 --- a/packages/client/src/types/index.ts +++ b/packages/client/src/types/index.ts @@ -1,4 +1,4 @@ -import { Hash } from 'viem'; +import { Chain, Hash } from 'viem'; export type IToken = { name: string; @@ -18,6 +18,9 @@ export enum RateToken { NATIVE = '0x0000000000000000000000000000000000000000', } +/** + * Defines the Config type for predefined chains supported by TalentLayer +*/ export type Config = { networkId: NetworkEnum; subgraphUrl: string; @@ -26,6 +29,17 @@ export type Config = { tokens: { [key: string]: IToken }; }; +export type CustomChainConfig = { + networkId: number; + chainDefinition: Chain; + subgraphUrl: string; + escrowConfig: { [key: string]: any }; + contracts: { [key: string]: { address: `0x${string}`; abi: any } }; + tokens: { [key: string]: IToken }; +} + +export type ChainConfig = Config | CustomChainConfig; + export type GraphQLConfig = { chainId: NetworkEnum; subgraphUrl: string; @@ -43,17 +57,29 @@ export type ViemClientConfig = { rpcUrl?: string; privateKey?: `0x${string}`; mnemonic?: string; - chainId?: NetworkEnum; + chainConfig: ChainConfig; }; export type TalentLayerClientConfig = { - chainId: NetworkEnum; + chainId?: NetworkEnum; ipfsConfig: IPFSClientConfig; - walletConfig?: ViemClientConfig; + walletConfig?: { + rpcUrl?: string; + privateKey?: `0x${string}`; + mnemonic?: string; + }; platformId: number; signatureApiUrl?: string; + customChainConfig?: ChainConfig; }; +/** + * Represents the response of a transaction made through the client. + * This type is typically used to encapsulate details of blockchain transactions initiated by the client. + * + * @property {Hash} tx - The transaction hash that uniquely identifies the transaction on the blockchain. + * @property {string} cid - The Content Identifier (CID) referring to the location of the transaction-related data stored on IPFS. + */ export type ClientTransactionResponse = { tx: Hash; cid: string; diff --git a/packages/client/src/utils/fees.ts b/packages/client/src/utils/fees.ts index 3ff5d4e..95f3430 100644 --- a/packages/client/src/utils/fees.ts +++ b/packages/client/src/utils/fees.ts @@ -5,15 +5,13 @@ export const calculateApprovalAmount = ( originServiceFeeRate: string, originValidatedProposalFeeRate: string, protocolEscrowFeeRate: string, + referralAmount: string, ): bigint => { - const jobRateAmount = BigInt(proposalRateAmount); + const jobRateAmount = BigInt(proposalRateAmount) + BigInt(referralAmount); const protocolFee = (jobRateAmount * BigInt(protocolEscrowFeeRate)) / BigInt(FEE_RATE_DIVIDER); const originServiceFee = (jobRateAmount * BigInt(originServiceFeeRate)) / BigInt(FEE_RATE_DIVIDER); const originValidatedProposalFee = (jobRateAmount * BigInt(originValidatedProposalFeeRate)) / BigInt(FEE_RATE_DIVIDER); - const totalAmount: bigint = - jobRateAmount + originServiceFee + originValidatedProposalFee + protocolFee; - - return totalAmount; + return jobRateAmount + originServiceFee + originValidatedProposalFee + protocolFee; }; diff --git a/packages/client/src/utils/typeguard.ts b/packages/client/src/utils/typeguard.ts new file mode 100644 index 0000000..e42be22 --- /dev/null +++ b/packages/client/src/utils/typeguard.ts @@ -0,0 +1,13 @@ +import { ChainConfig, CustomChainConfig, NetworkEnum } from "../types" + +// const isNecklace = (b: Accessory): b is Necklace => { +// return (b as Necklace).kind !== undefined +// } + +export const isCustomChainConfig = (config: ChainConfig): config is CustomChainConfig => { + return (config as CustomChainConfig).chainDefinition !== undefined; +} + +export const isNetworkEnum = (networkId: number): networkId is NetworkEnum => { + return Object.values(NetworkEnum).includes(networkId); +} \ No newline at end of file diff --git a/packages/client/src/viem/index.ts b/packages/client/src/viem/index.ts index efa2769..0dab1b3 100644 --- a/packages/client/src/viem/index.ts +++ b/packages/client/src/viem/index.ts @@ -6,29 +6,41 @@ import { WalletClient, PublicClient, Hash, + defineChain, + Chain, } from 'viem'; import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts'; -import { getChainConfig } from '../config'; -import { NetworkEnum, ViemClientConfig } from '../types'; +import { ChainConfig, CustomChainConfig, NetworkEnum, ViemClientConfig } from '../types'; import TalentLayerID from '../contracts/ABI/TalentLayerID.json'; import { chains } from '../blockchain-bindings/chains'; +import { isCustomChainConfig } from '../utils/typeguard'; export class ViemClient { client: WalletClient; publicClient: PublicClient; - chainId: NetworkEnum; + chainConfig: ChainConfig; + chain: Chain; - constructor(chainId: NetworkEnum, config: ViemClientConfig) { + constructor(config: ViemClientConfig) { // if chainId is not provided, set it to mumbai - this.chainId = chainId || config.chainId || NetworkEnum.MUMBAI; + this.chainConfig = config.chainConfig; + let chain; + if (isCustomChainConfig(config.chainConfig)) { + chain = defineChain((config.chainConfig as CustomChainConfig).chainDefinition) + } else { + chain = chains[config.chainConfig.networkId as NetworkEnum] + } + console.log('viem client initialising: ', chain.id) + + this.chain = chain; // initialise a default public wallet client; this.client = createWalletClient({ - chain: chains[this.chainId], + chain, transport: http(), }); this.publicClient = createPublicClient({ - chain: chains[this.chainId], + chain, transport: http(), }); @@ -45,7 +57,7 @@ export class ViemClient { const account = privateKeyToAccount(config.privateKey); this.client = createWalletClient({ account, - chain: chains[this.chainId], + chain: this.chain, transport: transportProtocol, }); @@ -56,7 +68,7 @@ export class ViemClient { const account = mnemonicToAccount(config.mnemonic); this.client = createWalletClient({ account, - chain: chains[this.chainId], + chain: this.chain, transport: transportProtocol, }); @@ -67,7 +79,7 @@ export class ViemClient { let browserProvider = globalThis?.ethereum || window?.ethereum; if (browserProvider) { this.client = createWalletClient({ - chain: chains[this.chainId], + chain: this.chain, transport: custom(browserProvider), }); return true; @@ -84,13 +96,16 @@ export class ViemClient { ): Promise { // @ts-ignore const [address] = await this.client.getAddresses(); - + console.log('racoon address', address) if (!address) { throw Error('Wallet Client not initialised properly'); } - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts[contractName]; + console.log('racoon contract', contract) + console.log('racoon this.client.getAddresses()', address) + console.log('racoon args', args) if (!contract) { throw Error(`Invalid contract name passed. ${contractName}`); @@ -113,7 +128,7 @@ export class ViemClient { } public async readContract(contractName: string, functionName: string, args: Array) { - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; const contract = chainConfig.contracts[contractName]; console.log('SDK: reading contract', contract); @@ -138,7 +153,7 @@ export class ViemClient { throw Error('Wallet Client not initialised properly'); } - const chainConfig = getChainConfig(this.chainId); + const chainConfig = this.chainConfig; // @ts-ignore return this.client.writeContract({ diff --git a/packages/client/tsdoc.json b/packages/client/tsdoc.json new file mode 100644 index 0000000..fda4823 --- /dev/null +++ b/packages/client/tsdoc.json @@ -0,0 +1,6 @@ +{ + "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json", + "extends": [ + "typedoc/tsdoc.json" + ] +} \ No newline at end of file diff --git a/packages/client/typedoc.json b/packages/client/typedoc.json new file mode 100644 index 0000000..0a2ee04 --- /dev/null +++ b/packages/client/typedoc.json @@ -0,0 +1,16 @@ +{ + "tsconfig": "./tsconfig.json", + "extends": [ + "../../typedoc.base.json" + ], + "entryPoints": [ + "src/disputes/index.ts", + "src/escrow/index.ts", + "src/platform/index.ts", + "src/profile/index.ts", + "src/proposals/index.ts", + "src/reviews/index.ts", + "src/services/index.ts", + "src/index.ts" + ] +} \ No newline at end of file diff --git a/packages/tsconfig/base.json b/packages/tsconfig/base.json index 95804de..78e2945 100644 --- a/packages/tsconfig/base.json +++ b/packages/tsconfig/base.json @@ -19,5 +19,7 @@ "strict": true, "strictNullChecks": true }, - "exclude": ["node_modules"] -} + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/typedoc.base.json b/typedoc.base.json new file mode 100644 index 0000000..fa8e790 --- /dev/null +++ b/typedoc.base.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "includeVersion": true, + "excludeExternals": false, + "excludeInternal": true, + "excludeNotDocumented": false, + "excludePrivate": true, + "excludeProtected": true, + "disableSources": true, + "gitRevision": "develop", + "hideGenerator": true +} \ No newline at end of file diff --git a/typedoc.json b/typedoc.json new file mode 100644 index 0000000..743d7a6 --- /dev/null +++ b/typedoc.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://typedoc.org/schema.json", + "entryPoints": [ + "packages/client" + ], + "entryPointStrategy": "packages", + "name": "TalentLayer SDK Reference", +} \ No newline at end of file