aboutsummaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
authorLeonid Logvinov <logvinov.leon@gmail.com>2019-01-10 18:51:13 +0800
committerLeonid Logvinov <logvinov.leon@gmail.com>2019-01-10 18:56:15 +0800
commitcee29542451d3bf8c99bd08963a2108768072195 (patch)
treef3d657be53459ce3851fcf9632bd94f32ee80184 /packages
parenta8d9263062e586b90ee4c303d3d3aca72e428edc (diff)
parent686f27a96f0cd749f6315d7edd2bb56cf1819245 (diff)
downloaddexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.tar
dexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.tar.gz
dexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.tar.bz2
dexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.tar.lz
dexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.tar.xz
dexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.tar.zst
dexon-sol-tools-cee29542451d3bf8c99bd08963a2108768072195.zip
Merge development
Diffstat (limited to 'packages')
-rw-r--r--packages/0x.js/CHANGELOG.json3
-rw-r--r--packages/0x.js/CHANGELOG.md4
-rw-r--r--packages/0x.js/package.json28
-rw-r--r--packages/abi-gen-wrappers/CHANGELOG.json3
-rw-r--r--packages/abi-gen-wrappers/CHANGELOG.md4
-rw-r--r--packages/abi-gen-wrappers/package.json12
-rw-r--r--packages/abi-gen/CHANGELOG.json9
-rw-r--r--packages/abi-gen/CHANGELOG.md4
-rw-r--r--packages/abi-gen/package.json4
-rw-r--r--packages/assert/CHANGELOG.json9
-rw-r--r--packages/assert/CHANGELOG.md4
-rw-r--r--packages/assert/package.json6
-rw-r--r--packages/asset-buyer/CHANGELOG.json18
-rw-r--r--packages/asset-buyer/CHANGELOG.md4
-rw-r--r--packages/asset-buyer/README.md2
-rw-r--r--packages/asset-buyer/package.json20
-rw-r--r--packages/asset-buyer/src/errors.ts22
-rw-r--r--packages/asset-buyer/src/index.ts1
-rw-r--r--packages/asset-buyer/src/types.ts2
-rw-r--r--packages/asset-buyer/src/utils/buy_quote_calculator.ts14
-rw-r--r--packages/asset-buyer/test/buy_quote_calculator_test.ts143
-rw-r--r--packages/asset-buyer/test/utils/test_helpers.ts26
-rw-r--r--packages/base-contract/CHANGELOG.json9
-rw-r--r--packages/base-contract/CHANGELOG.md4
-rw-r--r--packages/base-contract/package.json6
-rw-r--r--packages/connect/CHANGELOG.json9
-rw-r--r--packages/connect/CHANGELOG.md4
-rw-r--r--packages/connect/package.json12
-rw-r--r--packages/contract-addresses/CHANGELOG.json3
-rw-r--r--packages/contract-addresses/CHANGELOG.md4
-rw-r--r--packages/contract-addresses/package.json2
-rw-r--r--packages/contract-artifacts/CHANGELOG.json3
-rw-r--r--packages/contract-artifacts/CHANGELOG.md4
-rw-r--r--packages/contract-artifacts/package.json2
-rw-r--r--packages/contract-wrappers/CHANGELOG.json3
-rw-r--r--packages/contract-wrappers/CHANGELOG.md9
-rw-r--r--packages/contract-wrappers/package.json32
-rw-r--r--packages/dev-tools-pages/.gitignore3
-rw-r--r--packages/dev-tools-pages/assets/crawl.html20
-rw-r--r--packages/dev-tools-pages/assets/favicons/compiler.icobin0 -> 6518 bytes
-rw-r--r--packages/dev-tools-pages/assets/favicons/cov.icobin0 -> 6518 bytes
-rw-r--r--packages/dev-tools-pages/assets/favicons/profiler.icobin0 -> 6518 bytes
-rw-r--r--packages/dev-tools-pages/assets/favicons/trace.icobin0 -> 6518 bytes
-rw-r--r--packages/dev-tools-pages/assets/fonts/.gitkeep (renamed from packages/dev-tools-pages/less/all.less)0
-rw-r--r--packages/dev-tools-pages/assets/images/og-compiler.pngbin0 -> 14494 bytes
-rw-r--r--packages/dev-tools-pages/assets/images/og-cov.pngbin0 -> 13336 bytes
-rw-r--r--packages/dev-tools-pages/assets/images/og-profiler.pngbin0 -> 13717 bytes
-rw-r--r--packages/dev-tools-pages/assets/images/og-trace.pngbin0 -> 13670 bytes
-rw-r--r--packages/dev-tools-pages/assets/index.html14
-rw-r--r--packages/dev-tools-pages/package.json40
-rw-r--r--packages/dev-tools-pages/pages.js72
-rw-r--r--packages/dev-tools-pages/public/css/basscss_responsive_custom.css85
-rw-r--r--packages/dev-tools-pages/public/css/basscss_responsive_margin.css453
-rw-r--r--packages/dev-tools-pages/public/css/basscss_responsive_padding.css134
-rw-r--r--packages/dev-tools-pages/public/css/basscss_responsive_type_scale.css35
-rwxr-xr-xpackages/dev-tools-pages/public/images/favicon/favicon-2-16x16.pngbin684 -> 0 bytes
-rwxr-xr-xpackages/dev-tools-pages/public/images/favicon/favicon-2-32x32.pngbin1567 -> 0 bytes
-rwxr-xr-xpackages/dev-tools-pages/public/images/favicon/favicon.icobin5430 -> 0 bytes
-rw-r--r--packages/dev-tools-pages/public/index.html26
-rw-r--r--packages/dev-tools-pages/ts/components/animations/compiler/data.json1
-rw-r--r--packages/dev-tools-pages/ts/components/animations/compiler/index.tsx11
-rw-r--r--packages/dev-tools-pages/ts/components/animations/cov/data.json1
-rw-r--r--packages/dev-tools-pages/ts/components/animations/cov/index.tsx11
-rw-r--r--packages/dev-tools-pages/ts/components/animations/index.tsx96
-rw-r--r--packages/dev-tools-pages/ts/components/animations/profiler/data.json1
-rw-r--r--packages/dev-tools-pages/ts/components/animations/profiler/index.tsx11
-rw-r--r--packages/dev-tools-pages/ts/components/animations/trace/data.json1
-rw-r--r--packages/dev-tools-pages/ts/components/animations/trace/index.tsx11
-rw-r--r--packages/dev-tools-pages/ts/components/base.tsx26
-rw-r--r--packages/dev-tools-pages/ts/components/breakout.tsx12
-rw-r--r--packages/dev-tools-pages/ts/components/button.tsx55
-rw-r--r--packages/dev-tools-pages/ts/components/code.tsx204
-rw-r--r--packages/dev-tools-pages/ts/components/compiler.tsx90
-rw-r--r--packages/dev-tools-pages/ts/components/container.tsx16
-rw-r--r--packages/dev-tools-pages/ts/components/content-block.tsx78
-rw-r--r--packages/dev-tools-pages/ts/components/content.tsx34
-rw-r--r--packages/dev-tools-pages/ts/components/footer.tsx133
-rw-r--r--packages/dev-tools-pages/ts/components/header.tsx76
-rw-r--r--packages/dev-tools-pages/ts/components/hero.tsx63
-rw-r--r--packages/dev-tools-pages/ts/components/inline-code.tsx20
-rw-r--r--packages/dev-tools-pages/ts/components/intro.tsx70
-rw-r--r--packages/dev-tools-pages/ts/components/list.tsx50
-rw-r--r--packages/dev-tools-pages/ts/components/meta_tags.tsx25
-rw-r--r--packages/dev-tools-pages/ts/components/tabs.tsx64
-rw-r--r--packages/dev-tools-pages/ts/components/trace.tsx223
-rw-r--r--packages/dev-tools-pages/ts/components/typography.tsx33
-rw-r--r--packages/dev-tools-pages/ts/components/ui/button.tsx59
-rw-r--r--packages/dev-tools-pages/ts/components/ui/container.tsx55
-rw-r--r--packages/dev-tools-pages/ts/components/ui/text.tsx74
-rw-r--r--packages/dev-tools-pages/ts/context/compiler.tsx19
-rw-r--r--packages/dev-tools-pages/ts/context/cov.tsx19
-rw-r--r--packages/dev-tools-pages/ts/context/index.tsx21
-rw-r--r--packages/dev-tools-pages/ts/context/profiler.tsx19
-rw-r--r--packages/dev-tools-pages/ts/context/trace.tsx19
-rw-r--r--packages/dev-tools-pages/ts/globalStyles.tsx90
-rw-r--r--packages/dev-tools-pages/ts/globals.d.ts15
-rw-r--r--packages/dev-tools-pages/ts/highlight.tsx67
-rw-r--r--packages/dev-tools-pages/ts/icons/exact-location.svg1
-rw-r--r--packages/dev-tools-pages/ts/icons/logos/0x.svg1
-rw-r--r--packages/dev-tools-pages/ts/icons/logos/compiler.svg3
-rw-r--r--packages/dev-tools-pages/ts/icons/logos/cov.svg3
-rw-r--r--packages/dev-tools-pages/ts/icons/logos/profiler.svg3
-rw-r--r--packages/dev-tools-pages/ts/icons/logos/trace.svg1
-rw-r--r--packages/dev-tools-pages/ts/icons/no-location.svg1
-rw-r--r--packages/dev-tools-pages/ts/icons/time-consuming.svg1
-rw-r--r--packages/dev-tools-pages/ts/icons/time-saving.svg1
-rw-r--r--packages/dev-tools-pages/ts/index.tsx17
-rw-r--r--packages/dev-tools-pages/ts/pages/compiler.tsx170
-rw-r--r--packages/dev-tools-pages/ts/pages/cov.tsx149
-rw-r--r--packages/dev-tools-pages/ts/pages/landing.tsx27
-rw-r--r--packages/dev-tools-pages/ts/pages/profiler.tsx146
-rw-r--r--packages/dev-tools-pages/ts/pages/trace.tsx116
-rw-r--r--packages/dev-tools-pages/ts/utils/utils.ts32
-rw-r--r--packages/dev-tools-pages/ts/variables.tsx34
-rw-r--r--packages/dev-tools-pages/webpack.config.js38
-rw-r--r--packages/dev-utils/CHANGELOG.json9
-rw-r--r--packages/dev-utils/CHANGELOG.md4
-rw-r--r--packages/dev-utils/package.json10
-rw-r--r--packages/dev-utils/src/web3_factory.ts6
-rw-r--r--packages/fill-scenarios/CHANGELOG.json3
-rw-r--r--packages/fill-scenarios/CHANGELOG.md4
-rw-r--r--packages/fill-scenarios/package.json16
-rw-r--r--packages/instant/package.json20
-rw-r--r--packages/instant/src/constants.ts1
-rw-r--r--packages/instant/src/util/asset.ts21
-rw-r--r--packages/instant/src/util/buy_quote_updater.ts7
-rw-r--r--packages/instant/test/util/asset.test.ts43
-rw-r--r--packages/json-schemas/CHANGELOG.json9
-rw-r--r--packages/json-schemas/CHANGELOG.md4
-rw-r--r--packages/json-schemas/package.json4
-rw-r--r--packages/json-schemas/schemas/asset_pairs_request_opts_schema.json2
-rw-r--r--packages/json-schemas/schemas/call_data_schema.json6
-rw-r--r--packages/json-schemas/schemas/ec_signature_schema.json2
-rw-r--r--packages/json-schemas/schemas/js_number_schema.json (renamed from packages/json-schemas/schemas/js_number.json)2
-rw-r--r--packages/json-schemas/schemas/order_config_request_schema.json2
-rw-r--r--packages/json-schemas/schemas/orderbook_request_schema.json4
-rw-r--r--packages/json-schemas/schemas/orders_request_opts_schema.json2
-rw-r--r--packages/json-schemas/schemas/paged_request_opts_schema.json2
-rw-r--r--packages/json-schemas/schemas/request_opts_schema.json2
-rw-r--r--packages/json-schemas/schemas/tx_data_schema.json6
-rw-r--r--packages/json-schemas/schemas/whole_number_schema.json11
-rw-r--r--packages/json-schemas/src/schema_validator.ts8
-rw-r--r--packages/json-schemas/src/schemas.ts2
-rw-r--r--packages/json-schemas/tsconfig.json2
-rw-r--r--packages/metacoin/package.json20
-rw-r--r--packages/migrations/.gitignore2
-rw-r--r--packages/migrations/CHANGELOG.json3
-rw-r--r--packages/migrations/CHANGELOG.md4
-rw-r--r--packages/migrations/Dockerfile15
-rw-r--r--packages/migrations/README.md41
-rw-r--r--packages/migrations/package.json37
-rw-r--r--packages/migrations/src/migrate_snapshot.ts32
-rw-r--r--packages/monorepo-scripts/package.json3
-rw-r--r--packages/monorepo-scripts/src/constants.ts2
-rw-r--r--packages/monorepo-scripts/src/doc_gen_configs.ts1
-rw-r--r--packages/monorepo-scripts/src/prepublish_checks.ts7
-rw-r--r--packages/monorepo-scripts/src/publish.ts12
-rw-r--r--packages/monorepo-scripts/src/utils/discord.ts26
-rw-r--r--packages/monorepo-scripts/src/utils/github_release_utils.ts7
-rw-r--r--packages/order-utils/CHANGELOG.json3
-rw-r--r--packages/order-utils/CHANGELOG.md4
-rw-r--r--packages/order-utils/package.json20
-rw-r--r--packages/order-watcher/CHANGELOG.json3
-rw-r--r--packages/order-watcher/CHANGELOG.md8
-rw-r--r--packages/order-watcher/Dockerfile13
-rw-r--r--packages/order-watcher/package.json31
-rw-r--r--packages/order-watcher/src/server.ts44
-rw-r--r--packages/order-watcher/test/order_watcher_web_socket_server_test.ts36
-rw-r--r--packages/pipeline/migrations/1545440485644-CreateCopperTables.ts103
-rw-r--r--packages/pipeline/package.json22
-rw-r--r--packages/pipeline/src/data_sources/copper/index.ts126
-rw-r--r--packages/pipeline/src/entities/copper_activity.ts41
-rw-r--r--packages/pipeline/src/entities/copper_activity_type.ts17
-rw-r--r--packages/pipeline/src/entities/copper_custom_field.ts15
-rw-r--r--packages/pipeline/src/entities/copper_lead.ts38
-rw-r--r--packages/pipeline/src/entities/copper_opportunity.ts45
-rw-r--r--packages/pipeline/src/entities/index.ts6
-rw-r--r--packages/pipeline/src/ormconfig.ts10
-rw-r--r--packages/pipeline/src/parsers/copper/index.ts259
-rw-r--r--packages/pipeline/src/scripts/pull_copper.ts129
-rw-r--r--packages/pipeline/src/utils/transformers/number_to_bigint.ts8
-rw-r--r--packages/pipeline/test/entities/copper_test.ts54
-rw-r--r--packages/pipeline/test/entities/util.ts4
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_activity_types.json24
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_activity_types.ts16
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.json38
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.ts39
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_list_activities.json242
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_list_activities.ts305
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_list_leads.json583
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_list_leads.ts229
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.json662
-rw-r--r--packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.ts425
-rw-r--r--packages/pipeline/test/fixtures/copper/parsed_entities.ts5
-rw-r--r--packages/pipeline/test/parsers/copper/index_test.ts87
-rw-r--r--packages/pipeline/tsconfig.json12
-rw-r--r--packages/react-docs/CHANGELOG.json9
-rw-r--r--packages/react-docs/CHANGELOG.md4
-rw-r--r--packages/react-docs/package.json12
-rw-r--r--packages/react-shared/CHANGELOG.json3
-rw-r--r--packages/react-shared/CHANGELOG.md4
-rw-r--r--packages/react-shared/package.json8
-rw-r--r--packages/sol-compiler/CHANGELOG.json7
-rw-r--r--packages/sol-compiler/CHANGELOG.md6
-rw-r--r--packages/sol-compiler/package.json18
-rw-r--r--packages/sol-compiler/src/solc/bin_paths.ts59
-rw-r--r--packages/sol-doc/CHANGELOG.json9
-rw-r--r--packages/sol-doc/CHANGELOG.md4
-rw-r--r--packages/sol-doc/package.json8
-rw-r--r--packages/sol-resolver/CHANGELOG.json3
-rw-r--r--packages/sol-resolver/CHANGELOG.md5
-rw-r--r--packages/sol-resolver/package.json4
-rw-r--r--packages/sol-tracing-utils/CHANGELOG.json9
-rw-r--r--packages/sol-tracing-utils/CHANGELOG.md4
-rw-r--r--packages/sol-tracing-utils/package.json12
-rw-r--r--packages/sra-spec/CHANGELOG.json9
-rw-r--r--packages/sra-spec/CHANGELOG.md4
-rw-r--r--packages/sra-spec/package.json4
-rw-r--r--packages/subproviders/CHANGELOG.json9
-rw-r--r--packages/subproviders/CHANGELOG.md4
-rw-r--r--packages/subproviders/package.json10
-rw-r--r--packages/testnet-faucets/package.json10
-rw-r--r--packages/types/CHANGELOG.json3
-rw-r--r--packages/types/CHANGELOG.md5
-rw-r--r--packages/types/package.json2
-rw-r--r--packages/utils/CHANGELOG.json3
-rw-r--r--packages/utils/CHANGELOG.md8
-rw-r--r--packages/utils/package.json4
-rw-r--r--packages/web3-wrapper/CHANGELOG.json9
-rw-r--r--packages/web3-wrapper/CHANGELOG.md4
-rw-r--r--packages/web3-wrapper/package.json8
-rw-r--r--packages/website/package.json26
-rw-r--r--packages/website/translations/chinese.json2
-rw-r--r--packages/website/translations/english.json2
-rw-r--r--packages/website/translations/korean.json2
-rw-r--r--packages/website/translations/russian.json2
-rw-r--r--packages/website/translations/spanish.json2
-rw-r--r--packages/website/ts/components/documentation/sidebar_header.tsx4
-rw-r--r--packages/website/ts/components/modals/modal_contact.tsx3
-rw-r--r--packages/website/ts/components/newsletter_form.tsx3
-rw-r--r--packages/website/ts/pages/documentation/developers_page.tsx2
-rw-r--r--packages/website/ts/utils/configs.ts8
242 files changed, 7066 insertions, 1353 deletions
diff --git a/packages/0x.js/CHANGELOG.json b/packages/0x.js/CHANGELOG.json
index f73de96aa..2f7320fea 100644
--- a/packages/0x.js/CHANGELOG.json
+++ b/packages/0x.js/CHANGELOG.json
@@ -7,7 +7,8 @@
"Export `MultiAssetData`, `MultiAssetDataWithRecursiveDecoding`, `ObjectMap`, and `SingleAssetData` from types. No longer export `AssetData`.",
"pr": 1363
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "2.0.8",
diff --git a/packages/0x.js/CHANGELOG.md b/packages/0x.js/CHANGELOG.md
index 2923fdf03..258dee66a 100644
--- a/packages/0x.js/CHANGELOG.md
+++ b/packages/0x.js/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v3.0.0 - _January 9, 2019_
+
+ * Export `MultiAssetData`, `MultiAssetDataWithRecursiveDecoding`, `ObjectMap`, and `SingleAssetData` from types. No longer export `AssetData`. (#1363)
+
## v2.0.8 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/0x.js/package.json b/packages/0x.js/package.json
index 2960c9e4b..74522c784 100644
--- a/packages/0x.js/package.json
+++ b/packages/0x.js/package.json
@@ -1,6 +1,6 @@
{
"name": "0x.js",
- "version": "2.0.8",
+ "version": "3.0.0",
"engines": {
"node": ">=6.12"
},
@@ -42,10 +42,10 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@0x/abi-gen-wrappers": "^2.0.2",
- "@0x/contract-addresses": "^2.0.0",
- "@0x/dev-utils": "^1.0.21",
- "@0x/migrations": "^2.2.2",
+ "@0x/abi-gen-wrappers": "^2.1.0",
+ "@0x/contract-addresses": "^2.1.0",
+ "@0x/dev-utils": "^1.0.22",
+ "@0x/migrations": "^2.3.0",
"@0x/tslint-config": "^2.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
@@ -72,16 +72,16 @@
"webpack": "^4.20.2"
},
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/base-contract": "^3.0.10",
- "@0x/contract-wrappers": "^4.1.3",
- "@0x/order-utils": "^3.0.7",
- "@0x/order-watcher": "^2.2.8",
- "@0x/subproviders": "^2.1.8",
- "@0x/types": "^1.4.1",
+ "@0x/assert": "^1.0.21",
+ "@0x/base-contract": "^3.0.11",
+ "@0x/contract-wrappers": "^4.2.0",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/order-watcher": "^2.4.0",
+ "@0x/subproviders": "^2.1.9",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/web3-provider-engine": "^14.0.0",
"ethereum-types": "^1.1.4",
"ethers": "~4.0.4",
diff --git a/packages/abi-gen-wrappers/CHANGELOG.json b/packages/abi-gen-wrappers/CHANGELOG.json
index 214920a08..404ba0f1b 100644
--- a/packages/abi-gen-wrappers/CHANGELOG.json
+++ b/packages/abi-gen-wrappers/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Added Dutch Auction Wrapper",
"pr": 1465
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "2.0.2",
diff --git a/packages/abi-gen-wrappers/CHANGELOG.md b/packages/abi-gen-wrappers/CHANGELOG.md
index c13c7a60f..4090e045a 100644
--- a/packages/abi-gen-wrappers/CHANGELOG.md
+++ b/packages/abi-gen-wrappers/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.0 - _January 9, 2019_
+
+ * Added Dutch Auction Wrapper (#1465)
+
## v2.0.2 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/abi-gen-wrappers/package.json b/packages/abi-gen-wrappers/package.json
index 38b5e9a9b..f7d40d591 100644
--- a/packages/abi-gen-wrappers/package.json
+++ b/packages/abi-gen-wrappers/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/abi-gen-wrappers",
- "version": "2.0.2",
+ "version": "2.1.0",
"engines": {
"node": ">=6.12"
},
@@ -30,19 +30,19 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen-wrappers/README.md",
"devDependencies": {
- "@0x/abi-gen": "^1.0.19",
+ "@0x/abi-gen": "^1.0.20",
"@0x/abi-gen-templates": "^1.0.1",
"@0x/tslint-config": "^2.0.0",
- "@0x/types": "^1.4.1",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/types": "^1.5.0",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"ethereum-types": "^1.1.4",
"ethers": "~4.0.4",
"lodash": "^4.17.5",
"shx": "^0.2.2"
},
"dependencies": {
- "@0x/base-contract": "^3.0.10"
+ "@0x/base-contract": "^3.0.11"
},
"publishConfig": {
"access": "public"
diff --git a/packages/abi-gen/CHANGELOG.json b/packages/abi-gen/CHANGELOG.json
index 253fb124d..19cceb509 100644
--- a/packages/abi-gen/CHANGELOG.json
+++ b/packages/abi-gen/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "1.0.20",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "1.0.19",
"changes": [
{
diff --git a/packages/abi-gen/CHANGELOG.md b/packages/abi-gen/CHANGELOG.md
index 4ca19ad7e..26d42cd36 100644
--- a/packages/abi-gen/CHANGELOG.md
+++ b/packages/abi-gen/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.0.20 - _January 9, 2019_
+
+ * Dependencies updated
+
## v1.0.19 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/abi-gen/package.json b/packages/abi-gen/package.json
index b122c742d..4a2754233 100644
--- a/packages/abi-gen/package.json
+++ b/packages/abi-gen/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/abi-gen",
- "version": "1.0.19",
+ "version": "1.0.20",
"engines": {
"node": ">=6.12"
},
@@ -32,7 +32,7 @@
"homepage": "https://github.com/0xProject/0x-monorepo/packages/abi-gen/README.md",
"dependencies": {
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
+ "@0x/utils": "^2.1.1",
"chalk": "^2.3.0",
"ethereum-types": "^1.1.4",
"glob": "^7.1.2",
diff --git a/packages/assert/CHANGELOG.json b/packages/assert/CHANGELOG.json
index 3805a044f..275ec2e4e 100644
--- a/packages/assert/CHANGELOG.json
+++ b/packages/assert/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "1.0.21",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "1.0.20",
"changes": [
{
diff --git a/packages/assert/CHANGELOG.md b/packages/assert/CHANGELOG.md
index ef84c48d4..25383b2d1 100644
--- a/packages/assert/CHANGELOG.md
+++ b/packages/assert/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.0.21 - _January 9, 2019_
+
+ * Dependencies updated
+
## v1.0.20 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/assert/package.json b/packages/assert/package.json
index cec1748cd..e11ccb3cb 100644
--- a/packages/assert/package.json
+++ b/packages/assert/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/assert",
- "version": "1.0.20",
+ "version": "1.0.21",
"engines": {
"node": ">=6.12"
},
@@ -44,9 +44,9 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/json-schemas": "^2.1.4",
+ "@0x/json-schemas": "^2.1.5",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
+ "@0x/utils": "^2.1.1",
"lodash": "^4.17.5",
"valid-url": "^1.0.9"
},
diff --git a/packages/asset-buyer/CHANGELOG.json b/packages/asset-buyer/CHANGELOG.json
index 470d9b03b..a7f8d3418 100644
--- a/packages/asset-buyer/CHANGELOG.json
+++ b/packages/asset-buyer/CHANGELOG.json
@@ -1,5 +1,23 @@
[
{
+ "version": "4.0.0",
+ "changes": [
+ {
+ "note": "Raise custom InsufficientAssetLiquidityError error with amountAvailableToFill attribute",
+ "pr": 1437
+ }
+ ]
+ },
+ {
+ "timestamp": 1547040760,
+ "version": "3.0.5",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "3.0.4",
"changes": [
{
diff --git a/packages/asset-buyer/CHANGELOG.md b/packages/asset-buyer/CHANGELOG.md
index cadb1acf8..70bbe8302 100644
--- a/packages/asset-buyer/CHANGELOG.md
+++ b/packages/asset-buyer/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v3.0.5 - _January 9, 2019_
+
+ * Dependencies updated
+
## v3.0.4 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/asset-buyer/README.md b/packages/asset-buyer/README.md
index 383a3836a..b854bda11 100644
--- a/packages/asset-buyer/README.md
+++ b/packages/asset-buyer/README.md
@@ -1,7 +1,5 @@
## @0x/asset-buyer
-**Warning: In Beta, has not been extensively tested.**
-
Convenience package for buying assets represented on the Ethereum blockchain using 0x. In its simplest form, the package helps in the usage of the [0x forwarder contract](https://github.com/0xProject/0x-protocol-specification/blob/master/v2/forwarder-specification.md), which allows users to execute [Wrapped Ether](https://weth.io/) based 0x orders without having to set allowances, wrap Ether or own ZRX, meaning they can buy tokens with Ether alone. Given some liquidity (0x signed orders), it helps estimate the Ether cost of buying a certain asset (giving a range) and then buying that asset.
In its more advanced and useful form, it integrates with the [Standard Relayer API](https://github.com/0xProject/standard-relayer-api) and takes care of sourcing liquidity for you given an SRA compliant endpoint. The final result is a library that tells you what assets are available, provides an Ether based quote for any asset desired, and allows you to buy that asset using Ether alone.
diff --git a/packages/asset-buyer/package.json b/packages/asset-buyer/package.json
index 401aec120..dd6780e48 100644
--- a/packages/asset-buyer/package.json
+++ b/packages/asset-buyer/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/asset-buyer",
- "version": "3.0.4",
+ "version": "3.0.5",
"engines": {
"node": ">=6.12"
},
@@ -36,16 +36,16 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/asset-buyer/README.md",
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/connect": "^3.0.10",
- "@0x/contract-wrappers": "^4.1.3",
- "@0x/json-schemas": "^2.1.4",
- "@0x/order-utils": "^3.0.7",
- "@0x/subproviders": "^2.1.8",
- "@0x/types": "^1.4.1",
+ "@0x/assert": "^1.0.21",
+ "@0x/connect": "^3.0.11",
+ "@0x/contract-wrappers": "^4.2.0",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/subproviders": "^2.1.9",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"ethereum-types": "^1.1.4",
"lodash": "^4.17.5"
},
diff --git a/packages/asset-buyer/src/errors.ts b/packages/asset-buyer/src/errors.ts
new file mode 100644
index 000000000..ec5fe548c
--- /dev/null
+++ b/packages/asset-buyer/src/errors.ts
@@ -0,0 +1,22 @@
+import { BigNumber } from '@0x/utils';
+
+import { AssetBuyerError } from './types';
+
+/**
+ * Error class representing insufficient asset liquidity
+ */
+export class InsufficientAssetLiquidityError extends Error {
+ /**
+ * The amount availabe to fill (in base units) factoring in slippage.
+ */
+ public amountAvailableToFill: BigNumber;
+ /**
+ * @param amountAvailableToFill The amount availabe to fill (in base units) factoring in slippage
+ */
+ constructor(amountAvailableToFill: BigNumber) {
+ super(AssetBuyerError.InsufficientAssetLiquidity);
+ this.amountAvailableToFill = amountAvailableToFill;
+ // Setting prototype so instanceof works. See https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
+ Object.setPrototypeOf(this, InsufficientAssetLiquidityError.prototype);
+ }
+}
diff --git a/packages/asset-buyer/src/index.ts b/packages/asset-buyer/src/index.ts
index 8418edb42..a42d7e272 100644
--- a/packages/asset-buyer/src/index.ts
+++ b/packages/asset-buyer/src/index.ts
@@ -9,6 +9,7 @@ export { SignedOrder } from '@0x/types';
export { BigNumber } from '@0x/utils';
export { AssetBuyer } from './asset_buyer';
+export { InsufficientAssetLiquidityError } from './errors';
export { BasicOrderProvider } from './order_providers/basic_order_provider';
export { StandardRelayerAPIOrderProvider } from './order_providers/standard_relayer_api_order_provider';
export {
diff --git a/packages/asset-buyer/src/types.ts b/packages/asset-buyer/src/types.ts
index 3b573edca..d5d6be695 100644
--- a/packages/asset-buyer/src/types.ts
+++ b/packages/asset-buyer/src/types.ts
@@ -102,7 +102,7 @@ export interface AssetBuyerOpts {
}
/**
- * Possible errors thrown by an AssetBuyer instance or associated static methods.
+ * Possible error messages thrown by an AssetBuyer instance or associated static methods.
*/
export enum AssetBuyerError {
NoEtherTokenContractFound = 'NO_ETHER_TOKEN_CONTRACT_FOUND',
diff --git a/packages/asset-buyer/src/utils/buy_quote_calculator.ts b/packages/asset-buyer/src/utils/buy_quote_calculator.ts
index b15b880c2..fcded6ab1 100644
--- a/packages/asset-buyer/src/utils/buy_quote_calculator.ts
+++ b/packages/asset-buyer/src/utils/buy_quote_calculator.ts
@@ -3,6 +3,7 @@ import { BigNumber } from '@0x/utils';
import * as _ from 'lodash';
import { constants } from '../constants';
+import { InsufficientAssetLiquidityError } from '../errors';
import { AssetBuyerError, BuyQuote, BuyQuoteInfo, OrdersAndFillableAmounts } from '../types';
import { orderUtils } from './order_utils';
@@ -33,7 +34,18 @@ export const buyQuoteCalculator = {
});
// if we do not have enough orders to cover the desired assetBuyAmount, throw
if (remainingFillAmount.gt(constants.ZERO_AMOUNT)) {
- throw new Error(AssetBuyerError.InsufficientAssetLiquidity);
+ // We needed the amount they requested to buy, plus the amount for slippage
+ const totalAmountRequested = assetBuyAmount.plus(slippageBufferAmount);
+ const amountAbleToFill = totalAmountRequested.minus(remainingFillAmount);
+ // multiplierNeededWithSlippage represents what we need to multiply the assetBuyAmount by
+ // in order to get the total amount needed considering slippage
+ // i.e. if slippagePercent was 0.2 (20%), multiplierNeededWithSlippage would be 1.2
+ const multiplierNeededWithSlippage = new BigNumber(1).plus(slippagePercentage);
+ // Given amountAvailableToFillConsideringSlippage * multiplierNeededWithSlippage = amountAbleToFill
+ // We divide amountUnableToFill by multiplierNeededWithSlippage to determine amountAvailableToFillConsideringSlippage
+ const amountAvailableToFillConsideringSlippage = amountAbleToFill.div(multiplierNeededWithSlippage).floor();
+
+ throw new InsufficientAssetLiquidityError(amountAvailableToFillConsideringSlippage);
}
// if we are not buying ZRX:
// given the orders calculated above, find the fee-orders that cover the desired assetBuyAmount (with slippage)
diff --git a/packages/asset-buyer/test/buy_quote_calculator_test.ts b/packages/asset-buyer/test/buy_quote_calculator_test.ts
index a30017b72..fdc17ef25 100644
--- a/packages/asset-buyer/test/buy_quote_calculator_test.ts
+++ b/packages/asset-buyer/test/buy_quote_calculator_test.ts
@@ -1,4 +1,5 @@
import { orderFactory } from '@0x/order-utils/lib/src/order_factory';
+import { SignedOrder } from '@0x/types';
import { BigNumber } from '@0x/utils';
import * as chai from 'chai';
import * as _ from 'lodash';
@@ -8,6 +9,7 @@ import { AssetBuyerError, OrdersAndFillableAmounts } from '../src/types';
import { buyQuoteCalculator } from '../src/utils/buy_quote_calculator';
import { chaiSetup } from './utils/chai_setup';
+import { testHelpers } from './utils/test_helpers';
chaiSetup.configure();
const expect = chai.expect;
@@ -15,6 +17,10 @@ const expect = chai.expect;
// tslint:disable:custom-no-magic-numbers
describe('buyQuoteCalculator', () => {
describe('#calculate', () => {
+ let firstOrder: SignedOrder;
+ let firstRemainingFillAmount: BigNumber;
+ let secondOrder: SignedOrder;
+ let secondRemainingFillAmount: BigNumber;
let ordersAndFillableAmounts: OrdersAndFillableAmounts;
let smallFeeOrderAndFillableAmount: OrdersAndFillableAmounts;
let allFeeOrdersAndFillableAmounts: OrdersAndFillableAmounts;
@@ -24,18 +30,18 @@ describe('buyQuoteCalculator', () => {
// the second order has a rate of 2 makerAsset / WETH with a takerFee of 100 ZRX and has 200 / 200 makerAsset units left to fill (completely fillable)
// generate one order for fees
// the fee order has a rate of 1 ZRX / WETH with no taker fee and has 100 ZRX left to fill (completely fillable)
- const firstOrder = orderFactory.createSignedOrderFromPartial({
+ firstOrder = orderFactory.createSignedOrderFromPartial({
makerAssetAmount: new BigNumber(400),
takerAssetAmount: new BigNumber(100),
takerFee: new BigNumber(200),
});
- const firstRemainingFillAmount = new BigNumber(200);
- const secondOrder = orderFactory.createSignedOrderFromPartial({
+ firstRemainingFillAmount = new BigNumber(200);
+ secondOrder = orderFactory.createSignedOrderFromPartial({
makerAssetAmount: new BigNumber(200),
takerAssetAmount: new BigNumber(100),
takerFee: new BigNumber(100),
});
- const secondRemainingFillAmount = secondOrder.makerAssetAmount;
+ secondRemainingFillAmount = secondOrder.makerAssetAmount;
ordersAndFillableAmounts = {
orders: [firstOrder, secondOrder],
remainingFillableMakerAssetAmounts: [firstRemainingFillAmount, secondRemainingFillAmount],
@@ -61,18 +67,137 @@ describe('buyQuoteCalculator', () => {
],
};
});
- it('should throw if not enough maker asset liquidity', () => {
- // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
+ describe('InsufficientLiquidityError', () => {
+ it('should throw if not enough maker asset liquidity (multiple orders)', () => {
+ // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ ordersAndFillableAmounts,
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(500),
+ 0,
+ 0,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(400));
+ });
+ it('should throw if not enough maker asset liquidity (multiple orders with 20% slippage)', () => {
+ // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ ordersAndFillableAmounts,
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(500),
+ 0,
+ 0.2,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(333));
+ });
+ it('should throw if not enough maker asset liquidity (multiple orders with 5% slippage)', () => {
+ // we have 400 makerAsset units available to fill but attempt to calculate a quote for 500 makerAsset units
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ ordersAndFillableAmounts,
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(600),
+ 0,
+ 0.05,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(380));
+ });
+ it('should throw if not enough maker asset liquidity (partially filled order)', () => {
+ const firstOrderAndFillableAmount: OrdersAndFillableAmounts = {
+ orders: [firstOrder],
+ remainingFillableMakerAssetAmounts: [firstRemainingFillAmount],
+ };
+
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ firstOrderAndFillableAmount,
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(201),
+ 0,
+ 0,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(200));
+ });
+ it('should throw if not enough maker asset liquidity (completely fillable order)', () => {
+ const completelyFillableOrder = orderFactory.createSignedOrderFromPartial({
+ makerAssetAmount: new BigNumber(123),
+ takerAssetAmount: new BigNumber(100),
+ takerFee: new BigNumber(200),
+ });
+ const completelyFillableOrdersAndFillableAmount: OrdersAndFillableAmounts = {
+ orders: [completelyFillableOrder],
+ remainingFillableMakerAssetAmounts: [completelyFillableOrder.makerAssetAmount],
+ };
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ completelyFillableOrdersAndFillableAmount,
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(124),
+ 0,
+ 0,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(123));
+ });
+ it('should throw with 1 amount available if no slippage', () => {
+ const smallOrder = orderFactory.createSignedOrderFromPartial({
+ makerAssetAmount: new BigNumber(1),
+ takerAssetAmount: new BigNumber(1),
+ takerFee: new BigNumber(0),
+ });
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ { orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(600),
+ 0,
+ 0,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(1));
+ });
+ it('should throw without amount available to fill if amount rounds to 0', () => {
+ const smallOrder = orderFactory.createSignedOrderFromPartial({
+ makerAssetAmount: new BigNumber(1),
+ takerAssetAmount: new BigNumber(1),
+ takerFee: new BigNumber(0),
+ });
+ const errorFunction = () => {
+ buyQuoteCalculator.calculate(
+ { orders: [smallOrder], remainingFillableMakerAssetAmounts: [smallOrder.makerAssetAmount] },
+ smallFeeOrderAndFillableAmount,
+ new BigNumber(600),
+ 0,
+ 0.2,
+ false,
+ );
+ };
+ testHelpers.expectInsufficientLiquidityError(expect, errorFunction, undefined);
+ });
+ });
+ it('should not throw if order is fillable', () => {
expect(() =>
buyQuoteCalculator.calculate(
ordersAndFillableAmounts,
- smallFeeOrderAndFillableAmount,
- new BigNumber(500),
+ allFeeOrdersAndFillableAmounts,
+ new BigNumber(300),
0,
0,
false,
),
- ).to.throw(AssetBuyerError.InsufficientAssetLiquidity);
+ ).to.not.throw();
});
it('should throw if not enough ZRX liquidity', () => {
// we request 300 makerAsset units but the ZRX order is only enough to fill the first order, which only has 200 makerAssetUnits available
diff --git a/packages/asset-buyer/test/utils/test_helpers.ts b/packages/asset-buyer/test/utils/test_helpers.ts
new file mode 100644
index 000000000..9c7c244af
--- /dev/null
+++ b/packages/asset-buyer/test/utils/test_helpers.ts
@@ -0,0 +1,26 @@
+import { BigNumber } from '@0x/utils';
+
+import { InsufficientAssetLiquidityError } from '../../src/errors';
+
+export const testHelpers = {
+ expectInsufficientLiquidityError: (
+ expect: Chai.ExpectStatic,
+ functionWhichTriggersError: () => void,
+ expectedAmountAvailableToFill?: BigNumber,
+ ): void => {
+ let wasErrorThrown = false;
+ try {
+ functionWhichTriggersError();
+ } catch (e) {
+ wasErrorThrown = true;
+ expect(e).to.be.instanceOf(InsufficientAssetLiquidityError);
+ if (expectedAmountAvailableToFill) {
+ expect(e.amountAvailableToFill).to.be.bignumber.equal(expectedAmountAvailableToFill);
+ } else {
+ expect(e.amountAvailableToFill).to.be.undefined();
+ }
+ }
+
+ expect(wasErrorThrown).to.be.true();
+ },
+};
diff --git a/packages/base-contract/CHANGELOG.json b/packages/base-contract/CHANGELOG.json
index a4cd17d42..1a6e3f845 100644
--- a/packages/base-contract/CHANGELOG.json
+++ b/packages/base-contract/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "3.0.11",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "3.0.10",
"changes": [
{
diff --git a/packages/base-contract/CHANGELOG.md b/packages/base-contract/CHANGELOG.md
index a8ce346d7..7a1a96639 100644
--- a/packages/base-contract/CHANGELOG.md
+++ b/packages/base-contract/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v3.0.11 - _January 9, 2019_
+
+ * Dependencies updated
+
## v3.0.10 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/base-contract/package.json b/packages/base-contract/package.json
index 87d70dd5f..7193c4881 100644
--- a/packages/base-contract/package.json
+++ b/packages/base-contract/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/base-contract",
- "version": "3.0.10",
+ "version": "3.0.11",
"engines": {
"node": ">=6.12"
},
@@ -41,8 +41,8 @@
},
"dependencies": {
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"ethereum-types": "^1.1.4",
"ethers": "~4.0.4",
"lodash": "^4.17.5"
diff --git a/packages/connect/CHANGELOG.json b/packages/connect/CHANGELOG.json
index e5bde40ae..fe32990e2 100644
--- a/packages/connect/CHANGELOG.json
+++ b/packages/connect/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "3.0.11",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "3.0.10",
"changes": [
{
diff --git a/packages/connect/CHANGELOG.md b/packages/connect/CHANGELOG.md
index a5f95b988..d01caa613 100644
--- a/packages/connect/CHANGELOG.md
+++ b/packages/connect/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v3.0.11 - _January 9, 2019_
+
+ * Dependencies updated
+
## v3.0.10 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/connect/package.json b/packages/connect/package.json
index 4985d0410..76817f23e 100644
--- a/packages/connect/package.json
+++ b/packages/connect/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/connect",
- "version": "3.0.10",
+ "version": "3.0.11",
"engines": {
"node": ">=6.12"
},
@@ -44,12 +44,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/connect/README.md",
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/json-schemas": "^2.1.4",
- "@0x/order-utils": "^3.0.7",
- "@0x/types": "^1.4.1",
+ "@0x/assert": "^1.0.21",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
+ "@0x/utils": "^2.1.1",
"lodash": "^4.17.5",
"query-string": "^5.0.1",
"sinon": "^4.0.0",
diff --git a/packages/contract-addresses/CHANGELOG.json b/packages/contract-addresses/CHANGELOG.json
index ca79290da..36684d443 100644
--- a/packages/contract-addresses/CHANGELOG.json
+++ b/packages/contract-addresses/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Added testnet entries for Dutch Auction contract (kovan,rinkeby,ropsten)",
"pr": 1465
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "2.0.0",
diff --git a/packages/contract-addresses/CHANGELOG.md b/packages/contract-addresses/CHANGELOG.md
index c006c3b22..d7f2ff7ea 100644
--- a/packages/contract-addresses/CHANGELOG.md
+++ b/packages/contract-addresses/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.0 - _January 9, 2019_
+
+ * Added testnet entries for Dutch Auction contract (kovan,rinkeby,ropsten) (#1465)
+
## v2.0.0 - _November 28, 2018_
* Redeployed Rinkeby with testnet Exchange artifact (#1318)
diff --git a/packages/contract-addresses/package.json b/packages/contract-addresses/package.json
index c75ae6efa..c5a133ddf 100644
--- a/packages/contract-addresses/package.json
+++ b/packages/contract-addresses/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/contract-addresses",
- "version": "2.0.0",
+ "version": "2.1.0",
"engines": {
"node": ">=6.12"
},
diff --git a/packages/contract-artifacts/CHANGELOG.json b/packages/contract-artifacts/CHANGELOG.json
index b033943d2..237014d09 100644
--- a/packages/contract-artifacts/CHANGELOG.json
+++ b/packages/contract-artifacts/CHANGELOG.json
@@ -6,7 +6,8 @@
"pr": 1465,
"note": "Added artifact for Dutch Auction contract"
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "1.1.2",
diff --git a/packages/contract-artifacts/CHANGELOG.md b/packages/contract-artifacts/CHANGELOG.md
index 9e48058f5..7f96cb571 100644
--- a/packages/contract-artifacts/CHANGELOG.md
+++ b/packages/contract-artifacts/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.2.0 - _January 9, 2019_
+
+ * Added artifact for Dutch Auction contract (#1465)
+
## v1.1.2 - _November 28, 2018_
* Update Exchange artifact to receive ZRX asset data as a constructor argument (#1309)
diff --git a/packages/contract-artifacts/package.json b/packages/contract-artifacts/package.json
index 71d887545..b819520c6 100644
--- a/packages/contract-artifacts/package.json
+++ b/packages/contract-artifacts/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/contract-artifacts",
- "version": "1.1.2",
+ "version": "1.2.0",
"engines": {
"node": ">=6.12"
},
diff --git a/packages/contract-wrappers/CHANGELOG.json b/packages/contract-wrappers/CHANGELOG.json
index 677292030..fd8dfa427 100644
--- a/packages/contract-wrappers/CHANGELOG.json
+++ b/packages/contract-wrappers/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Added Dutch Auction wrapper",
"pr": 1465
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "4.1.4",
diff --git a/packages/contract-wrappers/CHANGELOG.md b/packages/contract-wrappers/CHANGELOG.md
index 595fbcc31..fe7bb7b81 100644
--- a/packages/contract-wrappers/CHANGELOG.md
+++ b/packages/contract-wrappers/CHANGELOG.md
@@ -5,6 +5,15 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v4.2.0 - _January 9, 2019_
+
+ * Added Dutch Auction wrapper (#1465)
+
+## v4.1.4 - _Invalid date_
+
+ * Add support for Trust Wallet signature denial error
+ * Add balance and allowance queries for `MultiAssetProxy` (#1363)
+
## v4.1.3 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/contract-wrappers/package.json b/packages/contract-wrappers/package.json
index e4de75ab2..708b4249a 100644
--- a/packages/contract-wrappers/package.json
+++ b/packages/contract-wrappers/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/contract-wrappers",
- "version": "4.1.3",
+ "version": "4.2.0",
"description": "Smart TS wrappers for 0x smart contracts",
"keywords": [
"0xproject",
@@ -37,9 +37,9 @@
"node": ">=6.0.0"
},
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
- "@0x/migrations": "^2.2.2",
- "@0x/subproviders": "^2.1.8",
+ "@0x/dev-utils": "^1.0.22",
+ "@0x/migrations": "^2.3.0",
+ "@0x/subproviders": "^2.1.9",
"@0x/tslint-config": "^2.0.0",
"@types/lodash": "4.14.104",
"@types/mocha": "^2.2.42",
@@ -65,20 +65,20 @@
"web3-provider-engine": "14.0.6"
},
"dependencies": {
- "@0x/abi-gen-wrappers": "^2.0.2",
- "@0x/assert": "^1.0.20",
- "@0x/contract-addresses": "^2.0.0",
- "@0x/contract-artifacts": "^1.1.2",
- "@0x/contracts-test-utils": "^1.0.2",
- "@0x/fill-scenarios": "^1.0.16",
- "@0x/json-schemas": "^2.1.4",
- "@0x/order-utils": "^3.0.7",
- "@0x/types": "^1.4.1",
+ "@0x/abi-gen-wrappers": "^2.1.0",
+ "@0x/assert": "^1.0.21",
+ "@0x/contract-addresses": "^2.1.0",
+ "@0x/contract-artifacts": "^1.2.0",
+ "@0x/contracts-test-utils": "^1.0.3",
+ "@0x/fill-scenarios": "^1.1.0",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
- "ethereumjs-abi": "0.6.5",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"ethereum-types": "^1.1.4",
+ "ethereumjs-abi": "0.6.5",
"ethereumjs-blockstream": "6.0.0",
"ethereumjs-util": "^5.1.1",
"ethers": "~4.0.4",
diff --git a/packages/dev-tools-pages/.gitignore b/packages/dev-tools-pages/.gitignore
new file mode 100644
index 000000000..557b82311
--- /dev/null
+++ b/packages/dev-tools-pages/.gitignore
@@ -0,0 +1,3 @@
+public
+assets/fonts/*.woff
+assets/fonts/*.woff2 \ No newline at end of file
diff --git a/packages/dev-tools-pages/assets/crawl.html b/packages/dev-tools-pages/assets/crawl.html
new file mode 100644
index 000000000..9135c3ede
--- /dev/null
+++ b/packages/dev-tools-pages/assets/crawl.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>Document</title>
+</head>
+<body>
+
+<ul>
+<li><a href="/compiler">Compiler</a></li>
+<li><a href="/cov">Cov</a></li>
+<li><a href="/profiler">Profiler</a></li>
+<li><a href="/trace">Trace</a></li>
+
+</ul>
+
+</body>
+</html> \ No newline at end of file
diff --git a/packages/dev-tools-pages/assets/favicons/compiler.ico b/packages/dev-tools-pages/assets/favicons/compiler.ico
new file mode 100644
index 000000000..ff9409b2a
--- /dev/null
+++ b/packages/dev-tools-pages/assets/favicons/compiler.ico
Binary files differ
diff --git a/packages/dev-tools-pages/assets/favicons/cov.ico b/packages/dev-tools-pages/assets/favicons/cov.ico
new file mode 100644
index 000000000..f04f4bf56
--- /dev/null
+++ b/packages/dev-tools-pages/assets/favicons/cov.ico
Binary files differ
diff --git a/packages/dev-tools-pages/assets/favicons/profiler.ico b/packages/dev-tools-pages/assets/favicons/profiler.ico
new file mode 100644
index 000000000..0a8fff329
--- /dev/null
+++ b/packages/dev-tools-pages/assets/favicons/profiler.ico
Binary files differ
diff --git a/packages/dev-tools-pages/assets/favicons/trace.ico b/packages/dev-tools-pages/assets/favicons/trace.ico
new file mode 100644
index 000000000..744a18860
--- /dev/null
+++ b/packages/dev-tools-pages/assets/favicons/trace.ico
Binary files differ
diff --git a/packages/dev-tools-pages/less/all.less b/packages/dev-tools-pages/assets/fonts/.gitkeep
index e69de29bb..e69de29bb 100644
--- a/packages/dev-tools-pages/less/all.less
+++ b/packages/dev-tools-pages/assets/fonts/.gitkeep
diff --git a/packages/dev-tools-pages/assets/images/og-compiler.png b/packages/dev-tools-pages/assets/images/og-compiler.png
new file mode 100644
index 000000000..871e8f279
--- /dev/null
+++ b/packages/dev-tools-pages/assets/images/og-compiler.png
Binary files differ
diff --git a/packages/dev-tools-pages/assets/images/og-cov.png b/packages/dev-tools-pages/assets/images/og-cov.png
new file mode 100644
index 000000000..1cfeada7a
--- /dev/null
+++ b/packages/dev-tools-pages/assets/images/og-cov.png
Binary files differ
diff --git a/packages/dev-tools-pages/assets/images/og-profiler.png b/packages/dev-tools-pages/assets/images/og-profiler.png
new file mode 100644
index 000000000..4338f23ea
--- /dev/null
+++ b/packages/dev-tools-pages/assets/images/og-profiler.png
Binary files differ
diff --git a/packages/dev-tools-pages/assets/images/og-trace.png b/packages/dev-tools-pages/assets/images/og-trace.png
new file mode 100644
index 000000000..5318128f2
--- /dev/null
+++ b/packages/dev-tools-pages/assets/images/og-trace.png
Binary files differ
diff --git a/packages/dev-tools-pages/assets/index.html b/packages/dev-tools-pages/assets/index.html
new file mode 100644
index 000000000..5ab1a45f1
--- /dev/null
+++ b/packages/dev-tools-pages/assets/index.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <link rel="preload" href="/fonts/MaisonNeue-Book-subset.woff2" as="font" type="font/woff2" crossorigin>
+ <link rel="preload" href="/fonts/MaisonNeue-Bold-subset.woff2" as="font" type="font/woff2" crossorigin>
+ <title><%= htmlWebpackPlugin.options.title %></title>
+</head>
+<body>
+ <div id="app"></div>
+</body>
+</html> \ No newline at end of file
diff --git a/packages/dev-tools-pages/package.json b/packages/dev-tools-pages/package.json
index 754db3208..db927849e 100644
--- a/packages/dev-tools-pages/package.json
+++ b/packages/dev-tools-pages/package.json
@@ -1,13 +1,13 @@
{
"name": "@0x/dev-tools-pages",
- "version": "0.0.10",
+ "version": "0.0.11",
"engines": {
"node": ">=6.12"
},
"private": true,
"description": "0x Dev tools pages",
"scripts": {
- "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production",
+ "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production && react-snap",
"build:ci": "yarn build",
"build:dev": "../../node_modules/.bin/webpack --mode development",
"clean": "shx rm -f public/bundle*",
@@ -16,33 +16,43 @@
},
"license": "Apache-2.0",
"dependencies": {
- "@0x/react-shared": "^1.0.25",
+ "@0x/react-shared": "^1.1.0",
"basscss": "^8.0.3",
"bowser": "^1.9.3",
+ "highlight.js": "^9.13.1",
"less": "^2.7.2",
- "lodash": "^4.17.5",
"polished": "^1.9.2",
- "react": "^16.4.2",
- "react-document-title": "^2.0.3",
- "react-dom": "^16.4.2",
- "react-helmet": "^5.2.0",
- "styled-components": "^3.3.0"
+ "react": "^16.5.2",
+ "react-dom": "^16.5.2",
+ "react-loadable": "^5.5.0",
+ "react-lottie": "^1.2.3",
+ "react-tabs": "^2.3.0",
+ "styled-components": "^4.1.1",
+ "styled-normalize": "^8.0.1"
},
"devDependencies": {
+ "@types/highlight.js": "^9.12.3",
"@types/lodash": "4.14.104",
"@types/node": "*",
"@types/react": "^16.4.2",
"@types/react-dom": "^16.0.7",
- "@types/react-helmet": "^5.0.6",
+ "@types/react-loadable": "^5.4.1",
+ "@types/react-lottie": "^1.2.0",
"@types/react-router-dom": "^4.0.4",
+ "@types/react-tabs": "^2.3.0",
"@types/react-tap-event-plugin": "0.0.30",
- "@types/styled-components": "^4.0.0",
+ "@types/styled-components": "4.1.1",
"awesome-typescript-loader": "^5.2.1",
+ "clean-webpack-plugin": "^0.1.19",
+ "copy-webpack-plugin": "^4.5.4",
"copyfiles": "^2.0.0",
"css-loader": "0.23.x",
+ "html-webpack-plugin": "^3.2.0",
"less-loader": "^4.1.0",
"make-promises-safe": "^1.1.0",
"raw-loader": "^0.5.1",
+ "react-snap": "^1.19.0",
+ "react-svg-loader": "^2.1.0",
"shx": "^0.2.2",
"source-map-loader": "^0.2.4",
"style-loader": "0.23.x",
@@ -52,7 +62,15 @@
"typescript": "3.0.1",
"uglifyjs-webpack-plugin": "^2.0.1",
"webpack": "^4.20.2",
+ "webpack-bundle-analyzer": "^3.0.3",
"webpack-cli": "3.1.2",
"webpack-dev-server": "^3.1.9"
+ },
+ "reactSnap": {
+ "source": "public",
+ "puppeteerArgs": [
+ "--no-sandbox",
+ "--disable-setuid-sandbox"
+ ]
}
}
diff --git a/packages/dev-tools-pages/pages.js b/packages/dev-tools-pages/pages.js
new file mode 100644
index 000000000..7609a07e9
--- /dev/null
+++ b/packages/dev-tools-pages/pages.js
@@ -0,0 +1,72 @@
+const pages = [
+ {
+ title: 'sol-compiler',
+ filename: 'compiler/index.html',
+ template: 'assets/index.html',
+ chunks: ['compiler'],
+ favicon: 'assets/favicons/compiler.ico',
+ minify: true,
+ meta: {
+ description: 'Solidity compilation that just works',
+ 'og-title': { property: 'og:title', content: 'sol-compiler' },
+ 'og-description': { property: 'og:description', content: 'Solidity compilation that just works' },
+ 'og-type': { property: 'og:type', content: 'website' },
+ 'og-image': { property: 'og:image', content: '/images/og-compiler' },
+ 'twitter:site': '@0xproject',
+ 'twitter:image': '/images/og-compiler',
+ },
+ },
+ {
+ title: 'sol-cov',
+ filename: 'cov/index.html',
+ template: 'assets/index.html',
+ chunks: ['cov'],
+ favicon: 'assets/favicons/cov.ico',
+ minify: true,
+ meta: {
+ description: 'Solidity code coverage',
+ 'og-title': { property: 'og:title', content: 'sol-cov' },
+ 'og-description': { property: 'og:description', content: 'Solidity code coverage' },
+ 'og-type': { property: 'og:type', content: 'website' },
+ 'og-image': { property: 'og:image', content: '/images/og-cov' },
+ 'twitter:site': '@0xproject',
+ 'twitter:image': '/images/og-cov',
+ },
+ },
+ {
+ title: 'sol-profiler',
+ filename: 'profiler/index.html',
+ template: 'assets/index.html',
+ chunks: ['profiler'],
+ favicon: 'assets/favicons/profiler.ico',
+ minify: true,
+ meta: {
+ description: 'Gas profiling for Solidity',
+ 'og-title': { property: 'og:title', content: 'sol-profiler' },
+ 'og-description': { property: 'og:description', content: 'Gas profiling for Solidity' },
+ 'og-type': { property: 'og:type', content: 'website' },
+ 'og-image': { property: 'og:image', content: '/images/og-profiler' },
+ 'twitter:site': '@0xproject',
+ 'twitter:image': '/images/og-profiler',
+ },
+ },
+ {
+ title: 'sol-trace',
+ filename: 'trace/index.html',
+ template: 'assets/index.html',
+ chunks: ['trace'],
+ favicon: 'assets/favicons/trace.ico',
+ minify: true,
+ meta: {
+ description: 'Human-readable stack traces',
+ 'og-title': { property: 'og:title', content: 'sol-trace' },
+ 'og-description': { property: 'og:description', content: 'Human-readable stack traces' },
+ 'og-type': { property: 'og:type', content: 'website' },
+ 'og-image': { property: 'og:image', content: '/images/og-trace' },
+ 'twitter:site': '@0xproject',
+ 'twitter:image': '/images/og-trace',
+ },
+ },
+];
+
+module.exports = pages;
diff --git a/packages/dev-tools-pages/public/css/basscss_responsive_custom.css b/packages/dev-tools-pages/public/css/basscss_responsive_custom.css
deleted file mode 100644
index 5f8bd9117..000000000
--- a/packages/dev-tools-pages/public/css/basscss_responsive_custom.css
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Custom Basscss Responsive Utilities */
-
-@media (max-width: 52em) {
- .sm-center {
- text-align: center;
- }
- .sm-align-middle {
- vertical-align: middle;
- }
- .sm-align-top {
- vertical-align: top;
- }
- .sm-left-align {
- text-align: left;
- }
- .sm-right-align {
- text-align: right;
- }
- .sm-table-cell {
- display: table-cell;
- }
- .sm-mx-auto {
- margin-left: auto;
- margin-right: auto;
- }
- .sm-right {
- float: right;
- }
-}
-
-@media (min-width: 52em) {
- .md-center {
- text-align: center;
- }
- .md-align-middle {
- vertical-align: middle;
- }
- .md-align-top {
- vertical-align: top;
- }
- .md-left-align {
- text-align: left;
- }
- .md-right-align {
- text-align: right;
- }
- .md-table-cell {
- display: table-cell;
- }
- .md-mx-auto {
- margin-left: auto;
- margin-right: auto;
- }
- .md-right {
- float: right;
- }
-}
-
-@media (min-width: 64em) {
- .lg-center {
- text-align: center;
- }
- .lg-align-middle {
- vertical-align: middle;
- }
- .lg-align-top {
- vertical-align: top;
- }
- .lg-left-align {
- text-align: left;
- }
- .lg-right-align {
- text-align: right;
- }
- .lg-table-cell {
- display: table-cell;
- }
- .lg-mx-auto {
- margin-left: auto;
- margin-right: auto;
- }
- .lg-right {
- float: right;
- }
-}
diff --git a/packages/dev-tools-pages/public/css/basscss_responsive_margin.css b/packages/dev-tools-pages/public/css/basscss_responsive_margin.css
deleted file mode 100644
index c9f3e855c..000000000
--- a/packages/dev-tools-pages/public/css/basscss_responsive_margin.css
+++ /dev/null
@@ -1,453 +0,0 @@
-/* Basscss Responsive Margin */
-
-@media (max-width: 52em) {
- /* Modified by Fabio Berger to max-width from min-width */
-
- .sm-m0 {
- margin: 0;
- }
- .sm-mt0 {
- margin-top: 0;
- }
- .sm-mr0 {
- margin-right: 0;
- }
- .sm-mb0 {
- margin-bottom: 0;
- }
- .sm-ml0 {
- margin-left: 0;
- }
- .sm-mx0 {
- margin-left: 0;
- margin-right: 0;
- }
- .sm-my0 {
- margin-top: 0;
- margin-bottom: 0;
- }
-
- .sm-m1 {
- margin: 0.5rem;
- }
- .sm-mt1 {
- margin-top: 0.5rem;
- }
- .sm-mr1 {
- margin-right: 0.5rem;
- }
- .sm-mb1 {
- margin-bottom: 0.5rem;
- }
- .sm-ml1 {
- margin-left: 0.5rem;
- }
- .sm-mx1 {
- margin-left: 0.5rem;
- margin-right: 0.5rem;
- }
- .sm-my1 {
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
-
- .sm-m2 {
- margin: 1rem;
- }
- .sm-mt2 {
- margin-top: 1rem;
- }
- .sm-mr2 {
- margin-right: 1rem;
- }
- .sm-mb2 {
- margin-bottom: 1rem;
- }
- .sm-ml2 {
- margin-left: 1rem;
- }
- .sm-mx2 {
- margin-left: 1rem;
- margin-right: 1rem;
- }
- .sm-my2 {
- margin-top: 1rem;
- margin-bottom: 1rem;
- }
-
- .sm-m3 {
- margin: 2rem;
- }
- .sm-mt3 {
- margin-top: 2rem;
- }
- .sm-mr3 {
- margin-right: 2rem;
- }
- .sm-mb3 {
- margin-bottom: 2rem;
- }
- .sm-ml3 {
- margin-left: 2rem;
- }
- .sm-mx3 {
- margin-left: 2rem;
- margin-right: 2rem;
- }
- .sm-my3 {
- margin-top: 2rem;
- margin-bottom: 2rem;
- }
-
- .sm-m4 {
- margin: 4rem;
- }
- .sm-mt4 {
- margin-top: 4rem;
- }
- .sm-mr4 {
- margin-right: 4rem;
- }
- .sm-mb4 {
- margin-bottom: 4rem;
- }
- .sm-ml4 {
- margin-left: 4rem;
- }
- .sm-mx4 {
- margin-left: 4rem;
- margin-right: 4rem;
- }
- .sm-my4 {
- margin-top: 4rem;
- margin-bottom: 4rem;
- }
-
- .sm-mxn1 {
- margin-left: -0.5rem;
- margin-right: -0.5rem;
- }
- .sm-mxn2 {
- margin-left: -1rem;
- margin-right: -1rem;
- }
- .sm-mxn3 {
- margin-left: -2rem;
- margin-right: -2rem;
- }
- .sm-mxn4 {
- margin-left: -4rem;
- margin-right: -4rem;
- }
-
- .sm-ml-auto {
- margin-left: auto;
- }
- .sm-mr-auto {
- margin-right: auto;
- }
- .sm-mx-auto {
- margin-left: auto;
- margin-right: auto;
- }
-}
-
-@media (min-width: 52em) {
- .md-m0 {
- margin: 0;
- }
- .md-mt0 {
- margin-top: 0;
- }
- .md-mr0 {
- margin-right: 0;
- }
- .md-mb0 {
- margin-bottom: 0;
- }
- .md-ml0 {
- margin-left: 0;
- }
- .md-mx0 {
- margin-left: 0;
- margin-right: 0;
- }
- .md-my0 {
- margin-top: 0;
- margin-bottom: 0;
- }
-
- .md-m1 {
- margin: 0.5rem;
- }
- .md-mt1 {
- margin-top: 0.5rem;
- }
- .md-mr1 {
- margin-right: 0.5rem;
- }
- .md-mb1 {
- margin-bottom: 0.5rem;
- }
- .md-ml1 {
- margin-left: 0.5rem;
- }
- .md-mx1 {
- margin-left: 0.5rem;
- margin-right: 0.5rem;
- }
- .md-my1 {
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
-
- .md-m2 {
- margin: 1rem;
- }
- .md-mt2 {
- margin-top: 1rem;
- }
- .md-mr2 {
- margin-right: 1rem;
- }
- .md-mb2 {
- margin-bottom: 1rem;
- }
- .md-ml2 {
- margin-left: 1rem;
- }
- .md-mx2 {
- margin-left: 1rem;
- margin-right: 1rem;
- }
- .md-my2 {
- margin-top: 1rem;
- margin-bottom: 1rem;
- }
-
- .md-m3 {
- margin: 2rem;
- }
- .md-mt3 {
- margin-top: 2rem;
- }
- .md-mr3 {
- margin-right: 2rem;
- }
- .md-mb3 {
- margin-bottom: 2rem;
- }
- .md-ml3 {
- margin-left: 2rem;
- }
- .md-mx3 {
- margin-left: 2rem;
- margin-right: 2rem;
- }
- .md-my3 {
- margin-top: 2rem;
- margin-bottom: 2rem;
- }
-
- .md-m4 {
- margin: 4rem;
- }
- .md-mt4 {
- margin-top: 4rem;
- }
- .md-mr4 {
- margin-right: 4rem;
- }
- .md-mb4 {
- margin-bottom: 4rem;
- }
- .md-ml4 {
- margin-left: 4rem;
- }
- .md-mx4 {
- margin-left: 4rem;
- margin-right: 4rem;
- }
- .md-my4 {
- margin-top: 4rem;
- margin-bottom: 4rem;
- }
-
- .md-mxn1 {
- margin-left: -0.5rem;
- margin-right: -0.5rem;
- }
- .md-mxn2 {
- margin-left: -1rem;
- margin-right: -1rem;
- }
- .md-mxn3 {
- margin-left: -2rem;
- margin-right: -2rem;
- }
- .md-mxn4 {
- margin-left: -4rem;
- margin-right: -4rem;
- }
-
- .md-ml-auto {
- margin-left: auto;
- }
- .md-mr-auto {
- margin-right: auto;
- }
- .md-mx-auto {
- margin-left: auto;
- margin-right: auto;
- }
-}
-
-@media (min-width: 64em) {
- .lg-m0 {
- margin: 0;
- }
- .lg-mt0 {
- margin-top: 0;
- }
- .lg-mr0 {
- margin-right: 0;
- }
- .lg-mb0 {
- margin-bottom: 0;
- }
- .lg-ml0 {
- margin-left: 0;
- }
- .lg-mx0 {
- margin-left: 0;
- margin-right: 0;
- }
- .lg-my0 {
- margin-top: 0;
- margin-bottom: 0;
- }
-
- .lg-m1 {
- margin: 0.5rem;
- }
- .lg-mt1 {
- margin-top: 0.5rem;
- }
- .lg-mr1 {
- margin-right: 0.5rem;
- }
- .lg-mb1 {
- margin-bottom: 0.5rem;
- }
- .lg-ml1 {
- margin-left: 0.5rem;
- }
- .lg-mx1 {
- margin-left: 0.5rem;
- margin-right: 0.5rem;
- }
- .lg-my1 {
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
-
- .lg-m2 {
- margin: 1rem;
- }
- .lg-mt2 {
- margin-top: 1rem;
- }
- .lg-mr2 {
- margin-right: 1rem;
- }
- .lg-mb2 {
- margin-bottom: 1rem;
- }
- .lg-ml2 {
- margin-left: 1rem;
- }
- .lg-mx2 {
- margin-left: 1rem;
- margin-right: 1rem;
- }
- .lg-my2 {
- margin-top: 1rem;
- margin-bottom: 1rem;
- }
-
- .lg-m3 {
- margin: 2rem;
- }
- .lg-mt3 {
- margin-top: 2rem;
- }
- .lg-mr3 {
- margin-right: 2rem;
- }
- .lg-mb3 {
- margin-bottom: 2rem;
- }
- .lg-ml3 {
- margin-left: 2rem;
- }
- .lg-mx3 {
- margin-left: 2rem;
- margin-right: 2rem;
- }
- .lg-my3 {
- margin-top: 2rem;
- margin-bottom: 2rem;
- }
-
- .lg-m4 {
- margin: 4rem;
- }
- .lg-mt4 {
- margin-top: 4rem;
- }
- .lg-mr4 {
- margin-right: 4rem;
- }
- .lg-mb4 {
- margin-bottom: 4rem;
- }
- .lg-ml4 {
- margin-left: 4rem;
- }
- .lg-mx4 {
- margin-left: 4rem;
- margin-right: 4rem;
- }
- .lg-my4 {
- margin-top: 4rem;
- margin-bottom: 4rem;
- }
-
- .lg-mxn1 {
- margin-left: -0.5rem;
- margin-right: -0.5rem;
- }
- .lg-mxn2 {
- margin-left: -1rem;
- margin-right: -1rem;
- }
- .lg-mxn3 {
- margin-left: -2rem;
- margin-right: -2rem;
- }
- .lg-mxn4 {
- margin-left: -4rem;
- margin-right: -4rem;
- }
-
- .lg-ml-auto {
- margin-left: auto;
- }
- .lg-mr-auto {
- margin-right: auto;
- }
- .lg-mx-auto {
- margin-left: auto;
- margin-right: auto;
- }
-}
diff --git a/packages/dev-tools-pages/public/css/basscss_responsive_padding.css b/packages/dev-tools-pages/public/css/basscss_responsive_padding.css
deleted file mode 100644
index e027c2d65..000000000
--- a/packages/dev-tools-pages/public/css/basscss_responsive_padding.css
+++ /dev/null
@@ -1,134 +0,0 @@
-/* Basscss Responsive Padding */
-/* Modified by Fabio Berger to include xs prefix */
-
-@media (max-width: 52em) { /* Modified by Fabio Berger to max-width from min-width */
-
- .sm-p0 { padding: 0 }
- .sm-pt0 { padding-top: 0 }
- .sm-pr0 { padding-right: 0 }
- .sm-pb0 { padding-bottom: 0 }
- .sm-pl0 { padding-left: 0 }
- .sm-px0 { padding-left: 0; padding-right: 0 }
- .sm-py0 { padding-top: 0; padding-bottom: 0 }
-
- .sm-p1 { padding: .5rem }
- .sm-pt1 { padding-top: .5rem }
- .sm-pr1 { padding-right: .5rem }
- .sm-pb1 { padding-bottom: .5rem }
- .sm-pl1 { padding-left: .5rem }
- .sm-px1 { padding-left: .5rem; padding-right: .5rem }
- .sm-py1 { padding-top: .5rem; padding-bottom: .5rem }
-
- .sm-p2 { padding: 1rem }
- .sm-pt2 { padding-top: 1rem }
- .sm-pr2 { padding-right: 1rem }
- .sm-pb2 { padding-bottom: 1rem }
- .sm-pl2 { padding-left: 1rem }
- .sm-px2 { padding-left: 1rem; padding-right: 1rem }
- .sm-py2 { padding-top: 1rem; padding-bottom: 1rem }
-
- .sm-p3 { padding: 2rem }
- .sm-pt3 { padding-top: 2rem }
- .sm-pr3 { padding-right: 2rem }
- .sm-pb3 { padding-bottom: 2rem }
- .sm-pl3 { padding-left: 2rem }
- .sm-px3 { padding-left: 2rem; padding-right: 2rem }
- .sm-py3 { padding-top: 2rem; padding-bottom: 2rem }
-
- .sm-p4 { padding: 4rem }
- .sm-pt4 { padding-top: 4rem }
- .sm-pr4 { padding-right: 4rem }
- .sm-pb4 { padding-bottom: 4rem }
- .sm-pl4 { padding-left: 4rem }
- .sm-px4 { padding-left: 4rem; padding-right: 4rem }
- .sm-py4 { padding-top: 4rem; padding-bottom: 4rem }
-
-}
-
-@media (min-width: 52em) {
-
- .md-p0 { padding: 0 }
- .md-pt0 { padding-top: 0 }
- .md-pr0 { padding-right: 0 }
- .md-pb0 { padding-bottom: 0 }
- .md-pl0 { padding-left: 0 }
- .md-px0 { padding-left: 0; padding-right: 0 }
- .md-py0 { padding-top: 0; padding-bottom: 0 }
-
- .md-p1 { padding: .5rem }
- .md-pt1 { padding-top: .5rem }
- .md-pr1 { padding-right: .5rem }
- .md-pb1 { padding-bottom: .5rem }
- .md-pl1 { padding-left: .5rem }
- .md-px1 { padding-left: .5rem; padding-right: .5rem }
- .md-py1 { padding-top: .5rem; padding-bottom: .5rem }
-
- .md-p2 { padding: 1rem }
- .md-pt2 { padding-top: 1rem }
- .md-pr2 { padding-right: 1rem }
- .md-pb2 { padding-bottom: 1rem }
- .md-pl2 { padding-left: 1rem }
- .md-px2 { padding-left: 1rem; padding-right: 1rem }
- .md-py2 { padding-top: 1rem; padding-bottom: 1rem }
-
- .md-p3 { padding: 2rem }
- .md-pt3 { padding-top: 2rem }
- .md-pr3 { padding-right: 2rem }
- .md-pb3 { padding-bottom: 2rem }
- .md-pl3 { padding-left: 2rem }
- .md-px3 { padding-left: 2rem; padding-right: 2rem }
- .md-py3 { padding-top: 2rem; padding-bottom: 2rem }
-
- .md-p4 { padding: 4rem }
- .md-pt4 { padding-top: 4rem }
- .md-pr4 { padding-right: 4rem }
- .md-pb4 { padding-bottom: 4rem }
- .md-pl4 { padding-left: 4rem }
- .md-px4 { padding-left: 4rem; padding-right: 4rem }
- .md-py4 { padding-top: 4rem; padding-bottom: 4rem }
-
-}
-
-@media (min-width: 64em) {
-
- .lg-p0 { padding: 0 }
- .lg-pt0 { padding-top: 0 }
- .lg-pr0 { padding-right: 0 }
- .lg-pb0 { padding-bottom: 0 }
- .lg-pl0 { padding-left: 0 }
- .lg-px0 { padding-left: 0; padding-right: 0 }
- .lg-py0 { padding-top: 0; padding-bottom: 0 }
-
- .lg-p1 { padding: .5rem }
- .lg-pt1 { padding-top: .5rem }
- .lg-pr1 { padding-right: .5rem }
- .lg-pb1 { padding-bottom: .5rem }
- .lg-pl1 { padding-left: .5rem }
- .lg-px1 { padding-left: .5rem; padding-right: .5rem }
- .lg-py1 { padding-top: .5rem; padding-bottom: .5rem }
-
- .lg-p2 { padding: 1rem }
- .lg-pt2 { padding-top: 1rem }
- .lg-pr2 { padding-right: 1rem }
- .lg-pb2 { padding-bottom: 1rem }
- .lg-pl2 { padding-left: 1rem }
- .lg-px2 { padding-left: 1rem; padding-right: 1rem }
- .lg-py2 { padding-top: 1rem; padding-bottom: 1rem }
-
- .lg-p3 { padding: 2rem }
- .lg-pt3 { padding-top: 2rem }
- .lg-pr3 { padding-right: 2rem }
- .lg-pb3 { padding-bottom: 2rem }
- .lg-pl3 { padding-left: 2rem }
- .lg-px3 { padding-left: 2rem; padding-right: 2rem }
- .lg-py3 { padding-top: 2rem; padding-bottom: 2rem }
-
- .lg-p4 { padding: 4rem }
- .lg-pt4 { padding-top: 4rem }
- .lg-pr4 { padding-right: 4rem }
- .lg-pb4 { padding-bottom: 4rem }
- .lg-pl4 { padding-left: 4rem }
- .lg-px4 { padding-left: 4rem; padding-right: 4rem }
- .lg-py4 { padding-top: 4rem; padding-bottom: 4rem }
-
-}
diff --git a/packages/dev-tools-pages/public/css/basscss_responsive_type_scale.css b/packages/dev-tools-pages/public/css/basscss_responsive_type_scale.css
deleted file mode 100644
index cae23b4e7..000000000
--- a/packages/dev-tools-pages/public/css/basscss_responsive_type_scale.css
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Basscss Responsive Type Scale */
-/* Modified by Fabio Berger to include xs prefix */
-
-@media (max-width: 52em) { /* Modified by Fabio Berger to max-width from min-width */
- .sm-h00 { font-size: 4rem }
- .sm-h0 { font-size: 3rem }
- .sm-h1 { font-size: 2rem }
- .sm-h2 { font-size: 1.5rem }
- .sm-h3 { font-size: 1.25rem }
- .sm-h4 { font-size: 1rem }
- .sm-h5 { font-size: .875rem }
- .sm-h6 { font-size: .75rem }
-}
-
-@media (min-width: 52em) {
- .md-h00 { font-size: 4rem }
- .md-h0 { font-size: 3rem }
- .md-h1 { font-size: 2rem }
- .md-h2 { font-size: 1.5rem }
- .md-h3 { font-size: 1.25rem }
- .md-h4 { font-size: 1rem }
- .md-h5 { font-size: .875rem }
- .md-h6 { font-size: .75rem }
-}
-
-@media (min-width: 64em) {
- .lg-h00 { font-size: 4rem }
- .lg-h0 { font-size: 3rem }
- .lg-h1 { font-size: 2rem }
- .lg-h2 { font-size: 1.5rem }
- .lg-h3 { font-size: 1.25rem }
- .lg-h4 { font-size: 1rem }
- .lg-h5 { font-size: .875rem }
- .lg-h6 { font-size: .75rem }
-}
diff --git a/packages/dev-tools-pages/public/images/favicon/favicon-2-16x16.png b/packages/dev-tools-pages/public/images/favicon/favicon-2-16x16.png
deleted file mode 100755
index 68c493c4f..000000000
--- a/packages/dev-tools-pages/public/images/favicon/favicon-2-16x16.png
+++ /dev/null
Binary files differ
diff --git a/packages/dev-tools-pages/public/images/favicon/favicon-2-32x32.png b/packages/dev-tools-pages/public/images/favicon/favicon-2-32x32.png
deleted file mode 100755
index a5abb0eb3..000000000
--- a/packages/dev-tools-pages/public/images/favicon/favicon-2-32x32.png
+++ /dev/null
Binary files differ
diff --git a/packages/dev-tools-pages/public/images/favicon/favicon.ico b/packages/dev-tools-pages/public/images/favicon/favicon.ico
deleted file mode 100755
index b7ada2a1c..000000000
--- a/packages/dev-tools-pages/public/images/favicon/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/packages/dev-tools-pages/public/index.html b/packages/dev-tools-pages/public/index.html
deleted file mode 100644
index f62d7b255..000000000
--- a/packages/dev-tools-pages/public/index.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
-
-<head>
- <meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="description" content="" />
- <meta property="og:type" content="website" />
- <meta property="og:title" content="0x" />
- <meta property="og:description" content="" />
- <meta property="og:image" content="/images/og_image.png" />
- <title>0x: The Protocol for Trading Tokens</title>
- <link rel="icon" type="image/png" href="/images/favicon/favicon-2-32x32.png" sizes="32x32" />
- <link rel="icon" type="image/png" href="/images/favicon/favicon-2-16x16.png" sizes="16x16" />
- <link rel="stylesheet" href="/css/basscss_responsive_custom.css">
- <link rel="stylesheet" href="/css/basscss_responsive_padding.css">
- <link rel="stylesheet" href="/css/basscss_responsive_margin.css">
- <link rel="stylesheet" href="/css/basscss_responsive_type_scale.css">
-</head>
-
-<body style="margin: 0px; min-width: 355px;">
- <div id="app"></div>
- <script type="text/javascript" crossorigin="anonymous" src="/bundle.js" charset="utf-8"></script>
-</body>
-
-</html> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/components/animations/compiler/data.json b/packages/dev-tools-pages/ts/components/animations/compiler/data.json
new file mode 100644
index 000000000..6b10e537b
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/compiler/data.json
@@ -0,0 +1 @@
+{"v":"5.4.1","fr":30,"ip":0,"op":420,"w":4300,"h":1400,"nm":"header-compiler","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Path Copy 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[328.5,911.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-61.75,-99.75],[99.75,61.75],[61.75,99.75],[-99.75,-61.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 3","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-280,-180,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-39.25,87.75],[87.75,-39.25],[39.25,-87.75],[-87.75,39.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1261.5,738.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[15.75,82.75],[82.75,15.75],[-15.75,-82.75],[-82.75,-15.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Path","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[370,-209,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[23.25,-23.25],[-23.25,23.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Path","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[347,-269,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-60.25,-60.25],[60.25,60.25]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Path","parent":12,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[330,-250,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-37.25,-84.25],[84.25,37.25],[37.25,84.25],[-84.25,-37.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Path Copy","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[449.5,348.5,0],"e":[223.5,574.5,0],"to":[-37.6666679382324,37.6666679382324,0],"ti":[37.6666679382324,-37.6666679382324,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":210,"s":[223.5,574.5,0],"e":[223.5,574.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390.5,"s":[223.5,574.5,0],"e":[449.5,348.5,0],"to":[37.6666679382324,-37.6666679382324,0],"ti":[-37.6666679382324,37.6666679382324,0]},{"t":420}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[9.42,-69.25],[-69.25,9.42],[-9.42,69.25],[69.25,-9.42]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2150,700,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1935,-90],[-1765,-260]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-2020,87],[-1946,13]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-2020,87],[-1946,13]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-2020,87],[-1946,13]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-2020,87],[-1946,13]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1935,-90],[-1765,-260]],"c":false}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117647066303,0.678431372549,0.803921628466,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[1,-1],"e":[0,0],"to":[-0.16666667163372,0.16666667163372],"ti":[0.16666667163372,-0.16666667163372]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":210,"s":[0,0],"e":[0,0],"to":[0,0],"ti":[0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[0,0],"e":[1,-1],"to":[0.16666667163372,-0.16666667163372],"ti":[-0.16666667163372,0.16666667163372]},{"t":420}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":527,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[2150,700,0],"e":[1920,930,0],"to":[-38.3333320617676,38.3333320617676,0],"ti":[38.3333320617676,-38.3333320617676,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":210,"s":[1920,930,0],"e":[1920,930,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[1920,930,0],"e":[2150,700,0],"to":[38.3333320617676,-38.3333320617676,0],"ti":[-38.3333320617676,38.3333320617676,0]},{"t":420}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1806,-241],[-1748,-183]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1750,-185],[-1748,-183]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1750,-185],[-1748,-183]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1750,-185],[-1748,-183]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1750,-185],[-1748,-183]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-1806,-241],[-1748,-183]],"c":false}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117647066303,0.678431372549,0.803921628466,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":527,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Path Copy 2","parent":8,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-134,194,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[28.03,-56.75],[-56.75,28.03],[-28.03,56.75],[56.75,-28.03]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.53,-28.25],[20.5,9.03],[20.72,9.25],[56.75,-28.03]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.53,-28.25],[20.5,9.03],[20.72,9.25],[56.75,-28.03]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.53,-28.25],[20.5,9.03],[20.72,9.25],[56.75,-28.03]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":391,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.53,-28.25],[20.5,9.03],[20.72,9.25],[56.75,-28.03]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[28.03,-56.75],[-56.75,28.03],[-28.03,56.75],[56.75,-28.03]],"c":true}]},{"t":421}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Big block","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[571.5,588.5,0],"e":[697.5,462.5,0],"to":[21,-21,0],"ti":[-21,21,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":120,"s":[697.5,462.5,0],"e":[697.5,462.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":300,"s":[697.5,462.5,0],"e":[571.5,588.5,0],"to":[-21,21,0],"ti":[21,-21,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[2,-2,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"st","c":{"a":0,"k":[0.117646998985,0.67843095368,0.803921987496,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[60.75,-182.25],[-182.25,60.75],[-60.75,182.25],[182.25,-60.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Path Copy 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[389.5,770.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-92.25,-29.25],[-92.25,-29.25],[29.25,92.25],[29.25,92.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-29.25,-92.25],[-92.25,-29.25],[29.25,92.25],[92.25,29.25]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 4","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Path Copy 9","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[273,647,0],"e":[317,695,0],"to":[7.33333349227905,8,0],"ti":[-7.33333349227905,-8,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[317,695,0],"e":[317,695,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":300,"s":[317,695,0],"e":[273,647,0],"to":[-7.33333349227905,-8,0],"ti":[7.33333349227905,8,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[30.75,-31.25],[-31.5,31]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 9","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Path Copy 8","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[329,832,0],"e":[349,812,0],"to":[3.33333325386047,-3.33333325386047,0],"ti":[-3.33333325386047,3.33333325386047,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[349,812,0],"e":[349,812,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":300,"s":[349,812,0],"e":[329,832,0],"to":[-3.33333325386047,3.33333325386047,0],"ti":[3.33333325386047,-3.33333325386047,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-61,-61],[61,61]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 8","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"wide box","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[971.5,988.5,0],"e":[1096.5,864.5,0],"to":[10.0566339492798,-9.97618103027344,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[1096.5,864.5,0],"e":[1096.5,864.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":300,"s":[1096.5,864.5,0],"e":[971.5,988.5,0],"to":[0,0,0],"ti":[-20.8333339691162,20.6666660308838,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[-1,1,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-129.25,-52.25],[-52.25,-129.25],[129.25,52.25],[52.25,129.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[993,766,0],"e":[1071,688,0],"to":[13,-13,0],"ti":[-13,13,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[1071,688,0],"e":[1071,688,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":300,"s":[1071,688,0],"e":[993,766,0],"to":[-13,13,0],"ti":[13,-13,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-89.5,-89.5],[89.5,89.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[1115,850,0],"e":[1311.5,799.5,0],"to":[18.5410747528076,-4.90381097793579,0],"ti":[-5.73690891265869,1.51731848716736,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[1311.5,799.5,0],"e":[1311.5,799.5,0],"to":[33.0833320617676,-8.75,0],"ti":[5.73690891265869,-1.51731848716736,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":300,"s":[1311.5,799.5,0],"e":[1115,850,0],"to":[-5.73690891265869,1.51731848716736,0],"ti":[-33.0833320617676,8.75,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[103.689,103.689,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[30.5,-30.5],[-30.5,30.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1011.5,748.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0},"n":"0p833_0p833_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[120.75,57.75],[58.25,120.25],[-120.25,-58.25],[-57.75,-120.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[120.514,57.986],[119.427,59.073],[-59.073,-119.427],[-57.986,-120.514]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[120.514,57.986],[119.427,59.073],[-59.073,-119.427],[-57.986,-120.514]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[120.514,57.986],[119.427,59.073],[-59.073,-119.427],[-57.986,-120.514]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.167},"n":"0p833_1_0p167_0p167","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[120.514,57.986],[119.427,59.073],[-59.073,-119.427],[-57.986,-120.514]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[120.75,57.75],[58.25,120.25],[-120.25,-58.25],[-57.75,-120.75]],"c":true}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":0,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3620,905,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[33,163],[-163,-33],[-33,-163],[163,33]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3274,751,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[86,-140],[140,-86],[-86,140],[-140,86]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3770,475,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-2,-162],[162,2],[2,162],[-162,-2]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3465,340,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-24],[24,-80],[-82,26],[-26,82]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[3420.5,966.5,0],"e":[3389.5,996.5,0],"to":[-5.16666650772095,5,0],"ti":[5.16666650772095,-5,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":120,"s":[3389.5,996.5,0],"e":[3389.5,996.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3389.5,996.5,0],"e":[3420.5,966.5,0],"to":[5.16666650772095,-5,0],"ti":[-5.16666650772095,5,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.75,-62.75],[-62.25,-62.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.75,-62.75],[62.75,62.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.75,-62.75],[62.75,62.75]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.75,-62.75],[62.75,62.75]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.75,-62.75],[62.75,62.75]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-62.75,-62.75],[-62.25,-62.25]],"c":false}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[3219.5,915.5,0],"e":[3339.5,1035.5,0],"to":[20,20,0],"ti":[-20,-20,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.167,"y":0.167},"n":"0p667_0p667_0p167_0p167","t":120,"s":[3339.5,1035.5,0],"e":[3339.5,1035.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3339.5,1035.5,0],"e":[3219.5,915.5,0],"to":[-20,-20,0],"ti":[20,20,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-38.25],[38.25,-38.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-38.25],[-38.25,38.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-38.25],[-38.25,38.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-38.25],[-38.25,38.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-38.25],[-38.25,38.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[38.25,-38.25],[38.25,-38.25]],"c":false}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3344,1041,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[42,42],[0,0],[0,0],[0,0]],"v":[[-25,-101],[-24,-100],[-24.5,-99.5],[-25.5,-100.5]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-25,-101],[101,25],[25,101],[-101,-25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-25,-101],[101,25],[25,101],[-101,-25]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-25,-101],[101,25],[25,101],[-101,-25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-25,-101],[101,25],[25,101],[-101,-25]],"c":false}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[42,42],[0,0],[0,0],[0,0]],"v":[[-25,-101],[-24,-100],[-24.5,-99.5],[-25.5,-100.5]],"c":false}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[3142.5,483.5,0],"e":[3266.5,359.5,0],"to":[20.6666660308838,-20.6666660308838,0],"ti":[-20.6666660308838,20.6666660308838,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[3266.5,359.5,0],"e":[3266.5,359.5,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3266.5,359.5,0],"e":[3142.5,483.5,0],"to":[-20.6666660308838,20.6666660308838,0],"ti":[20.6666660308838,-20.6666660308838,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-73.25,-73.25],[73.25,73.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-33.25,-33.25],[73.25,73.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-33.25,-33.25],[73.25,73.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-33.25,-33.25],[73.25,73.25]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-33.25,-33.25],[73.25,73.25]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-73.25,-73.25],[73.25,73.25]],"c":false}]},{"t":329.5}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[3163,420,0],"e":[3327,588,0],"to":[27.3333339691162,28,0],"ti":[-27.3333339691162,-28,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[3327,588,0],"e":[3327,588,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3327,588,0],"e":[3163,420,0],"to":[-27.3333339691162,-28,0],"ti":[27.3333339691162,28,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42,-42],[-42,42]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42,-42],[42.312,-42.125]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42,-42],[42.312,-42.125]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42,-42],[42.312,-42.125]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42,-42],[42.312,-42.125]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[42,-42],[-42,42]],"c":false}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3184,441,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31,115],[-115,-31],[-31,-115],[115,31]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[113.5,31.5],[8,-74],[8,-74],[113.5,31.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[113.5,31.5],[8,-74],[8,-74],[113.5,31.5]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[113.5,31.5],[8,-74],[8,-74],[113.5,31.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[113.5,31.5],[8,-74],[8,-74],[113.5,31.5]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31,115],[-115,-31],[-31,-115],[115,31]],"c":true}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[2954,751,0],"e":[3120,585,0],"to":[27.6666660308838,-27.6666660308838,0],"ti":[-27.6666660308838,27.6666660308838,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[3120,585,0],"e":[3120,585,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3120,585,0],"e":[2954,751,0],"to":[-27.6666660308838,27.6666660308838,0],"ti":[27.6666660308838,-27.6666660308838,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[146,-40],[40,-146],[-146,40],[-40,146]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117646999657,0.678430974483,0.803921997547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":188,"s":[2046,804,0],"e":[2150,700,0],"to":[17.3333339691162,-17.3333339691162,0],"ti":[-17.3333339691162,17.3333339691162,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":210,"s":[2150,700,0],"e":[2150,700,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[2150,700,0],"e":[2046,804,0],"to":[-17.3333339691162,17.3333339691162,0],"ti":[17.3333339691162,-17.3333339691162,0]},{"t":410}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1727,-6],[1858,125]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1727,-6],[1968,235]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1727,-6],[1968,235]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1727,-6],[1968,235]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1727,-6],[1968,235]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1727,-6],[1858,125]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117647066303,0.678431372549,0.803921628466,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":527,"st":0,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2120,670,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1684,158],[1685,157]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1746,220],[1963,3]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1746,220],[1963,3]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1746,220],[1963,3]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1746,220],[1963,3]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[1684,158],[1685,157]],"c":false}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117647066303,0.678431372549,0.803921628466,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":527,"st":0,"bm":0},{"ddd":0,"ind":33,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3138,417,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[-2516,745]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117647066303,0.678431372549,0.803921628466,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[1,-1],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[636,382],[636,382],[766,512],[766,512]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[854,164],[636,382],[876,622],[1094,404]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[854,164],[636,382],[876,622],[1094,404]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[854,164],[636,382],[876,622],[1094,404]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[854,164],[636,382],[876,622],[1094,404]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[636,382],[636,382],[766,512],[766,512]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.117647066303,0.678431372549,0.803921628466,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":527,"st":0,"bm":0}],"markers":[{"tm":90,"cm":"1","dr":0},{"tm":120,"cm":"2","dr":0},{"tm":180,"cm":"3","dr":0},{"tm":210,"cm":"4","dr":0},{"tm":300,"cm":"5","dr":0},{"tm":330,"cm":"6","dr":0},{"tm":390,"cm":"7","dr":0},{"tm":420,"cm":"8","dr":0}]} \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/components/animations/compiler/index.tsx b/packages/dev-tools-pages/ts/components/animations/compiler/index.tsx
new file mode 100644
index 000000000..ba98f8da3
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/compiler/index.tsx
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+import { BaseAnimation } from '../index';
+
+import * as animationData from './data.json';
+
+const CompilerAnimation: React.StatelessComponent<{}> = () => (
+ <BaseAnimation animationData={animationData} width={2150} height={700} />
+);
+
+export { CompilerAnimation };
diff --git a/packages/dev-tools-pages/ts/components/animations/cov/data.json b/packages/dev-tools-pages/ts/components/animations/cov/data.json
new file mode 100644
index 000000000..a259c2787
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/cov/data.json
@@ -0,0 +1 @@
+{"v":"5.4.1","fr":30,"ip":0,"op":420,"w":3962,"h":1320,"nm":"header-cov","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3418.5,924.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.696,"y":1},"o":{"x":0.304,"y":0},"n":"0p696_1_0p304_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31.25,66.25],[66.25,31.25],[-31.25,-66.25],[-66.25,-31.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[21.25,86.25],[71.25,36.25],[-31.25,-66.25],[-81.25,-16.25]],"c":true}]},{"i":{"x":0.696,"y":1},"o":{"x":0.333,"y":0},"n":"0p696_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[21.25,86.25],[71.25,36.25],[-31.25,-66.25],[-81.25,-16.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[21.25,86.25],[71.25,36.25],[-31.25,-66.25],[-81.25,-16.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[21.25,86.25],[71.25,36.25],[-31.25,-66.25],[-81.25,-16.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31.25,66.25],[66.25,31.25],[-31.25,-66.25],[-66.25,-31.25]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3392.5,970.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[18.25,89.25],[89.25,18.25],[-18.25,-89.25],[-89.25,-18.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2958,886,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[64,-94],[94,-64],[-64,94],[-94,64]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-126],[118,-88],[-64,94],[-102,56]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-126],[118,-88],[-64,94],[-102,56]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-126],[118,-88],[-64,94],[-102,56]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[80,-126],[118,-88],[-64,94],[-102,56]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[64,-94],[94,-64],[-64,94],[-94,64]],"c":true}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2988,816,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[79,-129],[129,-79],[-79,129],[-129,79]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3588,678,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0]],"o":[[0,0]],"v":[[-3784,-472]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.733332974303,0.572548959769,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"n":"0p833_1_0p167_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-18.5,-75],[75,18.5],[18.5,75],[-75,-18.5]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-26.5,-27],[47,46.5],[18.5,75],[-55,1.5]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-26.5,-27],[47,46.5],[18.5,75],[-55,1.5]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-26.5,-27],[47,46.5],[18.5,75],[-55,1.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-26.5,-27],[47,46.5],[18.5,75],[-55,1.5]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-18.5,-75],[75,18.5],[18.5,75],[-75,-18.5]],"c":true}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3678,548,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[26.5,-140],[140,-26.5],[-26.5,140],[-140,26.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3650.5,150.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-11.75,59.25],[59.25,-11.75],[11.75,-59.25],[-59.25,11.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3272.5,260.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31.25,66.25],[66.25,31.25],[-31.25,-66.25],[-66.25,-31.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[27.25,34.25],[48.25,13.25],[-31.25,-66.25],[-52.25,-45.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":211,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[27.25,34.25],[48.25,13.25],[-31.25,-66.25],[-52.25,-45.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[27.25,34.25],[48.25,13.25],[-31.25,-66.25],[-52.25,-45.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[27.25,34.25],[48.25,13.25],[-31.25,-66.25],[-52.25,-45.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[31.25,66.25],[66.25,31.25],[-31.25,-66.25],[-66.25,-31.25]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3246.5,306.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[18.25,89.25],[89.25,18.25],[-18.25,-89.25],[-89.25,-18.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2758.5,720.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-33.25,11.75],[-11.75,33.25],[33.25,-11.75],[11.75,-33.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2729.5,707.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-47.75,5.25],[-5.25,47.75],[47.75,-5.25],[5.25,-47.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1285.5,815.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[36.75,-8.25],[-8.25,36.75],[-36.75,8.25],[8.25,-36.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[94.75,37.75],[43.75,88.75],[-36.75,8.25],[14.25,-42.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":211,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[94.75,37.75],[43.75,88.75],[-36.75,8.25],[14.25,-42.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[94.75,37.75],[43.75,88.75],[-36.75,8.25],[14.25,-42.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[94.75,37.75],[43.75,88.75],[-36.75,8.25],[14.25,-42.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[36.75,-8.25],[-8.25,36.75],[-36.75,8.25],[8.25,-36.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1415.5,905.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[101.75,36.75],[36.75,101.75],[-101.75,-36.75],[-36.75,-101.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[611,329,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[62.5,-95.5],[95.5,-62.5],[-62.5,95.5],[-95.5,62.5]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[43,-47],[61.5,-28.5],[-62.5,95.5],[-81,77]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[43,-47],[61.5,-28.5],[-62.5,95.5],[-81,77]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[43,-47],[61.5,-28.5],[-62.5,95.5],[-81,77]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[43,-47],[61.5,-28.5],[-62.5,95.5],[-81,77]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[62.5,-95.5],[95.5,-62.5],[-62.5,95.5],[-95.5,62.5]],"c":true}]},{"t":329}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[644,262,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[79,-129],[129,-79],[-79,129],[-129,79]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1126.5,374.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[39.25,16.25],[16.25,39.25],[-39.25,-16.25],[-16.25,-39.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1186.5,414.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[69.25,36.25],[36.25,69.25],[-69.25,-36.25],[-36.25,-69.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,944,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-36,19.5],[-0.5,-16],[166,150.5],[130.5,186]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10,45.5],[13.5,22],[154,162.5],[130.5,186]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10,45.5],[13.5,22],[154,162.5],[130.5,186]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10,45.5],[13.5,22],[154,162.5],[130.5,186]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-10,45.5],[13.5,22],[154,162.5],[130.5,186]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-36,19.5],[-0.5,-16],[166,150.5],[130.5,186]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[375,944,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-186,-130.5],[-130.5,-186],[186,130.5],[130.5,186]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[815.5,863.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[39.75,-93.75],[93.75,-39.75],[-39.75,93.75],[-93.75,39.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[33.25,-145.25],[116.25,-62.25],[-39.75,93.75],[-122.75,10.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[33.25,-145.25],[116.25,-62.25],[-39.75,93.75],[-122.75,10.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[33.25,-145.25],[116.25,-62.25],[-39.75,93.75],[-122.75,10.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[33.25,-145.25],[116.25,-62.25],[-39.75,93.75],[-122.75,10.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[39.75,-93.75],[93.75,-39.75],[-39.75,93.75],[-93.75,39.75]],"c":true}]},{"t":329}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[777.5,721.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.75,-164.75],[164.75,-20.75],[-20.75,164.75],[-164.75,20.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.7333329916,0.572548985481,0,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":524.5,"st":0,"bm":0}],"markers":[{"tm":90,"cm":"1","dr":0},{"tm":120,"cm":"2","dr":0},{"tm":180,"cm":"3","dr":0},{"tm":210,"cm":"4","dr":0},{"tm":300,"cm":"5","dr":0},{"tm":330,"cm":"6","dr":0},{"tm":390,"cm":"7","dr":0},{"tm":420,"cm":"8","dr":0}]} \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/components/animations/cov/index.tsx b/packages/dev-tools-pages/ts/components/animations/cov/index.tsx
new file mode 100644
index 000000000..bd872cc85
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/cov/index.tsx
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+import { BaseAnimation } from '../index';
+
+import * as animationData from './data.json';
+
+const CovAnimation: React.StatelessComponent<{}> = () => (
+ <BaseAnimation animationData={animationData} width={1981} height={660} />
+);
+
+export { CovAnimation };
diff --git a/packages/dev-tools-pages/ts/components/animations/index.tsx b/packages/dev-tools-pages/ts/components/animations/index.tsx
new file mode 100644
index 000000000..8e5421f5c
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/index.tsx
@@ -0,0 +1,96 @@
+import * as React from 'react';
+import Lottie from 'react-lottie';
+import styled from 'styled-components';
+
+import { media } from 'ts/variables';
+
+interface AnimationProps {
+ animationData: object;
+ width: number;
+ height: number;
+}
+
+interface AnimationState {
+ width?: number | undefined;
+ height?: number | undefined;
+}
+
+class BaseAnimation extends React.PureComponent<AnimationProps, AnimationState> {
+ public state: AnimationState = {
+ height: undefined,
+ width: undefined,
+ };
+ private _timeout = undefined as number;
+ public componentDidMount(): void {
+ this._updateAnimationSize();
+ window.addEventListener('resize', this._handleResize.bind(this));
+ }
+ public componentWillUnmount(): void {
+ window.removeEventListener('resize', this._handleResize.bind(this));
+ }
+ public render(): React.ReactNode {
+ const { animationData } = this.props;
+ const height = this.state.height || this.props.height;
+ const width = this.state.width || this.props.width;
+
+ return (
+ <Container height={height}>
+ <InnerContainer>
+ <Lottie
+ width={width}
+ height={height}
+ options={{
+ loop: true,
+ autoplay: true,
+ animationData,
+ }}
+ />
+ </InnerContainer>
+ </Container>
+ );
+ }
+ private _handleResize(): void {
+ clearTimeout(this._timeout);
+ this._timeout = window.setTimeout(this._updateAnimationSize.bind(this), 50);
+ }
+ private _updateAnimationSize(): void {
+ const windowWidth = window.innerWidth;
+ let width;
+ let height;
+ if (windowWidth <= 1000) {
+ const maxWidth = windowWidth + 250;
+ const ratio = maxWidth / this.props.width;
+
+ height = Math.round(this.props.height * ratio);
+ width = Math.round(this.props.width * ratio);
+ }
+
+ this.setState({ width, height });
+ }
+}
+
+const Container =
+ styled.div <
+ AnimationProps >
+ `
+ width: 100%;
+ height: ${props => props.height}px;
+ position: absolute;
+ top: 40%;
+ left: 0;
+ z-index: -1;
+ overflow: hidden;
+ ${media.large`
+ top: 100%;
+ transform: translateY(-50%);
+ `};
+`;
+
+const InnerContainer = styled.div`
+ position: absolute;
+ top: 0;
+ left: 50%;
+ transform: translateX(-50%);
+`;
+
+export { BaseAnimation };
diff --git a/packages/dev-tools-pages/ts/components/animations/profiler/data.json b/packages/dev-tools-pages/ts/components/animations/profiler/data.json
new file mode 100644
index 000000000..2d769bc50
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/profiler/data.json
@@ -0,0 +1 @@
+{"v":"5.4.1","fr":30,"ip":0,"op":420,"w":3970,"h":1314,"nm":"header-profiler","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":2,"ty":4,"nm":"Path Copy","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[376,448,0],"e":[376,392,0],"to":[0,-9.33333301544189,0],"ti":[0,9.33333301544189,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[376,392,0],"e":[376,392,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[376,392,0],"e":[376,448,0],"to":[0,9.33333301544189,0],"ti":[0,-9.33333301544189,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-169.69,0],[134.5,0]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-142.19,0],[106.5,0]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-142.19,0],[106.5,0]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-142.19,0],[106.5,0]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-142.19,0],[106.5,0]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-169.69,0],[134.5,0]],"c":false}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3466.5,998.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[45.75,155.75],[-155.75,-45.75],[-45.75,-155.75],[155.75,45.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[1090.5,537,0],"e":[1170.5,617,0],"to":[12.0437898635864,12.0437898635864,0],"ti":[-1.2895439863205,-1.2895439863205,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[1170.5,617,0],"e":[1170.5,617,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[1170.5,617,0],"e":[1090.5,537,0],"to":[-13.3333330154419,-13.3333330154419,0],"ti":[13.3333330154419,13.3333330154419,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-41.25,-0.5],[41.25,-0.5]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[834,765,0],"e":[834,813,0],"to":[0,8,0],"ti":[0,-8,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0.333},"n":"0p833_0p833_0p333_0p333","t":210,"s":[834,813,0],"e":[834,813,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[834,813,0],"e":[834,765,0],"to":[0,-8,0],"ti":[0,8,0]},{"t":419}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.999},"o":{"x":0.167,"y":0.001},"n":"0p833_0p999_0p167_0p001","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-100,-0.5],[100,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-122,-0.5],[125,-0.5]],"c":true}]},{"i":{"x":0.833,"y":0.999},"o":{"x":0.333,"y":0},"n":"0p833_0p999_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-122,-0.5],[125,-0.5]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-122,-0.5],[125,-0.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-122,-0.5],[125,-0.5]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-100,-0.5],[100,-0.5]],"c":false}]},{"t":419}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[748.5,387,0],"e":[748.5,347,0],"to":[0,-6.66666650772095,0],"ti":[0,6.66666650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0.333},"n":"0p833_0p833_0p333_0p333","t":210,"s":[748.5,347,0],"e":[748.5,347,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[748.5,347,0],"e":[748.5,387,0],"to":[0,6.66666650772095,0],"ti":[0,-6.66666650772095,0]},{"t":419}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.999},"o":{"x":0.167,"y":0.001},"n":"0p833_0p999_0p167_0p001","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-36.25,-0.5],[36.25,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-57.75,-3],[58.75,-3]],"c":true}]},{"i":{"x":0.833,"y":0.999},"o":{"x":0.333,"y":0},"n":"0p833_0p999_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-57.75,-3],[58.75,-3]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-57.75,-3],[58.75,-3]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-57.75,-3],[58.75,-3]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-36.25,-0.5],[36.25,-0.5]],"c":false}]},{"t":419}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[3006.5,763,0],"e":[3006.5,823,0],"to":[0,10,0],"ti":[0,-10,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0.333},"n":"0p833_0p833_0p333_0p333","t":210,"s":[3006.5,823,0],"e":[3006.5,823,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[3006.5,823,0],"e":[3006.5,763,0],"to":[0,-10,0],"ti":[0,10,0]},{"t":419}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.999},"o":{"x":0.167,"y":0},"n":"0p833_0p999_0p167_0","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-66.25,-0.5],[66.25,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-36.25,-0.5],[36.25,-0.5]],"c":true}]},{"i":{"x":0.833,"y":0.999},"o":{"x":0.333,"y":0},"n":"0p833_0p999_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-36.25,-0.5],[36.25,-0.5]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-36.25,-0.5],[36.25,-0.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-36.25,-0.5],[36.25,-0.5]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-66.25,-0.5],[66.25,-0.5]],"c":false}]},{"t":419}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"n":"0p833_0p833_0p167_0p167","t":180,"s":[3375.5,857,0],"e":[3375.5,817,0],"to":[0,-6.66666650772095,0],"ti":[0,6.66666650772095,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.333,"y":0.333},"n":"0p833_0p833_0p333_0p333","t":210,"s":[3375.5,817,0],"e":[3375.5,817,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[3375.5,817,0],"e":[3375.5,857,0],"to":[0,6.66666650772095,0],"ti":[0,-6.66666650772095,0]},{"t":419}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.999},"o":{"x":0.167,"y":0.001},"n":"0p833_0p999_0p167_0p001","t":180,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-84.25,-0.5],[84.25,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-63.75,-0.5],[64.25,-0.5]],"c":true}]},{"i":{"x":0.833,"y":0.999},"o":{"x":0.333,"y":0},"n":"0p833_0p999_0p333_0","t":210,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-63.75,-0.5],[64.25,-0.5]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-63.75,-0.5],[64.25,-0.5]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-63.75,-0.5],[64.25,-0.5]],"c":true}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-84.25,-0.5],[84.25,-0.5]],"c":false}]},{"t":419}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-63.75,-0.5],[64.25,-0.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":1,"cix":2,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[3511,409,0],"e":[3491,289,0],"to":[-3.33333325386047,-20,0],"ti":[3.33333325386047,20,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[3491,289,0],"e":[3491,289,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3491,289,0],"e":[3511,409,0],"to":[3.33333325386047,20,0],"ti":[-3.33333325386047,-20,0]},{"t":330}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-51.5,-0.5],[50.5,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-101.5,-0.5],[120.5,-0.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":120,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-101.5,-0.5],[120.5,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-101.5,-0.5],[120.5,-0.5]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-101.5,-0.5],[120.5,-0.5]],"c":false}],"e":[{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-51.5,-0.5],[50.5,-0.5]],"c":false}]},{"t":330}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Path Copy 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[3718.5,576,0],"e":[3598.5,696,0],"to":[-20,20,0],"ti":[20,-20,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.333,"y":0.333},"n":"0p667_0p667_0p333_0p333","t":120,"s":[3598.5,696,0],"e":[3598.5,696,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[3598.5,696,0],"e":[3718.5,576,0],"to":[20,-20,0],"ti":[-20,20,0]},{"t":332}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-39.25,0],[39.25,0]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 2","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3738,557,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[114.5,-75],[75,-114.5],[-114.5,75],[-75,114.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3502,257,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[127,4.5],[4.5,127],[-127,-4.5],[-4.5,-127]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2653.5,703.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-92.25,55.75],[-55.75,92.25],[92.25,-55.75],[55.75,-92.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3087.5,645.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[40.25,-124.75],[124.75,-40.25],[-40.25,124.75],[-124.75,40.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1728,878,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[66,15],[15,66],[-66,-15],[-15,-66]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1200,646,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-95.5,-137],[-137,-95.5],[95.5,137],[137,95.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[356.5,496.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-7.75,-176.75],[-176.75,-7.75],[7.75,176.75],[176.75,7.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[821.5,268.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[36.25,-95.25],[95.25,-36.25],[-36.25,95.25],[-95.25,36.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[634.5,1150.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-8.75,68.25],[68.25,-8.75],[8.75,-68.25],[-68.25,8.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Path","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[858,834,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[11,135],[-135,-11],[-11,-135],[135,11]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.44313699007,0.2666670084,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0}],"markers":[{"tm":90,"cm":"1","dr":0},{"tm":120,"cm":"2","dr":0},{"tm":180,"cm":"3","dr":0},{"tm":210,"cm":"4","dr":0},{"tm":300,"cm":"5","dr":0},{"tm":330,"cm":"6","dr":0},{"tm":390,"cm":"7","dr":0},{"tm":419,"cm":"8","dr":0}]} \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/components/animations/profiler/index.tsx b/packages/dev-tools-pages/ts/components/animations/profiler/index.tsx
new file mode 100644
index 000000000..a2848b762
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/profiler/index.tsx
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+import { BaseAnimation } from '../index';
+
+import * as animationData from './data.json';
+
+const ProfilerAnimation: React.StatelessComponent<{}> = () => (
+ <BaseAnimation animationData={animationData} width={1985} height={657} />
+);
+
+export { ProfilerAnimation };
diff --git a/packages/dev-tools-pages/ts/components/animations/trace/data.json b/packages/dev-tools-pages/ts/components/animations/trace/data.json
new file mode 100644
index 000000000..7b2936fff
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/trace/data.json
@@ -0,0 +1 @@
+{"v":"5.4.1","fr":30,"ip":0,"op":420,"w":4482,"h":1220,"nm":"header-trace","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2241,610,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[],"ip":0,"op":529,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"â–½ header-trace","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2242,609,0],"ix":2},"a":{"a":0,"k":[2238,607,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3391.5,737.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[101.75,-11.75],[-11.75,101.75],[-101.75,11.75],[11.75,-101.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Path 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[4035.5,479.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[201.75,178.25],[158.25,221.75],[-221.75,-158.25],[-178.25,-201.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[201.75,178.25],[158.25,221.75],[-221.75,-158.25],[-178.25,-201.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[201.75,178.25],[158.25,221.75],[-221.75,-158.25],[-178.25,-201.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[201.75,178.25],[158.25,221.75],[-221.75,-158.25],[-178.25,-201.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Path 6","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[4035.5,479.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[211.75,168.25],[158.25,221.75],[-211.75,-148.25],[-158.25,-201.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[211.75,168.25],[158.25,221.75],[-211.75,-148.25],[-158.25,-201.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[211.75,168.25],[158.25,221.75],[-211.75,-148.25],[-158.25,-201.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[211.75,168.25],[158.25,221.75],[-211.75,-148.25],[-158.25,-201.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Path 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[4035.5,479.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-201.75,-138.25],[-138.25,-201.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-201.75,-138.25],[-138.25,-201.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-201.75,-138.25],[-138.25,-201.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-201.75,-138.25],[-138.25,-201.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[4031.5,477.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[221.75,158.25],[158.25,221.75],[-221.75,-158.25],[-158.25,-221.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3671.5,517.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[21.75,158.25],[158.25,21.75],[-21.75,-158.25],[-158.25,-21.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Path Copy 12","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3803.5,646.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[93.75,-43.75],[-43.75,93.75],[-73.75,63.75],[63.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-63.75],[-63.75,73.75],[-73.75,63.75],[63.75,-73.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-63.75],[-63.75,73.75],[-73.75,63.75],[63.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-63.75],[-63.75,73.75],[-73.75,63.75],[63.75,-73.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-63.75],[-63.75,73.75],[-73.75,63.75],[63.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[93.75,-43.75],[-43.75,93.75],[-73.75,63.75],[63.75,-73.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 12","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Path Copy 11","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3803.5,666.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[93.75,-53.75],[-43.75,83.75],[-73.75,53.75],[63.75,-83.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-53.75],[-53.75,73.75],[-73.75,53.75],[53.75,-73.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-53.75],[-53.75,73.75],[-73.75,53.75],[53.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-53.75],[-53.75,73.75],[-73.75,53.75],[53.75,-73.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-53.75],[-53.75,73.75],[-73.75,53.75],[53.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[93.75,-53.75],[-43.75,83.75],[-73.75,53.75],[63.75,-83.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 11","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Path Copy 10","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3803.5,686.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[93.75,-63.75],[-43.75,73.75],[-73.75,43.75],[63.75,-93.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-43.75],[-43.75,73.75],[-73.75,43.75],[43.75,-73.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-43.75],[-43.75,73.75],[-73.75,43.75],[43.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-43.75],[-43.75,73.75],[-73.75,43.75],[43.75,-73.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[73.75,-43.75],[-43.75,73.75],[-73.75,43.75],[43.75,-73.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[93.75,-63.75],[-43.75,73.75],[-73.75,43.75],[63.75,-93.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 10","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3101.5,747.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-126.75],[-126.75,136.75],[-136.75,126.75],[126.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-106.75],[-106.75,156.75],[-136.75,126.75],[126.75,-136.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-106.75],[-106.75,156.75],[-136.75,126.75],[126.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-106.75],[-106.75,156.75],[-136.75,126.75],[126.75,-136.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-106.75],[-106.75,156.75],[-136.75,126.75],[126.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-126.75],[-126.75,136.75],[-136.75,126.75],[126.75,-136.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3101.5,767.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-116.75],[-116.75,136.75],[-136.75,116.75],[116.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[146.75,-106.75],[-106.75,146.75],[-136.75,116.75],[116.75,-136.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[146.75,-106.75],[-106.75,146.75],[-136.75,116.75],[116.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[146.75,-106.75],[-106.75,146.75],[-136.75,116.75],[116.75,-136.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[146.75,-106.75],[-106.75,146.75],[-136.75,116.75],[116.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-116.75],[-116.75,136.75],[-136.75,116.75],[116.75,-136.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3101.5,787.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-106.75],[-106.75,136.75],[-136.75,106.75],[106.75,-136.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-126.75],[-106.75,136.75],[-136.75,106.75],[126.75,-156.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-126.75],[-106.75,136.75],[-136.75,106.75],[126.75,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-126.75],[-106.75,136.75],[-136.75,106.75],[126.75,-156.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,-126.75],[-106.75,136.75],[-136.75,106.75],[126.75,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-106.75],[-106.75,136.75],[-136.75,106.75],[106.75,-136.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3121.5,767.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[146.75,-116.75],[-116.75,146.75],[-146.75,116.75],[116.75,-146.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":17,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2881.5,567.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.998},"o":{"x":0.167,"y":0.001},"n":"0p833_0p998_0p167_0p001","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[66.75,-16.75],[-16.75,66.75],[-66.75,16.75],[16.75,-66.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[86.75,3.25],[3.25,86.75],[-66.75,16.75],[16.75,-66.75]],"c":true}]},{"i":{"x":0.833,"y":0.998},"o":{"x":0.333,"y":0},"n":"0p833_0p998_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[86.75,3.25],[3.25,86.75],[-66.75,16.75],[16.75,-66.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[86.75,3.25],[3.25,86.75],[-66.75,16.75],[16.75,-66.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[86.75,3.25],[3.25,86.75],[-66.75,16.75],[16.75,-66.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[66.75,-16.75],[-16.75,66.75],[-66.75,16.75],[16.75,-66.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":18,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2911.5,577.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.999},"o":{"x":0.167,"y":0.002},"n":"0p833_0p999_0p167_0p002","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[61.75,-11.75],[-11.75,61.75],[-61.75,11.75],[11.75,-61.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[71.75,-1.75],[-11.75,81.75],[-71.75,21.75],[11.75,-61.75]],"c":true}]},{"i":{"x":0.833,"y":0.999},"o":{"x":0.333,"y":0},"n":"0p833_0p999_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[71.75,-1.75],[-11.75,81.75],[-71.75,21.75],[11.75,-61.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[71.75,-1.75],[-11.75,81.75],[-71.75,21.75],[11.75,-61.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[71.75,-1.75],[-11.75,81.75],[-71.75,21.75],[11.75,-61.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[61.75,-11.75],[-11.75,61.75],[-61.75,11.75],[11.75,-61.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":19,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2941.5,587.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.998},"o":{"x":0.167,"y":0.002},"n":"0p833_0p998_0p167_0p002","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.75,-6.75],[-6.75,56.75],[-56.75,6.75],[6.75,-56.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.75,-6.75],[-26.75,76.75],[-76.75,26.75],[6.75,-56.75]],"c":true}]},{"i":{"x":0.833,"y":0.998},"o":{"x":0.333,"y":0},"n":"0p833_0p998_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.75,-6.75],[-26.75,76.75],[-76.75,26.75],[6.75,-56.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.75,-6.75],[-26.75,76.75],[-76.75,26.75],[6.75,-56.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.75,-6.75],[-26.75,76.75],[-76.75,26.75],[6.75,-56.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[56.75,-6.75],[-6.75,56.75],[-56.75,6.75],[6.75,-56.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":20,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[2901.5,587.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[76.75,-6.75],[-6.75,76.75],[-76.75,6.75],[6.75,-76.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":21,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3411.5,177.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-88.25,-31.75],[-31.75,-88.25],[88.25,31.75],[31.75,88.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":22,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3431.5,157.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-78.25,-41.75],[-41.75,-78.25],[78.25,41.75],[41.75,78.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":23,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3411.5,157.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-78.25,-31.75],[-31.75,-78.25],[78.25,31.75],[31.75,78.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":24,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3391.5,157.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-78.25,-21.75],[-21.75,-78.25],[78.25,21.75],[21.75,78.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":25,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[3101.5,627.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[136.75,-186.75],[-186.75,136.75],[-136.75,186.75],[186.75,-136.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":26,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1444.5,626.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[36.75,63.25],[63.25,36.75],[-36.75,-63.25],[-63.25,-36.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":27,"ty":4,"nm":"Path 4","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[704.5,527.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":28,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1064.5,887.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-3.25,163.25],[163.25,-3.25],[3.25,-163.25],[-163.25,3.25]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":29,"ty":4,"nm":"Path Copy 4","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1594.5,776.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[101.75,-51.75],[-51.75,101.75],[-101.75,51.75],[51.75,-101.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[121.75,-31.75],[-31.75,121.75],[-101.75,51.75],[51.75,-101.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[121.75,-31.75],[-31.75,121.75],[-101.75,51.75],[51.75,-101.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[121.75,-31.75],[-31.75,121.75],[-101.75,51.75],[51.75,-101.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[121.75,-31.75],[-31.75,121.75],[-101.75,51.75],[51.75,-101.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[101.75,-51.75],[-51.75,101.75],[-101.75,51.75],[51.75,-101.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 4","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":30,"ty":4,"nm":"Path Copy 3","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1624.5,787.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[96.75,-46.75],[-46.75,96.75],[-96.75,46.75],[46.75,-96.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[106.75,-36.75],[-46.75,116.75],[-116.75,46.75],[36.75,-106.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[106.75,-36.75],[-46.75,116.75],[-116.75,46.75],[36.75,-106.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[106.75,-36.75],[-46.75,116.75],[-116.75,46.75],[36.75,-106.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[106.75,-36.75],[-46.75,116.75],[-116.75,46.75],[36.75,-106.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[96.75,-46.75],[-46.75,96.75],[-96.75,46.75],[46.75,-96.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 3","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":31,"ty":4,"nm":"Path Copy 2","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1654.5,797.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.75,-41.75],[-41.75,91.75],[-91.75,41.75],[41.75,-91.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.75,-41.75],[-61.75,111.75],[-131.75,41.75],[21.75,-111.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.75,-41.75],[-61.75,111.75],[-131.75,41.75],[21.75,-111.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.75,-41.75],[-61.75,111.75],[-131.75,41.75],[21.75,-111.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0},"n":"0p667_1_0p167_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.75,-41.75],[-61.75,111.75],[-131.75,41.75],[21.75,-111.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[91.75,-41.75],[-41.75,91.75],[-91.75,41.75],[41.75,-91.75]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 2","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":32,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1615.5,796.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[41.75,-111.75],[-111.75,41.75],[-41.75,111.75],[111.75,-41.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":33,"ty":4,"nm":"Path 3","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[704.5,527.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.998},"o":{"x":0.167,"y":0.002},"n":"0p833_0p998_0p167_0p002","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-159.25,7.25],[7.25,-159.25],[183.25,16.75],[16.75,183.25]],"c":true}]},{"i":{"x":0.713,"y":0.984},"o":{"x":0.333,"y":0},"n":"0p713_0p984_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-159.25,7.25],[7.25,-159.25],[183.25,16.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-159.25,7.25],[7.25,-159.25],[183.25,16.75],[16.75,183.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-159.25,7.25],[7.25,-159.25],[183.25,16.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":34,"ty":4,"nm":"Path 2","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[702.5,527.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.996},"o":{"x":0.167,"y":0.002},"n":"0p833_0p996_0p167_0p002","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-169.25,-4.75],[-14.75,-159.25],[171.25,26.75],[16.75,183.25]],"c":true}]},{"i":{"x":0.689,"y":0.993},"o":{"x":0.333,"y":0},"n":"0p689_0p993_0p333_0","t":211,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-169.25,-4.75],[-14.75,-159.25],[171.25,26.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-169.25,-4.75],[-14.75,-159.25],[171.25,26.75],[16.75,183.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-169.25,-4.75],[-14.75,-159.25],[171.25,26.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":35,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[704.5,527.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.994},"o":{"x":0.167,"y":0.003},"n":"0p833_0p994_0p167_0p003","t":180,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-40.75,-159.25],[159.25,40.75],[16.75,183.25]],"c":true}]},{"i":{"x":0.682,"y":0.993},"o":{"x":0.333,"y":0},"n":"0p682_0p993_0p333_0","t":210,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-40.75,-159.25],[159.25,40.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-40.75,-159.25],[159.25,40.75],[16.75,183.25]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":390,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-40.75,-159.25],[159.25,40.75],[16.75,183.25]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-183.25,-16.75],[-16.75,-183.25],[183.25,16.75],[16.75,183.25]],"c":true}]},{"t":420}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":36,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1205.5,527.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,113.25],[113.25,156.75],[-156.75,-113.25],[-113.25,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,113.25],[93.25,176.75],[-176.75,-93.25],[-113.25,-156.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,113.25],[93.25,176.75],[-176.75,-93.25],[-113.25,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,113.25],[93.25,176.75],[-176.75,-93.25],[-113.25,-156.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,113.25],[93.25,176.75],[-176.75,-93.25],[-113.25,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,113.25],[113.25,156.75],[-156.75,-113.25],[-113.25,-156.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":37,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1205.5,547.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,103.25],[103.25,156.75],[-156.75,-103.25],[-103.25,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,103.25],[93.25,166.75],[-176.75,-103.25],[-113.25,-166.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,103.25],[93.25,166.75],[-176.75,-103.25],[-113.25,-166.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,103.25],[93.25,166.75],[-176.75,-103.25],[-113.25,-166.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,103.25],[93.25,166.75],[-176.75,-103.25],[-113.25,-166.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,103.25],[103.25,156.75],[-156.75,-103.25],[-103.25,-156.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":38,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1205.5,567.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,93.25],[93.25,156.75],[-156.75,-93.25],[-93.25,-156.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,93.25],[93.25,156.75],[-176.75,-113.25],[-113.25,-176.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":121,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,93.25],[93.25,156.75],[-176.75,-113.25],[-113.25,-176.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,93.25],[93.25,156.75],[-176.75,-113.25],[-113.25,-176.75]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,93.25],[93.25,156.75],[-176.75,-113.25],[-113.25,-176.75]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[156.75,93.25],[93.25,156.75],[-156.75,-93.25],[-93.25,-156.75]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":39,"ty":4,"nm":"Path Copy 16","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[549.878,808.122,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,65.119],[41.119,140.059],[-140.061,-41.121],[-65.121,-116.061]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,65.119],[65.119,116.059],[-116.061,-65.121],[-65.121,-116.061]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":122,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,65.119],[65.119,116.059],[-116.061,-65.121],[-65.121,-116.061]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,65.119],[65.119,116.059],[-116.061,-65.121],[-65.121,-116.061]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,65.119],[65.119,116.059],[-116.061,-65.121],[-65.121,-116.061]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,65.119],[41.119,140.059],[-140.061,-41.121],[-65.121,-116.061]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":-270,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 16","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":40,"ty":4,"nm":"Path Copy 15","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[526,808.122,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,53.409],[41.409,128.059],[-140.061,-53.411],[-65.411,-128.061]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,53.409],[53.409,116.059],[-116.061,-53.411],[-53.411,-116.061]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":122,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,53.409],[53.409,116.059],[-116.061,-53.411],[-53.411,-116.061]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,53.409],[53.409,116.059],[-116.061,-53.411],[-53.411,-116.061]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,53.409],[53.409,116.059],[-116.061,-53.411],[-53.411,-116.061]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,53.409],[41.409,128.059],[-140.061,-53.411],[-65.411,-128.061]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":-270,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 15","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":41,"ty":4,"nm":"Path Copy 14","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[503.425,808.122,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.333,"y":0},"n":"0p833_1_0p333_0","t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,42.045],[41.699,116.405],[-138.061,-64.045],[-63.701,-138.405]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,42.045],[41.699,116.405],[-116.061,-42.045],[-41.701,-116.405]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":122,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,42.045],[41.699,116.405],[-116.061,-42.045],[-41.701,-116.405]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,42.045],[41.699,116.405],[-116.061,-42.045],[-41.701,-116.405]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":300,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,42.045],[41.699,116.405],[-116.061,-42.045],[-41.701,-116.405]],"c":true}],"e":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[116.059,42.045],[41.699,116.405],[-138.061,-64.045],[-63.701,-138.405]],"c":true}]},{"t":331}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":-270,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 14","np":3,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":42,"ty":4,"nm":"Path Copy 13","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[391,697,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,-100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[195.5,121.05],[121.05,195.5],[-195.5,-121.05],[-121.05,-195.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":-270,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path Copy 13","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0},{"ddd":0,"ind":43,"ty":4,"nm":"Path","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1185.5,548.5,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[166.75,103.25],[103.25,166.75],[-166.75,-103.25],[-103.25,-166.75]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.30980399251,0.462745010853,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":2,"ix":5},"lc":1,"lj":1,"ml":4,"ml2":{"a":0,"k":4,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[200,200],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Path","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":420,"st":0,"bm":0}],"markers":[{"tm":90,"cm":"1","dr":0},{"tm":121,"cm":"2","dr":0},{"tm":180,"cm":"3","dr":0},{"tm":210,"cm":"4","dr":0},{"tm":300,"cm":"5","dr":0},{"tm":331,"cm":"6","dr":0},{"tm":390,"cm":"7","dr":0},{"tm":420,"cm":"8","dr":0}]} \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/components/animations/trace/index.tsx b/packages/dev-tools-pages/ts/components/animations/trace/index.tsx
new file mode 100644
index 000000000..2009c3cec
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/animations/trace/index.tsx
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+import { BaseAnimation } from '../index';
+
+import * as animationData from './data.json';
+
+const TraceAnimation: React.StatelessComponent<{}> = () => (
+ <BaseAnimation animationData={animationData} width={2241} height={610} />
+);
+
+export { TraceAnimation };
diff --git a/packages/dev-tools-pages/ts/components/base.tsx b/packages/dev-tools-pages/ts/components/base.tsx
new file mode 100644
index 000000000..4eb4e3ae3
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/base.tsx
@@ -0,0 +1,26 @@
+import * as React from 'react';
+import { ThemeProvider } from 'styled-components';
+
+import { Footer } from 'ts/components/footer';
+import { Header } from 'ts/components/header';
+import { ThemeContext } from 'ts/context';
+import { GlobalStyles } from 'ts/globalStyles';
+
+interface BaseProps {
+ context: any;
+}
+
+const Base: React.StatelessComponent<BaseProps> = props => (
+ <ThemeContext.Provider value={props.context}>
+ <ThemeProvider theme={props.context}>
+ <React.Fragment>
+ <GlobalStyles colors={props.context.colors} />
+ <Header />
+ {props.children}
+ <Footer />
+ </React.Fragment>
+ </ThemeProvider>
+ </ThemeContext.Provider>
+);
+
+export { Base };
diff --git a/packages/dev-tools-pages/ts/components/breakout.tsx b/packages/dev-tools-pages/ts/components/breakout.tsx
new file mode 100644
index 000000000..505d8de41
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/breakout.tsx
@@ -0,0 +1,12 @@
+import styled from 'styled-components';
+
+import { media } from 'ts/variables';
+
+const Breakout = styled.div`
+ ${media.small`
+ margin-left: -2.5rem;
+ width: calc(100% + 5rem);
+ `};
+`;
+
+export { Breakout };
diff --git a/packages/dev-tools-pages/ts/components/button.tsx b/packages/dev-tools-pages/ts/components/button.tsx
new file mode 100644
index 000000000..d3b36ebfd
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/button.tsx
@@ -0,0 +1,55 @@
+import styled from 'styled-components';
+
+import { colors, media } from 'ts/variables';
+
+interface ButtonProps {
+ large?: boolean;
+}
+
+const Button =
+ styled.button <
+ ButtonProps >
+ `
+ font-family: inherit;
+ line-height: 1;
+ font-weight: 500;
+ white-space: nowrap;
+ vertical-align: middle;
+ background-color: ${props => props.theme.colors.secondary};
+ color: ${colors.black};
+ border: 0;
+ border-radius: 5rem;
+ display: inline-flex;
+ justify-content: space-between;
+ align-items: center;
+
+ ${props =>
+ props.large
+ ? `
+ font-size: 1rem;
+ padding: 1.1875rem 2.375rem 1.0625rem;
+ `
+ : `
+ font-size: .875rem;
+ padding: .5625rem 1.25rem;
+ `}
+
+ :hover, :focus {
+ background-color: ${props => props.theme.colors.secondary_alt};
+ outline: 0;
+ }
+
+ ${media.small`
+ font-size: .875rem;
+ padding: .5625rem 1.25rem;
+ `}
+
+ ${props =>
+ props.large &&
+ media.small`
+ font-size: 1rem;
+ padding: 1rem 1.5rem .75rem;
+ `}
+`;
+
+export { Button };
diff --git a/packages/dev-tools-pages/ts/components/code.tsx b/packages/dev-tools-pages/ts/components/code.tsx
new file mode 100644
index 000000000..71d7a7752
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/code.tsx
@@ -0,0 +1,204 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { colors } from 'ts/variables';
+
+import { Button as BaseButton } from './button';
+
+const isTouch = Boolean(
+ 'ontouchstart' in window ||
+ (window as any).navigator.maxTouchPoints > 0 ||
+ (window as any).navigator.msMaxTouchPoints > 0,
+);
+
+interface CodeProps {
+ language?: string;
+ isLight?: boolean;
+ isDiff?: boolean;
+ gutter?: Array<number | undefined>;
+ gutterLength?: number;
+ canCopy?: boolean;
+ isEtc?: boolean;
+}
+
+interface CodeState {
+ hlCode?: string;
+ didCopy?: boolean;
+}
+
+const Button = styled(BaseButton)`
+ opacity: ${isTouch ? '1' : '0'};
+ position: absolute;
+ top: 1rem;
+ right: 1rem;
+ transition: opacity 0.2s;
+ :focus {
+ opacity: 1;
+ }
+`;
+
+const Container = styled.div`
+ position: relative;
+ &:hover ${Button} {
+ opacity: 1;
+ }
+`;
+
+const Base =
+ styled.div <
+ CodeProps >
+ `
+ font-size: .875rem;
+ color: ${props => (_.isUndefined(props.language) ? colors.white : 'inherit')};
+ background-color: ${props =>
+ props.isLight ? 'rgba(255,255,255,.15)' : _.isUndefined(props.language) ? colors.black : '#F1F4F5'};
+ white-space: ${props => (_.isUndefined(props.language) ? 'nowrap' : '')};
+ position: relative;
+
+ ${props =>
+ props.isDiff
+ ? `
+ background-color: #E9ECED;
+ display: flex;
+ padding-top: 1.5rem;
+ padding-bottom: 1.5rem;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ `
+ : ``}
+`;
+
+const CodeDiff: React.StatelessComponent<any> = ({ gutterLength, ...props }) => <code {...props} />;
+const StyledCodeDiff = styled(CodeDiff)`
+ ::before {
+ content: '';
+ width: calc(0.75rem + ${props => props.gutterLength}ch);
+ background-color: #e2e5e6;
+ position: absolute;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ }
+
+ [class^='line-'] {
+ display: inline-block;
+ width: 100%;
+ position: relative;
+ padding-right: 1.5rem;
+ padding-left: calc(2.25rem + ${props => props.gutterLength}ch);
+
+ ::before {
+ content: attr(data-gutter);
+
+ width: ${props => props.gutterLength};
+ padding-left: 0.375rem;
+ padding-right: 0.375rem;
+ position: absolute;
+ top: 50%;
+ left: 0;
+ transform: translateY(-50%);
+ z-index: 1;
+ }
+ }
+
+ .line-addition {
+ background-color: rgba(0, 202, 105, 0.1);
+ }
+ .line-deletion {
+ background-color: rgba(255, 0, 0, 0.07);
+ }
+`;
+
+const StyledPre =
+ styled.pre <
+ CodeProps >
+ `
+ margin: 0;
+ ${props =>
+ !props.isDiff
+ ? `
+ padding: 1.5rem;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ `
+ : ``};
+`;
+
+const StyledCopyInput = styled.textarea`
+ opacity: 0;
+ height: 0;
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: -1;
+`;
+
+class Code extends React.Component<CodeProps, CodeState> {
+ public state: CodeState = {};
+ private readonly _code = React.createRef<HTMLTextAreaElement>();
+ public componentDidMount(): void {
+ // _onMountAsync is only setting state, so no point in handling the promise
+ // tslint:disable-next-line:no-floating-promises
+ this._onMountAsync();
+ }
+ public render(): React.ReactNode {
+ const { language, isLight, isDiff, children, gutterLength, canCopy } = this.props;
+ const { hlCode } = this.state;
+
+ return (
+ <Container>
+ <Base language={language} isDiff={isDiff} isLight={isLight}>
+ <StyledPre isDiff={isDiff}>
+ {_.isUndefined(hlCode) ? (
+ <code>{children}</code>
+ ) : (
+ <StyledCodeDiff
+ gutterLength={gutterLength}
+ dangerouslySetInnerHTML={hlCode ? { __html: this.state.hlCode } : null}
+ />
+ )}
+ </StyledPre>
+ {!('clipboard' in navigator) ? (
+ <StyledCopyInput readOnly={true} aria-hidden="true" ref={this._code} value={children} />
+ ) : null}
+ </Base>
+ {navigator.userAgent !== 'ReactSnap' && canCopy ? (
+ <Button onClick={this._handleCopyAsync.bind(this)}>{this.state.didCopy ? 'Copied' : 'Copy'}</Button>
+ ) : null}
+ </Container>
+ );
+ }
+ private async _onMountAsync(): Promise<void> {
+ const { language, children, isDiff, gutter, isEtc } = this.props;
+
+ const code = children as string;
+
+ if (language !== undefined) {
+ const { highlight } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight');
+
+ this.setState({
+ hlCode: highlight({ language, code, isDiff, gutter, isEtc }),
+ });
+ }
+ }
+ private async _handleCopyAsync(): Promise<void> {
+ try {
+ if ('clipboard' in navigator) {
+ await (navigator as any).clipboard.writeText(this.props.children);
+ this.setState({ didCopy: true });
+ } else {
+ const lastActive = document.activeElement as HTMLElement;
+ this._code.current.focus();
+ this._code.current.select();
+ document.execCommand('copy');
+ lastActive.focus();
+ this.setState({ didCopy: true });
+ }
+ } catch (error) {
+ this.setState({ didCopy: false });
+ }
+ }
+}
+
+export { Code };
diff --git a/packages/dev-tools-pages/ts/components/compiler.tsx b/packages/dev-tools-pages/ts/components/compiler.tsx
new file mode 100644
index 000000000..694a535dd
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/compiler.tsx
@@ -0,0 +1,90 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { colors, media } from 'ts/variables';
+
+import { Breakout } from './breakout';
+import { Container } from './container';
+import { InlineCode } from './inline-code';
+
+const Cards = styled.dl`
+ column-count: 3;
+ column-gap: 1.25rem;
+
+ ${media.medium`
+ column-count: 1;
+ `};
+`;
+
+const Card = styled.div`
+ background-color: ${colors.lightGray};
+ padding: 3.125rem;
+ padding-bottom: 2.5rem;
+ display: inline-block;
+ margin-bottom: 1.25rem;
+ width: 100%;
+
+ ${media.medium`
+ padding: 1.875rem;
+ `};
+`;
+
+const Dt = styled.dt`
+ font-weight: 500;
+ display: inline;
+ ::after {
+ content: '. ';
+ }
+`;
+
+const Dd = styled.dd`
+ display: inline;
+ margin-left: 0;
+`;
+
+const cards = [
+ {
+ title: 'A Project-centric',
+ body: (
+ <React.Fragment>
+ Compiles an entire project instead of only individual <InlineCode isAlt={true}>.sol</InlineCode> files.
+ </React.Fragment>
+ ),
+ },
+ {
+ title: 'Incremental builds',
+ body: 'Recompiles your smart contracts after they have changed',
+ },
+ {
+ title: 'Customizable artifacts',
+ body:
+ 'Stores only the required compiler output in your artifacts, so you can have complete control over your bundle size.',
+ },
+ {
+ title: 'Seamless',
+ body: 'Fetches and caches the required compiler binaries.',
+ },
+ {
+ title: 'Versioning',
+ body:
+ 'Compiles each contract with the version specified at the top of its file (sol-compiler even supports version ranges!).',
+ },
+];
+
+const Compiler: React.StatelessComponent<{}> = () => (
+ <Container>
+ <Breakout>
+ <Cards>
+ {_.map(cards, card => (
+ <Card key={card.title.split(' ').join('-')}>
+ <Dt>{card.title}</Dt>
+ <Dd>{card.body}</Dd>
+ </Card>
+ ))}
+ </Cards>
+ </Breakout>
+ </Container>
+);
+
+export { Compiler };
diff --git a/packages/dev-tools-pages/ts/components/container.tsx b/packages/dev-tools-pages/ts/components/container.tsx
new file mode 100644
index 000000000..1b9212ed2
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/container.tsx
@@ -0,0 +1,16 @@
+import styled from 'styled-components';
+
+interface ContainerProps {
+ wide?: boolean;
+}
+
+const Container =
+ styled.div <
+ ContainerProps >
+ `
+ max-width: 77.5rem;
+ margin: 0 auto;
+ width: ${props => (props.wide ? '100%' : 'calc(100% - 5rem)')};
+`;
+
+export { Container };
diff --git a/packages/dev-tools-pages/ts/components/content-block.tsx b/packages/dev-tools-pages/ts/components/content-block.tsx
new file mode 100644
index 000000000..b800c5d44
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/content-block.tsx
@@ -0,0 +1,78 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { ContextInterface } from 'ts/context';
+import { media } from 'ts/variables';
+
+import { Alpha, Beta } from './typography';
+
+const Base = styled.div`
+ display: flex;
+ align-items: flex-start;
+ justify-content: space-between;
+ :not(:last-of-type) {
+ margin-bottom: 6.25rem;
+ }
+ ${Beta} {
+ margin-bottom: 2.5rem;
+ }
+ ${media.small`
+ display: block;
+ :not(:last-of-type) {
+ margin-bottom: 3.125rem;
+ }
+ `};
+`;
+
+const Content = styled.div`
+ width: 66.693548387%;
+ ${media.small`
+ width: 100%;
+ `};
+`;
+
+const Item = styled.div`
+ p {
+ max-width: 31.25rem;
+ }
+
+ &:not(:last-of-type) {
+ margin-bottom: 2.5rem;
+ ${media.small`
+ margin-bottom: 1.875rem;
+ `};
+ }
+`;
+
+const StyledTitle = styled(Alpha)`
+ color: ${props => props.color};
+ ${media.small`
+ & + div {
+ margin-top: 1.5rem;
+ }
+ `};
+`;
+
+interface ContentBlockProps extends ContextInterface {
+ title: string;
+ main?: boolean;
+ children?: React.ReactNode;
+}
+
+const ContentBlock: React.StatelessComponent<ContentBlockProps> = props => {
+ const children = React.Children.map(props.children, child => {
+ return <Item>{child}</Item>;
+ });
+
+ const Title = props.main ? StyledTitle : Beta;
+
+ return (
+ <Base>
+ <Title color={props.colors}>{props.title}</Title>
+ {_.isUndefined(children) ? null : <Content>{children}</Content>}
+ </Base>
+ );
+};
+
+export { ContentBlock };
diff --git a/packages/dev-tools-pages/ts/components/content.tsx b/packages/dev-tools-pages/ts/components/content.tsx
new file mode 100644
index 000000000..f74e09af7
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/content.tsx
@@ -0,0 +1,34 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { Container } from './container';
+
+const StyledMain =
+ styled.div <
+ MainProps >
+ `
+ padding-top: 6.25rem;
+ padding-bottom: 6.25rem;
+ ${props =>
+ props.dark
+ ? `
+ background-color: #000;
+ color: #fff;
+ p:not([class]) {
+ color: #CCC;
+ }
+ `
+ : ''};
+`;
+
+interface MainProps {
+ dark?: boolean;
+}
+
+const Content: React.StatelessComponent<MainProps> = props => (
+ <StyledMain dark={props.dark}>
+ <Container>{props.children}</Container>
+ </StyledMain>
+);
+
+export { Content };
diff --git a/packages/dev-tools-pages/ts/components/footer.tsx b/packages/dev-tools-pages/ts/components/footer.tsx
new file mode 100644
index 000000000..04fd9b88e
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/footer.tsx
@@ -0,0 +1,133 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { context as compiler } from 'ts/context/compiler';
+import { context as cov } from 'ts/context/cov';
+import { context as profiler } from 'ts/context/profiler';
+import { context as trace } from 'ts/context/trace';
+import MainIcon from 'ts/icons/logos/0x.svg';
+import { media } from 'ts/variables';
+
+import { Container } from './container';
+import { Alpha, Beta } from './typography';
+
+const tools = [trace, cov, compiler, profiler];
+
+const Footer: React.StatelessComponent<{}> = () => (
+ <StyledFooter>
+ <Container>
+ <Top>
+ <Alpha>Other tools by 0x</Alpha>
+ <List>
+ {_.map(tools, ({ title, subtitle, icon }) => (
+ <ListItem key={title}>
+ <ListLink href="#">
+ <Icon as={icon as 'svg'} />
+ <div>
+ <Beta>{title}</Beta>
+ <p>{subtitle}</p>
+ </div>
+ </ListLink>
+ </ListItem>
+ ))}
+ </List>
+ </Top>
+ <Media as="aside">
+ <Icon as={MainIcon} />
+ <Small>
+ 0x is an open, permissionless protocol allowing for tokens to be traded on the Ethereum blockchain.
+ </Small>
+ </Media>
+ </Container>
+ </StyledFooter>
+);
+
+const StyledFooter = styled.footer`
+ background-color: ${props => props.theme.colors.secondary};
+ padding-top: 6.25rem;
+ padding-bottom: 5.4375rem;
+
+ ${media.small`padding-top: 2.5rem;`};
+`;
+
+const Top = styled.div`
+ display: flex;
+ justify-content: space-between;
+ margin-bottom: 9.375rem;
+
+ ${media.medium`
+ display: block;
+ margin-bottom: 5.3125rem;
+ `};
+
+ ${Alpha} {
+ ${media.medium`margin-bottom: 3.8125rem;`};
+ }
+`;
+
+const Icon = styled.div`
+ margin-right: 1.3125rem;
+ flex-shrink: 0;
+ ${media.small`margin-right: 0.9375rem`};
+`;
+
+const Media = styled.div`
+ display: flex;
+ align-items: center;
+
+ ${Icon} {
+ margin-top: 0.5rem;
+ align-self: flex-start;
+ }
+`;
+
+const List = styled.ul`
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ width: 66.693548387%;
+ display: flex;
+ flex-wrap: wrap;
+
+ ${media.medium`
+ width: 100%;
+ `};
+
+ ${media.small`
+ display: block;
+ `};
+`;
+
+const ListItem = styled.li`
+ margin-bottom: 3.3125rem;
+ padding-right: 1rem;
+ flex-basis: 50%;
+ :nth-last-of-type(-n + 2) {
+ margin-bottom: 0;
+
+ ${media.small`margin-bottom: 1.875rem`};
+ }
+
+ ${media.small`
+ margin-bottom: 1.875rem
+ :last-of-type {
+ margin-bottom: 0;
+ }
+ `};
+`;
+
+const ListLink = styled.a`
+ display: flex;
+ align-items: center;
+ :hover {
+ color: ${props => props.theme.colors.dark};
+ }
+`;
+
+const Small = styled.small`
+ font-size: 1em;
+ max-width: 37.5rem;
+`;
+
+export { Footer };
diff --git a/packages/dev-tools-pages/ts/components/header.tsx b/packages/dev-tools-pages/ts/components/header.tsx
new file mode 100644
index 000000000..2787692c1
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/header.tsx
@@ -0,0 +1,76 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { ContextInterface, ThemeContext } from 'ts/context';
+import { media } from 'ts/variables';
+
+import { Container } from './container';
+import { Small } from './typography';
+
+const Header: React.StatelessComponent<{}> = () => (
+ <ThemeContext.Consumer>
+ {({ icon, title }: ContextInterface) => (
+ <StyledHeader>
+ <Container>
+ <LogoMark>
+ <Logo as={icon as 'svg'} />
+ <Title>{title}</Title>
+ </LogoMark>
+
+ <Link as="a" href="https://0xproject.com/">
+ Built by 0x
+ </Link>
+ </Container>
+ </StyledHeader>
+ )}
+ </ThemeContext.Consumer>
+);
+
+const StyledHeader = styled.header`
+ padding-top: 3.75rem;
+ padding-bottom: 0.875rem;
+ width: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2;
+ ${Container} {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ ${media.small`padding-top: 2.125rem;`};
+`;
+
+const LogoMark = styled.div`
+ position: relative;
+ height: 1.75rem;
+ display: flex;
+ align-items: center;
+`;
+
+const Logo = styled.div`
+ color: ${props => props.theme.colors.main};
+ width: 1.75rem;
+ height: 100%;
+`;
+
+const Title = styled.h1`
+ font-size: 1.5rem;
+ line-height: 1;
+ white-space: nowrap;
+ margin-top: 2px;
+ margin-bottom: 0;
+ margin-left: 0.8125rem;
+
+ ${media.small`font-size: 1.25rem;`};
+`;
+
+const Link = styled(Small)`
+ :hover {
+ text-decoration: underline;
+ }
+`;
+
+export { Header };
diff --git a/packages/dev-tools-pages/ts/components/hero.tsx b/packages/dev-tools-pages/ts/components/hero.tsx
new file mode 100644
index 000000000..cdcad6982
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/hero.tsx
@@ -0,0 +1,63 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { ContextInterface, ThemeContext } from 'ts/context';
+import { media } from 'ts/variables';
+
+import { Button } from './button';
+import { Beta } from './typography';
+
+const Hero: React.StatelessComponent<ContextInterface> = ({ children }) => (
+ <ThemeContext.Consumer>
+ {({ subtitle, tagline }: ContextInterface) => (
+ <StyledHero>
+ <HeroContainer>
+ <Subtitle>{subtitle}</Subtitle>
+ <Tagline as="p">{tagline}</Tagline>
+ <Button as="a" href="#" large={true}>
+ Read the Docs
+ </Button>
+ </HeroContainer>
+ {navigator.userAgent !== 'ReactSnap' ? children : null}
+ </StyledHero>
+ )}
+ </ThemeContext.Consumer>
+);
+
+const StyledHero = styled.section`
+ text-align: center;
+ padding-top: 9.375rem;
+ padding-bottom: 2rem;
+ padding-left: 2.5rem;
+ padding-right: 2.5rem;
+ min-height: min-content;
+ max-height: 37.5rem;
+ height: 80vh;
+ position: relative;
+`;
+
+const HeroContainer = styled.div`
+ margin: 0 auto;
+ max-width: 590px;
+`;
+
+const Subtitle = styled.h2`
+ font-size: 3.75rem;
+ line-height: 1.16;
+ margin-bottom: 1.5rem;
+
+ ${media.small`
+ font-size: 2.25rem;
+ line-height: 1.1;
+ margin-bottom: 1.375rem;
+ `};
+`;
+
+const Tagline = styled(Beta)`
+ margin-bottom: 2rem;
+ ${media.small`
+ margin-bottom: 1.25rem;
+ `};
+`;
+
+export { Hero };
diff --git a/packages/dev-tools-pages/ts/components/inline-code.tsx b/packages/dev-tools-pages/ts/components/inline-code.tsx
new file mode 100644
index 000000000..561666b0f
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/inline-code.tsx
@@ -0,0 +1,20 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { colors } from '../variables';
+
+interface InlineCodeProps {
+ isAlt?: boolean;
+ children: React.ReactNode;
+}
+
+const Code: React.StatelessComponent<InlineCodeProps> = ({ isAlt, children, ...props }) => (
+ <code {...props}>{children}</code>
+);
+
+const InlineCode = styled(Code)`
+ background-color: ${props => (props.isAlt ? '#E5E8E9' : colors.blueGray)};
+ padding: 0.3125rem;
+`;
+
+export { InlineCode };
diff --git a/packages/dev-tools-pages/ts/components/intro.tsx b/packages/dev-tools-pages/ts/components/intro.tsx
new file mode 100644
index 000000000..a0e76ab17
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/intro.tsx
@@ -0,0 +1,70 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { colors, media } from 'ts/variables';
+
+import { Breakout } from './breakout';
+import { Container } from './container';
+import { Alpha, Lead } from './typography';
+
+const Main = styled.div`
+ background-color: ${colors.lightGray};
+ padding: 6.25rem;
+ display: flex;
+ justify-content: space-between;
+
+ ${media.large`
+ padding: 2.5rem;
+ `};
+ ${media.medium`
+ display: block;
+ `};
+`;
+
+const Title = styled(Alpha)`
+ margin-bottom: 2.5rem;
+
+ ${media.medium`margin-bottom: 2.25rem;`};
+`;
+
+const StyledIntroLead = styled(Lead)`
+ max-width: 25.9375rem;
+ margin-right: 2rem;
+ ${media.medium`
+ max-width: 100%;
+ margin-bottom: 1.5625rem;
+ `};
+`;
+
+const StyledIntroAside = styled.div`
+ max-width: 32.5rem;
+ position: relative;
+ ${media.medium`
+ max-width: 100%;
+ `};
+`;
+
+interface IntroLeadProps {
+ title: string;
+}
+
+const IntroLead: React.StatelessComponent<IntroLeadProps> = props => (
+ <StyledIntroLead as="div">
+ <Title>{props.title}</Title>
+ {props.children}
+ </StyledIntroLead>
+);
+
+const IntroAside: React.StatelessComponent<{}> = props => (
+ <Breakout>
+ <StyledIntroAside>{props.children}</StyledIntroAside>
+ </Breakout>
+);
+
+const Intro: React.StatelessComponent<{}> = props => (
+ <Container wide={true}>
+ <Main>{props.children}</Main>
+ </Container>
+);
+
+export { IntroLead, IntroAside, Intro };
diff --git a/packages/dev-tools-pages/ts/components/list.tsx b/packages/dev-tools-pages/ts/components/list.tsx
new file mode 100644
index 000000000..ffa7c1cf3
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/list.tsx
@@ -0,0 +1,50 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { media } from 'ts/variables';
+
+const StyledList = styled.ul`
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+ position: relative;
+`;
+
+const StyledItem = styled.li`
+ position: relative;
+ padding-left: 1.625rem;
+
+ :before {
+ content: '';
+ border: 1px solid black;
+ width: 0.625rem;
+ height: 0.625rem;
+ display: inline-block;
+ position: absolute;
+ margin-top: 2px;
+ top: 0.3125rem;
+ left: 0;
+ transform: rotate(45deg);
+ }
+ :not(:last-child) {
+ margin-bottom: 0.5625rem;
+ ${media.small`
+ margin-bottom: 0.375rem;
+ `};
+ }
+`;
+
+interface ListProps {
+ items?: [];
+}
+
+const List: React.StatelessComponent<ListProps> = props => (
+ <StyledList>
+ {props.children !== undefined
+ ? props.children
+ : _.map(props.items, (bullet, index) => <StyledItem key={index}>{bullet}</StyledItem>)}
+ </StyledList>
+);
+
+export { List, StyledItem as ListItem };
diff --git a/packages/dev-tools-pages/ts/components/meta_tags.tsx b/packages/dev-tools-pages/ts/components/meta_tags.tsx
deleted file mode 100644
index f6c43d23f..000000000
--- a/packages/dev-tools-pages/ts/components/meta_tags.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import * as React from 'react';
-import { Helmet } from 'react-helmet';
-
-export interface MetaTagsProps {
- title: string;
- description: string;
- imgSrc?: string;
-}
-
-export const MetaTags: React.StatelessComponent<MetaTagsProps> = ({ title, description, imgSrc }) => (
- <Helmet>
- <title>{title}</title>
- <meta name="description" content={description} />
- <meta property="og:title" content={title} />
- <meta property="og:description" content={description} />
- <meta property="og:type" content="website" />
- <meta property="og:image" content={imgSrc} />
- <meta name="twitter:site" content="@0xproject" />
- <meta name="twitter:image" content={imgSrc} />
- </Helmet>
-);
-
-MetaTags.defaultProps = {
- imgSrc: '/images/og_image.png',
-};
diff --git a/packages/dev-tools-pages/ts/components/tabs.tsx b/packages/dev-tools-pages/ts/components/tabs.tsx
new file mode 100644
index 000000000..1d26f2777
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/tabs.tsx
@@ -0,0 +1,64 @@
+import * as React from 'react';
+import { Tab, TabList, TabPanel, Tabs as ReactTabs } from 'react-tabs';
+import styled from 'styled-components';
+
+import { colors } from 'ts/variables';
+
+import { Breakout } from './breakout';
+
+const StyledTabList = styled(TabList)`
+ text-transform: uppercase;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+`;
+
+const StyledTab = styled(Tab)`
+ background-color: ${props => props.theme.colors.secondary};
+ height: 2.5rem;
+ padding-left: 1rem;
+ padding-right: 1rem;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+ float: left;
+ &:not(:first-of-type) {
+ margin-left: 0.25rem;
+ }
+
+ &[aria-selected='true'] {
+ background-color: ${colors.gray};
+ }
+
+ &[aria-selected='false']:focus,
+ &[aria-selected='false']:hover {
+ background-color: ${props => props.theme.colors.secondary_alt};
+ cursor: pointer;
+ }
+`;
+
+const Tabs: React.StatelessComponent<{}> = props => (
+ <Breakout>
+ <ReactTabs>
+ <StyledTabList>
+ {React.Children.map(props.children, child => {
+ const { title } = React.cloneElement(child as React.ReactElement<any>).props;
+ return <StyledTab>{title}</StyledTab>;
+ })}
+ </StyledTabList>
+
+ {React.Children.map(props.children, child => <TabPanel>{child}</TabPanel>)}
+ </ReactTabs>
+ </Breakout>
+);
+
+interface TabBlockProps {
+ title: string;
+}
+
+const TabBlock: React.StatelessComponent<TabBlockProps> = props => <React.Fragment>{props.children}</React.Fragment>;
+
+const ContextTabs = Tabs;
+
+export { ContextTabs as Tabs, TabBlock };
diff --git a/packages/dev-tools-pages/ts/components/trace.tsx b/packages/dev-tools-pages/ts/components/trace.tsx
new file mode 100644
index 000000000..108154648
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/trace.tsx
@@ -0,0 +1,223 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+import { ContextInterface, ThemeContext } from 'ts/context';
+import ExactLocation from 'ts/icons/exact-location.svg';
+import NoLocation from 'ts/icons/no-location.svg';
+import TimeConsuming from 'ts/icons/time-consuming.svg';
+import TimeSaving from 'ts/icons/time-saving.svg';
+import { colors, media } from 'ts/variables';
+
+import { Breakout } from './breakout';
+import { Code } from './code';
+import { Container } from './container';
+import { Alpha, Gamma, Lead } from './typography';
+
+const Trace: React.StatelessComponent<{}> = () => (
+ <ThemeContext.Consumer>
+ {(props: ContextInterface) => (
+ <StyledSection background={props.colors.secondary}>
+ <Wrapper>
+ <Block>
+ <Alpha>The Issue</Alpha>
+ <MainCopy>
+ Every time an Ethereum transaction fails, it's extremely hard to trace down the
+ troublemaking line of code. The only hint you'll get is a generic error.
+ </MainCopy>
+ <Breakout>
+ <Code isLight={true}>Error: VM Exception while processing transaction: rever</Code>
+ </Breakout>
+
+ <List>
+ <Item>
+ <Copy dark={true}>
+ <Gamma as="h3">No location</Gamma>
+ <p>
+ The error basically says "anything could have gone wrong here", which keeps you
+ completely in the dark about its exact location.
+ </p>
+ </Copy>
+ <Icon as={NoLocation} />
+ </Item>
+
+ <Item>
+ <Copy dark={true}>
+ <Gamma as="h3">Time-consuming</Gamma>
+ <p>
+ Working with a large code-base that contains hundreds of smart contracts,
+ finding the failing line of code quickly becomes a daunting task.
+ </p>
+ </Copy>
+ <Icon as={TimeConsuming} />
+ </Item>
+ </List>
+ </Block>
+
+ <Block background={props.colors.secondary}>
+ <Alpha>The Fix</Alpha>
+ <MainCopy>
+ Sol-trace will give you full stack traces, including contract names, line numbers and code
+ snippets, every time you encounter an error.
+ </MainCopy>
+ <Breakout>
+ <Code isLight={true} language="javascript">
+ {`contracts/src/2.0.0/protocol/Exchange/MixinSignatureValidator.sol:51:8
+ require(
+ isValidSignature(
+ hash,
+ signerAddress,
+ signature
+ ),
+ "INVALID_SIGNATURE"
+ )`}
+ </Code>
+ </Breakout>
+
+ <List>
+ <Item>
+ <Copy>
+ <Gamma as="h3">Exact location</Gamma>
+ <p>
+ It shows you the exact location of the specific code linen and where it was
+ called from.
+ </p>
+ </Copy>
+ <Icon as={ExactLocation} />
+ </Item>
+
+ <Item>
+ <Copy>
+ <Gamma as="h3">Time-saving</Gamma>
+ <p>
+ Turning "Your code failed somewhere, good luck debugging it" into "Your code
+ failed on line X of contract Y", it drastically improves the developer
+ experience.
+ </p>
+ </Copy>
+ <Icon as={TimeSaving} />
+ </Item>
+ </List>
+ </Block>
+ </Wrapper>
+ </StyledSection>
+ )}
+ </ThemeContext.Consumer>
+);
+
+interface TraceProps {
+ background?: string;
+}
+
+const StyledSection =
+ styled.section <
+ TraceProps >
+ `
+ max-width: 90rem;
+ margin: 0 auto;
+ background: linear-gradient(to right, ${colors.black} 50%, ${props => props.background} 50%);
+ overflow: hidden;
+ ${media.large`
+ background: none
+ padding-top: 0;
+ padding-bottom: 0;
+ `};
+`;
+
+const Wrapper = styled(Container)`
+ display: flex;
+
+ ${Alpha} {
+ padding-bottom: 2.5rem;
+
+ ${media.small`padding-bottom: 1.875rem;`};
+ }
+
+ ${media.large`
+ display: block;
+ width: 100%;
+ `};
+`;
+
+const Block =
+ styled.div <
+ TraceProps >
+ `
+ width: 50%;
+ background: ${props => (props.background ? props.background : colors.black)};
+ color: ${props => (props.background ? 'inherit' : colors.white)};
+ padding-top: 6.25rem;
+ padding-bottom: 5.25rem;
+
+ :first-of-type {
+ padding-right: 6.25rem;
+ }
+ :last-of-type {
+ padding-left: 6.25rem;
+ }
+
+ ${media.xlarge`
+ :first-of-type {
+ padding-right: 2.5rem;
+ }
+ :last-of-type {
+ padding-left: 2.5rem;
+ }
+ `}
+ ${media.large`
+ width: 100%;
+ padding: 2.5rem;
+ `}
+
+ ${media.small`
+ padding-left: 1.875rem;
+ padding-right: 1.875rem;
+ `};
+`;
+
+const MainCopy = styled(Lead)`
+ margin-bottom: 3.1875rem;
+ ${media.small`
+ margin-bottom: 1.125rem;
+ `};
+`;
+
+const List = styled.ul`
+ margin-top: 6.25rem;
+ margin-bottom: 0;
+ padding: 0;
+
+ ${media.small`margin-top: 3.4375rem;`};
+`;
+
+const Item = styled.li`
+ display: flex;
+ align-items: center;
+
+ :not(:last-child) {
+ margin-bottom: 4.4375rem;
+
+ ${media.small`margin-bottom: 3.4375rem;`};
+ }
+`;
+
+const Copy =
+ styled.div <
+ { dark: boolean } >
+ `
+ margin-right: 5.875rem;
+ ${props =>
+ props.dark &&
+ `
+ p {
+ color: #ccc;
+ }
+ `}
+
+ ${media.small`margin-right: 2.0625rem;`};
+`;
+
+const Icon = styled.div`
+ flex-shrink: 0;
+`;
+
+export { Trace };
diff --git a/packages/dev-tools-pages/ts/components/typography.tsx b/packages/dev-tools-pages/ts/components/typography.tsx
new file mode 100644
index 000000000..e4b13163a
--- /dev/null
+++ b/packages/dev-tools-pages/ts/components/typography.tsx
@@ -0,0 +1,33 @@
+import styled from 'styled-components';
+
+import { media } from '../variables';
+
+const Alpha = styled.h2`
+ font-size: 1.75rem;
+ line-height: 1;
+
+ ${media.small`font-size: 1.5rem;`};
+`;
+
+const Beta = styled.h3`
+ font-size: 1.25rem;
+ line-height: 1.65;
+`;
+
+const Gamma = styled.h4`
+ font-size: 1rem;
+
+ ${media.small`font-size: 0.875rem;`};
+`;
+
+const Lead = styled.p`
+ font-size: 1.25rem;
+ line-height: 1.6;
+ ${media.small`font-size: 1rem;`};
+`;
+
+const Small = styled.p`
+ font-size: 0.875rem;
+`;
+
+export { Alpha, Beta, Gamma, Lead, Small };
diff --git a/packages/dev-tools-pages/ts/components/ui/button.tsx b/packages/dev-tools-pages/ts/components/ui/button.tsx
deleted file mode 100644
index 754eca40e..000000000
--- a/packages/dev-tools-pages/ts/components/ui/button.tsx
+++ /dev/null
@@ -1,59 +0,0 @@
-import { darken, saturate } from 'polished';
-import * as React from 'react';
-import styled from 'styled-components';
-
-/**
- * AN EXAMPLE OF HOW TO CREATE A STYLED COMPONENT USING STYLED-COMPONENTS
- * SEE: https://www.styled-components.com/docs/basics#coming-from-css
- */
-export interface ButtonProps {
- backgroundColor?: string;
- borderColor?: string;
- width?: string;
- padding?: string;
- type?: string;
- isDisabled?: boolean;
- onClick?: (event: React.MouseEvent<HTMLElement>) => void;
- className?: string;
-}
-
-const PlainButton: React.StatelessComponent<ButtonProps> = ({ children, isDisabled, onClick, type, className }) => (
- <button type={type} className={className} onClick={isDisabled ? undefined : onClick} disabled={isDisabled}>
- {children}
- </button>
-);
-
-const darkenOnHoverAmount = 0.1;
-const darkenOnActiveAmount = 0.2;
-const saturateOnFocusAmount = 0.2;
-export const Button = styled(PlainButton)`
- cursor: ${props => (props.isDisabled ? 'default' : 'pointer')};
- transition: background-color, opacity 0.5s ease;
- padding: ${props => props.padding};
- border-radius: 3px;
- outline: none;
- width: ${props => props.width};
- background-color: ${props => (props.backgroundColor ? props.backgroundColor : 'none')};
- border: ${props => (props.borderColor ? `1px solid ${props.backgroundColor}` : 'none')};
- &:hover {
- background-color: ${props =>
- !props.isDisabled ? darken(darkenOnHoverAmount, props.backgroundColor) : ''} !important;
- }
- &:active {
- background-color: ${props => (!props.isDisabled ? darken(darkenOnActiveAmount, props.backgroundColor) : '')};
- }
- &:disabled {
- opacity: 0.5;
- }
- &:focus {
- background-color: ${props => saturate(saturateOnFocusAmount, props.backgroundColor)};
- }
-`;
-
-Button.defaultProps = {
- backgroundColor: 'red',
- width: 'auto',
- isDisabled: false,
- padding: '1em 2.2em',
-};
-Button.displayName = 'Button';
diff --git a/packages/dev-tools-pages/ts/components/ui/container.tsx b/packages/dev-tools-pages/ts/components/ui/container.tsx
deleted file mode 100644
index f2ae68b70..000000000
--- a/packages/dev-tools-pages/ts/components/ui/container.tsx
+++ /dev/null
@@ -1,55 +0,0 @@
-import * as React from 'react';
-
-type StringOrNum = string | number;
-
-export type ContainerTag = 'div' | 'span';
-
-export interface ContainerProps {
- marginTop?: StringOrNum;
- marginBottom?: StringOrNum;
- marginRight?: StringOrNum;
- marginLeft?: StringOrNum;
- padding?: StringOrNum;
- paddingTop?: StringOrNum;
- paddingBottom?: StringOrNum;
- paddingRight?: StringOrNum;
- paddingLeft?: StringOrNum;
- backgroundColor?: string;
- borderRadius?: StringOrNum;
- maxWidth?: StringOrNum;
- maxHeight?: StringOrNum;
- width?: StringOrNum;
- height?: StringOrNum;
- minWidth?: StringOrNum;
- minHeight?: StringOrNum;
- isHidden?: boolean;
- className?: string;
- position?: 'absolute' | 'fixed' | 'relative' | 'unset';
- display?: 'inline-block' | 'block' | 'inline-flex' | 'inline';
- top?: string;
- left?: string;
- right?: string;
- bottom?: string;
- zIndex?: number;
- Tag?: ContainerTag;
- cursor?: string;
- id?: string;
- onClick?: (event: React.MouseEvent<HTMLElement>) => void;
- overflowX?: 'scroll' | 'hidden' | 'auto' | 'visible';
-}
-
-export const Container: React.StatelessComponent<ContainerProps> = props => {
- const { children, className, Tag, isHidden, id, onClick, ...style } = props;
- const visibility = isHidden ? 'hidden' : undefined;
- return (
- <Tag id={id} style={{ ...style, visibility }} className={className} onClick={onClick}>
- {children}
- </Tag>
- );
-};
-
-Container.defaultProps = {
- Tag: 'div',
-};
-
-Container.displayName = 'Container';
diff --git a/packages/dev-tools-pages/ts/components/ui/text.tsx b/packages/dev-tools-pages/ts/components/ui/text.tsx
deleted file mode 100644
index b4a61457f..000000000
--- a/packages/dev-tools-pages/ts/components/ui/text.tsx
+++ /dev/null
@@ -1,74 +0,0 @@
-import { colors } from '@0x/react-shared';
-import { darken } from 'polished';
-import * as React from 'react';
-import styled from 'styled-components';
-
-export type TextTag = 'p' | 'div' | 'span' | 'label' | 'h1' | 'h2' | 'h3' | 'h4' | 'i';
-
-export interface TextProps {
- className?: string;
- Tag?: TextTag;
- fontSize?: string;
- fontFamily?: string;
- fontStyle?: string;
- fontColor?: string;
- lineHeight?: string;
- minHeight?: string;
- center?: boolean;
- fontWeight?: number | string;
- textDecorationLine?: string;
- onClick?: (event: React.MouseEvent<HTMLElement>) => void;
- hoverColor?: string;
- noWrap?: boolean;
- display?: string;
-}
-
-const PlainText: React.StatelessComponent<TextProps> = ({ children, className, onClick, Tag }) => (
- <Tag className={className} onClick={onClick}>
- {children}
- </Tag>
-);
-
-export const Text = styled(PlainText)`
- font-family: ${props => props.fontFamily};
- font-style: ${props => props.fontStyle};
- font-weight: ${props => props.fontWeight};
- font-size: ${props => props.fontSize};
- text-decoration-line: ${props => props.textDecorationLine};
- ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')};
- ${props => (props.center ? 'text-align: center' : '')};
- color: ${props => props.fontColor};
- ${props => (props.minHeight ? `min-height: ${props.minHeight}` : '')};
- ${props => (props.onClick ? 'cursor: pointer' : '')};
- transition: color 0.5s ease;
- ${props => (props.noWrap ? 'white-space: nowrap' : '')};
- ${props => (props.display ? `display: ${props.display}` : '')};
- &:hover {
- ${props => (props.onClick ? `color: ${props.hoverColor || darken(0.3, props.fontColor || 'black')}` : '')};
- }
-`;
-
-Text.defaultProps = {
- fontFamily: 'Roboto',
- fontStyle: 'normal',
- fontWeight: 400,
- fontColor: colors.black,
- fontSize: '15px',
- lineHeight: '1.5em',
- textDecorationLine: 'none',
- Tag: 'div',
- noWrap: false,
-};
-
-Text.displayName = 'Text';
-
-export const Title: React.StatelessComponent<TextProps> = props => <Text {...props} />;
-
-Title.defaultProps = {
- Tag: 'h2',
- fontSize: '20px',
- fontWeight: 600,
- fontColor: colors.black,
-};
-
-Title.displayName = 'Title';
diff --git a/packages/dev-tools-pages/ts/context/compiler.tsx b/packages/dev-tools-pages/ts/context/compiler.tsx
new file mode 100644
index 000000000..177e265e5
--- /dev/null
+++ b/packages/dev-tools-pages/ts/context/compiler.tsx
@@ -0,0 +1,19 @@
+import Icon from 'ts/icons/logos/compiler.svg';
+
+import { ContextInterface } from './index';
+
+export const context: ContextInterface = {
+ title: 'sol-compiler',
+ name: 'compiler',
+ subtitle: 'Solidity compilation that just works',
+ tagline: 'Seamlessly compile an entire solidity project and generate customisable artifacts',
+ icon: Icon,
+ colors: {
+ main: '#1EADCD',
+ secondary: '#D1F4FC',
+ secondary_alt: '#C4F2FC',
+ type: '#30C3E3',
+ type_alt: '#16A9C9',
+ dark: '#4B818D',
+ },
+};
diff --git a/packages/dev-tools-pages/ts/context/cov.tsx b/packages/dev-tools-pages/ts/context/cov.tsx
new file mode 100644
index 000000000..1ade45e9d
--- /dev/null
+++ b/packages/dev-tools-pages/ts/context/cov.tsx
@@ -0,0 +1,19 @@
+import Icon from 'ts/icons/logos/cov.svg';
+
+import { ContextInterface } from './index';
+
+export const context: ContextInterface = {
+ title: 'sol-cov',
+ name: 'cov',
+ subtitle: 'Solidity code coverage',
+ tagline: 'Measure Solidity code coverage',
+ icon: Icon,
+ colors: {
+ main: '#BB9200',
+ secondary: '#F1DB8D',
+ secondary_alt: '#F1D882',
+ type: '#D7AE1B',
+ type_alt: '#BD9406',
+ dark: '#817033',
+ },
+};
diff --git a/packages/dev-tools-pages/ts/context/index.tsx b/packages/dev-tools-pages/ts/context/index.tsx
new file mode 100644
index 000000000..35c647ad6
--- /dev/null
+++ b/packages/dev-tools-pages/ts/context/index.tsx
@@ -0,0 +1,21 @@
+import { createContext } from 'react';
+
+interface ContextInterface {
+ title?: string;
+ name?: string;
+ subtitle?: string;
+ tagline?: string;
+ icon?: React.ReactNode;
+ colors?: {
+ main: string;
+ secondary: string;
+ secondary_alt: string;
+ type: string;
+ type_alt: string;
+ dark: string;
+ };
+}
+
+const ThemeContext = createContext({});
+
+export { ThemeContext, ContextInterface };
diff --git a/packages/dev-tools-pages/ts/context/profiler.tsx b/packages/dev-tools-pages/ts/context/profiler.tsx
new file mode 100644
index 000000000..5ccfa5b4c
--- /dev/null
+++ b/packages/dev-tools-pages/ts/context/profiler.tsx
@@ -0,0 +1,19 @@
+import Icon from 'ts/icons/logos/profiler.svg';
+
+import { ContextInterface } from './index';
+
+export const context: ContextInterface = {
+ title: 'sol-profiler',
+ name: 'profiler',
+ subtitle: 'Gas profiling for Solidity',
+ tagline: "Implement data-guided optimizations by profiling your contract's gas usage",
+ icon: Icon,
+ colors: {
+ main: '#FF7144',
+ secondary: '#FED7CB',
+ secondary_alt: '#FECEBE',
+ type: '#EB8666',
+ type_alt: '#D16745',
+ dark: '#985C49',
+ },
+};
diff --git a/packages/dev-tools-pages/ts/context/trace.tsx b/packages/dev-tools-pages/ts/context/trace.tsx
new file mode 100644
index 000000000..9627cc0a4
--- /dev/null
+++ b/packages/dev-tools-pages/ts/context/trace.tsx
@@ -0,0 +1,19 @@
+import Icon from 'ts/icons/logos/trace.svg';
+
+import { ContextInterface } from './index';
+
+export const context: ContextInterface = {
+ title: 'sol-trace',
+ name: 'trace',
+ subtitle: 'Human-readable stack traces',
+ tagline: 'Immediately locate Solidity errors and rapidly debug failed transactions',
+ icon: Icon,
+ colors: {
+ main: '#4F76FF',
+ secondary: '#CDD8FF',
+ secondary_alt: '#BFCDFF',
+ type: '#7090FF',
+ type_alt: '#355CE5',
+ dark: '#2A4ABC',
+ },
+};
diff --git a/packages/dev-tools-pages/ts/globalStyles.tsx b/packages/dev-tools-pages/ts/globalStyles.tsx
new file mode 100644
index 000000000..a77fb4eef
--- /dev/null
+++ b/packages/dev-tools-pages/ts/globalStyles.tsx
@@ -0,0 +1,90 @@
+import hljsStyles from 'highlight.js/styles/github-gist.css';
+import { createGlobalStyle } from 'styled-components';
+import styledNormalize from 'styled-normalize';
+
+import { ContextInterface } from 'ts/context';
+import { media } from 'ts/variables';
+
+const GlobalStyles =
+ createGlobalStyle <
+ ContextInterface >
+ `
+ ${styledNormalize}
+ ${hljsStyles}
+
+ @font-face {
+ font-family: "Maison Neue";
+ src: url("/fonts/MaisonNeue-Book-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Book-subset.woff") format("woff");
+ font-weight: 300;
+ font-display: swap;
+ unicode-range: U+20-7E;
+ }
+ @font-face {
+ font-family: "Maison Neue";
+ src: url("/fonts/MaisonNeue-Bold-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Bold-subset.woff") format("woff");
+ font-weight: 500;
+ font-display: swap;
+ unicode-range: U+20-7E;
+ }
+ @font-face {
+ font-family: "Maison Neue Mono";
+ src: url("/fonts/MaisonNeue-Mono-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Mono-subset.woff") format("woff");
+ font-weight: 300;
+ font-display: optional;
+ unicode-range: U+20-7E;
+ }
+
+ html {
+ font-size: 100%;
+ box-sizing: border-box;
+ }
+
+ *, *::before, *::after {
+ box-sizing: inherit;
+ }
+
+ body {
+ font-family: "Maison Neue", system-ui, sans-serif;
+ font-weight: 300;
+ font-size: 1rem;
+ line-height: 1.8;
+
+ ${media.small`font-size: 0.875rem;`};
+ }
+
+ a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ a:not([class]) {
+ color: ${props => props.colors.type_alt};
+ text-decoration: none;
+
+ &:hover {
+ color: ${props => props.colors.type_alt};
+ }
+ }
+
+ h1, h2, h3, h4 {
+ font-weight: 500;
+ margin: 0;
+ }
+
+ p {
+ margin-top: 0;
+ margin-bottom: 1em;
+ &:not([class]):last-of-type {
+ margin-bottom: 0;
+ }
+ }
+
+ code {
+ font-family: "Maison Neue Mono", monospace;
+ ${media.small`
+ font-size: .75rem;
+ `}
+ }
+`;
+
+export { GlobalStyles };
diff --git a/packages/dev-tools-pages/ts/globals.d.ts b/packages/dev-tools-pages/ts/globals.d.ts
index d0890161c..bfe13ee71 100644
--- a/packages/dev-tools-pages/ts/globals.d.ts
+++ b/packages/dev-tools-pages/ts/globals.d.ts
@@ -1,5 +1,10 @@
declare module 'whatwg-fetch';
declare module 'react-document-title';
+declare module 'highlight.js/lib/highlight';
+declare module 'highlight.js/lib/languages/javascript';
+declare module 'highlight.js/lib/languages/json';
+
+declare var System: any;
declare module '*.json' {
const json: any;
@@ -7,3 +12,13 @@ declare module '*.json' {
export default json;
/* tslint:enable */
}
+
+declare module '*.css' {
+ const css: any;
+ export default css;
+}
+
+declare module '*.svg' {
+ const svg: any;
+ export default svg;
+}
diff --git a/packages/dev-tools-pages/ts/highlight.tsx b/packages/dev-tools-pages/ts/highlight.tsx
new file mode 100644
index 000000000..02f4a753e
--- /dev/null
+++ b/packages/dev-tools-pages/ts/highlight.tsx
@@ -0,0 +1,67 @@
+import * as hljs from 'highlight.js/lib/highlight';
+import * as javascript from 'highlight.js/lib/languages/javascript';
+import * as json from 'highlight.js/lib/languages/json';
+import * as _ from 'lodash';
+
+hljs.registerLanguage('javascript', javascript);
+hljs.registerLanguage('json', json);
+
+interface PatchInterface {
+ [key: string]: string;
+}
+
+const PATCH_TYPES: PatchInterface = {
+ '+': 'addition',
+ '-': 'deletion',
+ '!': 'change',
+};
+
+function diffHighlight(language: string, code: any, gutter: any): string {
+ return _.map(code.split(/\r?\n/g), (line: string, index: number) => {
+ let type;
+ let currentLine = line;
+
+ if (/^-{3} [^-]+ -{4}$|^\*{3} [^*]+ \*{4}$|^@@ [^@]+ @@$/.test(currentLine)) {
+ type = 'chunk';
+ } else if (/^Index: |^[+\-*]{3}|^[*=]{5,}$/.test(currentLine)) {
+ type = 'header';
+ } else {
+ type = PATCH_TYPES[currentLine[0]] || 'null';
+ currentLine = currentLine.replace(/^[+\-! ]/, '');
+ }
+
+ const g = gutter[index];
+
+ return `<span data-gutter="${g !== undefined ? `${g}x` : ''}" class="line-${type}">${
+ hljs.highlight(language, currentLine).value
+ }</span>`;
+ }).join('\n');
+}
+
+interface HighlightProps {
+ language: string;
+ code: string;
+ isDiff?: boolean;
+ gutter?: [];
+ isEtc?: boolean;
+}
+
+function highlight({ language, code, isDiff, gutter, isEtc }: HighlightProps): string {
+ if (isDiff) {
+ return diffHighlight(language, code, gutter);
+ }
+
+ const hlCode = hljs.highlight(language, code).value;
+
+ if (!isEtc) {
+ return hlCode;
+ }
+
+ const hc = hlCode.split(/\r?\n/g);
+ hc.splice(1, 0, ' ...');
+ hc.splice(hc.length - 1, 0, ' ...');
+
+ return hc.join('\n');
+}
+
+export { highlight };
diff --git a/packages/dev-tools-pages/ts/icons/exact-location.svg b/packages/dev-tools-pages/ts/icons/exact-location.svg
new file mode 100644
index 000000000..4934cad58
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/exact-location.svg
@@ -0,0 +1 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M80 33.6772c0 5.1116-1.8855 10.4454-4.7935 15.617-2.9036 5.1637-6.7886 10.0987-10.6962 14.3941-3.9047 4.2922-7.8128 7.9248-10.746 10.4851-1.4659 1.2795-2.6866 2.2897-3.5393 2.9788-.2841.2296-.5273.4235-.725.5798-.1977-.1563-.4409-.3502-.725-.5798-.8527-.6891-2.0734-1.6993-3.5393-2.9788-2.9332-2.5603-6.8413-6.1929-10.746-10.4851-3.9076-4.2954-7.7926-9.2304-10.6962-14.3941C20.8855 44.1226 19 38.7888 19 33.6772 19 16.7294 32.6606 3 49.5 3 66.3394 3 80 16.7294 80 33.6772z" stroke="#fff" stroke-width="2"/><path d="M50 98V55M27.5 77H73" stroke="#000" stroke-width="2"/><circle cx="50" cy="34" r="10" stroke="#fff" stroke-width="2"/></svg> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/icons/logos/0x.svg b/packages/dev-tools-pages/ts/icons/logos/0x.svg
new file mode 100644
index 000000000..1856389db
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/logos/0x.svg
@@ -0,0 +1 @@
+<svg width="37" height="37" viewBox="0 0 37 37" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path d="M9.20465 34.4904c2.38415 1.3926 5.13725 2.2736 8.08905 2.4725 4.0871.2558 7.9188-.8242 11.1261-2.8704 1.5894-1.0232 3.0085-2.2737 4.229-3.7231-.9934-1.3926-2.0719-2.842-3.2072-4.3199-.3123-.3979-.6245-.7958-.9367-1.1937-1.1921 1.9042-2.9518 3.4389-4.9953 4.4052l-3.1789-3.0978-11.12605 8.3272zM2.44955 9.30988C1.08718 11.6972.235696 14.3971.0370167 17.3244-.218428 21.417.860116 25.2821 2.90368 28.4652c1.02177 1.5916 2.27062 3.0126 3.71814 4.2347 1.39075-.9947 2.83827-2.0747 4.31418-3.2115.3974-.3127.7947-.6253 1.1921-.9379-1.9017-1.2221-3.43434-2.9841-4.39936-5.0304l3.12206-3.1831L2.44955 9.30988zM27.7954 2.51741C25.4112 1.12481 22.6581.243776 19.7063.0448336 15.6192-.23937 11.7591.840605 8.55184 2.91529 6.96241 3.93843 5.54327 5.18893 4.32281 6.63837c.9934 1.3926 2.07194 2.84204 3.20725 4.31993.31221.3979.62442.7957.93663 1.1936 1.22046-1.9041 2.95181-3.43884 5.02371-4.40514l2.9802 2.87044 11.3248-8.09979zM34.5788 27.6126c1.334-2.3589 2.1855-5.0304 2.3842-7.9293.2554-4.0925-.8231-7.9293-2.8667-11.14077-1.0218-1.59154-2.2706-3.01256-3.7181-4.23464-1.3908.99472-2.8383 2.07469-4.3142 3.21151-.3974.31262-.7947.62525-1.1921.93787 1.9301 1.22208 3.4627 2.98413 4.4277 5.03043l.0284.0568-3.0085 3.1263 8.2593 10.9418z"/></svg> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/icons/logos/compiler.svg b/packages/dev-tools-pages/ts/icons/logos/compiler.svg
new file mode 100644
index 000000000..43c338f29
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/logos/compiler.svg
@@ -0,0 +1,3 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M0 28V15V0H15H28V15V28H15H0ZM26 13V2H15V13H26ZM15 15H26V26H15V15ZM13 13V2H2V13H13ZM2 15H13V26H2V15Z" />
+</svg>
diff --git a/packages/dev-tools-pages/ts/icons/logos/cov.svg b/packages/dev-tools-pages/ts/icons/logos/cov.svg
new file mode 100644
index 000000000..2c4dffb83
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/logos/cov.svg
@@ -0,0 +1,3 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H28V28H0V0ZM2 2V26H26V16H12V2H2ZM14 2V14H26V2H14Z"/>
+</svg>
diff --git a/packages/dev-tools-pages/ts/icons/logos/profiler.svg b/packages/dev-tools-pages/ts/icons/logos/profiler.svg
new file mode 100644
index 000000000..c3ea61294
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/logos/profiler.svg
@@ -0,0 +1,3 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2H26V9H2V2ZM2 11V26H26V11H2ZM0 0H2H26H28V2V26V28H26H2H0V26V2V0Z" />
+</svg>
diff --git a/packages/dev-tools-pages/ts/icons/logos/trace.svg b/packages/dev-tools-pages/ts/icons/logos/trace.svg
new file mode 100644
index 000000000..c207b24cb
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/logos/trace.svg
@@ -0,0 +1 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="currentColor" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M10 15H2V2h24v13H10zm0 2H2v9h8v-9zm2 9h14v-9H12v9zm-2 2H0V0h28v28H10z"/></svg> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/icons/no-location.svg b/packages/dev-tools-pages/ts/icons/no-location.svg
new file mode 100644
index 000000000..7df008ee1
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/no-location.svg
@@ -0,0 +1 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><path opacity=".5" d="M88.2609 41.4937c0 6.4322-2.3631 13.1253-5.9866 19.5928-3.6191 6.4597-8.4581 12.6276-13.3196 17.9909-4.8586 5.3602-9.7205 9.8958-13.3691 13.0921-1.8236 1.5975-3.3423 2.8589-4.4037 3.7198-.4285.3475-.7823.6297-1.0515.8423-.2692-.2126-.623-.4948-1.0514-.8423-1.0614-.8609-2.5802-2.1223-4.4038-3.7198-3.6486-3.1963-8.5105-7.7319-13.3691-13.0921-4.8614-5.3633-9.7004-11.5312-13.3196-17.9909C14.363 54.619 12 47.9259 12 41.4937 12 20.2255 29.0803 3 50.1304 3c21.0502 0 38.1305 17.2255 38.1305 38.4937z" stroke="#CDD8FF" stroke-width="2"/><circle opacity=".5" cx="50" cy="42" r="18" stroke="#CDD8FF" stroke-width="2"/><path d="M22.5 69.5L78 14" stroke="#fff" stroke-width="2"/></svg> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/icons/time-consuming.svg b/packages/dev-tools-pages/ts/icons/time-consuming.svg
new file mode 100644
index 000000000..330723394
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/time-consuming.svg
@@ -0,0 +1 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><circle opacity=".5" cx="50" cy="50" r="42" stroke="#CDD8FF" stroke-width="2"/><path opacity=".5" d="M34.6621 79.4343c6.9918 3.5363 15.2613 4.61 23.4252 2.4225 8.1639-2.1875 14.7886-7.2521 19.0755-13.8105M33.8711 58c2.9454 5.9269 9.0615 10 16.129 10 1.5538 0 3.0617-.1969 4.5-.5671M30 25.0185C35.4784 20.6269 42.4324 18 50 18c13.4295 0 24.9268 8.2727 29.6739 20" stroke="#CDD8FF" stroke-width="2"/><path d="M35 64l17.5-12.5L37.5 9" stroke="#fff" stroke-width="2"/></svg> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/icons/time-saving.svg b/packages/dev-tools-pages/ts/icons/time-saving.svg
new file mode 100644
index 000000000..935b1204e
--- /dev/null
+++ b/packages/dev-tools-pages/ts/icons/time-saving.svg
@@ -0,0 +1 @@
+<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="49.9092" cy="49.7499" r="40.4824" transform="rotate(45 49.9092 49.7499)" stroke="#fff" stroke-width="2"/><path d="M21.5991 79.4236l8.5269-8.5269M71.3965 29.6267l8.5268-8.5268M69.6914 70.8967l8.5269 8.5269M20.5761 21.7819l9.2091 9.2091M9.01002 50.4736H21.0688M79.4334 50.4736h12.0588M49.0449 78.45v12.0588M49.0449 8.99112V22.0146" stroke="#fff" stroke-width="2"/><path d="M35.584 36.789l14.3252 14.3252 30.0146-30.0146" stroke="#000" stroke-width="2"/></svg> \ No newline at end of file
diff --git a/packages/dev-tools-pages/ts/index.tsx b/packages/dev-tools-pages/ts/index.tsx
deleted file mode 100644
index 4591c6d76..000000000
--- a/packages/dev-tools-pages/ts/index.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import * as React from 'react';
-import { render } from 'react-dom';
-import { MetaTags } from 'ts/components/meta_tags';
-import { Landing } from 'ts/pages/landing';
-
-import 'basscss/css/basscss.css';
-
-const DOCUMENT_TITLE = '';
-const DOCUMENT_DESCRIPTION = '';
-
-render(
- <div>
- <MetaTags title={DOCUMENT_TITLE} description={DOCUMENT_DESCRIPTION} />
- <Landing />
- </div>,
- document.getElementById('app'),
-);
diff --git a/packages/dev-tools-pages/ts/pages/compiler.tsx b/packages/dev-tools-pages/ts/pages/compiler.tsx
new file mode 100644
index 000000000..93a667562
--- /dev/null
+++ b/packages/dev-tools-pages/ts/pages/compiler.tsx
@@ -0,0 +1,170 @@
+import * as React from 'react';
+import { hydrate, render } from 'react-dom';
+import * as Loadable from 'react-loadable';
+
+import { context } from 'ts/context/compiler';
+
+import { Base } from 'ts/components/base';
+import { Breakout } from 'ts/components/breakout';
+import { Code } from 'ts/components/code';
+import { Compiler as CompilerComponent } from 'ts/components/compiler';
+import { Content } from 'ts/components/content';
+import { ContentBlock } from 'ts/components/content-block';
+import { Hero } from 'ts/components/hero';
+import { InlineCode } from 'ts/components/inline-code';
+import { Lead } from 'ts/components/typography';
+
+const Animation = Loadable({
+ loader: () => System.import(/* webpackChunkName: 'compiler-animation' */ 'ts/components/animations/compiler'),
+ loading: () => <div />,
+ delay: 1000,
+ render(loadable: { CompilerAnimation: any }): React.ReactNode {
+ const Component = loadable.CompilerAnimation;
+ return <Component />;
+ },
+});
+
+const Compiler: React.StatelessComponent<{}> = () => (
+ <Base context={context}>
+ <Hero>
+ <Animation />
+ </Hero>
+ <CompilerComponent />
+ <Content>
+ <ContentBlock main={true} title="Get started" />
+ <ContentBlock title="Install">
+ <Breakout>
+ <Code canCopy={true}>npm install @0x/sol-compiler --g</Code>
+ </Breakout>
+ </ContentBlock>
+
+ <ContentBlock title="Run">
+ <Breakout>
+ <Code>cd /your_project_dir && sol-compiler</Code>
+ </Breakout>
+ </ContentBlock>
+
+ <ContentBlock title="Configure">
+ <p>
+ Configure via a <InlineCode>compiler.json</InlineCode> file.
+ </p>
+ <Breakout>
+ <Code>mkdir compiler.json</Code>
+ </Breakout>
+ <p>Example of settings:</p>
+ <Breakout>
+ <Code language="json">
+ {`{
+ "contractsDir": "contracts",
+ "artifactsDir": "artifacts",
+ "contracts": "*",
+ "compilerSettings": {
+ "optimizer": { "enabled": false },
+ "outputSelection": {
+ "*": {
+ "*": ["abi", "evm.bytecode.object"]
+ }
+ }
+ }
+}`}
+ </Code>
+ </Breakout>
+ </ContentBlock>
+ </Content>
+ <Content dark={true}>
+ <ContentBlock main={true} title="Artifacts">
+ <Lead>
+ Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
+ which parts of the artifact you need.
+ </Lead>
+ </ContentBlock>
+
+ <ContentBlock title="Production">
+ <p>
+ Sol compiler uses solidity standard JSON output format for the artifacts. This way, you can define
+ which parts of the artifact you need.
+ </p>
+ <Breakout>
+ <Code isLight={true} language="json" isEtc={true}>
+ {`{
+ "compilerSettings": {
+ "outputSelection": {
+ "*": {
+ "*": ["abi"]
+ }
+ }
+ }
+}`}
+ </Code>
+ </Breakout>
+ <Breakout>
+ <Code isLight={true} language="json" isEtc={true}>
+ {`{
+ "compilerOutput": {
+ "abi": [...],
+ },
+}`}
+ </Code>
+ </Breakout>
+ </ContentBlock>
+ <ContentBlock title="Development">
+ <p>
+ Sometimes you need to use some debuggers or other dev tools and you’ll need more info in the
+ artifact.
+ </p>
+ <Breakout>
+ <Code isLight={true} language="json" isEtc={true}>
+ {`{
+ "compilerSettings": {
+ "outputSelection": {
+ "*": {
+ "*": [
+ "abi",
+ "evm.bytecode.object",
+ "evm.bytecode.sourceMap",
+ "evm.deployedBytecode.object",
+ "evm.deployedBytecode.sourceMap"
+ ]
+ }
+ }
+ }
+}`}
+ </Code>
+ </Breakout>
+
+ <Breakout>
+ <Code isLight={true} language="json" isEtc={true}>
+ {`{
+ "compilerOutput": {
+ "abi": [...],
+ "evm": {
+ "bytecode": {
+ "object": "0xdeadbeef",
+ "sourceMap": "26:480:..."
+ },
+ "deployedBytecode": {
+ "object": "0xdeadbeef",
+ "sourceMap": "26:480:0..."
+ }
+ }
+ }
+ "sources": {
+ "Migrations.sol": {
+ "id": 0
+ }
+ },
+}`}
+ </Code>
+ </Breakout>
+ </ContentBlock>
+ </Content>
+ </Base>
+);
+
+const root = document.getElementById('app');
+
+if (root.hasChildNodes()) {
+ hydrate(<Compiler />, root);
+} else {
+ render(<Compiler />, root);
+}
diff --git a/packages/dev-tools-pages/ts/pages/cov.tsx b/packages/dev-tools-pages/ts/pages/cov.tsx
new file mode 100644
index 000000000..85487248a
--- /dev/null
+++ b/packages/dev-tools-pages/ts/pages/cov.tsx
@@ -0,0 +1,149 @@
+import * as React from 'react';
+import { hydrate, render } from 'react-dom';
+import * as Loadable from 'react-loadable';
+
+import { context } from 'ts/context/cov';
+
+import { Base } from 'ts/components/base';
+import { Breakout } from 'ts/components/breakout';
+import { Code } from 'ts/components/code';
+import { Content } from 'ts/components/content';
+import { ContentBlock } from 'ts/components/content-block';
+import { Hero } from 'ts/components/hero';
+import { InlineCode } from 'ts/components/inline-code';
+import { Intro, IntroAside, IntroLead } from 'ts/components/intro';
+import { List, ListItem } from 'ts/components/list';
+import { TabBlock, Tabs } from 'ts/components/tabs';
+
+const Animation = Loadable({
+ loader: () => System.import(/* webpackChunkName: 'cov-animation' */ 'ts/components/animations/cov'),
+ loading: () => <div />,
+ delay: 1000,
+ render(loadable: { CovAnimation: any }): React.ReactNode {
+ const Component = loadable.CovAnimation;
+ return <Component />;
+ },
+});
+
+const Cov: React.StatelessComponent<{}> = () => (
+ <Base context={context}>
+ <Hero>
+ <Animation />
+ </Hero>
+ <Intro>
+ <IntroLead title="Measure your tests">
+ <p>
+ When it comes to writing smart contracts, testing is one of the most important steps of the process.
+ In order to quantify the robustness of your Solidity testing suite, you need to measure its code
+ coverage.
+ </p>
+ </IntroLead>
+ <IntroAside>
+ <Code
+ language="javascript"
+ isDiff={true}
+ gutterLength={2}
+ gutter={[4, undefined, 4, 4, 4, undefined, 4, 2, 2, 2]}
+ >
+ {`+function executeTransaction(uint transactionId)
+ public
++ notExecuted(transactionId)
++ fullyConfirmed(transactionId)
++ pastTimeLock(transactionId)
+{
++ Transaction storage tx = transactions[transactionId]
++ tx.executed = true
++ if (tx.destination.call.value(tx.value)(tx.data))
++ Execution(transactionId)
+ else {
+- ExecutionFailure(transactionId)
+- tx.executed = false
+ }
+}`}
+ </Code>
+ </IntroAside>
+ </Intro>
+
+ <Content>
+ <ContentBlock main={true} title="Get started" />
+ <ContentBlock title="Prerequisites">
+ <List>
+ <ListItem>
+ Use <a href="#">ganache-cli</a> as a backing node.
+ </ListItem>
+ <ListItem>
+ Understand and use <a href="#">web3-provider-engine</a>.
+ </ListItem>
+ </List>
+ </ContentBlock>
+ <ContentBlock title="Installation">
+ <Breakout>
+ <Code>npm install @0x/sol-coverage --save</Code>
+ </Breakout>
+
+ <p>
+ Sol-cov is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
+ Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-cov ships with
+ the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with <a href="#">Sol-compiler</a>{' '}
+ and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
+ <a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
+ </p>
+
+ <Tabs>
+ <TabBlock title="Sol-compiler">
+ <Code language="javascript">
+ {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
+
+// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
+const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);`}
+ </Code>
+ </TabBlock>
+ <TabBlock title="Truffle">
+ <Code language="javascript">
+ {`import { TruffleArtifactAdapter } from '@0x/sol-trace';
+
+const projectRoot = '.';
+const solcVersion = '0.4.24';
+const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
+ </Code>
+ </TabBlock>
+ <TabBlock title="Custom">
+ <Code language="javascript">
+ {`import { AbstractArtifactAdapter } from '@0x/sol-trace';
+
+class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
+const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
+ </Code>
+ </TabBlock>
+ </Tabs>
+ <p>
+ Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
+ <InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
+ </p>
+
+ <Breakout>
+ <Code language="javascript">
+ {`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
+import { RevertTraceSubprovider } from '@0x/sol-coverage';
+
+const defaultFromAddress = "..."; // Some ethereum address with test funds
+const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
+
+const providerEngine = new ProviderEngine();
+providerEngine.addProvider(revertTraceSubprovider);
+providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
+providerEngine.start();`}
+ </Code>
+ </Breakout>
+ </ContentBlock>
+ </Content>
+ </Base>
+);
+
+const root = document.getElementById('app');
+
+if (root.hasChildNodes()) {
+ hydrate(<Cov />, root);
+} else {
+ render(<Cov />, root);
+}
diff --git a/packages/dev-tools-pages/ts/pages/landing.tsx b/packages/dev-tools-pages/ts/pages/landing.tsx
deleted file mode 100644
index a70a9de46..000000000
--- a/packages/dev-tools-pages/ts/pages/landing.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { Button } from '../components/ui/button';
-import { Container } from '../components/ui/container';
-import { Text } from '../components/ui/text';
-
-interface LandingProps {}
-
-interface LandingState {}
-
-export class Landing extends React.Component<LandingProps, LandingState> {
- constructor(props: LandingProps) {
- super(props);
- }
- public render(): React.ReactNode {
- return (
- <Container id="landing" className="clearfix">
- <Container className="mx-auto p4" width="200px">
- <Button>
- <Text fontColor="white">Click me!</Text>
- </Button>
- </Container>
- </Container>
- );
- }
-}
diff --git a/packages/dev-tools-pages/ts/pages/profiler.tsx b/packages/dev-tools-pages/ts/pages/profiler.tsx
new file mode 100644
index 000000000..16ac9088e
--- /dev/null
+++ b/packages/dev-tools-pages/ts/pages/profiler.tsx
@@ -0,0 +1,146 @@
+import * as React from 'react';
+import { hydrate, render } from 'react-dom';
+import * as Loadable from 'react-loadable';
+
+import { context } from 'ts/context/profiler';
+
+import { Base } from 'ts/components/base';
+import { Breakout } from 'ts/components/breakout';
+import { Code } from 'ts/components/code';
+import { Content } from 'ts/components/content';
+import { ContentBlock } from 'ts/components/content-block';
+import { Hero } from 'ts/components/hero';
+import { InlineCode } from 'ts/components/inline-code';
+import { Intro, IntroAside, IntroLead } from 'ts/components/intro';
+import { List, ListItem } from 'ts/components/list';
+import { TabBlock, Tabs } from 'ts/components/tabs';
+
+const Animation = Loadable({
+ loader: () => System.import(/* webpackChunkName: 'profiler-animation' */ 'ts/components/animations/profiler'),
+ loading: () => <div />,
+ delay: 1000,
+ render(loadable: { ProfilerAnimation: any }): React.ReactNode {
+ const Component = loadable.ProfilerAnimation;
+ return <Component />;
+ },
+});
+
+const Profiler: React.StatelessComponent<{}> = () => (
+ <Base context={context}>
+ <Hero>
+ <Animation />
+ </Hero>
+ <Intro>
+ <IntroLead title="Outline gas usage">
+ <p>
+ Sol-profiler gathers line-by-line gas usage for any transaction submitted through your provider.
+ This will help you find unexpected inefficiencies in parts of your smart contract, and take a
+ data-driven approach to optimizing it.
+ </p>
+ </IntroLead>
+ <IntroAside>
+ <Code
+ language="javascript"
+ isDiff={true}
+ gutterLength={6}
+ gutter={[15, 15, undefined, 21747, 20303, 1435]}
+ >
+ {`+function() public payable {
++ deposit();
+}
++function deposit() public payabble {
++ balanceOf[msg.sender] += msg.value;
++ Deposit(msg.sender, msg.value);
+}
+-function withdraw(uint wad) public {
+- require(balanceOf[msg.sender] >= wad);
+- balanceOf[msg.sender] -= wad;
+- msg.sender.transfer(wad);
+- Withdrawal(msg.sender, wad);
+}`}
+ </Code>
+ </IntroAside>
+ </Intro>
+ <Content>
+ <ContentBlock main={true} title="Get started" />
+ <ContentBlock title="Prerequisites">
+ <List>
+ <ListItem>
+ Use <a href="#">ganache-cli</a> as a backing node.
+ </ListItem>
+ <ListItem>
+ Understand and use <a href="#">web3-provider-engine</a>.
+ </ListItem>
+ </List>
+ </ContentBlock>
+ <ContentBlock title="Installation">
+ <Breakout>
+ <Code>npm install @0x/sol-trace --save</Code>
+ </Breakout>
+
+ <p>
+ Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
+ Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
+ with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
+ <a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
+ <a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
+ </p>
+
+ <Tabs>
+ <TabBlock title="Sol-compiler">
+ <Code language="javascript">
+ {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
+
+// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
+const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);`}
+ </Code>
+ </TabBlock>
+ <TabBlock title="Truffle">
+ <Code language="javascript">
+ {`import { TruffleArtifactAdapter } from '@0x/sol-trace';
+
+const projectRoot = '.';
+const solcVersion = '0.4.24';
+const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
+ </Code>
+ </TabBlock>
+ <TabBlock title="Custom">
+ <Code language="javascript">
+ {`import { AbstractArtifactAdapter } from '@0x/sol-trace';
+
+class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
+const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
+ </Code>
+ </TabBlock>
+ </Tabs>
+ <p>
+ Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
+ <InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
+ </p>
+
+ <Breakout>
+ <Code language="javascript">
+ {`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
+import { RevertTraceSubprovider } from '@0x/sol-coverage';
+
+const defaultFromAddress = "..."; // Some ethereum address with test funds
+const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
+
+const providerEngine = new ProviderEngine();
+providerEngine.addProvider(revertTraceSubprovider);
+providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
+providerEngine.start();`}
+ </Code>
+ </Breakout>
+ </ContentBlock>
+ </Content>
+ </Base>
+);
+
+const root = document.getElementById('app');
+
+if (root.hasChildNodes()) {
+ hydrate(<Profiler />, root);
+} else {
+ render(<Profiler />, root);
+}
diff --git a/packages/dev-tools-pages/ts/pages/trace.tsx b/packages/dev-tools-pages/ts/pages/trace.tsx
new file mode 100644
index 000000000..cc34e0fbe
--- /dev/null
+++ b/packages/dev-tools-pages/ts/pages/trace.tsx
@@ -0,0 +1,116 @@
+import * as React from 'react';
+import { hydrate, render } from 'react-dom';
+import * as Loadable from 'react-loadable';
+
+import { context } from 'ts/context/trace';
+
+import { Base } from 'ts/components/base';
+import { Breakout } from 'ts/components/breakout';
+import { Code } from 'ts/components/code';
+import { Content } from 'ts/components/content';
+import { ContentBlock } from 'ts/components/content-block';
+import { Hero } from 'ts/components/hero';
+import { InlineCode } from 'ts/components/inline-code';
+import { List, ListItem } from 'ts/components/list';
+import { TabBlock, Tabs } from 'ts/components/tabs';
+import { Trace as TraceComponent } from 'ts/components/trace';
+
+const Animation = Loadable({
+ loader: () => System.import(/* webpackChunkName: 'trace-animation' */ 'ts/components/animations/trace'),
+ loading: () => <div />,
+ delay: 1000,
+ render(loadable: { TraceAnimation: any }): React.ReactNode {
+ const Component = loadable.TraceAnimation;
+ return <Component />;
+ },
+});
+
+const Trace: React.StatelessComponent<{}> = () => (
+ <Base context={context}>
+ <Hero>
+ <Animation />
+ </Hero>
+ <TraceComponent />
+ <Content>
+ <ContentBlock main={true} title="Get started" />
+ <ContentBlock title="Prerequisites">
+ <List>
+ <ListItem>
+ Use <a href="#">ganache-cli</a> as a backing node.
+ </ListItem>
+ <ListItem>
+ Understand and use <a href="#">web3-provider-engine</a>.
+ </ListItem>
+ </List>
+ </ContentBlock>
+ <ContentBlock title="Installation">
+ <Breakout>
+ <Code>npm install @0x/sol-trace --save</Code>
+ </Breakout>
+
+ <p>
+ Sol-trace is a subprovider that needs to be prepended to your <a href="#">provider engine</a>.
+ Depending on your project setup, you will need to use a specific ArtifactAdapter. Sol-trace ships
+ with the <InlineCode>SolCompilerArtifactAdapter</InlineCode> for use with{' '}
+ <a href="#">Sol-compiler</a> and <InlineCode>TruffleArtifactAdapter</InlineCode> for use with the{' '}
+ <a href="#">Truffle framework</a>. You can also write your own and support any artifact format.
+ </p>
+
+ <Tabs>
+ <TabBlock title="Sol-compiler">
+ <Code language="javascript">
+ {`import { SolCompilerArtifactAdapter } from '@0x/sol-trace';
+
+// Both artifactsDir and contractsDir are optional and will be fetched from compiler.json if not passed in
+const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDir);`}
+ </Code>
+ </TabBlock>
+ <TabBlock title="Truffle">
+ <Code language="javascript">
+ {`import { TruffleArtifactAdapter } from '@0x/sol-trace';
+
+const projectRoot = '.';
+const solcVersion = '0.4.24';
+const artifactAdapter = new TruffleArtifactAdapter(projectRoot, solcVersion);`}
+ </Code>
+ </TabBlock>
+ <TabBlock title="Custom">
+ <Code language="javascript">
+ {`import { AbstractArtifactAdapter } from '@0x/sol-trace';
+
+class YourCustomArtifactsAdapter extends AbstractArtifactAdapter {...};
+const artifactAdapter = new YourCustomArtifactsAdapter(...);`}
+ </Code>
+ </TabBlock>
+ </Tabs>
+ <p>
+ Now that we have an <InlineCode>artifactAdapter</InlineCode>, we can create a{' '}
+ <InlineCode>RevertTraceSubprovider</InlineCode> and append it to our provider engine.
+ </p>
+
+ <Breakout>
+ <Code language="javascript">
+ {`import { ProviderEngine, RpcSubprovider } from 'web3-provider-engine';
+import { RevertTraceSubprovider } from '@0x/sol-coverage';
+
+const defaultFromAddress = "..."; // Some ethereum address with test funds
+const revertTraceSubprovider = new RevertTraceSubprovider(artifactAdapter, defaultFromAddress);
+
+const providerEngine = new ProviderEngine();
+providerEngine.addProvider(revertTraceSubprovider);
+providerEngine.addProvider(new RpcSubprovider({rpcUrl: 'http://localhost:8545'}));
+providerEngine.start();`}
+ </Code>
+ </Breakout>
+ </ContentBlock>
+ </Content>
+ </Base>
+);
+
+const root = document.getElementById('app');
+
+if (root.hasChildNodes()) {
+ hydrate(<Trace />, root);
+} else {
+ render(<Trace />, root);
+}
diff --git a/packages/dev-tools-pages/ts/utils/utils.ts b/packages/dev-tools-pages/ts/utils/utils.ts
deleted file mode 100644
index b274706a2..000000000
--- a/packages/dev-tools-pages/ts/utils/utils.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import * as bowser from 'bowser';
-import * as _ from 'lodash';
-
-export const utils = {
- getColSize(items: number): number {
- const bassCssGridSize = 12; // Source: http://basscss.com/#basscss-grid
- const colSize = bassCssGridSize / items;
- if (!_.isInteger(colSize)) {
- throw new Error(`Number of cols must be divisible by ${bassCssGridSize}`);
- }
- return colSize;
- },
- getCurrentBaseUrl(): string {
- const port = window.location.port;
- const hasPort = !_.isUndefined(port);
- const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`;
- return baseUrl;
- },
- onPageLoadPromise: new Promise<void>((resolve, _reject) => {
- if (document.readyState === 'complete') {
- resolve();
- return;
- }
- window.onload = () => resolve();
- }),
- openUrl(url: string): void {
- window.open(url, '_blank');
- },
- isMobileOperatingSystem(): boolean {
- return bowser.mobile;
- },
-};
diff --git a/packages/dev-tools-pages/ts/variables.tsx b/packages/dev-tools-pages/ts/variables.tsx
new file mode 100644
index 000000000..5ea495036
--- /dev/null
+++ b/packages/dev-tools-pages/ts/variables.tsx
@@ -0,0 +1,34 @@
+import { css } from 'styled-components';
+
+const colors = {
+ black: '#000000',
+ white: '#FFFFFF',
+ lightGray: '#F1F4F5',
+ gray: '#F1F2F7',
+ darkGray: '#E9ECED',
+ darkestGray: '#E2E5E6',
+ blueGray: '#ECEFF9',
+};
+
+interface SizesInterface {
+ [key: string]: number;
+}
+
+const sizes: SizesInterface = {
+ xlarge: 1420,
+ large: 1000,
+ medium: 900,
+ small: 650,
+};
+
+const media = Object.keys(sizes).reduce((acc: any, label: string) => {
+ acc[label] = (args: any) => css`
+ @media (max-width: ${sizes[label] / 16}em) {
+ ${css(args)};
+ }
+ `;
+
+ return acc;
+}, {});
+
+export { colors, media };
diff --git a/packages/dev-tools-pages/webpack.config.js b/packages/dev-tools-pages/webpack.config.js
index 6dfcf74e7..640297770 100644
--- a/packages/dev-tools-pages/webpack.config.js
+++ b/packages/dev-tools-pages/webpack.config.js
@@ -1,13 +1,24 @@
const path = require('path');
const webpack = require('webpack');
const TerserPlugin = require('terser-webpack-plugin');
+const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+const HtmlWebpackPlugin = require('html-webpack-plugin');
const childProcess = require('child_process');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const CleanWebpackPlugin = require('clean-webpack-plugin');
+
+const pages = require('./pages');
const config = {
- entry: ['./ts/index.tsx'],
+ entry: {
+ compiler: './ts/pages/compiler.tsx',
+ cov: './ts/pages/cov.tsx',
+ profiler: './ts/pages/profiler.tsx',
+ trace: './ts/pages/trace.tsx',
+ },
output: {
path: path.join(__dirname, '/public'),
- filename: 'bundle.js',
+ filename: 'bundle-[name].js',
chunkFilename: 'bundle-[name].js',
publicPath: '/',
},
@@ -48,6 +59,10 @@ const config = {
test: /\.css$/,
loaders: ['style-loader', 'css-loader'],
},
+ {
+ test: /\.svg$/,
+ loaders: ['react-svg-loader'],
+ },
],
},
optimization: {
@@ -60,21 +75,36 @@ const config = {
devServer: {
port: 3572,
disableHostCheck: true,
+ overlay: true,
+ historyApiFallback: true,
},
};
module.exports = (_env, argv) => {
- let plugins = [];
+ let plugins = [
+ new CleanWebpackPlugin('public'),
+ ...pages.map(p => new HtmlWebpackPlugin(p)),
+ new CopyWebpackPlugin([
+ { from: 'assets/crawl.html', to: 'index.html' },
+ { from: 'assets/fonts', to: 'fonts' },
+ { from: 'assets/images', to: 'images' },
+ ]),
+ ];
if (argv.mode === 'development') {
config.mode = 'development';
} else {
config.mode = 'production';
+ config.output.filename = 'bundle-[name].[chunkhash].js';
+ config.output.chunkFilename = 'bundle-[name].[chunkhash].js';
+
plugins = plugins.concat([
new webpack.DefinePlugin({
'process.env': {
- NODE_ENV: JSON.stringify(process.env.NODE_ENV),
+ NODE_ENV: JSON.stringify(process.env.NODE_ENV || config.mode),
},
}),
+ // commented out to check the bundle when needed
+ //new BundleAnalyzerPlugin(),
]);
}
console.log('i ï½¢atlï½£: Mode: ', config.mode);
diff --git a/packages/dev-utils/CHANGELOG.json b/packages/dev-utils/CHANGELOG.json
index b6cc74ce7..8f355466c 100644
--- a/packages/dev-utils/CHANGELOG.json
+++ b/packages/dev-utils/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "1.0.22",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "1.0.21",
"changes": [
{
diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md
index 9a55e4e58..04ee860b5 100644
--- a/packages/dev-utils/CHANGELOG.md
+++ b/packages/dev-utils/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.0.22 - _January 9, 2019_
+
+ * Dependencies updated
+
## v1.0.21 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json
index a3eb4651a..cb27ad5c5 100644
--- a/packages/dev-utils/package.json
+++ b/packages/dev-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/dev-utils",
- "version": "1.0.21",
+ "version": "1.0.22",
"engines": {
"node": ">=6.12"
},
@@ -41,11 +41,11 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/subproviders": "^2.1.8",
- "@0x/types": "^1.4.1",
+ "@0x/subproviders": "^2.1.9",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/web3-provider-engine": "^14.0.0",
"chai": "^4.0.1",
"ethereum-types": "^1.1.4",
diff --git a/packages/dev-utils/src/web3_factory.ts b/packages/dev-utils/src/web3_factory.ts
index b22bcc88b..5f8981a46 100644
--- a/packages/dev-utils/src/web3_factory.ts
+++ b/packages/dev-utils/src/web3_factory.ts
@@ -17,6 +17,7 @@ export interface Web3Config {
shouldThrowErrorsOnGanacheRPCResponse?: boolean; // default: true
rpcUrl?: string; // default: localhost:8545
shouldUseFakeGasEstimate?: boolean; // default: true
+ ganacheDatabasePath?: string; // default: undefined, creates a tmp dir
}
export const web3Factory = {
@@ -45,9 +46,14 @@ export const web3Factory = {
const shouldThrowErrorsOnGanacheRPCResponse =
_.isUndefined(config.shouldThrowErrorsOnGanacheRPCResponse) ||
config.shouldThrowErrorsOnGanacheRPCResponse;
+ if (!_.isUndefined(config.ganacheDatabasePath)) {
+ // Saving the snapshot to a local db. Ganache requires this directory to exist
+ fs.mkdirSync(config.ganacheDatabasePath);
+ }
provider.addProvider(
new GanacheSubprovider({
vmErrorsOnRPCResponse: shouldThrowErrorsOnGanacheRPCResponse,
+ db_path: config.ganacheDatabasePath,
gasLimit: constants.GAS_LIMIT,
logger,
verbose: env.parseBoolean(EnvVars.VerboseGanache),
diff --git a/packages/fill-scenarios/CHANGELOG.json b/packages/fill-scenarios/CHANGELOG.json
index 2c3e261cb..125a62cdf 100644
--- a/packages/fill-scenarios/CHANGELOG.json
+++ b/packages/fill-scenarios/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Add support for MultiAssetProxy",
"pr": 1363
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "1.0.16",
diff --git a/packages/fill-scenarios/CHANGELOG.md b/packages/fill-scenarios/CHANGELOG.md
index e9b88547d..45cee1ce3 100644
--- a/packages/fill-scenarios/CHANGELOG.md
+++ b/packages/fill-scenarios/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.1.0 - _January 9, 2019_
+
+ * Add support for MultiAssetProxy (#1363)
+
## v1.0.16 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/fill-scenarios/package.json b/packages/fill-scenarios/package.json
index 7a9d21e0a..a38dcc1c3 100644
--- a/packages/fill-scenarios/package.json
+++ b/packages/fill-scenarios/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/fill-scenarios",
- "version": "1.0.16",
+ "version": "1.1.0",
"description": "0x order fill scenario generator",
"main": "lib/index.js",
"types": "lib/index.d.ts",
@@ -28,14 +28,14 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/abi-gen-wrappers": "^2.0.2",
- "@0x/base-contract": "^3.0.10",
- "@0x/contract-artifacts": "^1.1.2",
- "@0x/order-utils": "^3.0.7",
- "@0x/types": "^1.4.1",
+ "@0x/abi-gen-wrappers": "^2.1.0",
+ "@0x/base-contract": "^3.0.11",
+ "@0x/contract-artifacts": "^1.2.0",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"ethereum-types": "^1.1.4",
"ethers": "~4.0.4",
"lodash": "^4.17.5"
diff --git a/packages/instant/package.json b/packages/instant/package.json
index 0a5e152ca..0888fc6a6 100644
--- a/packages/instant/package.json
+++ b/packages/instant/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/instant",
- "version": "1.0.4",
+ "version": "1.0.5",
"engines": {
"node": ">=6.12"
},
@@ -41,15 +41,15 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md",
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/asset-buyer": "^3.0.4",
- "@0x/json-schemas": "^2.1.4",
- "@0x/order-utils": "^3.0.7",
- "@0x/subproviders": "^2.1.8",
- "@0x/types": "^1.4.1",
+ "@0x/assert": "^1.0.21",
+ "@0x/asset-buyer": "^3.0.5",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/subproviders": "^2.1.9",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"bowser": "^1.9.4",
"copy-to-clipboard": "^3.0.8",
"ethereum-types": "^1.1.4",
@@ -76,7 +76,7 @@
"@types/react-dom": "^16.0.8",
"@types/react-redux": "^6.0.9",
"@types/redux": "^3.6.0",
- "@types/styled-components": "^4.0.1",
+ "@types/styled-components": "4.0.1",
"awesome-typescript-loader": "^5.2.1",
"dotenv-cli": "^1.4.0",
"enzyme": "^3.6.0",
diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts
index 22f0cb6a4..67558c84a 100644
--- a/packages/instant/src/constants.ts
+++ b/packages/instant/src/constants.ts
@@ -16,6 +16,7 @@ export const ONE_SECOND_MS = 1000;
export const ONE_MINUTE_MS = ONE_SECOND_MS * 60;
export const GIT_SHA = process.env.GIT_SHA;
export const NODE_ENV = process.env.NODE_ENV;
+export const SLIPPAGE_PERCENTAGE = 0.2;
export const NPM_PACKAGE_VERSION = process.env.NPM_PACKAGE_VERSION;
export const DEFAULT_UNKOWN_ASSET_NAME = '???';
export const ACCOUNT_UPDATE_INTERVAL_TIME_MS = ONE_SECOND_MS * 5;
diff --git a/packages/instant/src/util/asset.ts b/packages/instant/src/util/asset.ts
index faaeb7c22..b009a327f 100644
--- a/packages/instant/src/util/asset.ts
+++ b/packages/instant/src/util/asset.ts
@@ -1,8 +1,10 @@
-import { AssetBuyerError } from '@0x/asset-buyer';
+import { AssetBuyerError, InsufficientAssetLiquidityError } from '@0x/asset-buyer';
import { AssetProxyId, ObjectMap } from '@0x/types';
+import { BigNumber } from '@0x/utils';
+import { Web3Wrapper } from '@0x/web3-wrapper';
import * as _ from 'lodash';
-import { DEFAULT_UNKOWN_ASSET_NAME } from '../constants';
+import { BIG_NUMBER_ZERO, DEFAULT_UNKOWN_ASSET_NAME } from '../constants';
import { assetDataNetworkMapping } from '../data/asset_data_network_mapping';
import { Asset, AssetMetaData, ERC20Asset, Network, ZeroExInstantError } from '../types';
@@ -111,6 +113,21 @@ export const assetUtils = {
assetBuyerErrorMessage: (asset: ERC20Asset, error: Error): string | undefined => {
if (error.message === AssetBuyerError.InsufficientAssetLiquidity) {
const assetName = assetUtils.bestNameForAsset(asset, 'of this asset');
+ if (
+ error instanceof InsufficientAssetLiquidityError &&
+ error.amountAvailableToFill.greaterThan(BIG_NUMBER_ZERO)
+ ) {
+ const unitAmountAvailableToFill = Web3Wrapper.toUnitAmount(
+ error.amountAvailableToFill,
+ asset.metaData.decimals,
+ );
+ const roundedUnitAmountAvailableToFill = unitAmountAvailableToFill.round(2, BigNumber.ROUND_DOWN);
+
+ if (roundedUnitAmountAvailableToFill.greaterThan(BIG_NUMBER_ZERO)) {
+ return `There are only ${roundedUnitAmountAvailableToFill} ${assetName} available to buy`;
+ }
+ }
+
return `Not enough ${assetName} available`;
} else if (error.message === AssetBuyerError.InsufficientZrxLiquidity) {
return 'Not enough ZRX available';
diff --git a/packages/instant/src/util/buy_quote_updater.ts b/packages/instant/src/util/buy_quote_updater.ts
index 6191c92e3..37974e71c 100644
--- a/packages/instant/src/util/buy_quote_updater.ts
+++ b/packages/instant/src/util/buy_quote_updater.ts
@@ -5,6 +5,7 @@ import * as _ from 'lodash';
import { Dispatch } from 'redux';
import { oc } from 'ts-optchain';
+import { SLIPPAGE_PERCENTAGE } from '../constants';
import { Action, actions } from '../redux/actions';
import { AffiliateInfo, ERC20Asset, QuoteFetchOrigin } from '../types';
import { analytics } from '../util/analytics';
@@ -33,8 +34,12 @@ export const buyQuoteUpdater = {
}
const feePercentage = oc(options.affiliateInfo).feePercentage();
let newBuyQuote: BuyQuote | undefined;
+ const slippagePercentage = SLIPPAGE_PERCENTAGE;
try {
- newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, { feePercentage });
+ newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue, {
+ feePercentage,
+ slippagePercentage,
+ });
} catch (error) {
const errorMessage = assetUtils.assetBuyerErrorMessage(asset, error);
diff --git a/packages/instant/test/util/asset.test.ts b/packages/instant/test/util/asset.test.ts
index fc4e4e2e4..402a556d5 100644
--- a/packages/instant/test/util/asset.test.ts
+++ b/packages/instant/test/util/asset.test.ts
@@ -1,5 +1,6 @@
-import { AssetBuyerError } from '@0x/asset-buyer';
+import { AssetBuyerError, BigNumber, InsufficientAssetLiquidityError } from '@0x/asset-buyer';
import { AssetProxyId, ObjectMap } from '@0x/types';
+import { Web3Wrapper } from '@0x/web3-wrapper';
import { Asset, AssetMetaData, ERC20Asset, ERC20AssetMetaData, Network, ZeroExInstantError } from '../../src/types';
import { assetUtils } from '../../src/util/asset';
@@ -19,6 +20,16 @@ const ZRX_ASSET: ERC20Asset = {
const META_DATA_MAP: ObjectMap<AssetMetaData> = {
[ZRX_ASSET_DATA]: ZRX_META_DATA,
};
+const WAX_ASSET: ERC20Asset = {
+ assetData: '0xf47261b000000000000000000000000039bb259f66e1c59d5abef88375979b4d20d98022',
+ metaData: {
+ assetProxyId: AssetProxyId.ERC20,
+ decimals: 8,
+ primaryColor: '#EDB740',
+ symbol: 'wax',
+ name: 'WAX',
+ },
+};
describe('assetDataUtil', () => {
describe('bestNameForAsset', () => {
@@ -47,13 +58,39 @@ describe('assetDataUtil', () => {
});
});
describe('assetBuyerErrorMessage', () => {
- it('should return message for InsufficientAssetLiquidity', () => {
+ it('should return message for generic InsufficientAssetLiquidity error', () => {
const insufficientAssetError = new Error(AssetBuyerError.InsufficientAssetLiquidity);
expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, insufficientAssetError)).toEqual(
'Not enough ZRX available',
);
});
- it('should return message for InsufficientAssetLiquidity', () => {
+ describe('InsufficientAssetLiquidityError', () => {
+ it('should return custom message for token w/ 18 decimals', () => {
+ const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(20.059), 18);
+ expect(
+ assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)),
+ ).toEqual('There are only 20.05 ZRX available to buy');
+ });
+ it('should return custom message for token w/ 18 decimals and small amount available', () => {
+ const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.01), 18);
+ expect(
+ assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)),
+ ).toEqual('There are only 0.01 ZRX available to buy');
+ });
+ it('should return custom message for token w/ 8 decimals', () => {
+ const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(3), 8);
+ expect(
+ assetUtils.assetBuyerErrorMessage(WAX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)),
+ ).toEqual('There are only 3 WAX available to buy');
+ });
+ it('should return generic message when amount available rounds to zero', () => {
+ const amountAvailable = Web3Wrapper.toBaseUnitAmount(new BigNumber(0.002), 18);
+ expect(
+ assetUtils.assetBuyerErrorMessage(ZRX_ASSET, new InsufficientAssetLiquidityError(amountAvailable)),
+ ).toEqual('Not enough ZRX available');
+ });
+ });
+ it('should return message for InsufficientZrxLiquidity', () => {
const insufficientZrxError = new Error(AssetBuyerError.InsufficientZrxLiquidity);
expect(assetUtils.assetBuyerErrorMessage(ZRX_ASSET, insufficientZrxError)).toEqual(
'Not enough ZRX available',
diff --git a/packages/json-schemas/CHANGELOG.json b/packages/json-schemas/CHANGELOG.json
index 201190145..79435426b 100644
--- a/packages/json-schemas/CHANGELOG.json
+++ b/packages/json-schemas/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "2.1.5",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "2.1.4",
"changes": [
{
diff --git a/packages/json-schemas/CHANGELOG.md b/packages/json-schemas/CHANGELOG.md
index 7e407bdda..6d3373336 100644
--- a/packages/json-schemas/CHANGELOG.md
+++ b/packages/json-schemas/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.5 - _January 9, 2019_
+
+ * Dependencies updated
+
## v2.1.4 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/json-schemas/package.json b/packages/json-schemas/package.json
index 57dd9dc00..5103486db 100644
--- a/packages/json-schemas/package.json
+++ b/packages/json-schemas/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/json-schemas",
- "version": "2.1.4",
+ "version": "2.1.5",
"engines": {
"node": ">=6.12"
},
@@ -46,7 +46,7 @@
},
"devDependencies": {
"@0x/tslint-config": "^2.0.0",
- "@0x/utils": "^2.0.8",
+ "@0x/utils": "^2.1.1",
"@types/lodash.foreach": "^4.5.3",
"@types/lodash.values": "^4.3.3",
"@types/mocha": "^2.2.42",
diff --git a/packages/json-schemas/schemas/asset_pairs_request_opts_schema.json b/packages/json-schemas/schemas/asset_pairs_request_opts_schema.json
index 174a8fdc3..fad0bd371 100644
--- a/packages/json-schemas/schemas/asset_pairs_request_opts_schema.json
+++ b/packages/json-schemas/schemas/asset_pairs_request_opts_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/AssetPairsRequestOpts",
+ "id": "/AssetPairsRequestOptsSchema",
"type": "object",
"properties": {
"assetDataA": { "$ref": "/hexSchema" },
diff --git a/packages/json-schemas/schemas/call_data_schema.json b/packages/json-schemas/schemas/call_data_schema.json
index c5972e8c1..e5e6e3282 100644
--- a/packages/json-schemas/schemas/call_data_schema.json
+++ b/packages/json-schemas/schemas/call_data_schema.json
@@ -4,13 +4,13 @@
"from": { "$ref": "/addressSchema" },
"to": { "$ref": "/addressSchema" },
"value": {
- "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
+ "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumberSchema" }]
},
"gas": {
- "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
+ "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumberSchema" }]
},
"gasPrice": {
- "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
+ "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumberSchema" }]
},
"data": {
"type": "string",
diff --git a/packages/json-schemas/schemas/ec_signature_schema.json b/packages/json-schemas/schemas/ec_signature_schema.json
index bc79ca5e9..52ccfe7bb 100644
--- a/packages/json-schemas/schemas/ec_signature_schema.json
+++ b/packages/json-schemas/schemas/ec_signature_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/ECSignature",
+ "id": "/ecSignatureSchema",
"properties": {
"v": {
"type": "number",
diff --git a/packages/json-schemas/schemas/js_number.json b/packages/json-schemas/schemas/js_number_schema.json
index 6a72d92c0..7df1c4747 100644
--- a/packages/json-schemas/schemas/js_number.json
+++ b/packages/json-schemas/schemas/js_number_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/jsNumber",
+ "id": "/jsNumberSchema",
"type": "number",
"minimum": 0
}
diff --git a/packages/json-schemas/schemas/order_config_request_schema.json b/packages/json-schemas/schemas/order_config_request_schema.json
index ca9b2e30e..19b043e7f 100644
--- a/packages/json-schemas/schemas/order_config_request_schema.json
+++ b/packages/json-schemas/schemas/order_config_request_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/OrderConfigRequest",
+ "id": "/OrderConfigRequestSchema",
"type": "object",
"properties": {
"makerAddress": { "$ref": "/addressSchema" },
diff --git a/packages/json-schemas/schemas/orderbook_request_schema.json b/packages/json-schemas/schemas/orderbook_request_schema.json
index 27848bdcb..5ce6e8ab0 100644
--- a/packages/json-schemas/schemas/orderbook_request_schema.json
+++ b/packages/json-schemas/schemas/orderbook_request_schema.json
@@ -1,9 +1,9 @@
{
- "id": "/OrderBookRequest",
+ "id": "/OrderbookRequestSchema",
"type": "object",
"properties": {
"baseAssetData": { "$ref": "/hexSchema" },
"quoteAssetData": { "$ref": "/hexSchema" }
},
"required": ["baseAssetData", "quoteAssetData"]
-} \ No newline at end of file
+}
diff --git a/packages/json-schemas/schemas/orders_request_opts_schema.json b/packages/json-schemas/schemas/orders_request_opts_schema.json
index 10da51060..4c1b9b4e9 100644
--- a/packages/json-schemas/schemas/orders_request_opts_schema.json
+++ b/packages/json-schemas/schemas/orders_request_opts_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/OrdersRequestOpts",
+ "id": "/OrdersRequestOptsSchema",
"type": "object",
"properties": {
"makerAssetProxyId": { "$ref": "/hexSchema" },
diff --git a/packages/json-schemas/schemas/paged_request_opts_schema.json b/packages/json-schemas/schemas/paged_request_opts_schema.json
index 7cfc73947..f143c28b0 100644
--- a/packages/json-schemas/schemas/paged_request_opts_schema.json
+++ b/packages/json-schemas/schemas/paged_request_opts_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/PagedRequestOpts",
+ "id": "/PagedRequestOptsSchema",
"type": "object",
"properties": {
"page": { "type": "number" },
diff --git a/packages/json-schemas/schemas/request_opts_schema.json b/packages/json-schemas/schemas/request_opts_schema.json
index b50547d18..2206f5016 100644
--- a/packages/json-schemas/schemas/request_opts_schema.json
+++ b/packages/json-schemas/schemas/request_opts_schema.json
@@ -1,5 +1,5 @@
{
- "id": "/RequestOpts",
+ "id": "/RequestOptsSchema",
"type": "object",
"properties": {
"networkId": { "type": "number" }
diff --git a/packages/json-schemas/schemas/tx_data_schema.json b/packages/json-schemas/schemas/tx_data_schema.json
index 4643521ce..8c3daba4e 100644
--- a/packages/json-schemas/schemas/tx_data_schema.json
+++ b/packages/json-schemas/schemas/tx_data_schema.json
@@ -4,13 +4,13 @@
"from": { "$ref": "/addressSchema" },
"to": { "$ref": "/addressSchema" },
"value": {
- "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
+ "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumberSchema" }]
},
"gas": {
- "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
+ "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumberSchema" }]
},
"gasPrice": {
- "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumber" }]
+ "oneOf": [{ "$ref": "/numberSchema" }, { "$ref": "/jsNumberSchema" }]
},
"data": {
"type": "string",
diff --git a/packages/json-schemas/schemas/whole_number_schema.json b/packages/json-schemas/schemas/whole_number_schema.json
index 944ce820e..aa469954c 100644
--- a/packages/json-schemas/schemas/whole_number_schema.json
+++ b/packages/json-schemas/schemas/whole_number_schema.json
@@ -1,5 +1,12 @@
{
"id": "/wholeNumberSchema",
- "type": "string",
- "pattern": "^\\d+$"
+ "anyOf": [
+ {
+ "type": "string",
+ "pattern": "^\\d+$"
+ },
+ {
+ "type": "integer"
+ }
+ ]
}
diff --git a/packages/json-schemas/src/schema_validator.ts b/packages/json-schemas/src/schema_validator.ts
index 3f303137b..43647b594 100644
--- a/packages/json-schemas/src/schema_validator.ts
+++ b/packages/json-schemas/src/schema_validator.ts
@@ -8,12 +8,18 @@ import { schemas } from './schemas';
*/
export class SchemaValidator {
private readonly _validator: Validator;
+ private static _assertSchemaDefined(schema: Schema): void {
+ if (schema === undefined) {
+ throw new Error(`Cannot add undefined schema`);
+ }
+ }
/**
* Instantiates a SchemaValidator instance
*/
constructor() {
this._validator = new Validator();
for (const schema of values(schemas)) {
+ SchemaValidator._assertSchemaDefined(schema);
this._validator.addSchema(schema, schema.id);
}
}
@@ -24,6 +30,7 @@ export class SchemaValidator {
* @param schema The schema to add
*/
public addSchema(schema: Schema): void {
+ SchemaValidator._assertSchemaDefined(schema);
this._validator.addSchema(schema, schema.id);
}
// In order to validate a complex JS object using jsonschema, we must replace any complex
@@ -37,6 +44,7 @@ export class SchemaValidator {
* @returns The results of the validation
*/
public validate(instance: any, schema: Schema): ValidatorResult {
+ SchemaValidator._assertSchemaDefined(schema);
const jsonSchemaCompatibleObject = JSON.parse(JSON.stringify(instance));
return this._validator.validate(jsonSchemaCompatibleObject, schema);
}
diff --git a/packages/json-schemas/src/schemas.ts b/packages/json-schemas/src/schemas.ts
index 050f4e625..9e8eb6959 100644
--- a/packages/json-schemas/src/schemas.ts
+++ b/packages/json-schemas/src/schemas.ts
@@ -8,7 +8,7 @@ import * as ecSignatureSchema from '../schemas/ec_signature_schema.json';
import * as eip712TypedDataSchema from '../schemas/eip712_typed_data_schema.json';
import * as hexSchema from '../schemas/hex_schema.json';
import * as indexFilterValuesSchema from '../schemas/index_filter_values_schema.json';
-import * as jsNumber from '../schemas/js_number.json';
+import * as jsNumber from '../schemas/js_number_schema.json';
import * as numberSchema from '../schemas/number_schema.json';
import * as orderCancellationRequestsSchema from '../schemas/order_cancel_schema.json';
import * as orderConfigRequestSchema from '../schemas/order_config_request_schema.json';
diff --git a/packages/json-schemas/tsconfig.json b/packages/json-schemas/tsconfig.json
index ec573290c..7d7ce1d7e 100644
--- a/packages/json-schemas/tsconfig.json
+++ b/packages/json-schemas/tsconfig.json
@@ -42,7 +42,7 @@
"./schemas/relayer_api_orders_schema.json",
"./schemas/signed_orders_schema.json",
"./schemas/token_schema.json",
- "./schemas/js_number.json",
+ "./schemas/js_number_schema.json",
"./schemas/zero_ex_transaction_schema.json",
"./schemas/tx_data_schema.json",
"./schemas/index_filter_values_schema.json",
diff --git a/packages/metacoin/package.json b/packages/metacoin/package.json
index 33fc16a3e..0081e8be1 100644
--- a/packages/metacoin/package.json
+++ b/packages/metacoin/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/metacoin",
- "version": "0.0.32",
+ "version": "0.0.33",
"engines": {
"node": ">=6.12"
},
@@ -29,17 +29,15 @@
"author": "",
"license": "Apache-2.0",
"dependencies": {
- "@0x/abi-gen": "^1.0.19",
+ "@0x/abi-gen": "^1.0.20",
"@0x/abi-gen-templates": "^1.0.1",
- "@0x/base-contract": "^3.0.10",
- "@0x/sol-coverage": "^1.0.0",
- "@0x/sol-profiler": "^1.0.0",
- "@0x/subproviders": "^2.1.8",
+ "@0x/base-contract": "^3.0.11",
+ "@0x/subproviders": "^2.1.9",
"@0x/tslint-config": "^2.0.0",
- "@0x/types": "^1.4.1",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/mocha": "^5.2.2",
"copyfiles": "^2.0.0",
"ethereum-types": "^1.1.4",
@@ -48,8 +46,8 @@
"run-s": "^0.0.0"
},
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
- "@0x/sol-compiler": "^1.1.16",
+ "@0x/dev-utils": "^1.0.22",
+ "@0x/sol-compiler": "^2.0.0",
"chai": "^4.0.1",
"chai-as-promised": "^7.1.0",
"chai-bignumber": "^2.0.1",
diff --git a/packages/migrations/.gitignore b/packages/migrations/.gitignore
new file mode 100644
index 000000000..4de81c5a8
--- /dev/null
+++ b/packages/migrations/.gitignore
@@ -0,0 +1,2 @@
+*.zip
+0x_ganache_snapshot
diff --git a/packages/migrations/CHANGELOG.json b/packages/migrations/CHANGELOG.json
index cee64a69f..e09106bcd 100644
--- a/packages/migrations/CHANGELOG.json
+++ b/packages/migrations/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Added migrations for Dutch Auction contract",
"pr": 1465
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "2.2.2",
diff --git a/packages/migrations/CHANGELOG.md b/packages/migrations/CHANGELOG.md
index 0b7b9a364..420769187 100644
--- a/packages/migrations/CHANGELOG.md
+++ b/packages/migrations/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.3.0 - _January 9, 2019_
+
+ * Added migrations for Dutch Auction contract (#1465)
+
## v2.2.2 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/migrations/Dockerfile b/packages/migrations/Dockerfile
new file mode 100644
index 000000000..c4d6128c2
--- /dev/null
+++ b/packages/migrations/Dockerfile
@@ -0,0 +1,15 @@
+FROM mhart/alpine-node:10
+
+WORKDIR /usr/src/app
+
+RUN npm install -g ganache-cli@6.1.6
+
+ENV MNEMONIC "concert load couple harbor equip island argue ramp clarify fence smart topic"
+ENV NETWORK_ID 50
+ENV VERSION "latest"
+ENV SNAPSHOT_HOST "http://ganache-snapshots.0x.org.s3-website.us-east-2.amazonaws.com"
+ENV SNAPSHOT_NAME "0x_ganache_snapshot"
+EXPOSE 8545
+
+CMD [ "sh", "-c", "wget $SNAPSHOT_HOST/$SNAPSHOT_NAME-$VERSION.zip -O snapshot.zip && unzip snapshot.zip && ganache-cli --gasLimit 10000000 --db $SNAPSHOT_NAME --noVMErrorsOnRPCResponse -p 8545 --networkId \"$NETWORK_ID\" -m \"$MNEMONIC\" -h 0.0.0.0"]
+
diff --git a/packages/migrations/README.md b/packages/migrations/README.md
index b90d730eb..1e8b92bf8 100644
--- a/packages/migrations/README.md
+++ b/packages/migrations/README.md
@@ -57,3 +57,44 @@ In order to migrate the V2 0x smart contracts to TestRPC/Ganache running at `htt
```bash
yarn migrate:v2
```
+
+### Publish
+
+#### 0x Ganache Snapshot
+
+The 0x Ganache snapshot can be generated and published in this package. In order to build the snapshot for this version of migrations run:
+
+```bash
+yarn build:snapshot
+```
+
+This will run the migrations in Ganache and output a zip file to be uploaded to the s3 bucket. For example, after running this command you will have created `0x_ganache_snapshot-2.2.2.zip`. To publish the zip file to the s3 bucket run:
+
+```bash
+yarn publish:snapshot
+```
+
+This snapshot will now be publicly available at http://ganache-snapshots.0x.org.s3.amazonaws.com/0x_ganache_snapshot-latest.zip and also versioned with the package.json version.
+
+#### 0x Ganache Docker Image
+
+We also publish a simple docker image which downloads the latest snapshot, extracts and runs Ganache. This is not required to be built when migrations change as it always downloads and runs the latest zip file. If you have made changes to the Dockerfile then a publish of the image is required. To do this run:
+
+```bash
+yarn build:snapshot:docker
+yarn publish:snapshot:docker
+```
+
+The result is a published docker image to the 0xorg docker registry. To start the docker image run:
+
+```bash
+docker run -p 8545:8545 -ti 0xorg/ganache-cli:latest
+```
+
+This will pull the latest zip in the s3 bucket, extract and start Ganache with the snapshot.
+
+In the event you need a specific version of the published Ganache snapshot run the following specifying the VERSION environment variable:
+
+```bash
+docker run -e VERSION=2.2.2 -p 8545:8545 -ti 0xorg/ganache-cli:latest
+```
diff --git a/packages/migrations/package.json b/packages/migrations/package.json
index 72ffe67b2..774236ab4 100644
--- a/packages/migrations/package.json
+++ b/packages/migrations/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/migrations",
- "version": "2.2.2",
+ "version": "2.3.0",
"engines": {
"node": ">=6.12"
},
@@ -10,13 +10,22 @@
"scripts": {
"build": "tsc -b",
"build:ci": "yarn build",
- "clean": "shx rm -rf lib",
+ "clean": "shx rm -rf lib ${npm_package_config_snapshot_name} ${npm_package_config_snapshot_name}-*.zip",
"lint": "tslint --format stylish --project .",
"migrate:v2": "run-s build script:migrate:v2",
+ "migrate:v2:snapshot": "run-s build script:migrate:v2:snapshot",
"script:migrate:v2": "node ./lib/migrate.js",
- "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES"
+ "script:migrate:v2:snapshot": "node ./lib/migrate_snapshot.js",
+ "docs:json": "typedoc --excludePrivate --excludeExternals --target ES5 --tsconfig typedoc-tsconfig.json --json $JSON_FILE_PATH $PROJECT_FILES",
+ "build:snapshot": "rm -rf ${npm_package_config_snapshot_name} && yarn migrate:v2:snapshot && zip -r \"${npm_package_config_snapshot_name}-${npm_package_version}.zip\" ${npm_package_config_snapshot_name}",
+ "build:snapshot:docker": "docker build --tag ${npm_package_config_docker_snapshot_name}:${npm_package_version} --tag ${npm_package_config_docker_snapshot_name}:latest .",
+ "publish:snapshot": "aws s3 cp ${npm_package_config_snapshot_name}-${npm_package_version}.zip ${npm_package_config_s3_snapshot_bucket} && aws s3 cp ${npm_package_config_s3_snapshot_bucket}/${npm_package_config_snapshot_name}-${npm_package_version}.zip ${npm_package_config_s3_snapshot_bucket}/${npm_package_config_snapshot_name}-latest.zip",
+ "publish:snapshot:docker": "docker push ${npm_package_config_docker_snapshot_name}:latest"
},
"config": {
+ "s3_snapshot_bucket": "s3://ganache-snapshots.0x.org",
+ "docker_snapshot_name": "0xorg/ganache-cli",
+ "snapshot_name": "0x_ganache_snapshot",
"postpublish": {
"assets": []
}
@@ -26,9 +35,9 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
+ "@0x/dev-utils": "^1.0.22",
"@0x/tslint-config": "^2.0.0",
- "@0x/types": "^1.4.1",
+ "@0x/types": "^1.5.0",
"@types/yargs": "^10.0.0",
"make-promises-safe": "^1.1.0",
"npm-run-all": "^4.1.2",
@@ -39,16 +48,16 @@
"yargs": "^10.0.3"
},
"dependencies": {
- "@0x/abi-gen-wrappers": "^2.0.2",
- "@0x/base-contract": "^3.0.10",
- "@0x/contract-addresses": "^2.0.0",
- "@0x/contract-artifacts": "^1.1.2",
- "@0x/order-utils": "^3.0.7",
- "@0x/sol-compiler": "^1.1.16",
- "@0x/subproviders": "^2.1.8",
+ "@0x/abi-gen-wrappers": "^2.1.0",
+ "@0x/base-contract": "^3.0.11",
+ "@0x/contract-addresses": "^2.1.0",
+ "@0x/contract-artifacts": "^1.2.0",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/sol-compiler": "^2.0.0",
+ "@0x/subproviders": "^2.1.9",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@ledgerhq/hw-app-eth": "^4.3.0",
"ethereum-types": "^1.1.4",
"ethers": "~4.0.4",
diff --git a/packages/migrations/src/migrate_snapshot.ts b/packages/migrations/src/migrate_snapshot.ts
new file mode 100644
index 000000000..13fb063da
--- /dev/null
+++ b/packages/migrations/src/migrate_snapshot.ts
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+import { devConstants, web3Factory } from '@0x/dev-utils';
+import { logUtils } from '@0x/utils';
+import { Provider } from 'ethereum-types';
+import * as fs from 'fs';
+import * as _ from 'lodash';
+import * as path from 'path';
+
+import { runMigrationsAsync } from './migration';
+
+(async () => {
+ let providerConfigs;
+ let provider: Provider;
+ let txDefaults;
+ const packageJsonPath = path.join(__dirname, '..', 'package.json');
+ const packageJsonString = fs.readFileSync(packageJsonPath, 'utf8');
+ const packageJson = JSON.parse(packageJsonString);
+ if (_.isUndefined(packageJson.config) || _.isUndefined(packageJson.config.snapshot_name)) {
+ throw new Error(`Did not find 'snapshot_name' key in package.json config`);
+ }
+
+ providerConfigs = { shouldUseInProcessGanache: true, ganacheDatabasePath: packageJson.config.snapshot_name };
+ provider = web3Factory.getRpcProvider(providerConfigs);
+ txDefaults = {
+ from: devConstants.TESTRPC_FIRST_ADDRESS,
+ };
+ await runMigrationsAsync(provider, txDefaults);
+ process.exit(0);
+})().catch(err => {
+ logUtils.log(err);
+ process.exit(1);
+});
diff --git a/packages/monorepo-scripts/package.json b/packages/monorepo-scripts/package.json
index 0483e87c8..3286b8412 100644
--- a/packages/monorepo-scripts/package.json
+++ b/packages/monorepo-scripts/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@0x/monorepo-scripts",
- "version": "1.0.15",
+ "version": "1.0.16",
"engines": {
"node": ">=6.12"
},
@@ -47,6 +47,7 @@
"typescript": "3.0.1"
},
"dependencies": {
+ "@0x/utils": "^2.0.8",
"@lerna/batch-packages": "^3.0.0-beta.18",
"@types/depcheck": "^0.6.0",
"async-child-process": "^1.1.1",
diff --git a/packages/monorepo-scripts/src/constants.ts b/packages/monorepo-scripts/src/constants.ts
index acb4b211e..c15bcabf4 100644
--- a/packages/monorepo-scripts/src/constants.ts
+++ b/packages/monorepo-scripts/src/constants.ts
@@ -5,5 +5,7 @@ export const constants = {
stagingWebsite: 'http://staging-0xproject.s3-website-us-east-1.amazonaws.com',
lernaExecutable: path.join('node_modules', '@0x-lerna-fork', 'lerna', 'cli.js'),
githubPersonalAccessToken: process.env.GITHUB_PERSONAL_ACCESS_TOKEN_0X_JS,
+ discordAlertWebhookUrl: process.env.DISCORD_GITHUB_RELEASE_WEBHOOK_URL,
+ releasesUrl: 'https://github.com/0xProject/0x-monorepo/releases',
dependenciesUpdatedMessage: 'Dependencies updated',
};
diff --git a/packages/monorepo-scripts/src/doc_gen_configs.ts b/packages/monorepo-scripts/src/doc_gen_configs.ts
index dfbe98028..7a4e6bb2c 100644
--- a/packages/monorepo-scripts/src/doc_gen_configs.ts
+++ b/packages/monorepo-scripts/src/doc_gen_configs.ts
@@ -9,6 +9,7 @@ export const docGenConfigs: DocGenConfigs = {
Array: 'https://developer.mozilla.org/pt-PT/docs/Web/JavaScript/Reference/Global_Objects/Array',
BigNumber: 'http://mikemcl.github.io/bignumber.js',
Error: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error',
+ ErrorConstructor: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error',
Buffer: 'https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/node/v9/index.d.ts#L262',
'solc.StandardContractOutput':
'https://solidity.readthedocs.io/en/v0.4.24/using-the-compiler.html#output-description',
diff --git a/packages/monorepo-scripts/src/prepublish_checks.ts b/packages/monorepo-scripts/src/prepublish_checks.ts
index 36e61714b..82eaf5cf9 100644
--- a/packages/monorepo-scripts/src/prepublish_checks.ts
+++ b/packages/monorepo-scripts/src/prepublish_checks.ts
@@ -140,6 +140,13 @@ async function checkPublishRequiredSetupAsync(): Promise<void> {
);
}
+ // Check to see if discord URL is set up
+ if (_.isUndefined(constants.discordAlertWebhookUrl)) {
+ throw new Error(
+ 'You must have a discord webhook URL set to an envVar named `DISCORD_GITHUB_RELEASE_WEBHOOK_URL`. Add it then try again.',
+ );
+ }
+
// Check Yarn version is 1.X
utils.log('Checking the yarn version...');
const result = await execAsync(`yarn --version`);
diff --git a/packages/monorepo-scripts/src/publish.ts b/packages/monorepo-scripts/src/publish.ts
index 854a72b86..e0602a74f 100644
--- a/packages/monorepo-scripts/src/publish.ts
+++ b/packages/monorepo-scripts/src/publish.ts
@@ -14,6 +14,7 @@ import { constants } from './constants';
import { Package, PackageToNextVersion, VersionChangelog } from './types';
import { changelogUtils } from './utils/changelog_utils';
import { configs } from './utils/configs';
+import { alertDiscordAsync } from './utils/discord';
import { DocGenerateAndUploadUtils } from './utils/doc_generate_and_upload_utils';
import { publishReleaseNotesAsync } from './utils/github_release_utils';
import { utils } from './utils/utils';
@@ -84,7 +85,16 @@ async function confirmAsync(message: string): Promise<void> {
await generateAndUploadDocJsonsAsync(packagesWithDocs, isStaging, shouldUploadDocs);
}
const isDryRun = configs.IS_LOCAL_PUBLISH;
- await publishReleaseNotesAsync(updatedPublicPackages, isDryRun);
+ const releaseNotes = await publishReleaseNotesAsync(updatedPublicPackages, isDryRun);
+ utils.log('Published release notes');
+
+ if (!isDryRun && releaseNotes) {
+ try {
+ await alertDiscordAsync(releaseNotes);
+ } catch (e) {
+ utils.log("Publish successful, but couldn't auto-alert discord (", e.message, '), Please alert manually.');
+ }
+ }
})().catch(err => {
utils.log(err);
process.exit(1);
diff --git a/packages/monorepo-scripts/src/utils/discord.ts b/packages/monorepo-scripts/src/utils/discord.ts
new file mode 100644
index 000000000..3a0458769
--- /dev/null
+++ b/packages/monorepo-scripts/src/utils/discord.ts
@@ -0,0 +1,26 @@
+import { fetchAsync } from '@0x/utils';
+
+import { constants } from '../constants';
+
+import { utils } from './utils';
+
+export const alertDiscordAsync = async (releaseNotes: string): Promise<void> => {
+ const webhookUrl = constants.discordAlertWebhookUrl;
+ if (webhookUrl === undefined) {
+ throw new Error("No discord webhook url, can't alert");
+ }
+
+ utils.log('Alerting discord...');
+ const payload = {
+ content: `New monorepo package released! View at ${constants.releasesUrl} \n\n ${releaseNotes}`,
+ };
+ await fetchAsync(webhookUrl, {
+ method: 'POST',
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(payload),
+ });
+ return;
+};
diff --git a/packages/monorepo-scripts/src/utils/github_release_utils.ts b/packages/monorepo-scripts/src/utils/github_release_utils.ts
index e63244b46..48704f3aa 100644
--- a/packages/monorepo-scripts/src/utils/github_release_utils.ts
+++ b/packages/monorepo-scripts/src/utils/github_release_utils.ts
@@ -12,7 +12,10 @@ import { utils } from './utils';
const publishReleaseAsync = promisify(publishRelease);
// tslint:disable-next-line:completed-docs
-export async function publishReleaseNotesAsync(packagesToPublish: Package[], isDryRun: boolean): Promise<void> {
+export async function publishReleaseNotesAsync(
+ packagesToPublish: Package[],
+ isDryRun: boolean,
+): Promise<string | undefined> {
// Git push a tag representing this publish (publish-{commit-hash}) (truncate hash)
const result = await execAsync('git log -n 1 --pretty=format:"%H"', { cwd: constants.monorepoRootPath });
const latestGitCommit = result.stdout;
@@ -75,6 +78,8 @@ export async function publishReleaseNotesAsync(packagesToPublish: Package[], isD
utils.log('Publishing release notes ', releaseName, '...');
await publishReleaseAsync(publishReleaseConfigs);
+
+ return aggregateNotes;
}
// Asset paths should described from the monorepo root. This method prefixes
diff --git a/packages/order-utils/CHANGELOG.json b/packages/order-utils/CHANGELOG.json
index 292f7a57b..d3f15f092 100644
--- a/packages/order-utils/CHANGELOG.json
+++ b/packages/order-utils/CHANGELOG.json
@@ -7,7 +7,8 @@
"Use new ABI encoder, add encoding/decoding logic for MultiAsset assetData, and add information to return values in orderStateUtils",
"pr": 1363
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "3.0.7",
diff --git a/packages/order-utils/CHANGELOG.md b/packages/order-utils/CHANGELOG.md
index bc8b48767..eb36616d1 100644
--- a/packages/order-utils/CHANGELOG.md
+++ b/packages/order-utils/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v3.1.0 - _January 9, 2019_
+
+ * Use new ABI encoder, add encoding/decoding logic for MultiAsset assetData, and add information to return values in orderStateUtils (#1363)
+
## v3.0.7 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/order-utils/package.json b/packages/order-utils/package.json
index 400c9b66f..e59ea664f 100644
--- a/packages/order-utils/package.json
+++ b/packages/order-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/order-utils",
- "version": "3.0.7",
+ "version": "3.1.0",
"engines": {
"node": ">=6.12"
},
@@ -35,7 +35,7 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/order-utils/README.md",
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
+ "@0x/dev-utils": "^1.0.22",
"@0x/tslint-config": "^2.0.0",
"@types/bn.js": "^4.11.0",
"@types/lodash": "4.14.104",
@@ -53,15 +53,15 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/abi-gen-wrappers": "^2.0.2",
- "@0x/assert": "^1.0.20",
- "@0x/base-contract": "^3.0.10",
- "@0x/contract-artifacts": "^1.1.2",
- "@0x/json-schemas": "^2.1.4",
- "@0x/types": "^1.4.1",
+ "@0x/abi-gen-wrappers": "^2.1.0",
+ "@0x/assert": "^1.0.21",
+ "@0x/base-contract": "^3.0.11",
+ "@0x/contract-artifacts": "^1.2.0",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/node": "*",
"bn.js": "^4.11.8",
"ethereum-types": "^1.1.4",
diff --git a/packages/order-watcher/CHANGELOG.json b/packages/order-watcher/CHANGELOG.json
index 4cfecd034..afd523f88 100644
--- a/packages/order-watcher/CHANGELOG.json
+++ b/packages/order-watcher/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Add support for `MultiAssetProxy`",
"pr": 1363
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "2.3.0",
diff --git a/packages/order-watcher/CHANGELOG.md b/packages/order-watcher/CHANGELOG.md
index 4e49b4637..600b9fa6f 100644
--- a/packages/order-watcher/CHANGELOG.md
+++ b/packages/order-watcher/CHANGELOG.md
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.4.0 - _January 9, 2019_
+
+ * Add support for `MultiAssetProxy` (#1363)
+
+## v2.3.0 - _Invalid date_
+
+ * Added a WebSocket interface to OrderWatcher so that it can be used by a client written in any language (#1427)
+
## v2.2.8 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/order-watcher/Dockerfile b/packages/order-watcher/Dockerfile
new file mode 100644
index 000000000..3ffa1b72f
--- /dev/null
+++ b/packages/order-watcher/Dockerfile
@@ -0,0 +1,13 @@
+FROM node
+
+WORKDIR /order-watcher
+
+COPY package.json .
+RUN npm i
+RUN npm install forever -g
+
+COPY . .
+
+EXPOSE 8080
+
+CMD ["forever", "./lib/src/server.js"]
diff --git a/packages/order-watcher/package.json b/packages/order-watcher/package.json
index 16a46294e..5919759dd 100644
--- a/packages/order-watcher/package.json
+++ b/packages/order-watcher/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/order-watcher",
- "version": "2.2.8",
+ "version": "2.4.0",
"description": "An order watcher daemon that watches for order validity",
"keywords": [
"0x",
@@ -33,8 +33,9 @@
"node": ">=6.0.0"
},
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
- "@0x/migrations": "^2.2.2",
+ "@0x/dev-utils": "^1.0.22",
+ "@0x/migrations": "^2.3.0",
+ "@0x/subproviders": "^2.1.9",
"@0x/tslint-config": "^2.0.0",
"@types/bintrees": "^1.0.2",
"@types/lodash": "4.14.104",
@@ -57,19 +58,19 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/abi-gen-wrappers": "^2.0.2",
- "@0x/assert": "^1.0.20",
- "@0x/base-contract": "^3.0.10",
- "@0x/contract-addresses": "^2.0.0",
- "@0x/contract-artifacts": "^1.1.2",
- "@0x/contract-wrappers": "^4.1.3",
- "@0x/fill-scenarios": "^1.0.16",
- "@0x/json-schemas": "^2.1.4",
- "@0x/order-utils": "^3.0.7",
- "@0x/types": "^1.4.1",
+ "@0x/abi-gen-wrappers": "^2.1.0",
+ "@0x/assert": "^1.0.21",
+ "@0x/base-contract": "^3.0.11",
+ "@0x/contract-addresses": "^2.1.0",
+ "@0x/contract-artifacts": "^1.2.0",
+ "@0x/contract-wrappers": "^4.2.0",
+ "@0x/fill-scenarios": "^1.1.0",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"bintrees": "^1.0.2",
"ethereum-types": "^1.1.4",
"ethereumjs-blockstream": "6.0.0",
diff --git a/packages/order-watcher/src/server.ts b/packages/order-watcher/src/server.ts
new file mode 100644
index 000000000..1d31e87ab
--- /dev/null
+++ b/packages/order-watcher/src/server.ts
@@ -0,0 +1,44 @@
+import { getContractAddressesForNetworkOrThrow } from '@0x/contract-addresses';
+import { RPCSubprovider, Web3ProviderEngine } from '@0x/subproviders';
+import * as _ from 'lodash';
+
+import { OrderWatcherWebSocketServer } from './order_watcher/order_watcher_web_socket_server';
+
+const GANACHE_NETWORK_ID = 50;
+const DEFAULT_RPC_URL = 'http://localhost:8545';
+
+const provider = new Web3ProviderEngine();
+const jsonRpcUrl = process.env.JSON_RPC_URL || DEFAULT_RPC_URL;
+const rpcSubprovider = new RPCSubprovider(jsonRpcUrl);
+provider.addProvider(rpcSubprovider);
+provider.start();
+
+const networkId = process.env.NETWORK_ID !== undefined ? _.parseInt(process.env.NETWORK_ID) : GANACHE_NETWORK_ID;
+
+const contractAddressesString = process.env.contractAddresses;
+const contractAddressesIfExists =
+ contractAddressesString === undefined
+ ? getContractAddressesForNetworkOrThrow(networkId)
+ : JSON.parse(contractAddressesString);
+
+const orderWatcherConfig: any = {
+ isVerbose: process.env.IS_VERBOSE === 'true',
+};
+const orderExpirationCheckingIntervalMs = process.env.ORDER_EXPIRATION_CHECKING_INTERVAL_MS;
+if (orderExpirationCheckingIntervalMs !== undefined) {
+ orderWatcherConfig.orderExpirationCheckingIntervalMs = _.parseInt(orderExpirationCheckingIntervalMs);
+}
+const eventPollingIntervalMs = process.env.EVENT_POLLING_INTERVAL_MS;
+if (eventPollingIntervalMs !== undefined) {
+ orderWatcherConfig.eventPollingIntervalMs = _.parseInt(eventPollingIntervalMs);
+}
+const expirationMarginMs = process.env.EXPIRATION_MARGIN_MS;
+if (expirationMarginMs !== undefined) {
+ orderWatcherConfig.expirationMarginMs = _.parseInt(expirationMarginMs);
+}
+const cleanupJobIntervalMs = process.env.CLEANUP_JOB_INTERVAL_MS;
+if (cleanupJobIntervalMs !== undefined) {
+ orderWatcherConfig.cleanupJobIntervalMs = _.parseInt(cleanupJobIntervalMs);
+}
+const wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddressesIfExists, orderWatcherConfig);
+wsServer.start();
diff --git a/packages/order-watcher/test/order_watcher_web_socket_server_test.ts b/packages/order-watcher/test/order_watcher_web_socket_server_test.ts
index 6894f42fb..36135f65c 100644
--- a/packages/order-watcher/test/order_watcher_web_socket_server_test.ts
+++ b/packages/order-watcher/test/order_watcher_web_socket_server_test.ts
@@ -1,9 +1,10 @@
+import { ContractAddresses } from '@0x/contract-addresses';
import { ContractWrappers } from '@0x/contract-wrappers';
import { tokenUtils } from '@0x/contract-wrappers/lib/test/utils/token_utils';
import { BlockchainLifecycle } from '@0x/dev-utils';
import { FillScenarios } from '@0x/fill-scenarios';
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
-import { ExchangeContractErrs, OrderStateInvalid, OrderStateValid, SignedOrder } from '@0x/types';
+import { ExchangeContractErrs, OrderStateInvalid, SignedOrder } from '@0x/types';
import { BigNumber, logUtils } from '@0x/utils';
import { Web3Wrapper } from '@0x/web3-wrapper';
import * as chai from 'chai';
@@ -44,14 +45,16 @@ describe('OrderWatcherWebSocketServer', async () => {
let orderHash: string;
let addOrderPayload: AddOrderRequest;
let removeOrderPayload: RemoveOrderRequest;
+ let networkId: number;
+ let contractAddresses: ContractAddresses;
const decimals = constants.ZRX_DECIMALS;
const fillableAmount = Web3Wrapper.toBaseUnitAmount(new BigNumber(5), decimals);
before(async () => {
// Set up constants
- const contractAddresses = await migrateOnceAsync();
+ contractAddresses = await migrateOnceAsync();
await blockchainLifecycle.startAsync();
- const networkId = constants.TESTRPC_NETWORK_ID;
+ networkId = constants.TESTRPC_NETWORK_ID;
const config = {
networkId,
contractAddresses,
@@ -93,17 +96,16 @@ describe('OrderWatcherWebSocketServer', async () => {
method: OrderWatcherMethod.RemoveOrder,
params: { orderHash },
};
-
- // Prepare OrderWatcher WebSocket server
- const orderWatcherConfig = {
- isVerbose: true,
- };
- wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddresses, orderWatcherConfig);
});
after(async () => {
await blockchainLifecycle.revertAsync();
});
beforeEach(async () => {
+ // Prepare OrderWatcher WebSocket server
+ const orderWatcherConfig = {
+ isVerbose: true,
+ };
+ wsServer = new OrderWatcherWebSocketServer(provider, networkId, contractAddresses, orderWatcherConfig);
wsServer.start();
await blockchainLifecycle.startAsync();
wsClient = new WebSocket.w3cwebsocket('ws://127.0.0.1:8080/');
@@ -260,7 +262,9 @@ describe('OrderWatcherWebSocketServer', async () => {
id: 1,
jsonrpc: '2.0',
method: 'ADD_ORDER',
- signedOrder: nonZeroMakerFeeSignedOrder,
+ params: {
+ signedOrder: nonZeroMakerFeeSignedOrder,
+ },
};
// Set up a second client and have it add the order
@@ -278,15 +282,15 @@ describe('OrderWatcherWebSocketServer', async () => {
// Check that both clients receive the emitted event by awaiting the onMessageAsync promises
let updateMsg = await clientOneOnMessagePromise;
let updateData = JSON.parse(updateMsg.data);
- let orderState = updateData.result as OrderStateValid;
- expect(orderState.isValid).to.be.true();
- expect(orderState.orderRelevantState.makerFeeProxyAllowance).to.be.eq('0');
+ let orderState = updateData.result as OrderStateInvalid;
+ expect(orderState.isValid).to.be.false();
+ expect(orderState.error).to.be.eq('INSUFFICIENT_MAKER_FEE_ALLOWANCE');
updateMsg = await clientTwoOnMessagePromise;
updateData = JSON.parse(updateMsg.data);
- orderState = updateData.result as OrderStateValid;
- expect(orderState.isValid).to.be.true();
- expect(orderState.orderRelevantState.makerFeeProxyAllowance).to.be.eq('0');
+ orderState = updateData.result as OrderStateInvalid;
+ expect(orderState.isValid).to.be.false();
+ expect(orderState.error).to.be.eq('INSUFFICIENT_MAKER_FEE_ALLOWANCE');
wsClientTwo.close();
logUtils.log(`${new Date()} [Client] Closed.`);
diff --git a/packages/pipeline/migrations/1545440485644-CreateCopperTables.ts b/packages/pipeline/migrations/1545440485644-CreateCopperTables.ts
new file mode 100644
index 000000000..64bf70af4
--- /dev/null
+++ b/packages/pipeline/migrations/1545440485644-CreateCopperTables.ts
@@ -0,0 +1,103 @@
+import { MigrationInterface, QueryRunner, Table } from 'typeorm';
+
+const leads = new Table({
+ name: 'raw.copper_leads',
+ columns: [
+ { name: 'id', type: 'bigint', isPrimary: true },
+ { name: 'name', type: 'varchar', isNullable: true },
+ { name: 'first_name', type: 'varchar', isNullable: true },
+ { name: 'last_name', type: 'varchar', isNullable: true },
+ { name: 'middle_name', type: 'varchar', isNullable: true },
+ { name: 'assignee_id', type: 'bigint', isNullable: true },
+ { name: 'company_name', type: 'varchar', isNullable: true },
+ { name: 'customer_source_id', type: 'bigint', isNullable: true },
+ { name: 'monetary_value', type: 'integer', isNullable: true },
+ { name: 'status', type: 'varchar' },
+ { name: 'status_id', type: 'bigint' },
+ { name: 'title', type: 'varchar', isNullable: true },
+ { name: 'date_created', type: 'bigint' },
+ { name: 'date_modified', type: 'bigint', isPrimary: true },
+ ],
+});
+const activities = new Table({
+ name: 'raw.copper_activities',
+ columns: [
+ { name: 'id', type: 'bigint', isPrimary: true },
+ { name: 'parent_id', type: 'bigint' },
+ { name: 'parent_type', type: 'varchar' },
+ { name: 'type_id', type: 'bigint' },
+ { name: 'type_category', type: 'varchar' },
+ { name: 'type_name', type: 'varchar', isNullable: true },
+ { name: 'user_id', type: 'bigint' },
+ { name: 'old_value_id', type: 'bigint', isNullable: true },
+ { name: 'old_value_name', type: 'varchar', isNullable: true },
+ { name: 'new_value_id', type: 'bigint', isNullable: true },
+ { name: 'new_value_name', type: 'varchar', isNullable: true },
+ { name: 'date_created', type: 'bigint' },
+ { name: 'date_modified', type: 'bigint', isPrimary: true },
+ ],
+});
+
+const opportunities = new Table({
+ name: 'raw.copper_opportunities',
+ columns: [
+ { name: 'id', type: 'bigint', isPrimary: true },
+ { name: 'name', type: 'varchar' },
+ { name: 'assignee_id', isNullable: true, type: 'bigint' },
+ { name: 'close_date', isNullable: true, type: 'varchar' },
+ { name: 'company_id', isNullable: true, type: 'bigint' },
+ { name: 'company_name', isNullable: true, type: 'varchar' },
+ { name: 'customer_source_id', isNullable: true, type: 'bigint' },
+ { name: 'loss_reason_id', isNullable: true, type: 'bigint' },
+ { name: 'pipeline_id', type: 'bigint' },
+ { name: 'pipeline_stage_id', type: 'bigint' },
+ { name: 'primary_contact_id', isNullable: true, type: 'bigint' },
+ { name: 'priority', isNullable: true, type: 'varchar' },
+ { name: 'status', type: 'varchar' },
+ { name: 'interaction_count', type: 'bigint' },
+ { name: 'monetary_value', isNullable: true, type: 'integer' },
+ { name: 'win_probability', isNullable: true, type: 'integer' },
+ { name: 'date_created', type: 'bigint' },
+ { name: 'date_modified', type: 'bigint', isPrimary: true },
+ { name: 'custom_fields', type: 'jsonb' },
+ ],
+});
+
+const activityTypes = new Table({
+ name: 'raw.copper_activity_types',
+ columns: [
+ { name: 'id', type: 'bigint', isPrimary: true },
+ { name: 'category', type: 'varchar' },
+ { name: 'name', type: 'varchar' },
+ { name: 'is_disabled', type: 'boolean', isNullable: true },
+ { name: 'count_as_interaction', type: 'boolean', isNullable: true },
+ ],
+});
+
+const customFields = new Table({
+ name: 'raw.copper_custom_fields',
+ columns: [
+ { name: 'id', type: 'bigint', isPrimary: true },
+ { name: 'name', type: 'varchar' },
+ { name: 'data_type', type: 'varchar' },
+ { name: 'field_type', type: 'varchar', isNullable: true },
+ ],
+});
+
+export class CreateCopperTables1544055699284 implements MigrationInterface {
+ public async up(queryRunner: QueryRunner): Promise<any> {
+ await queryRunner.createTable(leads);
+ await queryRunner.createTable(activities);
+ await queryRunner.createTable(opportunities);
+ await queryRunner.createTable(activityTypes);
+ await queryRunner.createTable(customFields);
+ }
+
+ public async down(queryRunner: QueryRunner): Promise<any> {
+ await queryRunner.dropTable(leads.name);
+ await queryRunner.dropTable(activities.name);
+ await queryRunner.dropTable(opportunities.name);
+ await queryRunner.dropTable(activityTypes.name);
+ await queryRunner.dropTable(customFields.name);
+ }
+}
diff --git a/packages/pipeline/package.json b/packages/pipeline/package.json
index ab73642ec..47150300d 100644
--- a/packages/pipeline/package.json
+++ b/packages/pipeline/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/pipeline",
- "version": "1.0.2",
+ "version": "1.0.3",
"private": true,
"description": "Data pipeline for offline analysis",
"scripts": {
@@ -16,7 +16,7 @@
"test:coverage": "nyc npm run test:all --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"clean": "shx rm -rf lib",
- "lint": "tslint --project . --format stylish --exclude ./migrations/**/*",
+ "lint": "tslint --project . --format stylish --exclude ./migrations/**/* --exclude ./test/fixtures/**/**/*.json",
"migrate:run": "yarn typeorm migration:run --config ./lib/src/ormconfig",
"migrate:revert": "yarn typeorm migration:revert --config ./lib/src/ormconfig",
"migrate:create": "yarn typeorm migration:create --config ./lib/src/ormconfig --dir migrations"
@@ -39,16 +39,16 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/connect": "^3.0.10",
- "@0x/contract-addresses": "^2.0.0",
- "@0x/contract-artifacts": "^1.0.1",
+ "@0x/connect": "^3.0.11",
+ "@0x/contract-addresses": "^2.1.0",
+ "@0x/contract-artifacts": "^1.2.0",
"@0x/contract-wrappers": "^3.0.0",
- "@0x/dev-utils": "^1.0.21",
- "@0x/order-utils": "^3.0.7",
- "@0x/subproviders": "^2.1.8",
- "@0x/types": "^1.4.1",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/dev-utils": "^1.0.22",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/subproviders": "^2.1.9",
+ "@0x/types": "^1.5.0",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/dockerode": "^2.5.9",
"@types/p-limit": "^2.0.0",
"async-parallel": "^1.2.3",
diff --git a/packages/pipeline/src/data_sources/copper/index.ts b/packages/pipeline/src/data_sources/copper/index.ts
new file mode 100644
index 000000000..15df2fd7d
--- /dev/null
+++ b/packages/pipeline/src/data_sources/copper/index.ts
@@ -0,0 +1,126 @@
+import { fetchAsync } from '@0x/utils';
+import Bottleneck from 'bottleneck';
+
+import {
+ CopperActivityTypeCategory,
+ CopperActivityTypeResponse,
+ CopperCustomFieldResponse,
+ CopperSearchResponse,
+} from '../../parsers/copper';
+
+const HTTP_OK_STATUS = 200;
+const COPPER_URI = 'https://api.prosperworks.com/developer_api/v1';
+
+const DEFAULT_PAGINATION_PARAMS = {
+ page_size: 200,
+ sort_by: 'date_modified',
+ sort_direction: 'desc',
+};
+
+export type CopperSearchParams = CopperLeadSearchParams | CopperActivitySearchParams | CopperOpportunitySearchParams;
+export interface CopperLeadSearchParams {
+ page_number?: number;
+}
+
+export interface CopperActivitySearchParams {
+ minimum_activity_date: number;
+ page_number?: number;
+}
+
+export interface CopperOpportunitySearchParams {
+ sort_by: string; // must override the default 'date_modified' for this endpoint
+ page_number?: number;
+}
+export enum CopperEndpoint {
+ Leads = '/leads/search',
+ Opportunities = '/opportunities/search',
+ Activities = '/activities/search',
+}
+const ONE_SECOND = 1000;
+
+function httpErrorCheck(response: Response): void {
+ if (response.status !== HTTP_OK_STATUS) {
+ throw new Error(`HTTP error while scraping Copper: [${JSON.stringify(response)}]`);
+ }
+}
+export class CopperSource {
+ private readonly _accessToken: string;
+ private readonly _userEmail: string;
+ private readonly _defaultHeaders: any;
+ private readonly _limiter: Bottleneck;
+
+ constructor(maxConcurrentRequests: number, accessToken: string, userEmail: string) {
+ this._accessToken = accessToken;
+ this._userEmail = userEmail;
+ this._defaultHeaders = {
+ 'Content-Type': 'application/json',
+ 'X-PW-AccessToken': this._accessToken,
+ 'X-PW-Application': 'developer_api',
+ 'X-PW-UserEmail': this._userEmail,
+ };
+ this._limiter = new Bottleneck({
+ minTime: ONE_SECOND / maxConcurrentRequests,
+ reservoir: 30,
+ reservoirRefreshAmount: 30,
+ reservoirRefreshInterval: maxConcurrentRequests,
+ });
+ }
+
+ public async fetchNumberOfPagesAsync(endpoint: CopperEndpoint, searchParams?: CopperSearchParams): Promise<number> {
+ const resp = await this._limiter.schedule(() =>
+ fetchAsync(COPPER_URI + endpoint, {
+ method: 'POST',
+ body: JSON.stringify({ ...DEFAULT_PAGINATION_PARAMS, ...searchParams }),
+ headers: this._defaultHeaders,
+ }),
+ );
+
+ httpErrorCheck(resp);
+
+ // total number of records that match the request parameters
+ if (resp.headers.has('X-Pw-Total')) {
+ const totalRecords: number = parseInt(resp.headers.get('X-Pw-Total') as string, 10); // tslint:disable-line:custom-no-magic-numbers
+ return Math.ceil(totalRecords / DEFAULT_PAGINATION_PARAMS.page_size);
+ } else {
+ return 1;
+ }
+ }
+ public async fetchSearchResultsAsync<T extends CopperSearchResponse>(
+ endpoint: CopperEndpoint,
+ searchParams?: CopperSearchParams,
+ ): Promise<T[]> {
+ const request = { ...DEFAULT_PAGINATION_PARAMS, ...searchParams };
+ const response = await this._limiter.schedule(() =>
+ fetchAsync(COPPER_URI + endpoint, {
+ method: 'POST',
+ body: JSON.stringify(request),
+ headers: this._defaultHeaders,
+ }),
+ );
+ httpErrorCheck(response);
+ const json: T[] = await response.json();
+ return json;
+ }
+
+ public async fetchActivityTypesAsync(): Promise<Map<CopperActivityTypeCategory, CopperActivityTypeResponse[]>> {
+ const response = await this._limiter.schedule(() =>
+ fetchAsync(`${COPPER_URI}/activity_types`, {
+ method: 'GET',
+ headers: this._defaultHeaders,
+ }),
+ );
+ httpErrorCheck(response);
+ return response.json();
+ }
+
+ public async fetchCustomFieldsAsync(): Promise<CopperCustomFieldResponse[]> {
+ const response = await this._limiter.schedule(() =>
+ fetchAsync(`${COPPER_URI}/custom_field_definitions`, {
+ method: 'GET',
+ headers: this._defaultHeaders,
+ }),
+ );
+ httpErrorCheck(response);
+ return response.json();
+ }
+}
diff --git a/packages/pipeline/src/entities/copper_activity.ts b/packages/pipeline/src/entities/copper_activity.ts
new file mode 100644
index 000000000..cbc034285
--- /dev/null
+++ b/packages/pipeline/src/entities/copper_activity.ts
@@ -0,0 +1,41 @@
+import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
+
+import { numberToBigIntTransformer } from '../utils';
+
+@Entity({ name: 'copper_activities', schema: 'raw' })
+export class CopperActivity {
+ @PrimaryColumn({ type: 'bigint', transformer: numberToBigIntTransformer })
+ public id!: number;
+
+ @Index()
+ @Column({ name: 'parent_id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public parentId!: number;
+ @Column({ name: 'parent_type', type: 'varchar' })
+ public parentType!: string;
+
+ // join with CopperActivityType
+ @Index()
+ @Column({ name: 'type_id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public typeId!: number;
+ @Column({ name: 'type_category', type: 'varchar' })
+ public typeCategory!: string;
+ @Column({ name: 'type_name', type: 'varchar', nullable: true })
+ public typeName?: string;
+
+ @Column({ name: 'user_id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public userId!: number;
+ @Column({ name: 'old_value_id', type: 'bigint', nullable: true, transformer: numberToBigIntTransformer })
+ public oldValueId?: number;
+ @Column({ name: 'old_value_name', type: 'varchar', nullable: true })
+ public oldValueName?: string;
+ @Column({ name: 'new_value_id', type: 'bigint', nullable: true, transformer: numberToBigIntTransformer })
+ public newValueId?: number;
+ @Column({ name: 'new_value_name', type: 'varchar', nullable: true })
+ public newValueName?: string;
+
+ @Index()
+ @Column({ name: 'date_created', type: 'bigint', transformer: numberToBigIntTransformer })
+ public dateCreated!: number;
+ @PrimaryColumn({ name: 'date_modified', type: 'bigint', transformer: numberToBigIntTransformer })
+ public dateModified!: number;
+}
diff --git a/packages/pipeline/src/entities/copper_activity_type.ts b/packages/pipeline/src/entities/copper_activity_type.ts
new file mode 100644
index 000000000..8fb2dcf70
--- /dev/null
+++ b/packages/pipeline/src/entities/copper_activity_type.ts
@@ -0,0 +1,17 @@
+import { Column, Entity, PrimaryColumn } from 'typeorm';
+
+import { numberToBigIntTransformer } from '../utils';
+
+@Entity({ name: 'copper_activity_types', schema: 'raw' })
+export class CopperActivityType {
+ @PrimaryColumn({ type: 'bigint', transformer: numberToBigIntTransformer })
+ public id!: number;
+ @Column({ name: 'category', type: 'varchar' })
+ public category!: string;
+ @Column({ name: 'name', type: 'varchar' })
+ public name!: string;
+ @Column({ name: 'is_disabled', type: 'boolean', nullable: true })
+ public isDisabled?: boolean;
+ @Column({ name: 'count_as_interaction', type: 'boolean', nullable: true })
+ public countAsInteraction?: boolean;
+}
diff --git a/packages/pipeline/src/entities/copper_custom_field.ts b/packages/pipeline/src/entities/copper_custom_field.ts
new file mode 100644
index 000000000..f23f6ab22
--- /dev/null
+++ b/packages/pipeline/src/entities/copper_custom_field.ts
@@ -0,0 +1,15 @@
+import { Column, Entity, PrimaryColumn } from 'typeorm';
+
+import { numberToBigIntTransformer } from '../utils';
+
+@Entity({ name: 'copper_custom_fields', schema: 'raw' })
+export class CopperCustomField {
+ @PrimaryColumn({ type: 'bigint', transformer: numberToBigIntTransformer })
+ public id!: number;
+ @Column({ name: 'data_type', type: 'varchar' })
+ public dataType!: string;
+ @Column({ name: 'field_type', type: 'varchar', nullable: true })
+ public fieldType?: string;
+ @Column({ name: 'name', type: 'varchar' })
+ public name!: string;
+}
diff --git a/packages/pipeline/src/entities/copper_lead.ts b/packages/pipeline/src/entities/copper_lead.ts
new file mode 100644
index 000000000..c51ccd761
--- /dev/null
+++ b/packages/pipeline/src/entities/copper_lead.ts
@@ -0,0 +1,38 @@
+import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
+
+import { numberToBigIntTransformer } from '../utils';
+
+@Entity({ name: 'copper_leads', schema: 'raw' })
+export class CopperLead {
+ @PrimaryColumn({ type: 'bigint', transformer: numberToBigIntTransformer })
+ public id!: number;
+
+ @Column({ name: 'name', type: 'varchar', nullable: true })
+ public name?: string;
+ @Column({ name: 'first_name', type: 'varchar', nullable: true })
+ public firstName?: string;
+ @Column({ name: 'last_name', type: 'varchar', nullable: true })
+ public lastName?: string;
+ @Column({ name: 'middle_name', type: 'varchar', nullable: true })
+ public middleName?: string;
+ @Column({ name: 'assignee_id', type: 'bigint', transformer: numberToBigIntTransformer, nullable: true })
+ public assigneeId?: number;
+ @Column({ name: 'company_name', type: 'varchar', nullable: true })
+ public companyName?: string;
+ @Column({ name: 'customer_source_id', type: 'bigint', transformer: numberToBigIntTransformer, nullable: true })
+ public customerSourceId?: number;
+ @Column({ name: 'monetary_value', type: 'integer', nullable: true })
+ public monetaryValue?: number;
+ @Column({ name: 'status', type: 'varchar' })
+ public status!: string;
+ @Column({ name: 'status_id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public statusId!: number;
+ @Column({ name: 'title', type: 'varchar', nullable: true })
+ public title?: string;
+
+ @Index()
+ @Column({ name: 'date_created', type: 'bigint', transformer: numberToBigIntTransformer })
+ public dateCreated!: number;
+ @PrimaryColumn({ name: 'date_modified', type: 'bigint', transformer: numberToBigIntTransformer })
+ public dateModified!: number;
+}
diff --git a/packages/pipeline/src/entities/copper_opportunity.ts b/packages/pipeline/src/entities/copper_opportunity.ts
new file mode 100644
index 000000000..e12bd69ce
--- /dev/null
+++ b/packages/pipeline/src/entities/copper_opportunity.ts
@@ -0,0 +1,45 @@
+import { Column, Entity, PrimaryColumn } from 'typeorm';
+
+import { numberToBigIntTransformer } from '../utils';
+
+@Entity({ name: 'copper_opportunities', schema: 'raw' })
+export class CopperOpportunity {
+ @PrimaryColumn({ name: 'id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public id!: number;
+ @Column({ name: 'name', type: 'varchar' })
+ public name!: string;
+ @Column({ name: 'assignee_id', nullable: true, type: 'bigint', transformer: numberToBigIntTransformer })
+ public assigneeId?: number;
+ @Column({ name: 'close_date', nullable: true, type: 'varchar' })
+ public closeDate?: string;
+ @Column({ name: 'company_id', nullable: true, type: 'bigint', transformer: numberToBigIntTransformer })
+ public companyId?: number;
+ @Column({ name: 'company_name', nullable: true, type: 'varchar' })
+ public companyName?: string;
+ @Column({ name: 'customer_source_id', nullable: true, type: 'bigint', transformer: numberToBigIntTransformer })
+ public customerSourceId?: number;
+ @Column({ name: 'loss_reason_id', nullable: true, type: 'bigint', transformer: numberToBigIntTransformer })
+ public lossReasonId?: number;
+ @Column({ name: 'pipeline_id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public pipelineId!: number;
+ @Column({ name: 'pipeline_stage_id', type: 'bigint', transformer: numberToBigIntTransformer })
+ public pipelineStageId!: number;
+ @Column({ name: 'primary_contact_id', nullable: true, type: 'bigint', transformer: numberToBigIntTransformer })
+ public primaryContactId?: number;
+ @Column({ name: 'priority', nullable: true, type: 'varchar' })
+ public priority?: string;
+ @Column({ name: 'status', type: 'varchar' })
+ public status!: string;
+ @Column({ name: 'interaction_count', type: 'bigint', transformer: numberToBigIntTransformer })
+ public interactionCount!: number;
+ @Column({ name: 'monetary_value', nullable: true, type: 'integer' })
+ public monetaryValue?: number;
+ @Column({ name: 'win_probability', nullable: true, type: 'integer' })
+ public winProbability?: number;
+ @Column({ name: 'date_created', type: 'bigint', transformer: numberToBigIntTransformer })
+ public dateCreated!: number;
+ @PrimaryColumn({ name: 'date_modified', type: 'bigint', transformer: numberToBigIntTransformer })
+ public dateModified!: number;
+ @Column({ name: 'custom_fields', type: 'jsonb' })
+ public customFields!: { [key: number]: number };
+}
diff --git a/packages/pipeline/src/entities/index.ts b/packages/pipeline/src/entities/index.ts
index cc3de78bb..27c153c07 100644
--- a/packages/pipeline/src/entities/index.ts
+++ b/packages/pipeline/src/entities/index.ts
@@ -16,4 +16,10 @@ export { TokenOrderbookSnapshot } from './token_order';
export { Transaction } from './transaction';
export { ERC20ApprovalEvent } from './erc20_approval_event';
+export { CopperLead } from './copper_lead';
+export { CopperActivity } from './copper_activity';
+export { CopperOpportunity } from './copper_opportunity';
+export { CopperActivityType } from './copper_activity_type';
+export { CopperCustomField } from './copper_custom_field';
+
export type ExchangeEvent = ExchangeFillEvent | ExchangeCancelEvent | ExchangeCancelUpToEvent;
diff --git a/packages/pipeline/src/ormconfig.ts b/packages/pipeline/src/ormconfig.ts
index fe11d81d5..2700714cd 100644
--- a/packages/pipeline/src/ormconfig.ts
+++ b/packages/pipeline/src/ormconfig.ts
@@ -2,6 +2,11 @@ import { ConnectionOptions } from 'typeorm';
import {
Block,
+ CopperActivity,
+ CopperActivityType,
+ CopperCustomField,
+ CopperLead,
+ CopperOpportunity,
DexTrade,
ERC20ApprovalEvent,
ExchangeCancelEvent,
@@ -18,6 +23,11 @@ import {
const entities = [
Block,
+ CopperOpportunity,
+ CopperActivity,
+ CopperActivityType,
+ CopperCustomField,
+ CopperLead,
DexTrade,
ExchangeCancelEvent,
ExchangeCancelUpToEvent,
diff --git a/packages/pipeline/src/parsers/copper/index.ts b/packages/pipeline/src/parsers/copper/index.ts
new file mode 100644
index 000000000..6c0c5abd5
--- /dev/null
+++ b/packages/pipeline/src/parsers/copper/index.ts
@@ -0,0 +1,259 @@
+import * as R from 'ramda';
+
+import { CopperActivity, CopperActivityType, CopperCustomField, CopperLead, CopperOpportunity } from '../../entities';
+
+const ONE_SECOND = 1000;
+export type CopperSearchResponse = CopperLeadResponse | CopperActivityResponse | CopperOpportunityResponse;
+export interface CopperLeadResponse {
+ id: number;
+ name?: string;
+ first_name?: string;
+ last_name?: string;
+ middle_name?: string;
+ assignee_id?: number;
+ company_name?: string;
+ customer_source_id?: number;
+ monetary_value?: number;
+ status: string;
+ status_id: number;
+ title?: string;
+ date_created: number; // in seconds
+ date_modified: number; // in seconds
+}
+
+export interface CopperActivityResponse {
+ id: number;
+ parent: CopperActivityParentResponse;
+ type: CopperActivityTypeResponse;
+ user_id: number;
+ activity_date: number;
+ old_value: CopperActivityValueResponse;
+ new_value: CopperActivityValueResponse;
+ date_created: number; // in seconds
+ date_modified: number; // in seconds
+}
+
+export interface CopperActivityValueResponse {
+ id: number;
+ name: string;
+}
+export interface CopperActivityParentResponse {
+ id: number;
+ type: string;
+}
+
+// custom activity types
+export enum CopperActivityTypeCategory {
+ user = 'user',
+ system = 'system',
+}
+export interface CopperActivityTypeResponse {
+ id: number;
+ category: CopperActivityTypeCategory;
+ name: string;
+ is_disabled?: boolean;
+ count_as_interaction?: boolean;
+}
+
+export interface CopperOpportunityResponse {
+ id: number;
+ name: string;
+ assignee_id?: number;
+ close_date?: string;
+ company_id?: number;
+ company_name?: string;
+ customer_source_id?: number;
+ loss_reason_id?: number;
+ pipeline_id: number;
+ pipeline_stage_id: number;
+ primary_contact_id?: number;
+ priority?: string;
+ status: string;
+ tags: string[];
+ interaction_count: number;
+ monetary_value?: number;
+ win_probability?: number;
+ date_created: number; // in seconds
+ date_modified: number; // in seconds
+ custom_fields: CopperNestedCustomFieldResponse[];
+}
+interface CopperNestedCustomFieldResponse {
+ custom_field_definition_id: number;
+ value: number | number[] | null;
+}
+// custom fields
+export enum CopperCustomFieldType {
+ String = 'String',
+ Text = 'Text',
+ Dropdown = 'Dropdown',
+ MultiSelect = 'MultiSelect', // not in API documentation but shows up in results
+ Date = 'Date',
+ Checkbox = 'Checkbox',
+ Float = 'Float',
+ URL = 'URL',
+ Percentage = 'Percentage',
+ Currency = 'Currency',
+ Connect = 'Connect',
+}
+export interface CopperCustomFieldOptionResponse {
+ id: number;
+ name: string;
+}
+export interface CopperCustomFieldResponse {
+ id: number;
+ name: string;
+ data_type: CopperCustomFieldType;
+ options?: CopperCustomFieldOptionResponse[];
+}
+/**
+ * Parse response from Copper API /search/leads/
+ *
+ * @param leads - The array of leads returned from the API
+ * @returns Returns an array of Copper Lead entities
+ */
+export function parseLeads(leads: CopperLeadResponse[]): CopperLead[] {
+ return leads.map(lead => {
+ const entity = new CopperLead();
+ entity.id = lead.id;
+ entity.name = lead.name || undefined;
+ entity.firstName = lead.first_name || undefined;
+ entity.lastName = lead.last_name || undefined;
+ entity.middleName = lead.middle_name || undefined;
+ entity.assigneeId = lead.assignee_id || undefined;
+ entity.companyName = lead.company_name || undefined;
+ entity.customerSourceId = lead.customer_source_id || undefined;
+ entity.monetaryValue = lead.monetary_value || undefined;
+ entity.status = lead.status;
+ entity.statusId = lead.status_id;
+ entity.title = lead.title || undefined;
+ entity.dateCreated = lead.date_created * ONE_SECOND;
+ entity.dateModified = lead.date_modified * ONE_SECOND;
+ return entity;
+ });
+}
+
+/**
+ * Parse response from Copper API /search/activities/
+ *
+ * @param activities - The array of activities returned from the API
+ * @returns Returns an array of Copper Activity entities
+ */
+export function parseActivities(activities: CopperActivityResponse[]): CopperActivity[] {
+ return activities.map(activity => {
+ const entity = new CopperActivity();
+ entity.id = activity.id;
+
+ entity.parentId = activity.parent.id;
+ entity.parentType = activity.parent.type;
+
+ entity.typeId = activity.type.id;
+ entity.typeCategory = activity.type.category.toString();
+ entity.typeName = activity.type.name;
+
+ entity.userId = activity.user_id;
+ entity.dateCreated = activity.date_created * ONE_SECOND;
+ entity.dateModified = activity.date_modified * ONE_SECOND;
+
+ // nested nullable fields
+ entity.oldValueId = R.path(['old_value', 'id'], activity);
+ entity.oldValueName = R.path(['old_value', 'name'], activity);
+ entity.newValueId = R.path(['new_value', 'id'], activity);
+ entity.newValueName = R.path(['new_value', 'name'], activity);
+
+ return entity;
+ });
+}
+
+/**
+ * Parse response from Copper API /search/opportunities/
+ *
+ * @param opportunities - The array of opportunities returned from the API
+ * @returns Returns an array of Copper Opportunity entities
+ */
+export function parseOpportunities(opportunities: CopperOpportunityResponse[]): CopperOpportunity[] {
+ return opportunities.map(opp => {
+ const customFields: { [key: number]: number } = opp.custom_fields
+ .filter(f => f.value !== null)
+ .map(f => ({
+ ...f,
+ value: ([] as number[]).concat(f.value || []), // normalise all values to number[]
+ }))
+ .map(f => f.value.map(val => [f.custom_field_definition_id, val] as [number, number])) // pair each value with the custom_field_definition_id
+ .reduce((acc, pair) => acc.concat(pair)) // flatten
+ .reduce<{ [key: number]: number }>((obj, [key, value]) => {
+ // transform into object literal
+ obj[key] = value;
+ return obj;
+ }, {});
+
+ const entity = new CopperOpportunity();
+ entity.id = opp.id;
+ entity.name = opp.name;
+ entity.assigneeId = opp.assignee_id || undefined;
+ entity.closeDate = opp.close_date || undefined;
+ entity.companyId = opp.company_id || undefined;
+ entity.companyName = opp.company_name || undefined;
+ entity.customerSourceId = opp.customer_source_id || undefined;
+ entity.lossReasonId = opp.loss_reason_id || undefined;
+ entity.pipelineId = opp.pipeline_id;
+ entity.pipelineStageId = opp.pipeline_stage_id;
+ entity.primaryContactId = opp.primary_contact_id || undefined;
+ entity.priority = opp.priority || undefined;
+ entity.status = opp.status;
+ entity.interactionCount = opp.interaction_count;
+ entity.monetaryValue = opp.monetary_value || undefined;
+ entity.winProbability = opp.win_probability === null ? undefined : opp.win_probability;
+ entity.dateCreated = opp.date_created * ONE_SECOND;
+ entity.dateModified = opp.date_modified * ONE_SECOND;
+ entity.customFields = customFields;
+ return entity;
+ });
+}
+
+/**
+ * Parse response from Copper API /activity_types/
+ *
+ * @param activityTypeResponse - Activity Types response from the API, keyed by "user" or "system"
+ * @returns Returns an array of Copper Activity Type entities
+ */
+export function parseActivityTypes(
+ activityTypeResponse: Map<CopperActivityTypeCategory, CopperActivityTypeResponse[]>,
+): CopperActivityType[] {
+ const values: CopperActivityTypeResponse[] = R.flatten(Object.values(activityTypeResponse));
+ return values.map(activityType => ({
+ id: activityType.id,
+ name: activityType.name,
+ category: activityType.category.toString(),
+ isDisabled: activityType.is_disabled,
+ countAsInteraction: activityType.count_as_interaction,
+ }));
+}
+
+/**
+ * Parse response from Copper API /custom_field_definitions/
+ *
+ * @param customFieldResponse - array of custom field definitions returned from the API, consisting of top-level fields and nested fields
+ * @returns Returns an array of Copper Custom Field entities
+ */
+export function parseCustomFields(customFieldResponse: CopperCustomFieldResponse[]): CopperCustomField[] {
+ function parseTopLevelField(field: CopperCustomFieldResponse): CopperCustomField[] {
+ const topLevelField: CopperCustomField = {
+ id: field.id,
+ name: field.name,
+ dataType: field.data_type.toString(),
+ };
+
+ if (field.options !== undefined) {
+ const nestedFields: CopperCustomField[] = field.options.map(option => ({
+ id: option.id,
+ name: option.name,
+ dataType: field.name,
+ fieldType: 'option',
+ }));
+ return nestedFields.concat(topLevelField);
+ } else {
+ return [topLevelField];
+ }
+ }
+ return R.chain(parseTopLevelField, customFieldResponse);
+}
diff --git a/packages/pipeline/src/scripts/pull_copper.ts b/packages/pipeline/src/scripts/pull_copper.ts
new file mode 100644
index 000000000..69814f209
--- /dev/null
+++ b/packages/pipeline/src/scripts/pull_copper.ts
@@ -0,0 +1,129 @@
+// tslint:disable:no-console
+import * as R from 'ramda';
+import { Connection, ConnectionOptions, createConnection, Repository } from 'typeorm';
+
+import { CopperEndpoint, CopperSearchParams, CopperSource } from '../data_sources/copper';
+import { CopperActivity, CopperActivityType, CopperCustomField, CopperLead, CopperOpportunity } from '../entities';
+import * as ormConfig from '../ormconfig';
+import {
+ CopperSearchResponse,
+ parseActivities,
+ parseActivityTypes,
+ parseCustomFields,
+ parseLeads,
+ parseOpportunities,
+} from '../parsers/copper';
+import { handleError } from '../utils';
+const ONE_SECOND = 1000;
+const COPPER_RATE_LIMIT = 10;
+let connection: Connection;
+
+(async () => {
+ connection = await createConnection(ormConfig as ConnectionOptions);
+
+ const accessToken = process.env.COPPER_ACCESS_TOKEN;
+ const userEmail = process.env.COPPER_USER_EMAIL;
+ if (accessToken === undefined || userEmail === undefined) {
+ throw new Error('Missing required env var: COPPER_ACCESS_TOKEN and/or COPPER_USER_EMAIL');
+ }
+ const source = new CopperSource(COPPER_RATE_LIMIT, accessToken, userEmail);
+
+ const fetchPromises = [
+ fetchAndSaveLeadsAsync(source),
+ fetchAndSaveOpportunitiesAsync(source),
+ fetchAndSaveActivitiesAsync(source),
+ fetchAndSaveCustomFieldsAsync(source),
+ fetchAndSaveActivityTypesAsync(source),
+ ];
+ fetchPromises.forEach(async fn => {
+ await fn;
+ });
+})().catch(handleError);
+
+async function fetchAndSaveLeadsAsync(source: CopperSource): Promise<void> {
+ const repository = connection.getRepository(CopperLead);
+ const startTime = await getMaxAsync(connection, 'date_modified', 'raw.copper_leads');
+ console.log(`Fetching Copper leads starting from ${startTime}...`);
+ await fetchAndSaveAsync(CopperEndpoint.Leads, source, startTime, {}, parseLeads, repository);
+}
+
+async function fetchAndSaveOpportunitiesAsync(source: CopperSource): Promise<void> {
+ const repository = connection.getRepository(CopperOpportunity);
+ const startTime = await getMaxAsync(connection, 'date_modified', 'raw.copper_opportunities');
+ console.log(`Fetching Copper opportunities starting from ${startTime}...`);
+ await fetchAndSaveAsync(
+ CopperEndpoint.Opportunities,
+ source,
+ startTime,
+ { sort_by: 'name' },
+ parseOpportunities,
+ repository,
+ );
+}
+
+async function fetchAndSaveActivitiesAsync(source: CopperSource): Promise<void> {
+ const repository = connection.getRepository(CopperActivity);
+ const startTime = await getMaxAsync(connection, 'date_modified', 'raw.copper_activities');
+ const searchParams = {
+ minimum_activity_date: Math.floor(startTime / ONE_SECOND),
+ };
+ console.log(`Fetching Copper activities starting from ${startTime}...`);
+ await fetchAndSaveAsync(CopperEndpoint.Activities, source, startTime, searchParams, parseActivities, repository);
+}
+
+async function getMaxAsync(conn: Connection, sortColumn: string, tableName: string): Promise<number> {
+ const queryResult = await conn.query(`SELECT MAX(${sortColumn}) as _max from ${tableName};`);
+ if (R.isEmpty(queryResult)) {
+ return 0;
+ } else {
+ return queryResult[0]._max;
+ }
+}
+
+// (Xianny): Copper API doesn't allow queries to filter by date. To ensure that we are filling in ascending chronological
+// order and not missing any records, we are scraping all available pages. If Copper data gets larger,
+// it would make sense to search for and start filling from the first page that contains a new record.
+// This search would increase our network calls and is not efficient to implement with our current small volume
+// of Copper records.
+async function fetchAndSaveAsync<T extends CopperSearchResponse, E>(
+ endpoint: CopperEndpoint,
+ source: CopperSource,
+ startTime: number,
+ searchParams: CopperSearchParams,
+ parseFn: (recs: T[]) => E[],
+ repository: Repository<E>,
+): Promise<void> {
+ let saved = 0;
+ const numPages = await source.fetchNumberOfPagesAsync(endpoint);
+ try {
+ for (let i = numPages; i > 0; i--) {
+ console.log(`Fetching page ${i}/${numPages} of ${endpoint}...`);
+ const raw = await source.fetchSearchResultsAsync<T>(endpoint, {
+ ...searchParams,
+ page_number: i,
+ });
+ const newRecords = raw.filter(rec => rec.date_modified * ONE_SECOND > startTime);
+ const parsed = parseFn(newRecords);
+ await repository.save<any>(parsed);
+ saved += newRecords.length;
+ }
+ } catch (err) {
+ console.log(`Error fetching ${endpoint}, stopping: ${err.stack}`);
+ } finally {
+ console.log(`Saved ${saved} items from ${endpoint}, done.`);
+ }
+}
+
+async function fetchAndSaveActivityTypesAsync(source: CopperSource): Promise<void> {
+ console.log(`Fetching Copper activity types...`);
+ const activityTypes = await source.fetchActivityTypesAsync();
+ const repository = connection.getRepository(CopperActivityType);
+ await repository.save(parseActivityTypes(activityTypes));
+}
+
+async function fetchAndSaveCustomFieldsAsync(source: CopperSource): Promise<void> {
+ console.log(`Fetching Copper custom fields...`);
+ const customFields = await source.fetchCustomFieldsAsync();
+ const repository = connection.getRepository(CopperCustomField);
+ await repository.save(parseCustomFields(customFields));
+}
diff --git a/packages/pipeline/src/utils/transformers/number_to_bigint.ts b/packages/pipeline/src/utils/transformers/number_to_bigint.ts
index 85560c1f0..9736d7c18 100644
--- a/packages/pipeline/src/utils/transformers/number_to_bigint.ts
+++ b/packages/pipeline/src/utils/transformers/number_to_bigint.ts
@@ -9,8 +9,12 @@ const decimalRadix = 10;
// https://github.com/typeorm/typeorm/issues/2400 for more information.
export class NumberToBigIntTransformer implements ValueTransformer {
// tslint:disable-next-line:prefer-function-over-method
- public to(value: number): string {
- return value.toString();
+ public to(value: number): string | null {
+ if (value === null || value === undefined) {
+ return null;
+ } else {
+ return value.toString();
+ }
}
// tslint:disable-next-line:prefer-function-over-method
diff --git a/packages/pipeline/test/entities/copper_test.ts b/packages/pipeline/test/entities/copper_test.ts
new file mode 100644
index 000000000..2543364e6
--- /dev/null
+++ b/packages/pipeline/test/entities/copper_test.ts
@@ -0,0 +1,54 @@
+import 'mocha';
+import 'reflect-metadata';
+
+import {
+ CopperActivity,
+ CopperActivityType,
+ CopperCustomField,
+ CopperLead,
+ CopperOpportunity,
+} from '../../src/entities';
+import { createDbConnectionOnceAsync } from '../db_setup';
+import {
+ ParsedActivities,
+ ParsedActivityTypes,
+ ParsedCustomFields,
+ ParsedLeads,
+ ParsedOpportunities,
+} from '../fixtures/copper/parsed_entities';
+import { chaiSetup } from '../utils/chai_setup';
+
+import { testSaveAndFindEntityAsync } from './util';
+
+chaiSetup.configure();
+
+describe('Copper entities', () => {
+ describe('save and find', async () => {
+ it('Copper lead', async () => {
+ const connection = await createDbConnectionOnceAsync();
+ const repository = connection.getRepository(CopperLead);
+ ParsedLeads.forEach(async entity => testSaveAndFindEntityAsync(repository, entity));
+ });
+ it('Copper activity', async () => {
+ const connection = await createDbConnectionOnceAsync();
+ const repository = connection.getRepository(CopperActivity);
+ ParsedActivities.forEach(async entity => testSaveAndFindEntityAsync(repository, entity));
+ });
+ // searching on jsonb fields is broken in typeorm
+ it.skip('Copper opportunity', async () => {
+ const connection = await createDbConnectionOnceAsync();
+ const repository = connection.getRepository(CopperOpportunity);
+ ParsedOpportunities.forEach(async entity => testSaveAndFindEntityAsync(repository, entity));
+ });
+ it('Copper activity type', async () => {
+ const connection = await createDbConnectionOnceAsync();
+ const repository = connection.getRepository(CopperActivityType);
+ ParsedActivityTypes.forEach(async entity => testSaveAndFindEntityAsync(repository, entity));
+ });
+ it('Copper custom field', async () => {
+ const connection = await createDbConnectionOnceAsync();
+ const repository = connection.getRepository(CopperCustomField);
+ ParsedCustomFields.forEach(async entity => testSaveAndFindEntityAsync(repository, entity));
+ });
+ });
+});
diff --git a/packages/pipeline/test/entities/util.ts b/packages/pipeline/test/entities/util.ts
index 043a3b15d..42df23a4a 100644
--- a/packages/pipeline/test/entities/util.ts
+++ b/packages/pipeline/test/entities/util.ts
@@ -15,9 +15,9 @@ const expect = chai.expect;
* @param entity An instance of a TypeORM entity which will be saved/retrieved from the database.
*/
export async function testSaveAndFindEntityAsync<T>(repository: Repository<T>, entity: T): Promise<void> {
- // Note(albrow): We are forced to use an 'as any' hack here because
+ // Note(albrow): We are forced to use an 'any' hack here because
// TypeScript complains about stack depth when checking the types.
- await repository.save(entity as any);
+ await repository.save<any>(entity);
const gotEntity = await repository.findOneOrFail({
where: entity,
});
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_activity_types.json b/packages/pipeline/test/fixtures/copper/api_v1_activity_types.json
new file mode 100644
index 000000000..dbd39c31b
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_activity_types.json
@@ -0,0 +1,24 @@
+{
+ "user": [
+ { "id": 0, "category": "user", "name": "Note", "is_disabled": false, "count_as_interaction": false },
+ { "id": 660496, "category": "user", "name": "To Do", "is_disabled": false, "count_as_interaction": false },
+ { "id": 660495, "category": "user", "name": "Meeting", "is_disabled": false, "count_as_interaction": true },
+ { "id": 660494, "category": "user", "name": "Phone Call", "is_disabled": false, "count_as_interaction": true }
+ ],
+ "system": [
+ {
+ "id": 1,
+ "category": "system",
+ "name": "Property Changed",
+ "is_disabled": false,
+ "count_as_interaction": false
+ },
+ {
+ "id": 3,
+ "category": "system",
+ "name": "Pipeline Stage Changed",
+ "is_disabled": false,
+ "count_as_interaction": false
+ }
+ ]
+}
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_activity_types.ts b/packages/pipeline/test/fixtures/copper/api_v1_activity_types.ts
new file mode 100644
index 000000000..fd2d62a6c
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_activity_types.ts
@@ -0,0 +1,16 @@
+import { CopperActivityType } from '../../../src/entities';
+const ParsedActivityTypes: CopperActivityType[] = [
+ { id: 0, name: 'Note', category: 'user', isDisabled: false, countAsInteraction: false },
+ { id: 660496, name: 'To Do', category: 'user', isDisabled: false, countAsInteraction: false },
+ { id: 660495, name: 'Meeting', category: 'user', isDisabled: false, countAsInteraction: true },
+ { id: 660494, name: 'Phone Call', category: 'user', isDisabled: false, countAsInteraction: true },
+ { id: 1, name: 'Property Changed', category: 'system', isDisabled: false, countAsInteraction: false },
+ {
+ id: 3,
+ name: 'Pipeline Stage Changed',
+ category: 'system',
+ isDisabled: false,
+ countAsInteraction: false,
+ },
+];
+export { ParsedActivityTypes };
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.json b/packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.json
new file mode 100644
index 000000000..c6665cb0f
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.json
@@ -0,0 +1,38 @@
+[
+ {
+ "id": 261066,
+ "name": "Integration Type",
+ "canonical_name": null,
+ "data_type": "MultiSelect",
+ "available_on": ["opportunity", "company", "person"],
+ "options": [
+ { "id": 394020, "name": "Strategic Relationship", "rank": 7 },
+ { "id": 394013, "name": "ERC-20 Exchange", "rank": 0 },
+ { "id": 394014, "name": "ERC-721 Marketplace", "rank": 1 },
+ { "id": 394015, "name": "Trade Widget", "rank": 2 },
+ { "id": 394016, "name": "Prediction Market Exchange", "rank": 3 },
+ { "id": 394017, "name": "Security Token Exchange", "rank": 4 },
+ { "id": 394018, "name": "Complementary Company", "rank": 5 },
+ { "id": 394019, "name": "Service Provider", "rank": 6 }
+ ]
+ },
+ {
+ "id": 261067,
+ "name": "Company Type",
+ "canonical_name": null,
+ "data_type": "Dropdown",
+ "available_on": ["company", "opportunity", "person"],
+ "options": [
+ { "id": 394129, "name": "Market Maker", "rank": 6 },
+ { "id": 394130, "name": "Events", "rank": 2 },
+ { "id": 394023, "name": "Exchange", "rank": 3 },
+ { "id": 394024, "name": "Investor", "rank": 5 },
+ { "id": 394026, "name": "Service Provider", "rank": 8 },
+ { "id": 394027, "name": "Wallet", "rank": 9 },
+ { "id": 394134, "name": "Game", "rank": 4 },
+ { "id": 394025, "name": "OTC", "rank": 7 },
+ { "id": 394021, "name": "Blockchain/Protocol", "rank": 0 },
+ { "id": 394022, "name": "dApp", "rank": 1 }
+ ]
+ }
+]
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.ts b/packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.ts
new file mode 100644
index 000000000..a44bbd2c3
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_custom_field_definitions.ts
@@ -0,0 +1,39 @@
+import { CopperCustomField } from '../../../src/entities';
+const ParsedCustomFields: CopperCustomField[] = [
+ {
+ id: 394020,
+ name: 'Strategic Relationship',
+ dataType: 'Integration Type',
+ fieldType: 'option',
+ },
+ { id: 394013, name: 'ERC-20 Exchange', dataType: 'Integration Type', fieldType: 'option' },
+ { id: 394014, name: 'ERC-721 Marketplace', dataType: 'Integration Type', fieldType: 'option' },
+ { id: 394015, name: 'Trade Widget', dataType: 'Integration Type', fieldType: 'option' },
+ {
+ id: 394016,
+ name: 'Prediction Market Exchange',
+ dataType: 'Integration Type',
+ fieldType: 'option',
+ },
+ {
+ id: 394017,
+ name: 'Security Token Exchange',
+ dataType: 'Integration Type',
+ fieldType: 'option',
+ },
+ { id: 394018, name: 'Complementary Company', dataType: 'Integration Type', fieldType: 'option' },
+ { id: 394019, name: 'Service Provider', dataType: 'Integration Type', fieldType: 'option' },
+ { id: 261066, name: 'Integration Type', dataType: 'MultiSelect' },
+ { id: 394129, name: 'Market Maker', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394130, name: 'Events', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394023, name: 'Exchange', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394024, name: 'Investor', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394026, name: 'Service Provider', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394027, name: 'Wallet', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394134, name: 'Game', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394025, name: 'OTC', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394021, name: 'Blockchain/Protocol', dataType: 'Company Type', fieldType: 'option' },
+ { id: 394022, name: 'dApp', dataType: 'Company Type', fieldType: 'option' },
+ { id: 261067, name: 'Company Type', dataType: 'Dropdown' },
+];
+export { ParsedCustomFields };
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_list_activities.json b/packages/pipeline/test/fixtures/copper/api_v1_list_activities.json
new file mode 100644
index 000000000..a726111ac
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_list_activities.json
@@ -0,0 +1,242 @@
+[
+ {
+ "id": 5015299552,
+ "parent": { "id": 14667512, "type": "opportunity" },
+ "type": { "id": 3, "category": "system", "name": "Stage Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1545329595,
+ "old_value": { "id": 2392929, "name": "Evaluation" },
+ "new_value": { "id": 2392931, "name": "Integration Started" },
+ "date_created": 1545329595,
+ "date_modified": 1545329595
+ },
+ {
+ "id": 5010214065,
+ "parent": { "id": 14978865, "type": "opportunity" },
+ "type": { "id": 3, "category": "system", "name": "Stage Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1545245706,
+ "old_value": { "id": 2392928, "name": "Intro" },
+ "new_value": { "id": 2392929, "name": "Evaluation" },
+ "date_created": 1545245706,
+ "date_modified": 1545245706
+ },
+ {
+ "id": 5006149111,
+ "parent": { "id": 70430977, "type": "person" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1545166908,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1545168280,
+ "date_modified": 1545166908
+ },
+ {
+ "id": 5005314622,
+ "parent": { "id": 27778968, "type": "company" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1545080504,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1545160479,
+ "date_modified": 1545080504
+ },
+ {
+ "id": 5000006802,
+ "parent": { "id": 14956518, "type": "opportunity" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1545071374,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1545071500,
+ "date_modified": 1545071374
+ },
+ {
+ "id": 4985504199,
+ "parent": { "id": 14912790, "type": "opportunity" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544644058,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544644661,
+ "date_modified": 1544644058
+ },
+ {
+ "id": 4985456147,
+ "parent": { "id": 14912790, "type": "opportunity" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544644048,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544644053,
+ "date_modified": 1544644048
+ },
+ {
+ "id": 4980975996,
+ "parent": { "id": 14902828, "type": "opportunity" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544563171,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544563224,
+ "date_modified": 1544563171
+ },
+ {
+ "id": 4980910331,
+ "parent": { "id": 14902828, "type": "opportunity" },
+ "type": { "id": 3, "category": "system", "name": "Stage Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544562495,
+ "old_value": { "id": 2392928, "name": "Intro" },
+ "new_value": { "id": 2392931, "name": "Integration Started" },
+ "date_created": 1544562495,
+ "date_modified": 1544562495
+ },
+ {
+ "id": 4980872220,
+ "parent": { "id": 14888910, "type": "opportunity" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544559279,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544562118,
+ "date_modified": 1544559279
+ },
+ {
+ "id": 4980508097,
+ "parent": { "id": 14050167, "type": "opportunity" },
+ "type": { "id": 1, "category": "system", "name": "Status Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544558077,
+ "old_value": "Open",
+ "new_value": "Won",
+ "date_created": 1544558077,
+ "date_modified": 1544558077
+ },
+ {
+ "id": 4980508095,
+ "parent": { "id": 66538237, "type": "person" },
+ "type": { "id": 1, "category": "system" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544558077,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544558077,
+ "date_modified": 1544558077
+ },
+ {
+ "id": 4980508092,
+ "parent": { "id": 27779020, "type": "company" },
+ "type": { "id": 1, "category": "system" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544558077,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544558077,
+ "date_modified": 1544558077
+ },
+ {
+ "id": 4980507507,
+ "parent": { "id": 14050167, "type": "opportunity" },
+ "type": { "id": 3, "category": "system", "name": "Stage Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544558071,
+ "old_value": { "id": 2392931, "name": "Integration Started" },
+ "new_value": { "id": 2405442, "name": "Integration Complete" },
+ "date_created": 1544558071,
+ "date_modified": 1544558071
+ },
+ {
+ "id": 4980479684,
+ "parent": { "id": 14901232, "type": "opportunity" },
+ "type": { "id": 3, "category": "system", "name": "Stage Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544557777,
+ "old_value": { "id": 2392928, "name": "Intro" },
+ "new_value": { "id": 2392929, "name": "Evaluation" },
+ "date_created": 1544557777,
+ "date_modified": 1544557777
+ },
+ {
+ "id": 4980327164,
+ "parent": { "id": 14901232, "type": "opportunity" },
+ "type": { "id": 660495, "category": "user" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544554864,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544556132,
+ "date_modified": 1544554864
+ },
+ {
+ "id": 4975270470,
+ "parent": { "id": 14888744, "type": "opportunity" },
+ "type": { "id": 3, "category": "system", "name": "Stage Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544469501,
+ "old_value": { "id": 2392928, "name": "Intro" },
+ "new_value": { "id": 2392931, "name": "Integration Started" },
+ "date_created": 1544469501,
+ "date_modified": 1544469501
+ },
+ {
+ "id": 4975255523,
+ "parent": { "id": 64713448, "type": "person" },
+ "type": { "id": 1, "category": "system" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544469389,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544469389,
+ "date_modified": 1544469389
+ },
+ {
+ "id": 4975255519,
+ "parent": { "id": 13735617, "type": "opportunity" },
+ "type": { "id": 1, "category": "system", "name": "Status Change" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544469388,
+ "old_value": "Open",
+ "new_value": "Won",
+ "date_created": 1544469388,
+ "date_modified": 1544469388
+ },
+ {
+ "id": 4975255514,
+ "parent": { "id": 27778968, "type": "company" },
+ "type": { "id": 1, "category": "system" },
+ "user_id": 680302,
+ "details": "blah blah",
+ "activity_date": 1544469388,
+ "old_value": null,
+ "new_value": null,
+ "date_created": 1544469388,
+ "date_modified": 1544469388
+ }
+]
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_list_activities.ts b/packages/pipeline/test/fixtures/copper/api_v1_list_activities.ts
new file mode 100644
index 000000000..51ee9ced3
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_list_activities.ts
@@ -0,0 +1,305 @@
+import { CopperActivity } from '../../../src/entities';
+
+const ParsedActivities: CopperActivity[] = [
+ {
+ id: 5015299552,
+ parentId: 14667512,
+ parentType: 'opportunity',
+ typeId: 3,
+ typeCategory: 'system',
+ typeName: 'Stage Change',
+ userId: 680302,
+ dateCreated: 1545329595000,
+ dateModified: 1545329595000,
+ oldValueId: 2392929,
+ oldValueName: 'Evaluation',
+ newValueId: 2392931,
+ newValueName: 'Integration Started',
+ },
+ {
+ id: 5010214065,
+ parentId: 14978865,
+ parentType: 'opportunity',
+ typeId: 3,
+ typeCategory: 'system',
+ typeName: 'Stage Change',
+ userId: 680302,
+ dateCreated: 1545245706000,
+ dateModified: 1545245706000,
+ oldValueId: 2392928,
+ oldValueName: 'Intro',
+ newValueId: 2392929,
+ newValueName: 'Evaluation',
+ },
+ {
+ id: 5006149111,
+ parentId: 70430977,
+ parentType: 'person',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1545168280000,
+ dateModified: 1545166908000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 5005314622,
+ parentId: 27778968,
+ parentType: 'company',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1545160479000,
+ dateModified: 1545080504000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 5000006802,
+ parentId: 14956518,
+ parentType: 'opportunity',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1545071500000,
+ dateModified: 1545071374000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4985504199,
+ parentId: 14912790,
+ parentType: 'opportunity',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544644661000,
+ dateModified: 1544644058000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4985456147,
+ parentId: 14912790,
+ parentType: 'opportunity',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544644053000,
+ dateModified: 1544644048000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4980975996,
+ parentId: 14902828,
+ parentType: 'opportunity',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544563224000,
+ dateModified: 1544563171000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4980910331,
+ parentId: 14902828,
+ parentType: 'opportunity',
+ typeId: 3,
+ typeCategory: 'system',
+ typeName: 'Stage Change',
+ userId: 680302,
+ dateCreated: 1544562495000,
+ dateModified: 1544562495000,
+ oldValueId: 2392928,
+ oldValueName: 'Intro',
+ newValueId: 2392931,
+ newValueName: 'Integration Started',
+ },
+ {
+ id: 4980872220,
+ parentId: 14888910,
+ parentType: 'opportunity',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544562118000,
+ dateModified: 1544559279000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4980508097,
+ parentId: 14050167,
+ parentType: 'opportunity',
+ typeId: 1,
+ typeCategory: 'system',
+ typeName: 'Status Change',
+ userId: 680302,
+ dateCreated: 1544558077000,
+ dateModified: 1544558077000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4980508095,
+ parentId: 66538237,
+ parentType: 'person',
+ typeId: 1,
+ typeCategory: 'system',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544558077000,
+ dateModified: 1544558077000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4980508092,
+ parentId: 27779020,
+ parentType: 'company',
+ typeId: 1,
+ typeCategory: 'system',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544558077000,
+ dateModified: 1544558077000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4980507507,
+ parentId: 14050167,
+ parentType: 'opportunity',
+ typeId: 3,
+ typeCategory: 'system',
+ typeName: 'Stage Change',
+ userId: 680302,
+ dateCreated: 1544558071000,
+ dateModified: 1544558071000,
+ oldValueId: 2392931,
+ oldValueName: 'Integration Started',
+ newValueId: 2405442,
+ newValueName: 'Integration Complete',
+ },
+ {
+ id: 4980479684,
+ parentId: 14901232,
+ parentType: 'opportunity',
+ typeId: 3,
+ typeCategory: 'system',
+ typeName: 'Stage Change',
+ userId: 680302,
+ dateCreated: 1544557777000,
+ dateModified: 1544557777000,
+ oldValueId: 2392928,
+ oldValueName: 'Intro',
+ newValueId: 2392929,
+ newValueName: 'Evaluation',
+ },
+ {
+ id: 4980327164,
+ parentId: 14901232,
+ parentType: 'opportunity',
+ typeId: 660495,
+ typeCategory: 'user',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544556132000,
+ dateModified: 1544554864000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4975270470,
+ parentId: 14888744,
+ parentType: 'opportunity',
+ typeId: 3,
+ typeCategory: 'system',
+ typeName: 'Stage Change',
+ userId: 680302,
+ dateCreated: 1544469501000,
+ dateModified: 1544469501000,
+ oldValueId: 2392928,
+ oldValueName: 'Intro',
+ newValueId: 2392931,
+ newValueName: 'Integration Started',
+ },
+ {
+ id: 4975255523,
+ parentId: 64713448,
+ parentType: 'person',
+ typeId: 1,
+ typeCategory: 'system',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544469389000,
+ dateModified: 1544469389000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4975255519,
+ parentId: 13735617,
+ parentType: 'opportunity',
+ typeId: 1,
+ typeCategory: 'system',
+ typeName: 'Status Change',
+ userId: 680302,
+ dateCreated: 1544469388000,
+ dateModified: 1544469388000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+ {
+ id: 4975255514,
+ parentId: 27778968,
+ parentType: 'company',
+ typeId: 1,
+ typeCategory: 'system',
+ typeName: undefined,
+ userId: 680302,
+ dateCreated: 1544469388000,
+ dateModified: 1544469388000,
+ oldValueId: undefined,
+ oldValueName: undefined,
+ newValueId: undefined,
+ newValueName: undefined,
+ },
+];
+export { ParsedActivities };
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_list_leads.json b/packages/pipeline/test/fixtures/copper/api_v1_list_leads.json
new file mode 100644
index 000000000..5223976f9
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_list_leads.json
@@ -0,0 +1,583 @@
+[
+ {
+ "id": 9150547,
+ "name": "My Contact",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Contact",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mycontact@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1490045162,
+ "date_modified": 1490045162
+ },
+ {
+ "id": 9150552,
+ "name": "My Contact",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Contact",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": null,
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [
+ {
+ "number": "415-123-45678",
+ "category": "mobile"
+ }
+ ],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1490045237,
+ "date_modified": 1490045237
+ },
+ {
+ "id": 9150578,
+ "name": "My Contact",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Contact",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": null,
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [
+ {
+ "number": "415-123-45678",
+ "category": "mobile"
+ }
+ ],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1490045279,
+ "date_modified": 1490045279
+ },
+ {
+ "id": 8982554,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1489528899,
+ "date_modified": 1489528899
+ },
+ {
+ "id": 8982702,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@gmail.test",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1489531171,
+ "date_modified": 1489531171
+ },
+ {
+ "id": 9094361,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1489791225,
+ "date_modified": 1489791225
+ },
+ {
+ "id": 9094364,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": "123456789012345678901234567890"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": "123456789012345678901234567890"
+ }
+ ],
+ "date_created": 1489791283,
+ "date_modified": 1489791283
+ },
+ {
+ "id": 9094371,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value":
+ "|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": "123456789012345678901234567890"
+ }
+ ],
+ "date_created": 1489791417,
+ "date_modified": 1489791417
+ },
+ {
+ "id": 9094372,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value":
+ "|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5-----"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": "123456789012345678901234567890"
+ }
+ ],
+ "date_created": 1489791453,
+ "date_modified": 1489791453
+ },
+ {
+ "id": 9094373,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value":
+ "|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5-----"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value":
+ "|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------"
+ }
+ ],
+ "date_created": 1489791470,
+ "date_modified": 1489791470
+ },
+ {
+ "id": 9094383,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value":
+ "|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5-----"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value":
+ "|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------|--------1---------2---------3---------4---------5---------6---------7---------8---------9---------"
+ }
+ ],
+ "date_created": 1489791672,
+ "date_modified": 1489791672
+ },
+ {
+ "id": 9174441,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": "Text fields are 255 chars or less!"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": "text \n text"
+ }
+ ],
+ "date_created": 1490112942,
+ "date_modified": 1490112942
+ },
+ {
+ "id": 9174443,
+ "name": "My Lead",
+ "prefix": null,
+ "first_name": "My",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": null,
+ "assignee_id": null,
+ "company_name": null,
+ "customer_source_id": null,
+ "details": null,
+ "email": {
+ "email": "mylead@noemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": null,
+ "socials": [],
+ "status": "New",
+ "status_id": 208231,
+ "tags": [],
+ "title": null,
+ "websites": [],
+ "phone_numbers": [],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": "Text fields are 255 chars or less!"
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": "text /n text"
+ }
+ ],
+ "date_created": 1490112953,
+ "date_modified": 1490112953
+ },
+ {
+ "id": 8894157,
+ "name": "Test Lead",
+ "prefix": null,
+ "first_name": "Test",
+ "last_name": "Lead",
+ "middle_name": null,
+ "suffix": null,
+ "address": {
+ "street": "301 Howard St Ste 600",
+ "city": "San Francisco",
+ "state": "CA",
+ "postal_code": "94105",
+ "country": "US"
+ },
+ "assignee_id": 137658,
+ "company_name": "Lead's Company",
+ "customer_source_id": 331241,
+ "details": "This is an update",
+ "email": {
+ "email": "address@workemail.com",
+ "category": "work"
+ },
+ "interaction_count": 0,
+ "monetary_value": 100,
+ "socials": [
+ {
+ "url": "facebook.com/test_lead",
+ "category": "facebook"
+ }
+ ],
+ "status": "New",
+ "status_id": 208231,
+ "tags": ["tag 1", "tag 2"],
+ "title": "Title",
+ "websites": [
+ {
+ "url": "www.workwebsite.com",
+ "category": "work"
+ }
+ ],
+ "phone_numbers": [
+ {
+ "number": "415-999-4321",
+ "category": "mobile"
+ },
+ {
+ "number": "415-555-1234",
+ "category": "work"
+ }
+ ],
+ "custom_fields": [
+ {
+ "custom_field_definition_id": 100764,
+ "value": null
+ },
+ {
+ "custom_field_definition_id": 103481,
+ "value": null
+ }
+ ],
+ "date_created": 1489018784,
+ "date_modified": 1496692911
+ }
+]
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_list_leads.ts b/packages/pipeline/test/fixtures/copper/api_v1_list_leads.ts
new file mode 100644
index 000000000..b1f00cba7
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_list_leads.ts
@@ -0,0 +1,229 @@
+import { CopperLead } from '../../../src/entities';
+const ParsedLeads: CopperLead[] = [
+ {
+ id: 9150547,
+ name: 'My Contact',
+ firstName: 'My',
+ lastName: 'Contact',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1490045162000,
+ dateModified: 1490045162000,
+ },
+ {
+ id: 9150552,
+ name: 'My Contact',
+ firstName: 'My',
+ lastName: 'Contact',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1490045237000,
+ dateModified: 1490045237000,
+ },
+ {
+ id: 9150578,
+ name: 'My Contact',
+ firstName: 'My',
+ lastName: 'Contact',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1490045279000,
+ dateModified: 1490045279000,
+ },
+ {
+ id: 8982554,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489528899000,
+ dateModified: 1489528899000,
+ },
+ {
+ id: 8982702,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489531171000,
+ dateModified: 1489531171000,
+ },
+ {
+ id: 9094361,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489791225000,
+ dateModified: 1489791225000,
+ },
+ {
+ id: 9094364,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489791283000,
+ dateModified: 1489791283000,
+ },
+ {
+ id: 9094371,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489791417000,
+ dateModified: 1489791417000,
+ },
+ {
+ id: 9094372,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489791453000,
+ dateModified: 1489791453000,
+ },
+ {
+ id: 9094373,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489791470000,
+ dateModified: 1489791470000,
+ },
+ {
+ id: 9094383,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1489791672000,
+ dateModified: 1489791672000,
+ },
+ {
+ id: 9174441,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1490112942000,
+ dateModified: 1490112942000,
+ },
+ {
+ id: 9174443,
+ name: 'My Lead',
+ firstName: 'My',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: undefined,
+ companyName: undefined,
+ customerSourceId: undefined,
+ monetaryValue: undefined,
+ status: 'New',
+ statusId: 208231,
+ title: undefined,
+ dateCreated: 1490112953000,
+ dateModified: 1490112953000,
+ },
+ {
+ id: 8894157,
+ name: 'Test Lead',
+ firstName: 'Test',
+ lastName: 'Lead',
+ middleName: undefined,
+ assigneeId: 137658,
+ companyName: "Lead's Company",
+ customerSourceId: 331241,
+ monetaryValue: 100,
+ status: 'New',
+ statusId: 208231,
+ title: 'Title',
+ dateCreated: 1489018784000,
+ dateModified: 1496692911000,
+ },
+];
+
+export { ParsedLeads };
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.json b/packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.json
new file mode 100644
index 000000000..34ac58c30
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.json
@@ -0,0 +1,662 @@
+[
+ {
+ "id": 14050269,
+ "name": "8Base RaaS",
+ "assignee_id": 680302,
+ "close_date": "11/19/2018",
+ "company_id": 27778962,
+ "company_name": "8base",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 66088850,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 81,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542653860,
+ "date_last_contacted": 1544757550,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1538414159,
+ "date_modified": 1544769562,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013, 394018] },
+ { "custom_field_definition_id": 261067, "value": 394026 }
+ ]
+ },
+ {
+ "id": 14631430,
+ "name": "Alice.si TW + ERC 20 Marketplace",
+ "assignee_id": 680302,
+ "close_date": "12/15/2018",
+ "company_id": 30238847,
+ "company_name": "Alice SI",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 69354024,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 4,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542304481,
+ "date_last_contacted": 1542304800,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542304481,
+ "date_modified": 1542304943,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013, 394015] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14632057,
+ "name": "Altcoin.io Relayer",
+ "assignee_id": 680302,
+ "close_date": "12/15/2018",
+ "company_id": 29936486,
+ "company_name": "Altcoin.io",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 68724646,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 22,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542310909,
+ "date_last_contacted": 1543864597,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542306827,
+ "date_modified": 1543864667,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013, 394017] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14667523,
+ "name": "Altcoin.io Relayer",
+ "assignee_id": 680302,
+ "close_date": "12/19/2018",
+ "company_id": 29936486,
+ "company_name": "Altcoin.io",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 68724646,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 21,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542657437,
+ "date_last_contacted": 1543864597,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542657437,
+ "date_modified": 1543864667,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013, 394017] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14666706,
+ "name": "Amadeus Relayer",
+ "assignee_id": 680302,
+ "close_date": "11/19/2018",
+ "company_id": 29243209,
+ "company_name": "Amadeus",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 66912020,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 11,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542654284,
+ "date_last_contacted": 1543264254,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542654284,
+ "date_modified": 1543277520,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14666718,
+ "name": "Ambo Relayer",
+ "assignee_id": 680302,
+ "close_date": "11/19/2018",
+ "company_id": 29249190,
+ "company_name": "Ambo",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 66927869,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 126,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542654352,
+ "date_last_contacted": 1545252349,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542654352,
+ "date_modified": 1545253761,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14164318,
+ "name": "Augur TW",
+ "assignee_id": 680302,
+ "close_date": "12/10/2018",
+ "company_id": 27778967,
+ "company_name": "Augur",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 67248692,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 22,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1544469362,
+ "date_last_contacted": 1544491567,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1539204858,
+ "date_modified": 1544653867,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394021 }
+ ]
+ },
+ {
+ "id": 14666626,
+ "name": "Autonio",
+ "assignee_id": 680302,
+ "close_date": "12/19/2018",
+ "company_id": 27920701,
+ "company_name": "Auton",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392931,
+ "primary_contact_id": 64742640,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 54,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542653834,
+ "date_last_contacted": 1542658568,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542653834,
+ "date_modified": 1542658808,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013, 394019] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14050921,
+ "name": "Axie Infinity 721 Marketplace",
+ "assignee_id": 680302,
+ "close_date": "11/1/2018",
+ "company_id": 27779033,
+ "company_name": "Axie Infinity",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392931,
+ "primary_contact_id": 66499254,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 4,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1543861025,
+ "date_last_contacted": 1539024738,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1538416687,
+ "date_modified": 1543861025,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394014] },
+ { "custom_field_definition_id": 261067, "value": 394134 }
+ ]
+ },
+ {
+ "id": 13735617,
+ "name": "Balance TW",
+ "assignee_id": 680302,
+ "close_date": "12/10/2018",
+ "company_id": 27778968,
+ "company_name": "Balance",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 64713448,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 34,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1544469382,
+ "date_last_contacted": 1545082200,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1535668009,
+ "date_modified": 1545082454,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394027 }
+ ]
+ },
+ {
+ "id": 14667112,
+ "name": "Bamboo Relayer",
+ "assignee_id": 680302,
+ "close_date": "11/19/2018",
+ "company_id": 29243795,
+ "company_name": "Bamboo Relay",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 66914687,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 46,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542655143,
+ "date_last_contacted": 1545252349,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542655143,
+ "date_modified": 1545253761,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 13627309,
+ "name": "Ben TW",
+ "assignee_id": 680302,
+ "close_date": "1/1/2019",
+ "company_id": 27702348,
+ "company_name": "Ben",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 64262622,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 64,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1541527279,
+ "date_last_contacted": 1541639882,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1534887789,
+ "date_modified": 1541651395,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394027 }
+ ]
+ },
+ {
+ "id": 14808512,
+ "name": "Bit2Me Relayer",
+ "assignee_id": 680302,
+ "close_date": "12/3/2018",
+ "company_id": 30793050,
+ "company_name": "Bit2Me",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405442,
+ "primary_contact_id": 70267217,
+ "priority": "None",
+ "status": "Won",
+ "tags": [],
+ "interaction_count": 0,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1543861167,
+ "date_last_contacted": null,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1543861167,
+ "date_modified": 1543861189,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394013] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14050312,
+ "name": "Bitcoin.tax Reporting Integration",
+ "assignee_id": 680302,
+ "close_date": "11/1/2018",
+ "company_id": 27957614,
+ "company_name": "Bitcoin",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392928,
+ "primary_contact_id": 66539479,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 5,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1538414308,
+ "date_last_contacted": 1536766098,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1538414308,
+ "date_modified": 1538414314,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394019] },
+ { "custom_field_definition_id": 261067, "value": 394026 }
+ ]
+ },
+ {
+ "id": 14331463,
+ "name": "Bitpie TW",
+ "assignee_id": 680302,
+ "close_date": "11/19/2018",
+ "company_id": 27779026,
+ "company_name": "Bitpie",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 67700943,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 9,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1539984566,
+ "date_last_contacted": 1541529947,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1539984566,
+ "date_modified": 1541530233,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394027 }
+ ]
+ },
+ {
+ "id": 14331481,
+ "name": "Bitski Wallet SDK TW",
+ "assignee_id": 680302,
+ "close_date": "11/19/2018",
+ "company_id": 29489300,
+ "company_name": "Bitski",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 67697528,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 23,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1539984735,
+ "date_last_contacted": 1544811399,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1539984735,
+ "date_modified": 1544818605,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394026 }
+ ]
+ },
+ {
+ "id": 14531554,
+ "name": "BitUniverse TW",
+ "assignee_id": 680302,
+ "close_date": "12/6/2018",
+ "company_id": 29901805,
+ "company_name": "BitUniverse Co., Ltd (Cryptocurrency Portfolio)",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 68692107,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 15,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1543861104,
+ "date_last_contacted": 1544803276,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1541527110,
+ "date_modified": 1544812979,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394026 }
+ ]
+ },
+ {
+ "id": 14050895,
+ "name": "BlitzPredict PMR",
+ "assignee_id": 680302,
+ "close_date": "11/1/2018",
+ "company_id": 28758258,
+ "company_name": "BlitzPredict",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 66378659,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 32,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1539985501,
+ "date_last_contacted": 1544830560,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1538416597,
+ "date_modified": 1544830709,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394016] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ },
+ {
+ "id": 14209841,
+ "name": "Blockfolio TW",
+ "assignee_id": 680302,
+ "close_date": "11/15/2018",
+ "company_id": 29332516,
+ "company_name": "Blockfolio",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2405443,
+ "primary_contact_id": 67247027,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 20,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1539984098,
+ "date_last_contacted": 1539977661,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1539624801,
+ "date_modified": 1539984098,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394015] },
+ { "custom_field_definition_id": 261067, "value": 394026 }
+ ]
+ },
+ {
+ "id": 14633220,
+ "name": "BlockSwap 721 / 1155 Conversational Marketplace",
+ "assignee_id": 680302,
+ "close_date": "12/15/2018",
+ "company_id": 30210921,
+ "company_name": "BlockSwap",
+ "customer_source_id": null,
+ "details": "blah blah",
+ "loss_reason_id": null,
+ "pipeline_id": 512676,
+ "pipeline_stage_id": 2392929,
+ "primary_contact_id": 69296220,
+ "priority": "None",
+ "status": "Open",
+ "tags": [],
+ "interaction_count": 82,
+ "monetary_unit": null,
+ "monetary_value": null,
+ "converted_unit": null,
+ "converted_value": null,
+ "win_probability": 0,
+ "date_stage_changed": 1542311056,
+ "date_last_contacted": 1543536442,
+ "leads_converted_from": [],
+ "date_lead_created": null,
+ "date_created": 1542311056,
+ "date_modified": 1543557877,
+ "custom_fields": [
+ { "custom_field_definition_id": 261066, "value": [394014] },
+ { "custom_field_definition_id": 261067, "value": 394023 }
+ ]
+ }
+]
diff --git a/packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.ts b/packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.ts
new file mode 100644
index 000000000..3c2d4ae5e
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/api_v1_list_opportunities.ts
@@ -0,0 +1,425 @@
+// tslint:disable:custom-no-magic-numbers
+import { CopperOpportunity } from '../../../src/entities';
+const ParsedOpportunities: CopperOpportunity[] = [
+ {
+ id: 14050269,
+ name: '8Base RaaS',
+ assigneeId: 680302,
+ closeDate: '11/19/2018',
+ companyId: 27778962,
+ companyName: '8base',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 66088850,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 81,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1538414159000,
+ dateModified: 1544769562000,
+ customFields: { '261066': 394018, '261067': 394026 },
+ },
+ {
+ id: 14631430,
+ name: 'Alice.si TW + ERC 20 Marketplace',
+ assigneeId: 680302,
+ closeDate: '12/15/2018',
+ companyId: 30238847,
+ companyName: 'Alice SI',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 69354024,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 4,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542304481000,
+ dateModified: 1542304943000,
+ customFields: { '261066': 394015, '261067': 394023 },
+ },
+ {
+ id: 14632057,
+ name: 'Altcoin.io Relayer',
+ assigneeId: 680302,
+ closeDate: '12/15/2018',
+ companyId: 29936486,
+ companyName: 'Altcoin.io',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 68724646,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 22,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542306827000,
+ dateModified: 1543864667000,
+ customFields: { '261066': 394017, '261067': 394023 },
+ },
+ {
+ id: 14667523,
+ name: 'Altcoin.io Relayer',
+ assigneeId: 680302,
+ closeDate: '12/19/2018',
+ companyId: 29936486,
+ companyName: 'Altcoin.io',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 68724646,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 21,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542657437000,
+ dateModified: 1543864667000,
+ customFields: { '261066': 394017, '261067': 394023 },
+ },
+ {
+ id: 14666706,
+ name: 'Amadeus Relayer',
+ assigneeId: 680302,
+ closeDate: '11/19/2018',
+ companyId: 29243209,
+ companyName: 'Amadeus',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 66912020,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 11,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542654284000,
+ dateModified: 1543277520000,
+ customFields: { '261066': 394013, '261067': 394023 },
+ },
+ {
+ id: 14666718,
+ name: 'Ambo Relayer',
+ assigneeId: 680302,
+ closeDate: '11/19/2018',
+ companyId: 29249190,
+ companyName: 'Ambo',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 66927869,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 126,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542654352000,
+ dateModified: 1545253761000,
+ customFields: { '261066': 394013, '261067': 394023 },
+ },
+ {
+ id: 14164318,
+ name: 'Augur TW',
+ assigneeId: 680302,
+ closeDate: '12/10/2018',
+ companyId: 27778967,
+ companyName: 'Augur',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 67248692,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 22,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1539204858000,
+ dateModified: 1544653867000,
+ customFields: { '261066': 394015, '261067': 394021 },
+ },
+ {
+ id: 14666626,
+ name: 'Autonio',
+ assigneeId: 680302,
+ closeDate: '12/19/2018',
+ companyId: 27920701,
+ companyName: 'Auton',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392931,
+ primaryContactId: 64742640,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 54,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542653834000,
+ dateModified: 1542658808000,
+ customFields: { '261066': 394019, '261067': 394023 },
+ },
+ {
+ id: 14050921,
+ name: 'Axie Infinity 721 Marketplace',
+ assigneeId: 680302,
+ closeDate: '11/1/2018',
+ companyId: 27779033,
+ companyName: 'Axie Infinity',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392931,
+ primaryContactId: 66499254,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 4,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1538416687000,
+ dateModified: 1543861025000,
+ customFields: { '261066': 394014, '261067': 394134 },
+ },
+ {
+ id: 13735617,
+ name: 'Balance TW',
+ assigneeId: 680302,
+ closeDate: '12/10/2018',
+ companyId: 27778968,
+ companyName: 'Balance',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 64713448,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 34,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1535668009000,
+ dateModified: 1545082454000,
+ customFields: { '261066': 394015, '261067': 394027 },
+ },
+ {
+ id: 14667112,
+ name: 'Bamboo Relayer',
+ assigneeId: 680302,
+ closeDate: '11/19/2018',
+ companyId: 29243795,
+ companyName: 'Bamboo Relay',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 66914687,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 46,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542655143000,
+ dateModified: 1545253761000,
+ customFields: { '261066': 394013, '261067': 394023 },
+ },
+ {
+ id: 13627309,
+ name: 'Ben TW',
+ assigneeId: 680302,
+ closeDate: '1/1/2019',
+ companyId: 27702348,
+ companyName: 'Ben',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 64262622,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 64,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1534887789000,
+ dateModified: 1541651395000,
+ customFields: { '261066': 394015, '261067': 394027 },
+ },
+ {
+ id: 14808512,
+ name: 'Bit2Me Relayer',
+ assigneeId: 680302,
+ closeDate: '12/3/2018',
+ companyId: 30793050,
+ companyName: 'Bit2Me',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405442,
+ primaryContactId: 70267217,
+ priority: 'None',
+ status: 'Won',
+ interactionCount: 0,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1543861167000,
+ dateModified: 1543861189000,
+ customFields: { '261066': 394013, '261067': 394023 },
+ },
+ {
+ id: 14050312,
+ name: 'Bitcoin.tax Reporting Integration',
+ assigneeId: 680302,
+ closeDate: '11/1/2018',
+ companyId: 27957614,
+ companyName: 'Bitcoin',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392928,
+ primaryContactId: 66539479,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 5,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1538414308000,
+ dateModified: 1538414314000,
+ customFields: { '261066': 394019, '261067': 394026 },
+ },
+ {
+ id: 14331463,
+ name: 'Bitpie TW',
+ assigneeId: 680302,
+ closeDate: '11/19/2018',
+ companyId: 27779026,
+ companyName: 'Bitpie',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 67700943,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 9,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1539984566000,
+ dateModified: 1541530233000,
+ customFields: { '261066': 394015, '261067': 394027 },
+ },
+ {
+ id: 14331481,
+ name: 'Bitski Wallet SDK TW',
+ assigneeId: 680302,
+ closeDate: '11/19/2018',
+ companyId: 29489300,
+ companyName: 'Bitski',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 67697528,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 23,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1539984735000,
+ dateModified: 1544818605000,
+ customFields: { '261066': 394015, '261067': 394026 },
+ },
+ {
+ id: 14531554,
+ name: 'BitUniverse TW',
+ assigneeId: 680302,
+ closeDate: '12/6/2018',
+ companyId: 29901805,
+ companyName: 'BitUniverse Co., Ltd (Cryptocurrency Portfolio)',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 68692107,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 15,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1541527110000,
+ dateModified: 1544812979000,
+ customFields: { '261066': 394015, '261067': 394026 },
+ },
+ {
+ id: 14050895,
+ name: 'BlitzPredict PMR',
+ assigneeId: 680302,
+ closeDate: '11/1/2018',
+ companyId: 28758258,
+ companyName: 'BlitzPredict',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 66378659,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 32,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1538416597000,
+ dateModified: 1544830709000,
+ customFields: { '261066': 394016, '261067': 394023 },
+ },
+ {
+ id: 14209841,
+ name: 'Blockfolio TW',
+ assigneeId: 680302,
+ closeDate: '11/15/2018',
+ companyId: 29332516,
+ companyName: 'Blockfolio',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2405443,
+ primaryContactId: 67247027,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 20,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1539624801000,
+ dateModified: 1539984098000,
+ customFields: { '261066': 394015, '261067': 394026 },
+ },
+ {
+ id: 14633220,
+ name: 'BlockSwap 721 / 1155 Conversational Marketplace',
+ assigneeId: 680302,
+ closeDate: '12/15/2018',
+ companyId: 30210921,
+ companyName: 'BlockSwap',
+ customerSourceId: undefined,
+ lossReasonId: undefined,
+ pipelineId: 512676,
+ pipelineStageId: 2392929,
+ primaryContactId: 69296220,
+ priority: 'None',
+ status: 'Open',
+ interactionCount: 82,
+ monetaryValue: undefined,
+ winProbability: 0,
+ dateCreated: 1542311056000,
+ dateModified: 1543557877000,
+ customFields: { '261066': 394014, '261067': 394023 },
+ },
+];
+export { ParsedOpportunities };
diff --git a/packages/pipeline/test/fixtures/copper/parsed_entities.ts b/packages/pipeline/test/fixtures/copper/parsed_entities.ts
new file mode 100644
index 000000000..1f49d38ed
--- /dev/null
+++ b/packages/pipeline/test/fixtures/copper/parsed_entities.ts
@@ -0,0 +1,5 @@
+export { ParsedActivityTypes } from './api_v1_activity_types';
+export { ParsedCustomFields } from './api_v1_custom_field_definitions';
+export { ParsedActivities } from './api_v1_list_activities';
+export { ParsedLeads } from './api_v1_list_leads';
+export { ParsedOpportunities } from './api_v1_list_opportunities';
diff --git a/packages/pipeline/test/parsers/copper/index_test.ts b/packages/pipeline/test/parsers/copper/index_test.ts
new file mode 100644
index 000000000..bb8e70da1
--- /dev/null
+++ b/packages/pipeline/test/parsers/copper/index_test.ts
@@ -0,0 +1,87 @@
+import * as chai from 'chai';
+import 'mocha';
+
+import {
+ CopperActivity,
+ CopperActivityType,
+ CopperCustomField,
+ CopperLead,
+ CopperOpportunity,
+} from '../../../src/entities';
+import {
+ CopperActivityResponse,
+ CopperActivityTypeCategory,
+ CopperActivityTypeResponse,
+ CopperCustomFieldResponse,
+ CopperSearchResponse,
+ parseActivities,
+ parseActivityTypes,
+ parseCustomFields,
+ parseLeads,
+ parseOpportunities,
+} from '../../../src/parsers/copper';
+import { chaiSetup } from '../../utils/chai_setup';
+
+chaiSetup.configure();
+const expect = chai.expect;
+
+type CopperResponse = CopperSearchResponse | CopperCustomFieldResponse;
+type CopperEntity = CopperLead | CopperActivity | CopperOpportunity | CopperActivityType | CopperCustomField;
+
+import * as activityTypesApiResponse from '../../fixtures/copper/api_v1_activity_types.json';
+import * as customFieldsApiResponse from '../../fixtures/copper/api_v1_custom_field_definitions.json';
+import * as listActivitiesApiResponse from '../../fixtures/copper/api_v1_list_activities.json';
+import * as listLeadsApiResponse from '../../fixtures/copper/api_v1_list_leads.json';
+import * as listOpportunitiesApiResponse from '../../fixtures/copper/api_v1_list_opportunities.json';
+import {
+ ParsedActivities,
+ ParsedActivityTypes,
+ ParsedCustomFields,
+ ParsedLeads,
+ ParsedOpportunities,
+} from '../../fixtures/copper/parsed_entities';
+
+interface TestCase {
+ input: CopperResponse[];
+ expected: CopperEntity[];
+ parseFn(input: CopperResponse[]): CopperEntity[];
+}
+const testCases: TestCase[] = [
+ {
+ input: listLeadsApiResponse,
+ expected: ParsedLeads,
+ parseFn: parseLeads,
+ },
+ {
+ input: (listActivitiesApiResponse as unknown) as CopperActivityResponse[],
+ expected: ParsedActivities,
+ parseFn: parseActivities,
+ },
+ {
+ input: listOpportunitiesApiResponse,
+ expected: ParsedOpportunities,
+ parseFn: parseOpportunities,
+ },
+ {
+ input: customFieldsApiResponse,
+ expected: ParsedCustomFields,
+ parseFn: parseCustomFields,
+ },
+];
+describe('Copper parser', () => {
+ it('parses API responses', () => {
+ testCases.forEach(testCase => {
+ const actual: CopperEntity[] = testCase.parseFn(testCase.input);
+ expect(actual).deep.equal(testCase.expected);
+ });
+ });
+
+ // special case because the API response is not an array
+ it('parses activity types API response', () => {
+ const actual: CopperActivityType[] = parseActivityTypes((activityTypesApiResponse as unknown) as Map<
+ CopperActivityTypeCategory,
+ CopperActivityTypeResponse[]
+ >);
+ expect(actual).deep.equal(ParsedActivityTypes);
+ });
+});
diff --git a/packages/pipeline/tsconfig.json b/packages/pipeline/tsconfig.json
index 6f138f260..45e07374c 100644
--- a/packages/pipeline/tsconfig.json
+++ b/packages/pipeline/tsconfig.json
@@ -4,7 +4,15 @@
"outDir": "lib",
"rootDir": ".",
"emitDecoratorMetadata": true,
- "experimentalDecorators": true
+ "experimentalDecorators": true,
+ "resolveJsonModule": true
},
- "include": ["./src/**/*", "./test/**/*", "./migrations/**/*"]
+ "include": ["./src/**/*", "./test/**/*", "./migrations/**/*"],
+ "files": [
+ "./test/fixtures/copper/api_v1_activity_types.json",
+ "./test/fixtures/copper/api_v1_custom_field_definitions.json",
+ "./test/fixtures/copper/api_v1_list_activities.json",
+ "./test/fixtures/copper/api_v1_list_leads.json",
+ "./test/fixtures/copper/api_v1_list_opportunities.json"
+ ]
}
diff --git a/packages/react-docs/CHANGELOG.json b/packages/react-docs/CHANGELOG.json
index 9d8b5bc88..13109e613 100644
--- a/packages/react-docs/CHANGELOG.json
+++ b/packages/react-docs/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "1.0.23",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "1.0.22",
"changes": [
{
diff --git a/packages/react-docs/CHANGELOG.md b/packages/react-docs/CHANGELOG.md
index 5c702d562..01f987645 100644
--- a/packages/react-docs/CHANGELOG.md
+++ b/packages/react-docs/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.0.23 - _January 9, 2019_
+
+ * Dependencies updated
+
## v1.0.22 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json
index f58a51c90..7cd0ae55a 100644
--- a/packages/react-docs/package.json
+++ b/packages/react-docs/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/react-docs",
- "version": "1.0.22",
+ "version": "1.0.23",
"engines": {
"node": ">=6.12"
},
@@ -24,19 +24,19 @@
"url": "https://github.com/0xProject/0x-monorepo.git"
},
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
+ "@0x/dev-utils": "^1.0.22",
"@0x/tslint-config": "^2.0.0",
"@types/compare-versions": "^3.0.0",
- "@types/styled-components": "^4.0.0",
+ "@types/styled-components": "4.0.0",
"make-promises-safe": "^1.1.0",
"shx": "^0.2.2",
"tslint": "^5.9.1",
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/react-shared": "^1.0.25",
- "@0x/types": "^1.4.1",
- "@0x/utils": "^2.0.8",
+ "@0x/react-shared": "^1.1.0",
+ "@0x/types": "^1.5.0",
+ "@0x/utils": "^2.1.1",
"@types/lodash": "4.14.104",
"@types/material-ui": "^0.20.0",
"@types/node": "*",
diff --git a/packages/react-shared/CHANGELOG.json b/packages/react-shared/CHANGELOG.json
index 9ef0d079f..aaf2485d1 100644
--- a/packages/react-shared/CHANGELOG.json
+++ b/packages/react-shared/CHANGELOG.json
@@ -7,7 +7,8 @@
"Change implementation to use react-router-dom NavLink instead of Link. Expose `activeStyle` prop.",
"pr": 1448
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "1.0.25",
diff --git a/packages/react-shared/CHANGELOG.md b/packages/react-shared/CHANGELOG.md
index 8afa94e04..a8f2764dd 100644
--- a/packages/react-shared/CHANGELOG.md
+++ b/packages/react-shared/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.1.0 - _January 9, 2019_
+
+ * Change implementation to use react-router-dom NavLink instead of Link. Expose `activeStyle` prop. (#1448)
+
## v1.0.25 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/react-shared/package.json b/packages/react-shared/package.json
index 17defe35a..5754e238b 100644
--- a/packages/react-shared/package.json
+++ b/packages/react-shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/react-shared",
- "version": "1.0.25",
+ "version": "1.1.0",
"engines": {
"node": ">=6.12"
},
@@ -25,7 +25,7 @@
"url": "https://github.com/0xProject/0x-monorepo.git"
},
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
+ "@0x/dev-utils": "^1.0.22",
"@0x/tslint-config": "^2.0.0",
"make-promises-safe": "^1.1.0",
"shx": "^0.2.2",
@@ -33,7 +33,7 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/types": "^1.4.1",
+ "@0x/types": "^1.5.0",
"@material-ui/core": "^3.0.1",
"@types/is-mobile": "0.3.0",
"@types/lodash": "4.14.104",
@@ -43,7 +43,7 @@
"@types/react-dom": "*",
"@types/react-router-dom": "^4.0.4",
"@types/react-scroll": "1.5.3",
- "@types/styled-components": "^4.0.0",
+ "@types/styled-components": "4.0.0",
"@types/valid-url": "^1.0.2",
"basscss": "^8.0.3",
"change-case": "^3.0.2",
diff --git a/packages/sol-compiler/CHANGELOG.json b/packages/sol-compiler/CHANGELOG.json
index 8548fd73f..3c88bf4e9 100644
--- a/packages/sol-compiler/CHANGELOG.json
+++ b/packages/sol-compiler/CHANGELOG.json
@@ -9,8 +9,13 @@
{
"note": "Make error and warning colouring more visually pleasant and consistent with other compilers",
"pr": 1461
+ },
+ {
+ "note": "Add newest solidity versions from 0.4.25 to 0.5.2",
+ "pr": 1496
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "1.1.16",
diff --git a/packages/sol-compiler/CHANGELOG.md b/packages/sol-compiler/CHANGELOG.md
index b2066448d..6ec804c3a 100644
--- a/packages/sol-compiler/CHANGELOG.md
+++ b/packages/sol-compiler/CHANGELOG.md
@@ -5,6 +5,12 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.0.0 - _January 9, 2019_
+
+ * Add sol-compiler watch mode with -w flag (#1461)
+ * Make error and warning colouring more visually pleasant and consistent with other compilers (#1461)
+ * Add newest solidity versions from 0.4.25 to 0.5.2 (#1496)
+
## v1.1.16 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/sol-compiler/package.json b/packages/sol-compiler/package.json
index 86167a603..6c9435bcd 100644
--- a/packages/sol-compiler/package.json
+++ b/packages/sol-compiler/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/sol-compiler",
- "version": "1.1.16",
+ "version": "2.0.0",
"engines": {
"node": ">=6.12"
},
@@ -42,7 +42,7 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-compiler/README.md",
"devDependencies": {
- "@0x/dev-utils": "^1.0.21",
+ "@0x/dev-utils": "^1.0.22",
"@0x/tslint-config": "^2.0.0",
"@types/chokidar": "^1.7.5",
"@types/mkdirp": "^0.5.2",
@@ -67,13 +67,13 @@
"zeppelin-solidity": "1.8.0"
},
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/json-schemas": "^2.1.4",
- "@0x/sol-resolver": "^1.1.1",
- "@0x/types": "^1.4.1",
+ "@0x/assert": "^1.0.21",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/sol-resolver": "^1.2.1",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/yargs": "^11.0.0",
"chalk": "^2.3.0",
"chokidar": "^2.0.4",
@@ -84,7 +84,7 @@
"pluralize": "^7.0.0",
"require-from-string": "^2.0.1",
"semver": "5.5.0",
- "solc": "^0.4.23",
+ "solc": "^0.5.2",
"source-map-support": "^0.5.0",
"web3-eth-abi": "^1.0.0-beta.24",
"yargs": "^10.0.3"
diff --git a/packages/sol-compiler/src/solc/bin_paths.ts b/packages/sol-compiler/src/solc/bin_paths.ts
index a75255dc6..b653c0926 100644
--- a/packages/sol-compiler/src/solc/bin_paths.ts
+++ b/packages/sol-compiler/src/solc/bin_paths.ts
@@ -3,19 +3,50 @@ export interface BinaryPaths {
}
export const binPaths: BinaryPaths = {
- '0.4.10': 'soljson-v0.4.10+commit.f0d539ae.js',
- '0.4.11': 'soljson-v0.4.11+commit.68ef5810.js',
- '0.4.12': 'soljson-v0.4.12+commit.194ff033.js',
- '0.4.13': 'soljson-v0.4.13+commit.fb4cb1a.js',
- '0.4.14': 'soljson-v0.4.14+commit.c2215d46.js',
- '0.4.15': 'soljson-v0.4.15+commit.bbb8e64f.js',
- '0.4.16': 'soljson-v0.4.16+commit.d7661dd9.js',
- '0.4.17': 'soljson-v0.4.17+commit.bdeb9e52.js',
- '0.4.18': 'soljson-v0.4.18+commit.9cf6e910.js',
- '0.4.19': 'soljson-v0.4.19+commit.c4cbbb05.js',
- '0.4.20': 'soljson-v0.4.20+commit.3155dd80.js',
- '0.4.21': 'soljson-v0.4.21+commit.dfe3193c.js',
- '0.4.22': 'soljson-v0.4.22+commit.4cb486ee.js',
- '0.4.23': 'soljson-v0.4.23+commit.124ca40d.js',
+ '0.5.2': 'soljson-v0.5.2+commit.1df8f40c.js',
+ '0.5.1': 'soljson-v0.5.1+commit.c8a2cb62.js',
+ '0.5.0': 'soljson-v0.5.0+commit.1d4f565a.js',
+ '0.4.25': 'soljson-v0.4.25+commit.59dbf8f1.js',
'0.4.24': 'soljson-v0.4.24+commit.e67f0147.js',
+ '0.4.23': 'soljson-v0.4.23+commit.124ca40d.js',
+ '0.4.22': 'soljson-v0.4.22+commit.4cb486ee.js',
+ '0.4.21': 'soljson-v0.4.21+commit.dfe3193c.js',
+ '0.4.20': 'soljson-v0.4.20+commit.3155dd80.js',
+ '0.4.19': 'soljson-v0.4.19+commit.c4cbbb05.js',
+ '0.4.18': 'soljson-v0.4.18+commit.9cf6e910.js',
+ '0.4.17': 'soljson-v0.4.17+commit.bdeb9e52.js',
+ '0.4.16': 'soljson-v0.4.16+commit.d7661dd9.js',
+ '0.4.15': 'soljson-v0.4.15+commit.bbb8e64f.js',
+ '0.4.14': 'soljson-v0.4.14+commit.c2215d46.js',
+ '0.4.13': 'soljson-v0.4.13+commit.fb4cb1a.js',
+ '0.4.12': 'soljson-v0.4.12+commit.194ff033.js',
+ '0.4.11': 'soljson-v0.4.11+commit.68ef5810.js',
+ '0.4.10': 'soljson-v0.4.10+commit.f0d539ae.js',
+ '0.4.9': 'soljson-v0.4.9+commit.364da425.js',
+ '0.4.8': 'soljson-v0.4.8+commit.60cc1668.js',
+ '0.4.7': 'soljson-v0.4.7+commit.822622cf.js',
+ '0.4.6': 'soljson-v0.4.6+commit.2dabbdf0.js',
+ '0.4.5': 'soljson-v0.4.5+commit.b318366e.js',
+ '0.4.4': 'soljson-v0.4.4+commit.4633f3de.js',
+ '0.4.3': 'soljson-v0.4.3+commit.2353da71.js',
+ '0.4.2': 'soljson-v0.4.2+commit.af6afb04.js',
+ '0.4.1': 'soljson-v0.4.1+commit.4fc6fc2c.js',
+ '0.4.0': 'soljson-v0.4.0+commit.acd334c9.js',
+ '0.3.6': 'soljson-v0.3.6+commit.3fc68da.js',
+ '0.3.5': 'soljson-v0.3.5+commit.5f97274.js',
+ '0.3.4': 'soljson-v0.3.4+commit.7dab890.js',
+ '0.3.3': 'soljson-v0.3.3+commit.4dc1cb1.js',
+ '0.3.2': 'soljson-v0.3.2+commit.81ae2a7.js',
+ '0.3.1': 'soljson-v0.3.1+commit.c492d9b.js',
+ '0.3.0': 'soljson-v0.3.0+commit.11d6736.js',
+ '0.2.2': 'soljson-v0.2.2+commit.ef92f56.js',
+ '0.2.1': 'soljson-v0.2.1+commit.91a6b35.js',
+ '0.2.0': 'soljson-v0.2.0+commit.4dc2445.js',
+ '0.1.7': 'soljson-v0.1.7+commit.b4e666c.js',
+ '0.1.6': 'soljson-v0.1.6+commit.d41f8b7.js',
+ '0.1.5': 'soljson-v0.1.5+commit.23865e3.js',
+ '0.1.4': 'soljson-v0.1.4+commit.5f6c3cd.js',
+ '0.1.3': 'soljson-v0.1.3+commit.28f561.js',
+ '0.1.2': 'soljson-v0.1.2+commit.d0d36e3.js',
+ '0.1.1': 'soljson-v0.1.1+commit.6ff4cd6.js',
};
diff --git a/packages/sol-doc/CHANGELOG.json b/packages/sol-doc/CHANGELOG.json
index e8fef746e..1be3b2121 100644
--- a/packages/sol-doc/CHANGELOG.json
+++ b/packages/sol-doc/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "1.0.12",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "1.0.11",
"changes": [
{
diff --git a/packages/sol-doc/CHANGELOG.md b/packages/sol-doc/CHANGELOG.md
index 1b4a938af..3416662e5 100644
--- a/packages/sol-doc/CHANGELOG.md
+++ b/packages/sol-doc/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.0.12 - _January 9, 2019_
+
+ * Dependencies updated
+
## v1.0.11 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/sol-doc/package.json b/packages/sol-doc/package.json
index c83c122df..f93abfe49 100644
--- a/packages/sol-doc/package.json
+++ b/packages/sol-doc/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/sol-doc",
- "version": "1.0.11",
+ "version": "1.0.12",
"description": "Solidity documentation generator",
"main": "lib/src/index.js",
"types": "lib/src/index.d.js",
@@ -25,9 +25,9 @@
"author": "F. Eugene Aumson",
"license": "Apache-2.0",
"dependencies": {
- "@0x/sol-compiler": "^1.1.16",
- "@0x/types": "^1.4.1",
- "@0x/utils": "^2.0.8",
+ "@0x/sol-compiler": "^2.0.0",
+ "@0x/types": "^1.5.0",
+ "@0x/utils": "^2.1.1",
"ethereum-types": "^1.1.4",
"ethereumjs-util": "^5.1.1",
"lodash": "^4.17.10",
diff --git a/packages/sol-resolver/CHANGELOG.json b/packages/sol-resolver/CHANGELOG.json
index 74c4d39c5..d541dc320 100644
--- a/packages/sol-resolver/CHANGELOG.json
+++ b/packages/sol-resolver/CHANGELOG.json
@@ -10,7 +10,8 @@
"note": "Add `SpyResolver` that records all resolved contracts data",
"pr": 1461
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "1.1.1",
diff --git a/packages/sol-resolver/CHANGELOG.md b/packages/sol-resolver/CHANGELOG.md
index 98435be19..b03f21b79 100644
--- a/packages/sol-resolver/CHANGELOG.md
+++ b/packages/sol-resolver/CHANGELOG.md
@@ -5,6 +5,11 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.2.1 - _January 9, 2019_
+
+ * Add `absolutePath` to `ContractSource` type (#1461)
+ * Add `SpyResolver` that records all resolved contracts data (#1461)
+
## v1.1.1 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/sol-resolver/package.json b/packages/sol-resolver/package.json
index 0163765d9..b33a4f494 100644
--- a/packages/sol-resolver/package.json
+++ b/packages/sol-resolver/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/sol-resolver",
- "version": "1.1.1",
+ "version": "1.2.1",
"engines": {
"node": ">=6.12"
},
@@ -30,7 +30,7 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/types": "^1.4.1",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
"lodash": "^4.17.5"
},
diff --git a/packages/sol-tracing-utils/CHANGELOG.json b/packages/sol-tracing-utils/CHANGELOG.json
index caccb3fff..c39753ea1 100644
--- a/packages/sol-tracing-utils/CHANGELOG.json
+++ b/packages/sol-tracing-utils/CHANGELOG.json
@@ -9,6 +9,15 @@
]
},
{
+ "timestamp": 1547040760,
+ "version": "2.1.17",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "2.1.16",
"changes": [
{
diff --git a/packages/sol-tracing-utils/CHANGELOG.md b/packages/sol-tracing-utils/CHANGELOG.md
index 879ef9c95..c2bc3cd01 100644
--- a/packages/sol-tracing-utils/CHANGELOG.md
+++ b/packages/sol-tracing-utils/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.17 - _January 9, 2019_
+
+ * Dependencies updated
+
## v2.1.16 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/sol-tracing-utils/package.json b/packages/sol-tracing-utils/package.json
index f351ccc08..9486ab541 100644
--- a/packages/sol-tracing-utils/package.json
+++ b/packages/sol-tracing-utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/sol-tracing-utils",
- "version": "2.1.16",
+ "version": "2.1.17",
"engines": {
"node": ">=6.12"
},
@@ -42,12 +42,12 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/sol-tracing-utils/README.md",
"dependencies": {
- "@0x/dev-utils": "^1.0.21",
- "@0x/sol-compiler": "^1.1.16",
- "@0x/subproviders": "^2.1.8",
+ "@0x/dev-utils": "^1.0.22",
+ "@0x/sol-compiler": "^2.0.0",
+ "@0x/subproviders": "^2.1.9",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@types/solidity-parser-antlr": "^0.2.0",
"ethereum-types": "^1.1.4",
"ethereumjs-util": "^5.1.1",
diff --git a/packages/sra-spec/CHANGELOG.json b/packages/sra-spec/CHANGELOG.json
index 393054465..fe52a8111 100644
--- a/packages/sra-spec/CHANGELOG.json
+++ b/packages/sra-spec/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "1.0.14",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "1.0.13",
"changes": [
{
diff --git a/packages/sra-spec/CHANGELOG.md b/packages/sra-spec/CHANGELOG.md
index fd673b837..36b6b1fb0 100644
--- a/packages/sra-spec/CHANGELOG.md
+++ b/packages/sra-spec/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.0.14 - _January 9, 2019_
+
+ * Dependencies updated
+
## v1.0.13 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/sra-spec/package.json b/packages/sra-spec/package.json
index 3a6ee96d3..a0caea0f4 100644
--- a/packages/sra-spec/package.json
+++ b/packages/sra-spec/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/sra-spec",
- "version": "1.0.13",
+ "version": "1.0.14",
"engines": {
"node": ">=6.12"
},
@@ -35,7 +35,7 @@
},
"homepage": "https://github.com/0xProject/0x-monorepo/packages/sra-spec/README.md",
"dependencies": {
- "@0x/json-schemas": "^2.1.4",
+ "@0x/json-schemas": "^2.1.5",
"@loopback/openapi-v3-types": "^0.8.2"
},
"devDependencies": {
diff --git a/packages/subproviders/CHANGELOG.json b/packages/subproviders/CHANGELOG.json
index 938b2a717..cc0e0414a 100644
--- a/packages/subproviders/CHANGELOG.json
+++ b/packages/subproviders/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "2.1.9",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "2.1.8",
"changes": [
{
diff --git a/packages/subproviders/CHANGELOG.md b/packages/subproviders/CHANGELOG.md
index 002c76395..076cce935 100644
--- a/packages/subproviders/CHANGELOG.md
+++ b/packages/subproviders/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.9 - _January 9, 2019_
+
+ * Dependencies updated
+
## v2.1.8 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/subproviders/package.json b/packages/subproviders/package.json
index 90ef6b677..178e7a99c 100644
--- a/packages/subproviders/package.json
+++ b/packages/subproviders/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/subproviders",
- "version": "2.1.8",
+ "version": "2.1.9",
"engines": {
"node": ">=6.12"
},
@@ -29,11 +29,11 @@
}
},
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/types": "^1.4.1",
+ "@0x/assert": "^1.0.21",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@ledgerhq/hw-app-eth": "^4.3.0",
"@ledgerhq/hw-transport-u2f": "4.24.0",
"@types/eth-lightwallet": "^3.0.0",
diff --git a/packages/testnet-faucets/package.json b/packages/testnet-faucets/package.json
index 70d785c74..b01ef4b8e 100644
--- a/packages/testnet-faucets/package.json
+++ b/packages/testnet-faucets/package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@0x/testnet-faucets",
- "version": "1.0.60",
+ "version": "1.0.61",
"engines": {
"node": ">=6.12"
},
@@ -18,11 +18,11 @@
"author": "Fabio Berger",
"license": "Apache-2.0",
"dependencies": {
- "0x.js": "^2.0.8",
- "@0x/subproviders": "^2.1.8",
+ "0x.js": "^3.0.0",
+ "@0x/subproviders": "^2.1.9",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
- "@0x/web3-wrapper": "^3.2.1",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"body-parser": "^1.17.1",
"ethereum-types": "^1.1.4",
"ethereumjs-tx": "^1.3.5",
diff --git a/packages/types/CHANGELOG.json b/packages/types/CHANGELOG.json
index 7094953cb..754cd29dc 100644
--- a/packages/types/CHANGELOG.json
+++ b/packages/types/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Added types for Dutch Auction contract",
"pr": 1465
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "1.4.1",
diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md
index 5170eb4db..a1745cf94 100644
--- a/packages/types/CHANGELOG.md
+++ b/packages/types/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v1.5.0 - _January 9, 2019_
+
+ * Added types for Dutch Auction contract (#1465)
+
## v1.4.1 - _December 13, 2018_
* Dependencies updated
@@ -13,6 +17,7 @@ CHANGELOG
* Add `LengthMismatch` and `LengthGreaterThan3Required` revert reasons (#1224)
* Add RevertReasons for DutchAuction contract (#1225)
+ * Add MultiAsset types (#1363)
## v1.3.0 - _November 21, 2018_
diff --git a/packages/types/package.json b/packages/types/package.json
index 3c4bb6fe6..75c3b7c63 100644
--- a/packages/types/package.json
+++ b/packages/types/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/types",
- "version": "1.4.1",
+ "version": "1.5.0",
"engines": {
"node": ">=6.12"
},
diff --git a/packages/utils/CHANGELOG.json b/packages/utils/CHANGELOG.json
index eb94da8d6..fb85c4174 100644
--- a/packages/utils/CHANGELOG.json
+++ b/packages/utils/CHANGELOG.json
@@ -6,7 +6,8 @@
"note": "Add `should` prefix to names of properties in EncodingRules and DecodingRules",
"pr": 1363
}
- ]
+ ],
+ "timestamp": 1547040760
},
{
"version": "2.1.0",
diff --git a/packages/utils/CHANGELOG.md b/packages/utils/CHANGELOG.md
index c0437392d..15d78e321 100644
--- a/packages/utils/CHANGELOG.md
+++ b/packages/utils/CHANGELOG.md
@@ -5,6 +5,14 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v2.1.1 - _January 9, 2019_
+
+ * Add `should` prefix to names of properties in EncodingRules and DecodingRules (#1363)
+
+## v2.1.0 - _Invalid date_
+
+ * Add `logWithTime` to `logUtils` (#1461)
+
## v2.0.8 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/utils/package.json b/packages/utils/package.json
index 5ffec049a..49d6e3013 100644
--- a/packages/utils/package.json
+++ b/packages/utils/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/utils",
- "version": "2.0.8",
+ "version": "2.1.1",
"engines": {
"node": ">=6.12"
},
@@ -44,7 +44,7 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/types": "^1.4.1",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.6",
"@types/node": "*",
"abortcontroller-polyfill": "^1.1.9",
diff --git a/packages/web3-wrapper/CHANGELOG.json b/packages/web3-wrapper/CHANGELOG.json
index 6b76626a9..65f811028 100644
--- a/packages/web3-wrapper/CHANGELOG.json
+++ b/packages/web3-wrapper/CHANGELOG.json
@@ -1,5 +1,14 @@
[
{
+ "timestamp": 1547040760,
+ "version": "3.2.2",
+ "changes": [
+ {
+ "note": "Dependencies updated"
+ }
+ ]
+ },
+ {
"version": "3.2.1",
"changes": [
{
diff --git a/packages/web3-wrapper/CHANGELOG.md b/packages/web3-wrapper/CHANGELOG.md
index 76ca80e69..4242fe0cc 100644
--- a/packages/web3-wrapper/CHANGELOG.md
+++ b/packages/web3-wrapper/CHANGELOG.md
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
CHANGELOG
+## v3.2.2 - _January 9, 2019_
+
+ * Dependencies updated
+
## v3.2.1 - _December 13, 2018_
* Dependencies updated
diff --git a/packages/web3-wrapper/package.json b/packages/web3-wrapper/package.json
index e5af24965..b67472a8a 100644
--- a/packages/web3-wrapper/package.json
+++ b/packages/web3-wrapper/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/web3-wrapper",
- "version": "3.2.1",
+ "version": "3.2.2",
"engines": {
"node": ">=6.12"
},
@@ -54,10 +54,10 @@
"typescript": "3.0.1"
},
"dependencies": {
- "@0x/assert": "^1.0.20",
- "@0x/json-schemas": "^2.1.4",
+ "@0x/assert": "^1.0.21",
+ "@0x/json-schemas": "^2.1.5",
"@0x/typescript-typings": "^3.0.6",
- "@0x/utils": "^2.0.8",
+ "@0x/utils": "^2.1.1",
"ethereum-types": "^1.1.4",
"ethereumjs-util": "^5.1.1",
"ethers": "~4.0.4",
diff --git a/packages/website/package.json b/packages/website/package.json
index bb97ea4e8..af43fabf9 100644
--- a/packages/website/package.json
+++ b/packages/website/package.json
@@ -1,6 +1,6 @@
{
"name": "@0x/website",
- "version": "0.0.63",
+ "version": "0.0.64",
"engines": {
"node": ">=6.12"
},
@@ -20,23 +20,23 @@
"author": "Fabio Berger",
"license": "Apache-2.0",
"dependencies": {
- "@0x/asset-buyer": "^3.0.4",
- "@0x/contract-addresses": "^2.0.0",
- "@0x/contract-wrappers": "^4.1.1",
- "@0x/json-schemas": "^2.1.2",
- "@0x/order-utils": "^3.0.4",
- "@0x/react-docs": "^1.0.20",
- "@0x/react-shared": "^1.0.23",
- "@0x/subproviders": "^2.1.6",
- "@0x/types": "^1.3.0",
+ "@0x/asset-buyer": "^3.0.5",
+ "@0x/contract-addresses": "^2.1.0",
+ "@0x/contract-wrappers": "^4.2.0",
+ "@0x/json-schemas": "^2.1.5",
+ "@0x/order-utils": "^3.1.0",
+ "@0x/react-docs": "^1.0.23",
+ "@0x/react-shared": "^1.1.0",
+ "@0x/subproviders": "^2.1.9",
+ "@0x/types": "^1.5.0",
"@0x/typescript-typings": "^3.0.4",
- "@0x/utils": "^2.0.6",
- "@0x/web3-wrapper": "^3.1.6",
+ "@0x/utils": "^2.1.1",
+ "@0x/web3-wrapper": "^3.2.2",
"@reach/dialog": "^0.1.2",
"@types/react-lazyload": "^2.3.1",
"@types/react-loadable": "^5.4.2",
"@types/react-syntax-highlighter": "^0.0.8",
- "@types/styled-components": "^4.1.1",
+ "@types/styled-components": "4.1.1",
"accounting": "^0.4.1",
"basscss": "^8.0.3",
"blockies": "^0.0.2",
diff --git a/packages/website/translations/chinese.json b/packages/website/translations/chinese.json
index b99a3cdcb..88193a181 100644
--- a/packages/website/translations/chinese.json
+++ b/packages/website/translations/chinese.json
@@ -83,7 +83,7 @@
"BUILD_A_RELAYER": "build a relayer",
"BUILD_A_RELAYER_DESCRIPTION": "Learn how to build your own 0x relayer from scratch",
"DEVELOP_ON_ETHEREUM": "develop on Ethereum",
- "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications ontop of Ethereum",
+ "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications on top of Ethereum",
"ORDER_BASICS": "Make & take orders",
"ORDER_BASICS_DESCRIPTION": "Tutorial on how to create, validate and fill an order using 0x",
"USE_NETWORKED_LIQUIDITY": "use networked liquidity",
diff --git a/packages/website/translations/english.json b/packages/website/translations/english.json
index 2914ffead..a1d8ecc43 100644
--- a/packages/website/translations/english.json
+++ b/packages/website/translations/english.json
@@ -87,7 +87,7 @@
"BUILD_A_RELAYER": "build a relayer",
"BUILD_A_RELAYER_DESCRIPTION": "Learn how to build your own 0x relayer from scratch",
"DEVELOP_ON_ETHEREUM": "develop on Ethereum",
- "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications ontop of Ethereum",
+ "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications on top of Ethereum",
"ORDER_BASICS": "Make & take orders",
"ORDER_BASICS_DESCRIPTION": "Tutorial on how to create, validate and fill an order using 0x",
"USE_NETWORKED_LIQUIDITY": "use networked liquidity",
diff --git a/packages/website/translations/korean.json b/packages/website/translations/korean.json
index a421ffb94..539b81470 100644
--- a/packages/website/translations/korean.json
+++ b/packages/website/translations/korean.json
@@ -83,7 +83,7 @@
"BUILD_A_RELAYER": "build a relayer",
"BUILD_A_RELAYER_DESCRIPTION": "Learn how to build your own 0x relayer from scratch",
"DEVELOP_ON_ETHEREUM": "develop on Ethereum",
- "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications ontop of Ethereum",
+ "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications on top of Ethereum",
"ORDER_BASICS": "Make & take orders",
"ORDER_BASICS_DESCRIPTION": "Tutorial on how to create, validate and fill an order using 0x",
"USE_NETWORKED_LIQUIDITY": "use networked liquidity",
diff --git a/packages/website/translations/russian.json b/packages/website/translations/russian.json
index b3ea29cf3..feb5df02e 100644
--- a/packages/website/translations/russian.json
+++ b/packages/website/translations/russian.json
@@ -83,7 +83,7 @@
"BUILD_A_RELAYER": "build a relayer",
"BUILD_A_RELAYER_DESCRIPTION": "Learn how to build your own 0x relayer from scratch",
"DEVELOP_ON_ETHEREUM": "develop on Ethereum",
- "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications ontop of Ethereum",
+ "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications on top of Ethereum",
"ORDER_BASICS": "Make & take orders",
"ORDER_BASICS_DESCRIPTION": "Tutorial on how to create, validate and fill an order using 0x",
"USE_NETWORKED_LIQUIDITY": "use networked liquidity",
diff --git a/packages/website/translations/spanish.json b/packages/website/translations/spanish.json
index db75312c5..f4762a67e 100644
--- a/packages/website/translations/spanish.json
+++ b/packages/website/translations/spanish.json
@@ -84,7 +84,7 @@
"BUILD_A_RELAYER": "build a relayer",
"BUILD_A_RELAYER_DESCRIPTION": "Learn how to build your own 0x relayer from scratch",
"DEVELOP_ON_ETHEREUM": "develop on Ethereum",
- "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications ontop of Ethereum",
+ "DEVELOP_ON_ETHEREUM_DESCRIPTION": "Learn more about building applications on top of Ethereum",
"ORDER_BASICS": "Make & take orders",
"ORDER_BASICS_DESCRIPTION": "Tutorial on how to create, validate and fill an order using 0x",
"USE_NETWORKED_LIQUIDITY": "use networked liquidity",
diff --git a/packages/website/ts/components/documentation/sidebar_header.tsx b/packages/website/ts/components/documentation/sidebar_header.tsx
index 0ab24ab5e..d158ab926 100644
--- a/packages/website/ts/components/documentation/sidebar_header.tsx
+++ b/packages/website/ts/components/documentation/sidebar_header.tsx
@@ -24,7 +24,7 @@ export const SidebarHeader: React.StatelessComponent<SidebarHeaderProps> = ({
return (
<Container>
<Container className="flex justify-bottom">
- <Container className="col col-7 pl1">
+ <Container className="col col-8 pl1">
<Text
fontColor={colors.lightLinkBlue}
fontSize={screenWidth === ScreenWidths.Sm ? '20px' : '22px'}
@@ -37,7 +37,7 @@ export const SidebarHeader: React.StatelessComponent<SidebarHeaderProps> = ({
{!_.isUndefined(docsVersion) &&
!_.isUndefined(availableDocVersions) &&
!_.isUndefined(onVersionSelected) && (
- <div className="col col-5 pl1" style={{ alignSelf: 'flex-end', paddingBottom: 4 }}>
+ <div className="col col-4 pl1" style={{ alignSelf: 'flex-end', paddingBottom: 4 }}>
<Container className="right">
<VersionDropDown
selectedVersion={docsVersion}
diff --git a/packages/website/ts/components/modals/modal_contact.tsx b/packages/website/ts/components/modals/modal_contact.tsx
index a3a1f13f5..7414df7d9 100644
--- a/packages/website/ts/components/modals/modal_contact.tsx
+++ b/packages/website/ts/components/modals/modal_contact.tsx
@@ -12,6 +12,7 @@ import { Icon } from 'ts/components/icon';
import { Input, InputWidth } from 'ts/components/modals/input';
import { Heading, Paragraph } from 'ts/components/text';
import { GlobalStyle } from 'ts/constants/globalStyle';
+import { utils } from 'ts/utils/utils';
export enum ModalContactType {
General = 'GENERAL',
@@ -279,7 +280,7 @@ export class ModalContact extends React.Component<Props> {
try {
// Disabling no-unbound method b/c no reason for _.isEmpty to be bound
// tslint:disable:no-unbound-method
- const response = await fetch(`https://website-api.0xproject.com${endpoint}`, {
+ const response = await fetch(`${utils.getBackendBaseUrl()}${endpoint}`, {
method: 'post',
mode: 'cors',
credentials: 'same-origin',
diff --git a/packages/website/ts/components/newsletter_form.tsx b/packages/website/ts/components/newsletter_form.tsx
index 4a7abb7ec..bd61e3f4d 100644
--- a/packages/website/ts/components/newsletter_form.tsx
+++ b/packages/website/ts/components/newsletter_form.tsx
@@ -4,6 +4,7 @@ import styled, { withTheme } from 'styled-components';
import { ThemeValuesInterface } from 'ts/components/siteWrap';
import { colors } from 'ts/style/colors';
import { errorReporter } from 'ts/utils/error_reporter';
+import { utils } from 'ts/utils/utils';
interface FormProps {
theme: ThemeValuesInterface;
@@ -92,7 +93,7 @@ class Form extends React.Component<FormProps> {
}
try {
- await fetch('https://website-api.0x.org/newsletter_subscriber/substack', {
+ await fetch(`${utils.getBackendBaseUrl()}/newsletter_subscriber/substack`, {
method: 'post',
mode: 'cors',
headers: {
diff --git a/packages/website/ts/pages/documentation/developers_page.tsx b/packages/website/ts/pages/documentation/developers_page.tsx
index fcca2b6ad..78376a0f2 100644
--- a/packages/website/ts/pages/documentation/developers_page.tsx
+++ b/packages/website/ts/pages/documentation/developers_page.tsx
@@ -153,7 +153,7 @@ export class DevelopersPage extends React.Component<DevelopersPageProps, Develop
<Container className="flex mx-auto" height="100vh">
<Container
className="sm-hide xs-hide relative"
- width={234}
+ width={270}
paddingLeft={22}
paddingRight={22}
paddingTop={0}
diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts
index fab382b07..7cc854ca0 100644
--- a/packages/website/ts/utils/configs.ts
+++ b/packages/website/ts/utils/configs.ts
@@ -5,8 +5,8 @@ const INFURA_API_KEY = 'T5WSC8cautR4KXyYgsRs';
export const configs = {
AMOUNT_DISPLAY_PRECSION: 5,
- BACKEND_BASE_PROD_URL: 'https://website-api.0xproject.com',
- BACKEND_BASE_STAGING_URL: 'https://staging-website-api.0xproject.com',
+ BACKEND_BASE_PROD_URL: 'https://website-api.0x.org',
+ BACKEND_BASE_STAGING_URL: 'https://staging-website-api.0x.org',
BASE_URL,
BITLY_ACCESS_TOKEN: 'ffc4c1a31e5143848fb7c523b39f91b9b213d208',
DEFAULT_DERIVATION_PATH: `44'/60'/0'`,
@@ -39,8 +39,8 @@ export const configs = {
] as OutdatedWrappedEtherByNetworkId[],
// The order matters. We first try first node and only then fall back to others.
PUBLIC_NODE_URLS_BY_NETWORK_ID: {
- [1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0xproject.com'],
- [42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0xproject.com'],
+ [1]: [`https://mainnet.infura.io/${INFURA_API_KEY}`, 'https://mainnet.0x.org'],
+ [42]: [`https://kovan.infura.io/${INFURA_API_KEY}`, 'https://kovan.0x.org'],
[3]: [`https://ropsten.infura.io/${INFURA_API_KEY}`],
[4]: [`https://rinkeby.infura.io/${INFURA_API_KEY}`],
} as PublicNodeUrlsByNetworkId,