diff --git a/.editorconfig b/.editorconfig
index 6e87a003da..d9d012d53e 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -11,3 +11,6 @@ trim_trailing_whitespace = true
[*.md]
max_line_length = off
trim_trailing_whitespace = false
+
+[*.rs]
+indent_size = 4
diff --git a/.env.ci b/.env.ci
index a07d05981f..b1e7e0b844 100644
--- a/.env.ci
+++ b/.env.ci
@@ -1,6 +1,6 @@
#Tinny ENV Vars
MAX_ATTEMTPS=1
-NETWORK=localchain
+NETWORK=custom
DEBUG=true
WAIT_FOR_KEY_INTERVAL=3000
TIME_TO_RELEASE_KEY=10000
@@ -16,4 +16,4 @@ STOP_TESTNET=false
TESTNET_MANAGER_URL=http://127.0.0.1:8000
USE_LIT_BINARIES=true
LIT_NODE_BINARY_PATH=/usr/bin/lit_node
-LIT_ACTION_BINARY_PATH=/usr/bin/lit_actions
\ No newline at end of file
+LIT_ACTION_BINARY_PATH=/usr/bin/lit_actions
diff --git a/.env.sample b/.env.sample
index 55c89a1454..f25e351f3b 100644
--- a/.env.sample
+++ b/.env.sample
@@ -1,6 +1,6 @@
#Tinny ENV Vars
MAX_ATTEMPTS=1
-NETWORK=cayenne
+NETWORK=datil-dev
DEBUG=true
WAIT_FOR_KEY_INTERVAL=3000
LIT_OFFICAL_RPC=https://chain-rpc.litprotocol.com/http
@@ -18,4 +18,4 @@ STOP_TESTNET=false
TESTNET_MANAGER_URL=http://0.0.0.0:8000
USE_LIT_BINARIES=true
LIT_NODE_BINARY_PATH=/path/to/lit_node/binary
-LIT_ACTION_BINARY_PATH=/path/to/lit_action_binary
\ No newline at end of file
+LIT_ACTION_BINARY_PATH=/path/to/lit_action_binary
diff --git a/.eslintignore b/.eslintignore
index 3c3629e647..4157000266 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1 +1,3 @@
node_modules
+packages/wasm/rust/**/*
+packages/wasm/src/pkg/*
diff --git a/.eslintrc.json b/.eslintrc.json
index 1f4899674d..a6d5acb28d 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -68,6 +68,7 @@
"type"
]
}
- ]
+ ],
+ "no-throw-literal": "error"
}
}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 87b29d4f74..583391a7f2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,29 +9,36 @@ on:
- staging/**
- feat/**
- feature/**
+ - staging/**
jobs:
- unit-tests:
- runs-on: warp-ubuntu-latest-x64-16x
- timeout-minutes: 30
- steps:
- - name: Checkout repo
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
- - name: Set up Node.js
- uses: actions/setup-node@v3
- with:
- node-version: '20'
- cache: 'yarn'
- - name: Install project dependencies
- run: yarn --frozen-lockfile
- - uses: nrwl/nx-set-shas@v3
- with:
- main-branch-name: 'master'
- - name: Build
- run: yarn build:dev
- - name: Run Unit tests
- run: yarn tools --test --unit
+ # unit-tests:
+ # runs-on: warp-ubuntu-latest-x64-16x
+ # timeout-minutes: 30
+ # steps:
+ # - name: Checkout repo
+ # uses: actions/checkout@v2
+ # with:
+ # fetch-depth: 0
+ # - name: Set up Node.js
+ # uses: actions/setup-node@v3
+ # with:
+ # node-version: '20'
+ # cache: 'yarn'
+ # - name: Install rust
+ # uses: dtolnay/rust-toolchain@1.76.0
+ # - uses: jetli/wasm-pack-action@v0.4.0
+ # with:
+ # # Optional version of wasm-pack to install(eg. 'v0.9.1', 'latest')
+ # version: 'latest'
+ # - name: Install project dependencies
+ # run: yarn --frozen-lockfile
+ # - uses: nrwl/nx-set-shas@v3
+ # with:
+ # main-branch-name: 'master'
+ # - name: Build
+ # run: yarn build:dev
+ # - name: Run Unit tests
+ # run: yarn tools --test --unit
integration-tests:
runs-on: ubuntu-latest
timeout-minutes: 30
@@ -42,57 +49,94 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
- - name: Checkout Lit Actions
- uses: actions/checkout@v4
- id: checkout
- with:
- fetch-depth: 0
- repository: LIT-Protocol/lit-assets
- ref: ${{env.DATIL_COMMIT_HASH}}
- token: ${{secrets.GH_PAT}}
- path: ${{ github.workspace }}/lit-assets/
- submodules: false
- sparse-checkout: |
- blockchain
- rust/lit-node
- - name: Check LA dir
- run: ls -la ${{github.workspace}}/lit-assets
- - name: Install LA Blockchain Dependencies
- run: npm i
- working-directory: ${{github.workspace}}/lit-assets/blockchain/contracts
- - name: Docker login
- id: login
- run: docker login ghcr.io/ -u ${{secrets.GH_USER}} --password ${{secrets.GH_PAT}}
+ # - name: Checkout Lit Actions
+ # uses: actions/checkout@v4
+ # id: checkout
+ # with:
+ # fetch-depth: 0
+ # repository: LIT-Protocol/lit-assets
+ # ref: ${{env.DATIL_COMMIT_HASH}}
+ # token: ${{secrets.GH_PAT_FOR_SHIVA}}
+ # path: ${{ github.workspace }}/lit-assets/
+ # submodules: false
+ # sparse-checkout: |
+ # blockchain
+ # rust/lit-node
+ # - name: Check LA dir
+ # run: ls -la ${{github.workspace}}/lit-assets
+ # - name: Install LA Blockchain Dependencies
+ # run: npm i
+ # working-directory: ${{github.workspace}}/lit-assets/blockchain/contracts
+ - name: Log in to GitHub Container Registry
+ uses: docker/login-action@v2
+ with:
+ registry: ghcr.io
+ username: ${{ github.actor }}
+ password: ${{ secrets.GH_PAT_FOR_SHIVA }}
- name: Pull Shiva Container
id: shiva-pull
- run: docker pull ghcr.io/lit-protocol/shiva:latest
- - name: Run Shiva Container
- id: shiva-runner
- run: docker run -d -m 32g -p 8000:8000 -p 8545:8545 -p 7470:7470 -p 7471:7471 -p 7472:7472 -p 7473:7473 -p 7474:7474 -p 7475:7475 -v ${{github.workspace}}/lit-assets:/data -e GH_PAT=${{secrets.GH_PAT}} -e HASH=$DATIL_COMMIT_HASH -e IPFS_API_KEY=${{secrets.IPFS_API_KEY}} --name shiva ghcr.io/lit-protocol/shiva:latest
- - name: Set up Node.js
- uses: actions/setup-node@v3
- with:
- node-version: '20'
- - name: Install project dependencies
- run: yarn --frozen-lockfile
- - uses: nrwl/nx-set-shas@v3
- with:
- main-branch-name: 'master'
- - name: Build packages
- id: build
- run: yarn build:dev
- - name: Copy ENV File
- run: cp .env.ci .env
- - name: Run End to End Tests
- if: steps.build.outputs.exit_code == 0
- run: yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning,testUseEoaSessionSigsToPkpSign,testUsePkpSessionSigsToExecuteJsSigning,testUsePkpSessionSigsToPkpSign,testUseValidLitActionCodeGeneratedSessionSigsToPkpSign,testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning,testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs,testEthAuthSigToEncryptDecryptString,testExecuteJsSignAndCombineEcdsa,testExecutJsDecryptAndCombine,testExecuteJsBroadcastAndCollect --exclude=Parallel
- - name: Get Container Logs
- if: always()
- run: docker logs shiva
- - name: Post Pull Shiva Container
- id: container-stop
- if: steps.shiva-pull.outputs.exit_code == 0
- run: docker stop shiva && docker rm shiva
- - name: Post Pull Shiva Image
- if: steps.shiva-pull.outputs.exit_code == 0
- run: docker rmi ghcr.io/lit-protocol/shiva
\ No newline at end of file
+ run: docker pull ghcr.io/lit-protocol/shiva:latest
+ # - name: Run Shiva Container
+ # id: shiva-runner
+ # run: docker run -d -m 32g -p 8000:8000 -p 8545:8545 -p 7470:7470 -p 7471:7471 -p 7472:7472 -p 7473:7473 -p 7474:7474 -p 7475:7475 -v ${{github.workspace}}/lit-assets:/data -e GH_PAT=${{secrets.GH_PAT_FOR_SHIVA}} -e HASH=$DATIL_COMMIT_HASH -e IPFS_API_KEY=${{secrets.IPFS_API_KEY}} --name shiva ghcr.io/lit-protocol/shiva:latest
+ # - name: Set up Node.js
+ # uses: actions/setup-node@v3
+ # with:
+ # node-version: '20'
+ # - uses: jetli/wasm-pack-action@v0.4.0
+ # with:
+ # # Optional version of wasm-pack to install(eg. 'v0.9.1', 'latest')
+ # version: 'latest'
+ # - name: Install project dependencies
+ # run: yarn --frozen-lockfile
+ # - uses: nrwl/nx-set-shas@v3
+ # with:
+ # main-branch-name: 'master'
+ # - name: Build packages
+ # id: build
+ # run: yarn build:dev
+ # - name: Copy ENV File
+ # run: cp .env.ci .env
+ # - name: Run End to End Tests
+ # if: steps.build.outputs.exit_code == 0
+ # run: yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning,testUseEoaSessionSigsToPkpSign,testUsePkpSessionSigsToExecuteJsSigning,testUsePkpSessionSigsToPkpSign,testUseValidLitActionCodeGeneratedSessionSigsToPkpSign,testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning,testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs,testEthAuthSigToEncryptDecryptString,testExecuteJsSignAndCombineEcdsa,testExecutJsDecryptAndCombine,testExecuteJsBroadcastAndCollect --exclude=Parallel
+ # - name: Get Container Logs
+ # if: always()
+ # run: docker logs shiva
+ # - name: Post Pull Shiva Container
+ # id: container-stop
+ # if: steps.shiva-pull.outputs.exit_code == 0
+ # run: docker stop shiva && docker rm shiva
+ # - name: Post Pull Shiva Image
+ # if: steps.shiva-pull.outputs.exit_code == 0
+ # run: docker rmi ghcr.io/lit-protocol/shiva
+ # ping-lit-configuration-guides:
+ # runs-on: ubuntu-latest
+ # # needs: [unit-tests, integration-tests] # Make sure this job runs after others complete
+ # steps:
+ # - name: Get PR labels
+ # id: pr-labels
+ # uses: actions/github-script@v6
+ # if: github.event_name == 'pull_request'
+ # with:
+ # script: |
+ # const labels = context.payload.pull_request.labels
+ # .map(label => label.name)
+ # .filter(name => name.startsWith('tag:'))
+ # .map(name => name.split(':')[1]);
+ # if (labels.length > 0) {
+ # core.setOutput('tag', labels[0]);
+ # } else {
+ # core.setOutput('skip', 'true');
+ # }
+ # - name: Trigger dependencies bot in lit-configuration-guides
+ # if: steps.pr-labels.outputs.skip != 'true'
+ # run: |
+ # TAG="${{ steps.pr-labels.outputs.tag }}"
+ # curl -X POST \
+ # -H "Accept: application/vnd.github.everest-preview+json" \
+ # -H "Authorization: token ${{ secrets.GH_PAT_FOR_SHIVA_LIT_CONFIGURATION_GUIDES_REPO }}" \
+ # https://api.github.com/repos/LIT-Protocol/lit-configuration-guides/dispatches \
+ # -d "{\"event_type\":\"dependency_update\", \"client_payload\": {\"labels\": [\"$TAG\"]}}"
+ # env:
+ # GH_PAT_LIT_CONFIGURATION_GUIDES_REPO: ${{ secrets.GH_PAT_FOR_SHIVA_LIT_CONFIGURATION_GUIDES_REPO }}
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 3b93e30175..de5ae4fdbe 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -1,24 +1,30 @@
-name: lint
-on:
- pull_request:
- push:
- branches:
- - master
-jobs:
- linter:
- runs-on: ubuntu-latest
- timeout-minutes: 10
- steps:
- - name: Checkout repo
- uses: actions/checkout@v2
- with:
- fetch-depth: 0
- - name: Set up Node.js
- uses: actions/setup-node@v3
- with:
- node-version: '18'
- cache: 'yarn'
- - name: Install project dependencies
- run: yarn install
- - name: Lint
- run: yarn nx format:check --all
+# name: lint
+# on:
+# pull_request:
+# push:
+# branches:
+# - master
+# jobs:
+# linter:
+# runs-on: ubuntu-latest
+# timeout-minutes: 10
+# steps:
+# - name: Checkout repo
+# uses: actions/checkout@v2
+# with:
+# fetch-depth: 0
+# - name: Set up Node.js
+# uses: actions/setup-node@v3
+# with:
+# node-version: '18'
+# cache: 'yarn'
+# - name: Install rust
+# uses: dtolnay/rust-toolchain@1.76.0
+# - uses: jetli/wasm-pack-action@v0.4.0
+# with:
+# # Optional version of wasm-pack to install(eg. 'v0.9.1', 'latest')
+# version: 'latest'
+# - name: Install project dependencies
+# run: yarn install
+# - name: Lint
+# run: yarn nx format:check --all
diff --git a/.prettierignore b/.prettierignore
index 8eec17d4c9..86d942ab30 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -12,4 +12,6 @@
/packages/*/dist
.nx
tools
-**/*/dist
\ No newline at end of file
+/packages/wasm/rust/*
+/packages/wasm/src/pkg/*
+**/*/dist
diff --git a/README.md b/README.md
index 8551e64259..b2595b03f3 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-
Lit Protocol Javascript/Typescript SDK V6.5.x
+
Lit Protocol Javascript/Typescript SDK V7.x.x
@@ -61,25 +61,22 @@ If you're a tech-savvy user and wish to utilize only specific submodules that ou
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [@lit-protocol/access-control-conditions](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/access-control-conditions) |  |

|
| [@lit-protocol/auth-helpers](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-helpers) |  |

|
-| [@lit-protocol/bls-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/bls-sdk) |  |

|
| [@lit-protocol/constants](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/constants) |  |

|
| [@lit-protocol/contracts-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/contracts-sdk) |  |

|
| [@lit-protocol/core](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/core) |  |

|
| [@lit-protocol/crypto](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/crypto) |  |

|
-| [@lit-protocol/ecdsa-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/ecdsa-sdk) |  |

|
| [@lit-protocol/encryption](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/encryption) |  |

|
| [@lit-protocol/logger](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/logger) |  |

|
| [@lit-protocol/misc](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/misc) |  |

|
| [@lit-protocol/nacl](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/nacl) |  |

|
| [@lit-protocol/pkp-base](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-base) |  |

|
-| [@lit-protocol/pkp-client](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-client) |  |

|
| [@lit-protocol/pkp-cosmos](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-cosmos) |  |

|
| [@lit-protocol/pkp-ethers](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-ethers) |  |

|
| [@lit-protocol/pkp-sui](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-sui) |  |

|
| [@lit-protocol/pkp-walletconnect](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/pkp-walletconnect) |  |

|
-| [@lit-protocol/sev-snp-utils-sdk](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/sev-snp-utils-sdk) |  |

|
| [@lit-protocol/types](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/types) |  |

|
| [@lit-protocol/uint8arrays](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/uint8arrays) |  |

|
+| [@lit-protocol/wasm](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/wasm) |  |

|
| [@lit-protocol/wrapped-keys](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/wrapped-keys) |  |

|
| [@lit-protocol/wrapped-keys-lit-actions](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/wrapped-keys-lit-actions) |  |

|
| [@lit-protocol/auth-browser](https://github.com/LIT-Protocol/js-sdk/tree/master/packages/auth-browser) |  |

|
@@ -89,11 +86,12 @@ If you're a tech-savvy user and wish to utilize only specific submodules that ou
## API Doc
-| Version | Link |
-| ---------------- | -------------------------------------------------------- |
-| V6 (Beta) | [6.x.x docs](https://v6-api-doc-lit-js-sdk.vercel.app/) |
-| V5 (**Current**) | [5.x.x docs](https://v3.api-docs.getlit.dev/) |
-| V2 | [2.x.x docs](http://docs.lit-js-sdk-v2.litprotocol.com/) |
+| Version | Link |
+| ------------ | -------------------------------------------------------- |
+| V7 (Current) | [7.x.x docs](https://v7-api-doc-lit-js-sdk.vercel.app/) |
+| V6 | [6.x.x docs](https://v6-api-doc-lit-js-sdk.vercel.app/) |
+| V5 | [5.x.x docs](https://v3.api-docs.getlit.dev/) |
+| V2 | [2.x.x docs](http://docs.lit-js-sdk-v2.litprotocol.com/) |
@@ -102,6 +100,8 @@ If you're a tech-savvy user and wish to utilize only specific submodules that ou
## Prerequisite
- node (v19.x or above)
+- rust (v1.70.00 or above)
+- [wasm-pack](https://github.com/rustwasm/wasm-pack)
## Recommended
@@ -149,7 +149,7 @@ yarn test:local
## Create a new react demo app using the Lit JS SDK
-```js
+```sh
yarn tools --create --react contracts-sdk --demo
```
@@ -165,13 +165,13 @@ yarn delete:package
## Building
-```jsx
+```sh
yarn build
```
### Building target package
-```jsx
+```sh
yarn nx run :build
```
@@ -209,6 +209,10 @@ Having done this setup, this is what the development cycle looks like moving for
2. Rebuild specific package
3. Rebuild client application.
+### Building changes to Rust source
+
+If changes are made to `packages/wasm` see [here](./packages/wasm/README.md) for info on building from source.
+
## Publishing
You must have at least nodejs v18 to do this.
@@ -223,19 +227,10 @@ You must have at least nodejs v18 to do this.
5. Update the docs with `yarn gen:docs --push`
-6. Finally, publish with the `@cayenne` tag: `yarn publish:cayenne`
+6. Finally, publish with `yarn publish:packages`
7. Commit these changes "Published version X.X.X"
-### Publishing to Serrano / Jalapno
-
-```sh
-git checkout serrano
-yarn bump
-yarn build
-yarn node ./tools/scripts/pub.mjs --tag serrano-jalapeno
-```
-
## Testing
### Quick Start on E2E Testing
@@ -248,7 +243,7 @@ yarn test:local
### Unit Tests
-```jsx
+```sh
yarn test:unit
```
@@ -283,6 +278,56 @@ To run manual tests:
- LIT_JS_SDK_LOCAL_NODE_DEV - set to true to use a local node
- LIT_JS_SDK_FUNDED_WALLET_PRIVATE_KEY - set to a funded wallet on Chronicle Testnet
+# Error Handling
+
+This SDK uses custom error classes derived from [@openagenda/verror](https://github.com/OpenAgenda/verror) to handle errors between packages and to the SDK consumers.
+Normal error handling is also supported as VError extends the native Error class, but using VError allows for better error composition and information propagation.
+You can check their documentation for the extra fields that are added to the error object and methods on how to handle them in a safe way.
+
+## Example
+
+```ts
+import { VError } from '@openagenda/verror';
+import { LitNodeClientBadConfigError } from '@lit-protocol/constants';
+
+try {
+ const someNativeError = new Error('some native error');
+
+ throw new LitNodeClientBadConfigError(
+ {
+ cause: someNativeError,
+ info: {
+ foo: 'bar',
+ },
+ meta: {
+ baz: 'qux',
+ },
+ },
+ 'some useful message'
+ );
+} catch (e) {
+ console.log(e.name); // LitNodeClientBadConfigError
+ console.log(e.message); // some useful message: some native error
+ console.log(e.info); // { foo: 'bar' }
+ console.log(e.baz); // qux
+ // VError.cause(e) is someNativeError
+ // VError.info(e) is { foo: 'bar' }
+ // VError.meta(e) is { baz: 'qux', code: 'lit_node_client_bad_config_error', kind: 'Config' }
+ // Verror.fullStack(e) is the full stack trace composed of the error chain including the causes
+}
+```
+
+## Creating a new error
+
+In file `packages/constants/src/lib/errors.ts` you can find the list of errors that are currently supported and add new ones if needed.
+
+To create and use a new error, you need to:
+
+1. Add the error information to the `LIT_ERROR` object in `packages/constants/src/lib/errors.ts`
+2. Export the error from the `errors.ts` file at the end of the file
+3. Import the error where you need it
+4. Throw the error in your code adding all the information a user might need to know about the error such as the cause, the info, etc.
+
# Dockerfile
...coming soon
@@ -317,34 +362,6 @@ eg.
-
-Web bundling using esbuild
-
-It’s currently using a custom plugin [@websaam/nx-esbuild](https://www.npmjs.com/package/@websaam/nx-esbuild) which is a fork from [@wanews/nx-esbuild](https://www.npmjs.com/package/@wanews/nx-esbuild)
-
-```json
-"_buildWeb": {
- "executor": "@websaam/nx-esbuild:package",
- "options": {
- "banner": {
- "js": "import { createRequire } from 'module';const require = createRequire(import.meta.url);"
- },
- "globalName": "LitJsSdk_CoreBrowser",
- "outfile":"dist/packages/core-browser-vanilla/core-browser.js",
- "entryPoints": ["./packages/core-browser/src/index.ts"],
- "define": { "global": "window" },
- "plugins":[
- {
- "package": "esbuild-node-builtins",
- "function": "nodeBuiltIns"
- }
- ]
- }
- }
-```
-
-
-
Reference Error: crypto is not defined
diff --git a/doc.css b/doc.css
new file mode 100644
index 0000000000..ecbbb67d3b
--- /dev/null
+++ b/doc.css
@@ -0,0 +1,310 @@
+/* Base styles */
+:root {
+ /* Colors */
+ --background-color: hsl(0, 0%, 100%);
+ --foreground-color: hsl(222.2, 84%, 4.9%);
+
+ --card-bg: hsl(0, 0%, 100%);
+ --card-color: hsl(222.2, 84%, 4.9%);
+
+ --primary-color: hsl(221.2, 83.2%, 53.3%);
+ --primary-foreground: hsl(210, 40%, 98%);
+
+ --secondary-color: hsl(222, 47.4%, 34.7%);
+ --secondary-foreground: hsl(210, 40%, 98%);
+
+ --muted-color: hsl(210, 40%, 96.1%);
+ --muted-foreground: hsl(215.4, 16.3%, 46.9%);
+
+ --accent-color: hsl(210, 40%, 96.1%);
+ --accent-foreground: hsl(222.2, 47.4%, 11.2%);
+
+ --destructive-color: hsl(0, 84.2%, 60.2%);
+ --destructive-foreground: hsl(210, 40%, 98%);
+
+ --border-color: hsl(214.3, 31.8%, 91.4%);
+ --input-color: hsl(214.3, 31.8%, 91.4%);
+ --ring-color: hsl(221.2, 83.2%, 53.3%);
+
+ /* Spacing & Sizing */
+ --radius: 0.5rem;
+ --spacing-1: 0.25rem;
+ --spacing-2: 0.5rem;
+ --spacing-3: 0.75rem;
+ --spacing-4: 1rem;
+ --spacing-6: 1.5rem;
+}
+
+/* Dark mode */
+@media (prefers-color-scheme: dark) {
+ :root {
+ --background-color: hsl(222.2, 84%, 4.9%);
+ --foreground-color: hsl(210, 40%, 98%);
+
+ --card-bg: hsl(222.2, 84%, 4.9%);
+ --card-color: hsl(210, 40%, 98%);
+
+ --primary-color: hsl(217.2, 91.2%, 59.8%);
+ --primary-foreground: hsl(222.2, 47.4%, 11.2%);
+
+ --secondary-color: hsl(217.2, 32.6%, 17.5%);
+ --secondary-foreground: hsl(210, 40%, 98%);
+
+ --muted-color: hsl(217.2, 32.6%, 17.5%);
+ --muted-foreground: hsl(215, 20.2%, 65.1%);
+
+ --accent-color: hsl(217.2, 32.6%, 17.5%);
+ --accent-foreground: hsl(210, 40%, 98%);
+
+ --destructive-color: hsl(0, 62.8%, 30.6%);
+ --destructive-foreground: hsl(210, 40%, 98%);
+
+ --border-color: hsl(217.2, 32.6%, 17.5%);
+ --input-color: hsl(217.2, 32.6%, 17.5%);
+ --ring-color: hsl(224.3, 76.3%, 48%);
+ }
+}
+
+/* Base elements */
+* {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ border-color: var(--border-color);
+}
+
+body {
+ background-color: var(--background-color);
+ color: var(--foreground-color);
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
+ 'Helvetica Neue', Arial, sans-serif;
+ line-height: 1.6;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-feature-settings: 'rlig' 1, 'calt' 1;
+}
+
+/* Typography */
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ letter-spacing: -0.025em;
+ font-weight: 700;
+ line-height: 1.2;
+}
+
+h1 {
+ font-size: 2.5rem;
+}
+
+h2 {
+ font-size: 2rem;
+}
+
+h3 {
+ font-size: 1.75rem;
+}
+
+h4 {
+ font-size: 1.5rem;
+}
+
+p {
+ line-height: 1.75;
+ margin-top: 1.5rem;
+}
+
+p:first-child {
+ margin-top: 0;
+}
+
+/* Block elements */
+blockquote {
+ margin-top: 1.5rem;
+ border-left: 4px solid var(--primary-color);
+ padding-left: 1.5rem;
+ font-style: italic;
+}
+
+code {
+ position: relative;
+ border-radius: var(--radius);
+ background-color: var(--muted-color);
+ padding: 0.2rem 0.3rem;
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+ font-size: 0.875rem;
+}
+
+pre {
+ margin: 1.5rem 0 1rem 0;
+ padding: 1rem;
+ overflow-x: auto;
+ border-radius: var(--radius);
+ border: 1px solid var(--border-color);
+ background-color: var(--muted-color);
+}
+
+pre code {
+ background-color: transparent;
+ padding: 0;
+}
+
+/* Tables */
+table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+tr {
+ margin: 0;
+ border-top: 1px solid var(--border-color);
+ padding: 0;
+}
+
+th,
+td {
+ border: 1px solid var(--border-color);
+ padding: 0.5rem 1rem;
+ text-align: left;
+}
+
+th[align='center'],
+td[align='center'] {
+ text-align: center;
+}
+
+th[align='right'],
+td[align='right'] {
+ text-align: right;
+}
+
+/* Lists */
+ul,
+ol {
+ margin: 1.5rem 0;
+ padding-left: 1.5rem;
+}
+
+ul {
+ list-style-type: disc;
+}
+
+ol {
+ list-style-type: decimal;
+}
+
+li {
+ margin-top: 0.5rem;
+}
+
+/* Interactive elements */
+details {
+ border-radius: var(--radius);
+ border: 1px solid var(--border-color);
+ padding: 1rem;
+}
+
+summary {
+ cursor: pointer;
+ font-weight: 600;
+}
+
+summary:hover {
+ color: var(--primary-color);
+}
+
+/* Media elements */
+img {
+ max-width: 100%;
+ height: auto;
+ border-radius: var(--radius);
+}
+
+/* Scrollbar */
+::-webkit-scrollbar {
+ width: 0.5rem;
+}
+
+::-webkit-scrollbar-track {
+ background-color: var(--muted-color);
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 9999px;
+ background-color: color-mix(
+ in srgb,
+ var(--muted-foreground) 50%,
+ transparent
+ );
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background-color: var(--muted-foreground);
+}
+
+/* Selection */
+::selection {
+ background-color: color-mix(in srgb, var(--primary-color) 20%, transparent);
+ color: var(--foreground-color);
+}
+
+/* Focus */
+:focus-visible {
+ outline: none;
+ box-shadow: 0 0 0 2px var(--background-color), 0 0 0 4px var(--ring-color);
+}
+
+/* Animations */
+@keyframes enter {
+ from {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+
+@keyframes exit {
+ from {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+
+.animate-in {
+ animation: enter 0.2s ease-out;
+}
+
+.animate-out {
+ animation: exit 0.2s ease-in;
+}
+
+/* Responsive Design */
+@media (min-width: 768px) {
+ h1 {
+ font-size: 3rem;
+ }
+
+ h2 {
+ font-size: 2.5rem;
+ }
+
+ h3 {
+ font-size: 2rem;
+ }
+
+ h4 {
+ font-size: 1.75rem;
+ }
+}
+.tsd-page-title {
+ display: none;
+}
+.col-content {
+ margin-left: 16px;
+}
diff --git a/lerna.json b/lerna.json
index a4e855968f..91f5574120 100644
--- a/lerna.json
+++ b/lerna.json
@@ -2,5 +2,5 @@
"$schema": "node_modules/lerna/schemas/lerna-schema.json",
"useNx": true,
"useWorkspaces": true,
- "version": "6.11.0"
+ "version": "7.0.0-alpha.8"
}
diff --git a/local-tests/README.md b/local-tests/README.md
index 065e528056..8196ddc46b 100644
--- a/local-tests/README.md
+++ b/local-tests/README.md
@@ -5,7 +5,7 @@ Tinny is a mini test framework, serving as a temporary solution for running e2e
# Prerequisite
- Node v20 or above
-- The generated file `networkContext.ts` after running `npm run deploy -- --network localchain` in the `lit-assets` repo
+- The generated file `networkContext.ts` after running `npm run deploy -- --network custom` in the `lit-assets` repo
# How to run
@@ -16,15 +16,15 @@ The `testName` specified in the filter **must be the same as the function name**
## to run all tests
```
-// run all tests on localchain
-DEBUG=true NETWORK=localchain yarn test:local
+// run all tests on local chain
+DEBUG=true NETWORK=custom yarn test:local
-// run filtered tests on manzano
-DEBUG=true NETWORK=manzano yarn test:local --filter=testExample
-DEBUG=true NETWORK=manzano yarn test:local --filter=testExample,testBundleSpeed
+// run filtered tests on datil-test
+DEBUG=true NETWORK=datil-test yarn test:local --filter=testExample
+DEBUG=true NETWORK=datil-test yarn test:local --filter=testExample,testBundleSpeed
// run filtered tests by keyword
-DEBUG=true NETWORK=manzano yarn test:local --filter=Encrypt
+DEBUG=true NETWORK=datil-test yarn test:local --filter=Encrypt
// eg.
yarn test:local --filter=testExample,testBundleSpeed
@@ -41,7 +41,7 @@ Below is the API documentation for the `ProcessEnvs` interface, detailing the co
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MAX_ATTEMPTS` | Each test is executed in a loop with a maximum number of attempts specified by `devEnv.processEnvs.MAX_ATTEMPTS`. |
| `TEST_TIMEOUT` | The maximum number of milliseconds to wait for a test to complete. |
-| `NETWORK` | The network to use for testing, which can be one of the following: `LIT_TESTNET.LOCALCHAIN`, `LIT_TESTNET.MANZANO`, or `LIT_TESTNET.CAYENNE`. |
+| `NETWORK` | The network to use for testing, which can be one of the following: `LIT_NETWORK.Custom`, `LIT_NETWORK.DatilDev`, or `LIT_NETWORK.Datil`. |
| `DEBUG` | Specifies whether to enable debug mode. |
| `REQUEST_PER_KILOSECOND` | To execute a transaction with Lit, you must reserve capacity on the network using Capacity Credits. These allow a set number of requests over a period (default 2 days). |
| `WAIT_FOR_KEY_INTERVAL` | Wait time in milliseconds if no private keys are available. |
@@ -50,7 +50,7 @@ Below is the API documentation for the `ProcessEnvs` interface, detailing the co
| `RUN_IN_BAND_INTERVAL` | The interval in milliseconds to run the tests in a single thread. |
| `LIT_RPC_URL` | The URL of the Lit RPC server:
- For local Anvil: `http://127.0.0.1:8545`
- For Chronicle: `https://chain-rpc.litprotocol.com/http`
- For Yellowstone: `https://yellowstone-rpc.litprotocol.com` |
| `STOP_TESTNET` | Flag to stop a single running testnet after the test run concludes. |
-| `USE_SHIVA` | A flag to determine if `Shiva` should be used for the `localchain` network. |
+| `USE_SHIVA` | A flag to determine if `Shiva` should be used for the local `custom` network. |
| `PRIVATE_KEYS` | A set of private keys to use which will be used to perform chain operations. |
| `CHUNK_SIZE` | Determines the number of tests run concurrently during parallel execution |
@@ -76,8 +76,8 @@ In the test function, a `devEnv` variable will automatically be added as the fir
export const testExample = async (devEnv: TinnyEnvironment) => {
// ========== Enviorment ==========
- // This test will be skipped if we are testing on the Cayenne network
- devEnv.setUnavailable(LIT_TESTNET.CAYENNE);
+ // This test will be skipped if we are testing on the DatilDev network
+ devEnv.setUnavailable(LIT_NETWORK.DatilDev);
// Using litNodeClient
const res = await devEnv.litNodeClient.executeJs({...});
@@ -126,7 +126,6 @@ The `TinnyPerson` class encapsulates various functionalities to manage wallet op
# esbuild benchmark
```ts
-
// test-bundle-speed.ts
export const testBundleSpeed = async (devEnv: TinnyEnvironment) => {
const a = await import('@lit-protocol/lit-node-client');
@@ -137,6 +136,7 @@ export const testBundleSpeed = async (devEnv: TinnyEnvironment) => {
console.log(a, b, c, d, e);
};
-----------------
-Build time: 77ms
+// ----------------
+// Build time: 77ms
+// ----------------
```
diff --git a/local-tests/setup/session-sigs/get-eoa-session-sigs.ts b/local-tests/setup/session-sigs/get-eoa-session-sigs.ts
index 68c060f01d..8b6d03102e 100644
--- a/local-tests/setup/session-sigs/get-eoa-session-sigs.ts
+++ b/local-tests/setup/session-sigs/get-eoa-session-sigs.ts
@@ -7,12 +7,14 @@ import {
import {
AuthCallbackParams,
AuthSig,
- LitAbility,
LitResourceAbilityRequest,
} from '@lit-protocol/types';
import { log } from '@lit-protocol/misc';
import { ethers } from 'ethers';
-import { CENTRALISATION_BY_NETWORK, LitNetwork } from '@lit-protocol/constants';
+import {
+ LIT_ABILITY,
+ CENTRALISATION_BY_NETWORK,
+} from '@lit-protocol/constants';
import { TinnyPerson } from '../tinny-person';
import { TinnyEnvironment } from '../tinny-environment';
@@ -42,11 +44,11 @@ export const getEoaSessionSigs = async (
const _resourceAbilityRequests = resourceAbilityRequests || [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
];
@@ -118,11 +120,11 @@ export const getEoaSessionSigsWithCapacityDelegations = async (
resourceAbilityRequests: [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
],
authNeededCallback: async ({
diff --git a/local-tests/setup/session-sigs/get-lit-action-session-sigs.ts b/local-tests/setup/session-sigs/get-lit-action-session-sigs.ts
index a3c85bdda6..9586302484 100644
--- a/local-tests/setup/session-sigs/get-lit-action-session-sigs.ts
+++ b/local-tests/setup/session-sigs/get-lit-action-session-sigs.ts
@@ -1,8 +1,9 @@
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LitAbility, LitResourceAbilityRequest } from '@lit-protocol/types';
+import { LitResourceAbilityRequest } from '@lit-protocol/types';
import {
CENTRALISATION_BY_NETWORK,
GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK,
+ LIT_ABILITY,
} from '@lit-protocol/constants';
import { TinnyPerson } from '../tinny-person';
import { TinnyEnvironment } from '../tinny-environment';
@@ -52,11 +53,11 @@ export const getLitActionSessionSigs = async (
const _resourceAbilityRequests = resourceAbilityRequests || [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
];
@@ -99,11 +100,11 @@ export const getLitActionSessionSigsUsingIpfsId = async (
const _resourceAbilityRequests = resourceAbilityRequests || [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
];
@@ -135,7 +136,7 @@ export const getInvalidLitActionSessionSigs = async (
resourceAbilityRequests: [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
],
litActionCode: Buffer.from(INVALID_SESSION_SIG_LIT_ACTION_CODE).toString(
@@ -166,7 +167,7 @@ export const getInvalidLitActionIpfsSessionSigs = async (
resourceAbilityRequests: [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
],
litActionIpfsId: INVALID_IPFS_ID,
diff --git a/local-tests/setup/session-sigs/get-pkp-session-sigs.ts b/local-tests/setup/session-sigs/get-pkp-session-sigs.ts
index 99097085fe..3eba991709 100644
--- a/local-tests/setup/session-sigs/get-pkp-session-sigs.ts
+++ b/local-tests/setup/session-sigs/get-pkp-session-sigs.ts
@@ -1,7 +1,10 @@
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LitAbility, LitResourceAbilityRequest } from '@lit-protocol/types';
+import { LitResourceAbilityRequest } from '@lit-protocol/types';
import { log } from '@lit-protocol/misc';
-import { CENTRALISATION_BY_NETWORK, LitNetwork } from '@lit-protocol/constants';
+import {
+ LIT_ABILITY,
+ CENTRALISATION_BY_NETWORK,
+} from '@lit-protocol/constants';
import { TinnyEnvironment } from '../tinny-environment';
import { TinnyPerson } from '../tinny-person';
@@ -24,11 +27,11 @@ export const getPkpSessionSigs = async (
const _resourceAbilityRequests = resourceAbilityRequests || [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
];
diff --git a/local-tests/setup/shiva-client.ts b/local-tests/setup/shiva-client.ts
index fbf1075179..a09aba4ccc 100644
--- a/local-tests/setup/shiva-client.ts
+++ b/local-tests/setup/shiva-client.ts
@@ -23,13 +23,13 @@ class ShivaError extends Error {
export interface ShivaEnvs {
/**
- * If runnnig no localchain this flag will stop the running testnet when the test
+ * If running on local chain this flag will stop the running testnet when the test
* run has finished. Which is when all pending task promises have settled.
*/
STOP_TESTNET: boolean;
/**
- * URL for Testnet manager intigration
+ * URL for Testnet manager integration
*/
TESTNET_MANAGER_URL: string;
@@ -58,7 +58,7 @@ export interface ShivaEnvs {
/**
* Client implementation for a single testnet instance managed by the Shiva tool
- * Is essentially a localchain setup but allows for programmatic operations to be performed
+ * Is essentially a local chain setup but allows for programmatic operations to be performed
* on the network from the implementation within this class. Each testnet is a unique network
*/
export class TestnetClient {
diff --git a/local-tests/setup/tinny-config.ts b/local-tests/setup/tinny-config.ts
index 8ebf013197..296e55dd9b 100644
--- a/local-tests/setup/tinny-config.ts
+++ b/local-tests/setup/tinny-config.ts
@@ -1,33 +1,7 @@
+import { LIT_NETWORK_VALUES } from '@lit-protocol/constants';
import { LitNodeClient } from '@lit-protocol/lit-node-client';
import { LitContractResolverContext } from '@lit-protocol/types';
-export enum LIT_TESTNET {
- LOCALCHAIN = 'localchain',
- MANZANO = 'manzano',
- CAYENNE = 'cayenne',
- DATIL_DEV = 'datil-dev',
- DATIL_TEST = 'datil-test',
- DATIL_PROD = 'datil',
-}
-
-export enum LIT_RPC {
- LOCAL_ANVIL = 'http://127.0.0.1:8545',
- CHRONICLE = 'https://chain-rpc.litprotocol.com/http',
- YELLOWSTONE = 'https://yellowstone-rpc.litprotocol.com',
-}
-
-/**
- * Mapping of testnet names to corresponding RPC endpoints.
- */
-export const RPC_MAP = {
- [LIT_TESTNET.LOCALCHAIN]: LIT_RPC.LOCAL_ANVIL,
- [LIT_TESTNET.MANZANO]: LIT_RPC.CHRONICLE,
- [LIT_TESTNET.CAYENNE]: LIT_RPC.CHRONICLE,
- [LIT_TESTNET.DATIL_DEV]: LIT_RPC.YELLOWSTONE,
- [LIT_TESTNET.DATIL_TEST]: LIT_RPC.YELLOWSTONE,
- [LIT_TESTNET.DATIL_PROD]: LIT_RPC.YELLOWSTONE,
-};
-
/**
* Represents the configuration options for the process environment.
*/
@@ -44,12 +18,10 @@ export interface ProcessEnvs {
/**
* The network to use for testing. This can be one of the following:
- * - `LIT_TESTNET.LOCALCHAIN`
- * - `LIT_TESTNET.MANZANO`
- * - `LIT_TESTNET.CAYENNE`
- * - `LIT_TESTNET.DATIL_DEV`
+ * - `LIT_NETWORK.Custom`
+ * - `LIT_NETWORK.DatilDev`
*/
- NETWORK: LIT_TESTNET;
+ NETWORK: LIT_NETWORK_VALUES;
/**
* The number of milliseconds to wait between each request.
@@ -137,7 +109,7 @@ export type PKPInfo = {
export interface TinnyEnvConfig {
rpc: string;
litNodeClient: LitNodeClient;
- network: LIT_TESTNET;
+ network: LIT_NETWORK_VALUES;
processEnvs: ProcessEnvs;
contractContext?: LitContractResolverContext;
}
diff --git a/local-tests/setup/tinny-environment.ts b/local-tests/setup/tinny-environment.ts
index 50c2c5552c..7163ca6d81 100644
--- a/local-tests/setup/tinny-environment.ts
+++ b/local-tests/setup/tinny-environment.ts
@@ -1,9 +1,4 @@
-import {
- LIT_TESTNET,
- ProcessEnvs,
- RPC_MAP,
- TinnyEnvConfig,
-} from './tinny-config';
+import { ProcessEnvs, TinnyEnvConfig } from './tinny-config';
import { LitNodeClient } from '@lit-protocol/lit-node-client';
import { LitContracts } from '@lit-protocol/contracts-sdk';
import {
@@ -19,11 +14,16 @@ import { ethers, Signer } from 'ethers';
import { createSiweMessage, generateAuthSig } from '@lit-protocol/auth-helpers';
import { ShivaClient, TestnetClient } from './shiva-client';
import { toErrorWithMessage } from './tinny-utils';
-import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants';
+import {
+ CENTRALISATION_BY_NETWORK,
+ LIT_NETWORK,
+ LIT_NETWORK_VALUES,
+ RPC_URL_BY_NETWORK,
+} from '@lit-protocol/constants';
console.log('checking env', process.env['DEBUG']);
export class TinnyEnvironment {
- public network: LIT_TESTNET;
+ public network: LIT_NETWORK_VALUES;
/**
* Environment variables used in the process.
@@ -31,11 +31,12 @@ export class TinnyEnvironment {
public processEnvs: ProcessEnvs = {
MAX_ATTEMPTS: parseInt(process.env['MAX_ATTEMPTS']) || 1,
TEST_TIMEOUT: parseInt(process.env['TEST_TIMEOUT']) || 45000,
- NETWORK: (process.env['NETWORK'] as LIT_TESTNET) || LIT_TESTNET.LOCALCHAIN,
+ NETWORK:
+ (process.env['NETWORK'] as LIT_NETWORK_VALUES) || LIT_NETWORK.Custom,
DEBUG: process.env['DEBUG'] === 'true',
REQUEST_PER_KILOSECOND:
parseInt(process.env['REQUEST_PER_KILOSECOND']) ||
- (process.env['NETWORK'] as LIT_TESTNET) === 'datil-dev'
+ (process.env['NETWORK'] as LIT_NETWORK_VALUES) === 'datil-dev'
? 1
: 200,
LIT_RPC_URL: process.env['LIT_RPC_URL'],
@@ -104,14 +105,14 @@ export class TinnyEnvironment {
private _shivaClient: ShivaClient = new ShivaClient();
private _contractContext: LitContractContext | LitContractResolverContext;
- constructor(network?: LIT_TESTNET) {
- // -- setup networkj
+ constructor(network?: LIT_NETWORK_VALUES) {
+ // -- setup network
this.network = network || this.processEnvs.NETWORK;
- if (Object.values(LIT_TESTNET).indexOf(this.network) === -1) {
+ if (Object.values(LIT_NETWORK).indexOf(this.network) === -1) {
throw new Error(
`Invalid network environment. Please use one of ${Object.values(
- LIT_TESTNET
+ LIT_NETWORK
)}`
);
}
@@ -124,24 +125,24 @@ export class TinnyEnvironment {
// -- setup rpc
// Priority:
// 1. Use environment variable if set
- // 2. Use RPC_MAP if network is recognized
+ // 2. Use RPC_URL_BY_NETWORK if network is recognized
// 3. Throw error if neither condition is met
if (this.processEnvs.LIT_RPC_URL) {
// If LIT_RPC_URL is set in the environment, use it
this.rpc = this.processEnvs.LIT_RPC_URL;
- } else if (this.network in RPC_MAP) {
- // If the network is recognized in RPC_MAP, use the corresponding RPC URL
- this.rpc = RPC_MAP[this.network];
+ } else if (this.network in RPC_URL_BY_NETWORK) {
+ // If the network is recognized in RPC_URL_BY_NETWORK, use the corresponding RPC URL
+ this.rpc = RPC_URL_BY_NETWORK[this.network];
} else {
// If neither condition is met, throw an error with available options
- const availableNetworks = Object.keys(RPC_MAP).join(', ');
+ const availableNetworks = Object.keys(RPC_URL_BY_NETWORK).join(', ');
throw new Error(
`No RPC URL found for network "${this.network}". Available networks are: ${availableNetworks}`
);
}
console.log(
- '[𐬺🧪 Tinny Environment𐬺] Done configuring enviorment current config: ',
+ '[𐬺🧪 Tinny Environment𐬺] Done configuring environment current config: ',
this.processEnvs
);
}
@@ -220,8 +221,8 @@ export class TinnyEnvironment {
* and sets network-specific parameters. The function ensures the client is connected and ready before proceeding.
*
* The LitNodeClient is configured differently based on the network:
- * - LOCALCHAIN: Uses custom settings for local testing, with node attestation disabled.
- * - MANZANO (or other specified testnets): Configures for specific network environments with node attestation enabled.
+ * - Custom: Uses custom settings for local testing, with node attestation disabled.
+ * - DatilTest (or other specified testnets): Configures for specific network environments with node attestation enabled.
*
* Logs the process and exits if the client is not ready after attempting to connect.
*/
@@ -232,14 +233,11 @@ export class TinnyEnvironment {
console.log('this.network:', this.network);
const centralisation = CENTRALISATION_BY_NETWORK[this.network];
- if (
- this.network === LIT_TESTNET.LOCALCHAIN ||
- centralisation === 'unknown'
- ) {
+ if (this.network === LIT_NETWORK.Custom || centralisation === 'unknown') {
const networkContext =
this?.testnet?.ContractContext ?? this._contractContext;
this.litNodeClient = new LitNodeClient({
- litNetwork: 'custom',
+ litNetwork: LIT_NETWORK.Custom,
rpcUrl: this.rpc,
debug: this.processEnvs.DEBUG,
checkNodeAttestation: false, // disable node attestation check for local testing
@@ -263,19 +261,19 @@ export class TinnyEnvironment {
if (globalThis.wasmExports) {
console.warn(
- 'WASM modules already loaded. Will overide when connect is called'
+ 'WASM modules already loaded. Will override when connect is called'
);
}
if (globalThis.wasmECDSA) {
console.warn(
- 'WASM modules already loaded. wil overide. when connect is called'
+ 'WASM modules already loaded. wil override. when connect is called'
);
}
if (globalThis.wasmSevSnpUtils) {
console.warn(
- 'WASM modules already loaded. wil overide. when connect is called'
+ 'WASM modules already loaded. wil override. when connect is called'
);
}
@@ -347,7 +345,7 @@ export class TinnyEnvironment {
return await this.createNewPerson('Alice');
}
- setUnavailable = (network: LIT_TESTNET) => {
+ setUnavailable = (network: LIT_NETWORK_VALUES) => {
if (this.processEnvs.NETWORK === network) {
throw new Error('LIT_IGNORE_TEST');
}
@@ -362,10 +360,7 @@ export class TinnyEnvironment {
console.log('[𐬺🧪 Tinny Environment𐬺] Skipping setup');
return;
}
- if (
- this.network === LIT_TESTNET.LOCALCHAIN &&
- this.processEnvs.USE_SHIVA
- ) {
+ if (this.network === LIT_NETWORK.Custom && this.processEnvs.USE_SHIVA) {
this.testnet = await this._shivaClient.startTestnetManager();
// wait for the testnet to be active before we start the tests.
let state = await this.testnet.pollTestnetForActive();
@@ -377,7 +372,7 @@ export class TinnyEnvironment {
}
await this.testnet.getTestnetConfig();
- } else if (this.network === LIT_TESTNET.LOCALCHAIN) {
+ } else if (this.network === LIT_NETWORK.Custom) {
const context = await import('./networkContext.json');
this._contractContext = context;
}
@@ -429,7 +424,7 @@ export class TinnyEnvironment {
*/
async stopTestnet() {
if (
- this.network === LIT_TESTNET.LOCALCHAIN &&
+ this.network === LIT_NETWORK.Custom &&
this._shivaClient.processEnvs.STOP_TESTNET
) {
await this.testnet.stopTestnet();
@@ -480,7 +475,7 @@ export class TinnyEnvironment {
* Setup contracts-sdk client
* ====================================
*/
- if (this.network === LIT_TESTNET.LOCALCHAIN) {
+ if (this.network === LIT_NETWORK.Custom) {
const networkContext =
this?.testnet?.ContractContext ?? this._contractContext;
this.contractsClient = new LitContracts({
@@ -503,15 +498,16 @@ export class TinnyEnvironment {
// THE FOLLOWING WILL TECHNICALLY NEVER BE CALLED, BUT IT'S HERE FOR FUTURE REFERENCE FOR SWITCHING WALLETS
else {
+ const rpc = this.rpc;
async function _switchWallet() {
- // TODO: This wallet should be cached somehwere and reused to create delegation signatures.
+ // TODO: This wallet should be cached somewhere and reused to create delegation signatures.
// There is a correlation between the number of Capacity Credit NFTs in a wallet and the speed at which nodes can verify a given rate limit authorization. Creating a single wallet to hold all Capacity Credit NFTs improves network performance during tests.
const capacityCreditWallet =
ethers.Wallet.createRandom().connect(provider);
// get wallet balance
const balance = await wallet.getBalance();
- console.log('this.rpc:', this.rpc);
+ console.log('this.rpc:', rpc);
console.log('this.wallet.address', wallet.address);
console.log('Balance:', balance.toString());
diff --git a/local-tests/setup/tinny-person.ts b/local-tests/setup/tinny-person.ts
index 43cf604820..f1457ec34c 100644
--- a/local-tests/setup/tinny-person.ts
+++ b/local-tests/setup/tinny-person.ts
@@ -7,13 +7,12 @@ import { LitContracts } from '@lit-protocol/contracts-sdk';
import {
AuthMethod,
BaseSiweMessage,
- LIT_NETWORKS_KEYS,
LitContractContext,
} from '@lit-protocol/types';
import { ethers } from 'ethers';
-import { LIT_TESTNET, PKPInfo, TinnyEnvConfig } from './tinny-config';
+import { PKPInfo, TinnyEnvConfig } from './tinny-config';
import { EthWalletProvider } from '@lit-protocol/lit-auth-client';
-import { AuthMethodScope } from '@lit-protocol/constants';
+import { AUTH_METHOD_SCOPE, LIT_NETWORK } from '@lit-protocol/constants';
export class TinnyPerson {
public privateKey: string;
@@ -53,6 +52,10 @@ export class TinnyPerson {
this.wallet = new ethers.Wallet(privateKey, this.provider);
}
+ async getAuthMethodId(): Promise {
+ return EthWalletProvider.authMethodId(this.authMethod);
+ }
+
/**
* FIXME: Enabling this is causing the test to fail
* Switches the current wallet to a new funding wallet by creating a new funding wallet,
@@ -65,7 +68,7 @@ export class TinnyPerson {
// Create a new funding wallet, funds it with small amount of ethers, and updates the current wallet to the new one.
const fundingWallet = ethers.Wallet.createRandom().connect(this.provider);
- if (this.envConfig.network != LIT_TESTNET.LOCALCHAIN) {
+ if (this.envConfig.network != LIT_NETWORK.Custom) {
// check balance this.wallet
const balance = await this.wallet.getBalance();
console.log(
@@ -123,14 +126,14 @@ export class TinnyPerson {
* Setup contracts-sdk client
* ====================================
*/
- if (this.envConfig.network === LIT_TESTNET.LOCALCHAIN) {
+ if (this.envConfig.network === LIT_NETWORK.Custom) {
const networkContext = this.envConfig.contractContext;
this.contractsClient = new LitContracts({
signer: this.wallet,
debug: this.envConfig.processEnvs.DEBUG,
rpc: this.envConfig.processEnvs.LIT_RPC_URL, // anvil rpc
customContext: networkContext as unknown as LitContractContext,
- network: 'custom',
+ network: LIT_NETWORK.Custom,
});
} else {
this.contractsClient = new LitContracts({
@@ -163,7 +166,7 @@ export class TinnyPerson {
this.authMethodOwnedPkp = (
await this.contractsClient.mintWithAuth({
authMethod: this.authMethod,
- scopes: [AuthMethodScope.SignAnything],
+ scopes: [AUTH_METHOD_SCOPE.SignAnything],
})
).pkp;
diff --git a/local-tests/test.ts b/local-tests/test.ts
index c66998d30b..e140a2d913 100644
--- a/local-tests/test.ts
+++ b/local-tests/test.ts
@@ -22,11 +22,11 @@ import { testUseEoaSessionSigsToExecuteJsClaimMultipleKeys } from './tests/testU
import { testUseEoaSessionSigsToExecuteJsJsonResponse } from './tests/testUseEoaSessionSigsToExecuteJsJsonResponse';
import { testUseEoaSessionSigsToExecuteJsConsoleLog } from './tests/testUseEoaSessionSigsToExecuteJsConsoleLog';
import { testUseEoaSessionSigsToEncryptDecryptString } from './tests/testUseEoaSessionSigsToEncryptDecryptString';
+import { testUseEoaSessionSigsToEncryptDecryptUint8Array } from './tests/testUseEoaSessionSigsToEncryptDecryptUint8Array';
import { testUsePkpSessionSigsToEncryptDecryptString } from './tests/testUsePkpSessionSigsToEncryptDecryptString';
import { testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString';
import { testUseInvalidLitActionCodeToGenerateSessionSigs } from './tests/testUseInvalidLitActionCodeToGenerateSessionSigs';
import { testUseEoaSessionSigsToEncryptDecryptFile } from './tests/testUseEoaSessionSigsToEncryptDecryptFile';
-import { testUseEoaSessionSigsToEncryptDecryptZip } from './tests/testUseEoaSessionSigsToEncryptDecryptZip';
import { testUsePkpSessionSigsToExecuteJsSigningInParallel } from './tests/testUsePkpSessionSigsToExecuteJsSigningInParallel';
import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel';
import { testUsePkpSessionSigsToExecuteJsClaimKeys } from './tests/testUsePkpSessionSigsToExecuteJsClaimKeys';
@@ -34,13 +34,11 @@ import { testUsePkpSessionSigsToExecuteJsClaimMultipleKeys } from './tests/testU
import { testUsePkpSessionSigsToExecuteJsJsonResponse } from './tests/testUsePkpSessionSigsToExecuteJsJsonResponse';
import { testUsePkpSessionSigsToExecuteJsConsoleLog } from './tests/testUsePkpSessionSigsToExecuteJsConsoleLog';
import { testUsePkpSessionSigsToEncryptDecryptFile } from './tests/testUsePkpSessionSigsToEncryptDecryptFile';
-import { testUsePkpSessionSigsToEncryptDecryptZip } from './tests/testUsePkpSessionSigsToEncryptDecryptZip';
import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys';
import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys';
import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse';
import { testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog';
import { testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile';
-import { testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip } from './tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip';
import { testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign } from './tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign';
import { testUseInvalidLitActionIpfsCodeToGenerateSessionSigs } from './tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs';
import { testSolAuthSigToEncryptDecryptString } from './tests/testSolAuthSigToEncryptDecryptString';
@@ -171,9 +169,8 @@ setLitActionsCodeToLocal();
testUseEoaSessionSigsToExecuteJsJsonResponse,
testUseEoaSessionSigsToExecuteJsConsoleLog,
testUseEoaSessionSigsToEncryptDecryptString,
+ testUseEoaSessionSigsToEncryptDecryptUint8Array,
testUseEoaSessionSigsToEncryptDecryptFile,
- testUseEoaSessionSigsToEncryptDecryptZip,
- testUseEoaSessionSigsToRequestSingleResponse,
};
const pkpSessionSigsTests = {
@@ -186,7 +183,6 @@ setLitActionsCodeToLocal();
testUsePkpSessionSigsToExecuteJsConsoleLog,
testUsePkpSessionSigsToEncryptDecryptString,
testUsePkpSessionSigsToEncryptDecryptFile,
- testUsePkpSessionSigsToEncryptDecryptZip,
};
const litActionSessionSigsTests = {
@@ -199,7 +195,6 @@ setLitActionsCodeToLocal();
testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog,
testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString,
testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile,
- testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip,
// -- invalid cases
testUseInvalidLitActionIpfsCodeToGenerateSessionSigs,
diff --git a/local-tests/tests/test-example.ts b/local-tests/tests/test-example.ts
index 9deedaebac..7cf55fd939 100644
--- a/local-tests/tests/test-example.ts
+++ b/local-tests/tests/test-example.ts
@@ -2,12 +2,12 @@ import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-sessio
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
export const testExample = async (devEnv: TinnyEnvironment) => {
- // Note: This test will be skipped if we are testing on the Cayenne network
- devEnv.setUnavailable(LIT_TESTNET.CAYENNE);
+ // Note: This test will be skipped if we are testing on the DatilDev network
+ devEnv.setUnavailable(LIT_NETWORK.DatilDev);
const alice = await devEnv.createRandomPerson();
diff --git a/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts b/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts
index 0b2589a916..de72d7e878 100644
--- a/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts
+++ b/local-tests/tests/testCosmosAuthSigToEncryptDecryptString.ts
@@ -1,14 +1,14 @@
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
+import { encryptString, decryptToString } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ❌ NETWORK=cayenne yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
- * ❌ NETWORK=manzano yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
- * ❌ NETWORK=localchain yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
+ * ❌ NETWORK=datil-dev yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
+ * ❌ NETWORK=datil-test yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
+ * ❌ NETWORK=custom yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
* ❌ NETWORK=datil-dev yarn test:local --filter=testCosmosAuthSigToEncryptDecryptString
*/
export const testCosmosAuthSigToEncryptDecryptString = async (
@@ -16,16 +16,14 @@ export const testCosmosAuthSigToEncryptDecryptString = async (
) => {
console.log('❌❌ THIS IS A KNOWN FAILING TEST, PLEASE IGNORE FOR NOW. ❌❌');
- devEnv.setUnavailable(LIT_TESTNET.CAYENNE);
- devEnv.setUnavailable(LIT_TESTNET.LOCALCHAIN);
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
- devEnv.setUnavailable(LIT_TESTNET.DATIL_DEV);
+ devEnv.setUnavailable(LIT_NETWORK.Custom);
+ devEnv.setUnavailable(LIT_NETWORK.DatilDev);
const accs = AccessControlConditions.getCosmosBasicAccessControlConditions({
userAddress: devEnv.bareCosmosAuthSig.address,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
unifiedAccessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -52,7 +50,7 @@ export const testCosmosAuthSigToEncryptDecryptString = async (
// -- Decrypt the encrypted string
try {
- const decryptRes = await LitJsSdk.decryptToString(
+ const decryptRes = await decryptToString(
{
unifiedAccessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts
index 40f980c158..96da189589 100644
--- a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts
+++ b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs.ts
@@ -1,13 +1,7 @@
-import {
- AuthMethodScope,
- AuthMethodType,
- LIT_ENDPOINT_VERSION,
-} from '@lit-protocol/constants';
-import { LitAuthClient } from '@lit-protocol/lit-auth-client';
+import { AUTH_METHOD_SCOPE, AUTH_METHOD_TYPE } from '@lit-protocol/constants';
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
/**
* ## Scenario:
@@ -19,9 +13,8 @@ import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne
- * - ✅ NETWORK=manzano yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs
- * - ✅ NETWORK=localchain yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs
+ * - ✅ NETWORK=custom yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs
*/
export const testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs = async (
devEnv: TinnyEnvironment
@@ -30,19 +23,17 @@ export const testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs = async (
const bob = await devEnv.createRandomPerson();
// Checking the scopes of the PKP owned by Bob
- const bobsAuthMethodAuthId = await LitAuthClient.getAuthIdByAuthMethod(
- bob.authMethod
- );
+ const bobsAuthMethodAuthId = await bob.getAuthMethodId();
const scopes =
await bob.contractsClient.pkpPermissionsContract.read.getPermittedAuthMethodScopes(
bob.authMethodOwnedPkp.tokenId,
- AuthMethodType.EthWallet,
+ AUTH_METHOD_TYPE.EthWallet,
bobsAuthMethodAuthId,
3
);
- if (!scopes[AuthMethodScope.SignAnything]) {
+ if (!scopes[AUTH_METHOD_SCOPE.SignAnything]) {
throw new Error('Bob does not have the "SignAnything" scope on his PKP');
}
@@ -58,11 +49,11 @@ export const testDelegatingCapacityCreditsNFTToAnotherPkpToExecuteJs = async (
resourceAbilityRequests: [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
],
capabilityAuthSigs: [capacityDelegationAuthSig],
diff --git a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts
index ea397ebd8e..b32eedf24e 100644
--- a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts
+++ b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs
- * - ✅ NETWORK=localchain yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs
+ * - ✅ NETWORK=custom yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs
*/
export const testDelegatingCapacityCreditsNFTToAnotherWalletToExecuteJs =
async (devEnv: TinnyEnvironment) => {
diff --git a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts
index 1d625ad771..44ddf4e64e 100644
--- a/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts
+++ b/local-tests/tests/testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign
- * - ✅ NETWORK=localchain yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign
+ * - ✅ NETWORK=custom yarn test:local --filter=testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign
*/
export const testDelegatingCapacityCreditsNFTToAnotherWalletToPkpSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts b/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts
index 744dc55cdc..3375ec744a 100644
--- a/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts
+++ b/local-tests/tests/testEthAuthSigToEncryptDecryptString.ts
@@ -1,15 +1,15 @@
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToString } from '@lit-protocol/encryption';
import { CENTRALISATION_BY_NETWORK } from '@lit-protocol/constants';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthAuthSigToEncryptDecryptString
- * ✅ NETWORK=manzano yarn test:local --filter=testEthAuthSigToEncryptDecryptString
- * ✅ NETWORK=localchain yarn test:local --filter=testEthAuthSigToEncryptDecryptString
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthAuthSigToEncryptDecryptString
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthAuthSigToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testEthAuthSigToEncryptDecryptString
*/
export const testEthAuthSigToEncryptDecryptString = async (
devEnv: TinnyEnvironment
@@ -26,7 +26,7 @@ export const testEthAuthSigToEncryptDecryptString = async (
userAddress: alice.authSig.address,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -54,7 +54,7 @@ export const testEthAuthSigToEncryptDecryptString = async (
}
// -- Decrypt the encrypted string
- const decryptRes = await LitJsSdk.decryptToString(
+ const decryptRes = await decryptToString(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testExecuteJsBroadcastAndCollect.ts b/local-tests/tests/testExecuteJsBroadcastAndCollect.ts
index 3b056db7f5..9dd305832c 100644
--- a/local-tests/tests/testExecuteJsBroadcastAndCollect.ts
+++ b/local-tests/tests/testExecuteJsBroadcastAndCollect.ts
@@ -1,21 +1,17 @@
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
- * ❌ NOT AVAILABLE IN MANZANO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
*
*/
export const testExecuteJsBroadcastAndCollect = async (
devEnv: TinnyEnvironment
) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
// set access control conditions for encrypting and decrypting
const accs = AccessControlConditions.getEmvBasicAccessControlConditions({
diff --git a/local-tests/tests/testExecuteJsDecryptAndCombine.ts b/local-tests/tests/testExecuteJsDecryptAndCombine.ts
index 3b24cd4416..44cd66738e 100644
--- a/local-tests/tests/testExecuteJsDecryptAndCombine.ts
+++ b/local-tests/tests/testExecuteJsDecryptAndCombine.ts
@@ -1,29 +1,20 @@
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_NETWORK } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
-import {
- LitAccessControlConditionResource,
- LitActionResource,
-} from '@lit-protocol/auth-helpers';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
-import * as accessControlConditions from '@lit-protocol/access-control-conditions';
+import { encryptString } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
- * ❌ NOT AVAILABLE IN MANZANO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
*
*/
export const testExecutJsDecryptAndCombine = async (
devEnv: TinnyEnvironment
) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
// set access control conditions for encrypting and decrypting
const accs = AccessControlConditions.getEmvBasicAccessControlConditions({
@@ -32,7 +23,7 @@ export const testExecutJsDecryptAndCombine = async (
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice);
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
diff --git a/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts b/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts
index d2c808e776..39af41c07b 100644
--- a/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts
+++ b/local-tests/tests/testExecuteJsSignAndCombineEcdsa.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
- * - ✅ NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
+ * - ✅ NETWORK=custom yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
*/
export const testExecuteJsSignAndCombineEcdsa = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts
index ff681d6c07..39bddee303 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSign.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSign
*/
export const testPkpEthersWithEoaSessionSigsToEthSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts
index accf022ad0..f5feba67fa 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTransaction.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTransaction
*/
export const testPkpEthersWithEoaSessionSigsToEthSignTransaction = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts
index c1d7c29a4b..3fc8cc12f6 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedData.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedData
*/
export const testPkpEthersWithEoaSessionSigsToEthSignTypedData = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts
index 41b0d7f2e4..2d8ae34c48 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil.ts
@@ -9,9 +9,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil
*/
export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataUtil = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts
index a63712d77a..c40f0b4c5d 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1.ts
@@ -9,9 +9,9 @@ import {
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1
*/
export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataV1 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts
index 96c1727b14..22913dda46 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3.ts
@@ -9,9 +9,9 @@ import {
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3
*/
export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataV3 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts
index 1f2c6ff0a7..b473c6ac42 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4.ts
@@ -9,9 +9,9 @@ import {
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4
*/
export const testPkpEthersWithEoaSessionSigsToEthSignTypedDataV4 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts
index b4cb9f79df..f97c781056 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToPersonalSign.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToPersonalSign
*/
export const testPkpEthersWithEoaSessionSigsToPersonalSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts
index ad333351d3..d2c8ea195a 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSendTx.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSendTx
*/
export const testPkpEthersWithEoaSessionSigsToSendTx = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts
index d3e5e4cb98..6c73456ae4 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignMessage.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignMessage
*/
export const testPkpEthersWithEoaSessionSigsToSignMessage = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts
index 456aa2692c..aca18c4d54 100644
--- a/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts
+++ b/local-tests/tests/testPkpEthersWithEoaSessionSigsToSignWithAuthContext.ts
@@ -1,19 +1,19 @@
import {
- LitAbility,
LitActionResource,
LitPKPResource,
createSiweMessageWithRecaps,
generateAuthSig,
} from '@lit-protocol/auth-helpers';
+import { LIT_ABILITY } from '@lit-protocol/constants';
import { PKPEthersWallet } from '@lit-protocol/pkp-ethers';
import { AuthCallbackParams, AuthSig } from '@lit-protocol/types';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithEoaSessionSigsToSignWithAuthContext
*/
export const testPkpEthersWithEoaSessionSigsToSignWithAuthContext = async (
devEnv: TinnyEnvironment
@@ -48,11 +48,11 @@ export const testPkpEthersWithEoaSessionSigsToSignWithAuthContext = async (
resourceAbilityRequests: [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
],
},
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts
index 28439833ab..a4359b8155 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSign.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSign
*/
export const testPkpEthersWithLitActionSessionSigsToEthSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts
index 8542bcc55c..dea9f42591 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTransaction.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTransaction
*/
export const testPkpEthersWithLitActionSessionSigsToEthSignTransaction = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts
index 2ddf80f082..5811ee4958 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedData.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedData
*/
export const testPkpEthersWithLitActionSessionSigsToEthSignTypedData = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts
index f6102c40ae..8f3f626c19 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil
*/
export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataUtil =
async (devEnv: TinnyEnvironment) => {
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts
index 0c96a2689c..570a7044b0 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1.ts
@@ -9,9 +9,9 @@ import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1
*/
export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV1 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts
index a12d0efc05..e616d5914c 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3.ts
@@ -8,9 +8,9 @@ import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3
*/
export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV3 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts
index 5159129a8e..2970de0cbb 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4.ts
@@ -9,9 +9,9 @@ import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4
*/
export const testPkpEthersWithLitActionSessionSigsToEthSignTypedDataV4 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts
index b303cf69f3..f375ecb068 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToPersonalSign.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToPersonalSign
*/
export const testPkpEthersWithLitActionSessionSigsToPersonalSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts
index 92dfc6f3c8..778f13b08e 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSendTx.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSendTx
*/
export const testPkpEthersWithLitActionSessionSigsToSendTx = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts
index cb7a2f35ac..88c88d06a9 100644
--- a/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts
+++ b/local-tests/tests/testPkpEthersWithLitActionSessionSigsToSignMessage.ts
@@ -4,9 +4,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithLitActionSessionSigsToSignMessage
*/
export const testPkpEthersWithLitActionSessionSigsToSignMessage = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts
index 3a63f307ae..9046df3250 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSign.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSign
*/
export const testPkpEthersWithPkpSessionSigsToEthSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts
index 794989c722..8b9401dc14 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTransaction.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTransaction
*/
export const testPkpEthersWithPkpSessionSigsToEthSignTransaction = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts
index 31d20c98be..4ae832e193 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedData.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedData
*/
export const testPkpEthersWithPkpSessionSigsToEthSignTypedData = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts
index 1ec0ba2010..d71700bf6d 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil
*/
export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataUtil = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts
index ccaeb7cb48..7a79e6f55c 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1.ts
@@ -9,9 +9,9 @@ import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-sessio
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1
*/
export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataV1 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts
index bfae5a64ab..97be6d172a 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3.ts
@@ -8,9 +8,9 @@ import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-sessio
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3
*/
export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataV3 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts
index a4712ed587..2b916eb1ac 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4.ts
@@ -9,9 +9,9 @@ import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-sessio
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4
*/
export const testPkpEthersWithPkpSessionSigsToEthSignTypedDataV4 = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts
index 49a14f561a..2a1df06206 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToPersonalSign.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToPersonalSign
*/
export const testPkpEthersWithPkpSessionSigsToPersonalSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts
index 73a0105fe7..7f013f1fa1 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToSendTx.ts
@@ -5,9 +5,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSendTx
*/
export const testPkpEthersWithPkpSessionSigsToSendTx = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts b/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts
index 3ad2a2a3d4..b7a1e08412 100644
--- a/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts
+++ b/local-tests/tests/testPkpEthersWithPkpSessionSigsToSignMessage.ts
@@ -4,9 +4,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage
- * ✅ NETWORK=manzano yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage
- * ✅ NETWORK=localchain yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage
+ * ✅ NETWORK=datil-test yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage
+ * ✅ NETWORK=custom yarn test:local --filter=testPkpEthersWithPkpSessionSigsToSignMessage
*/
export const testPkpEthersWithPkpSessionSigsToSignMessage = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testRelayer.ts b/local-tests/tests/testRelayer.ts
index 9cdabd0962..6b07955bc8 100644
--- a/local-tests/tests/testRelayer.ts
+++ b/local-tests/tests/testRelayer.ts
@@ -1,39 +1,28 @@
import { log } from '@lit-protocol/misc';
-import {
- ClaimRequest,
- ClaimResult,
- ClientClaimProcessor,
-} from '@lit-protocol/types';
+import { ClaimRequest, ClientClaimProcessor } from '@lit-protocol/types';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
-import {
- EthWalletProvider,
- LitAuthClient,
-} from '@lit-protocol/lit-auth-client';
-import { ProviderType } from '@lit-protocol/constants';
-import { withTimeout } from 'local-tests/setup/tinny-utils';
+import { EthWalletProvider, LitRelay } from '@lit-protocol/lit-auth-client';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testRelayer
- * ✅ NETWORK=manzano yarn test:local --filter=testRelayer
- * ✅ NETWORK=localchain yarn test:local --filter=testRelayer
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testRelayer
+ * ✅ NETWORK=datil-test yarn test:local --filter=testRelayer
+ * ✅ NETWORK=custom yarn test:local --filter=testRelayer
* ✅ NETWORK=datil-dev yarn test:local --filter=testRelayer
*/
export const testRelayer = async (devEnv: TinnyEnvironment) => {
const alice = await devEnv.createRandomPerson();
- const litAuthClient = new LitAuthClient({
- litRelayConfig: {
- relayApiKey: 'test-api-key',
- },
+ // -- test fetch pkps
+ const litRelay = new LitRelay({
+ relayUrl: LitRelay.getRelayUrl(devEnv.network),
+ relayApiKey: 'test-api-key',
+ });
+ const ethWalletProvider = new EthWalletProvider({
+ relay: litRelay,
litNodeClient: devEnv.litNodeClient,
});
- // -- test fetch pkps
- const ethWalletProvider = litAuthClient.initProvider(
- ProviderType.EthWallet
- );
-
const pkps = await ethWalletProvider.fetchPKPsThroughRelayer(
alice.authMethod
);
diff --git a/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts b/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts
index 9e110e177c..5e17b1beea 100644
--- a/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts
+++ b/local-tests/tests/testSolAuthSigToEncryptDecryptString.ts
@@ -1,16 +1,13 @@
-import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility, SolanaAuthSig } from '@lit-protocol/types';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
-import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
-import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToString } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testSolAuthSigToEncryptDecryptString
- * ✅ NETWORK=manzano yarn test:local --filter=testSolAuthSigToEncryptDecryptString
- * ✅ NETWORK=localchain yarn test:local --filter=testSolAuthSigToEncryptDecryptString
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testSolAuthSigToEncryptDecryptString
+ * ✅ NETWORK=datil-test yarn test:local --filter=testSolAuthSigToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testSolAuthSigToEncryptDecryptString
*/
export const testSolAuthSigToEncryptDecryptString = async (
devEnv: TinnyEnvironment
@@ -19,7 +16,7 @@ export const testSolAuthSigToEncryptDecryptString = async (
userAddress: devEnv.bareSolAuthSig.address,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
solRpcConditions: accs,
dataToEncrypt: 'Hello world',
@@ -45,7 +42,7 @@ export const testSolAuthSigToEncryptDecryptString = async (
}
// -- Decrypt the encrypted string
- const decryptRes = await LitJsSdk.decryptToString(
+ const decryptRes = await decryptToString(
{
solRpcConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts
index c6cf228505..a11273ca4a 100644
--- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts
+++ b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
- * - ✅ NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
+ * - ✅ NETWORK=custom yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs
*/
export const testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToExecuteJs =
async (devEnv: TinnyEnvironment) => {
diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts
index 342c4419f3..8daefbec5b 100644
--- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts
+++ b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign
- * - ✅ NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign
+ * - ✅ NETWORK=custom yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign
*/
export const testUseCapacityDelegationAuthSigWithUnspecifiedCapacityTokenIdToPkpSign =
async (devEnv: TinnyEnvironment) => {
diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts
index 0ffb15dacc..18818f307b 100644
--- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts
+++ b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs
- * - ✅ NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs
+ * - ✅ NETWORK=custom yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs
*/
export const testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToExecuteJs =
diff --git a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts
index 6cdd9d2779..e479d9c3ab 100644
--- a/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts
+++ b/local-tests/tests/testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigsWithCapacityDelegations } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
*
*
* ## Test Commands:
- * - ❌ Not supported in Cayenne, but session sigs would still work
- * - ✅ NETWORK=manzano yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign
- * - ✅ NETWORK=localchain yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign
+ * - ✅ NETWORK=datil-test yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign
+ * - ✅ NETWORK=custom yarn test:local --filter=testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign
*/
export const testUseCapacityDelegationAuthSigWithUnspecifiedDelegateesToPkpSign =
diff --git a/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts b/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts
index aed18b9456..5a7cedeb12 100644
--- a/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts
+++ b/local-tests/tests/testUseCustomAuthSessionSigsToPkpSignExecuteJs.ts
@@ -1,20 +1,16 @@
+import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
import {
- LitAbility,
- LitActionResource,
- LitPKPResource,
-} from '@lit-protocol/auth-helpers';
-import {
- AuthMethodScope,
+ AUTH_METHOD_SCOPE,
CENTRALISATION_BY_NETWORK,
+ LIT_ABILITY,
} from '@lit-protocol/constants';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { stringToIpfsHash } from 'local-tests/setup/tinny-utils';
/**
* Test Commands:
- * NETWORK=cayenne yarn test:local --filter=testUseCustomAuthSessionSigsToPkpSignExecuteJs
- * NOT AVAILABLE IN HABANERO
- * NETWORK=localchain yarn test:local --filter=testUseCustomAuthSessionSigsToPkpSignExecuteJs
+ * NETWORK=datil-dev yarn test:local --filter=testUseCustomAuthSessionSigsToPkpSignExecuteJs
+ * NETWORK=custom yarn test:local --filter=testUseCustomAuthSessionSigsToPkpSignExecuteJs
*/
export const testUseCustomAuthSessionSigsToPkpSignExecuteJs = async (
devEnv: TinnyEnvironment
@@ -39,7 +35,7 @@ export const testUseCustomAuthSessionSigsToPkpSignExecuteJs = async (
pkpTokenId: alice.pkp.tokenId,
authMethodType: customAuthMethod.authMethodType,
authMethodId: customAuthMethod.authMethodId,
- authMethodScopes: [AuthMethodScope.SignAnything],
+ authMethodScopes: [AUTH_METHOD_SCOPE.SignAnything],
});
console.log(
@@ -75,7 +71,7 @@ export const testUseCustomAuthSessionSigsToPkpSignExecuteJs = async (
await alice.contractsClient.addPermittedAction({
ipfsId: IPFSID,
pkpTokenId: alice.pkp.tokenId,
- authMethodScopes: [AuthMethodScope.SignAnything],
+ authMethodScopes: [AUTH_METHOD_SCOPE.SignAnything],
});
console.log('✅ addPermittedActionReceipt:', addPermittedActionReceipt);
@@ -89,11 +85,11 @@ export const testUseCustomAuthSessionSigsToPkpSignExecuteJs = async (
resourceAbilityRequests: [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
],
// litActionIpfsId: IPFSID,
diff --git a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts
index 302b2a0a38..a113de926e 100644
--- a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptFile.ts
@@ -1,16 +1,17 @@
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToFile } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptFile
*/
export const testUseEoaSessionSigsToEncryptDecryptFile = async (
devEnv: TinnyEnvironment
@@ -25,7 +26,7 @@ export const testUseEoaSessionSigsToEncryptDecryptFile = async (
userAddress: alice.wallet.address,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -61,12 +62,12 @@ export const testUseEoaSessionSigsToEncryptDecryptFile = async (
const eoaSessionSigs2 = await getEoaSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decriptedFile = await LitJsSdk.decryptToFile(
+ const decriptedFile = await decryptToFile(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts
index 6a951cfc88..ac423ceb21 100644
--- a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptString.ts
@@ -1,16 +1,17 @@
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToString } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptString
*/
export const testUseEoaSessionSigsToEncryptDecryptString = async (
devEnv: TinnyEnvironment
@@ -21,7 +22,7 @@ export const testUseEoaSessionSigsToEncryptDecryptString = async (
userAddress: alice.wallet.address,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -57,12 +58,12 @@ export const testUseEoaSessionSigsToEncryptDecryptString = async (
const eoaSessionSigs2 = await getEoaSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decryptRes = await LitJsSdk.decryptToString(
+ const decryptRes = await decryptToString(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptZip.ts b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptUint8Array.ts
similarity index 64%
rename from local-tests/tests/testUseEoaSessionSigsToEncryptDecryptZip.ts
rename to local-tests/tests/testUseEoaSessionSigsToEncryptDecryptUint8Array.ts
index f64eab4a5c..5bfff9103c 100644
--- a/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptZip.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToEncryptDecryptUint8Array.ts
@@ -1,38 +1,49 @@
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
+import {
+ encryptUint8Array,
+ decryptToUint8Array,
+} from '@lit-protocol/encryption';
+import {
+ uint8arrayFromString,
+ uint8arrayToString,
+} from '@lit-protocol/uint8arrays';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptZip
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptZip
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptZip
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptUint8Array
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptUint8Array
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToEncryptDecryptUint8Array
*/
-export const testUseEoaSessionSigsToEncryptDecryptZip = async (
+export const testUseEoaSessionSigsToEncryptDecryptUint8Array = async (
devEnv: TinnyEnvironment
) => {
const alice = await devEnv.createRandomPerson();
- const message = 'Hello world';
-
// set access control conditions for encrypting and decrypting
const accs = AccessControlConditions.getEmvBasicAccessControlConditions({
userAddress: alice.wallet.address,
});
- const encryptRes = await LitJsSdk.zipAndEncryptString(
+ const message = 'Hello world';
+ const messageToEncrypt = uint8arrayFromString(message, 'utf8');
+
+ const encryptRes = await encryptUint8Array(
{
accessControlConditions: accs,
- dataToEncrypt: message,
+ dataToEncrypt: messageToEncrypt,
},
devEnv.litNodeClient as unknown as ILitNodeClient
);
log('encryptRes:', encryptRes);
+ // await 5 seconds for the encryption to be mined
+
// -- Expected output:
// {
// ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D",
@@ -57,12 +68,12 @@ export const testUseEoaSessionSigsToEncryptDecryptZip = async (
const eoaSessionSigs2 = await getEoaSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decryptedZip = await LitJsSdk.decryptToZip(
+ const decryptRes = await decryptToUint8Array(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
@@ -72,16 +83,13 @@ export const testUseEoaSessionSigsToEncryptDecryptZip = async (
},
devEnv.litNodeClient as unknown as ILitNodeClient
);
+ const decryptResString = uint8arrayToString(decryptRes, 'utf8');
devEnv.releasePrivateKeyFromUser(alice);
- const decryptedMessage = await decryptedZip['string.txt'].async('string');
-
- if (message !== decryptedMessage) {
+ if (decryptResString !== message) {
throw new Error(
- `decryptedMessage should be ${message} but received ${decryptedMessage}`
+ `Expected decryptRes to be 'Hello world' but got ${decryptRes}`
);
}
-
- console.log('decryptedMessage:', decryptedMessage);
};
diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts
index 038b232e32..628a6f4173 100644
--- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimKeys.ts
@@ -5,8 +5,6 @@
// ClaimResult,
// ClientClaimProcessor,
// } from '@lit-protocol/types';
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
@@ -23,9 +21,9 @@ import { log } from '@lit-protocol/misc';
* - Note: The key claiming process involves multiple nodes within the Lit network verifying the sessionSigs and collaboratively signing the claim, which results in the generation of a new key pair if successful.
*
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimKeys
*/
export const testUseEoaSessionSigsToExecuteJsClaimKeys = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts
index c18f740365..56d81c3110 100644
--- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToExecuteJsClaimMultipleKeys.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
* - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results.
* *
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToExecuteJsClaimMultipleKeys
*/
export const testUseEoaSessionSigsToExecuteJsClaimMultipleKeys = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts
index f6b90ae481..85a9127d79 100644
--- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToExecuteJsConsoleLog.ts
@@ -1,13 +1,11 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToExecuteJsConsoleLog
*/
export const testUseEoaSessionSigsToExecuteJsConsoleLog = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts
index 4e219a264f..112a8b1ebd 100644
--- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToExecuteJsJsonResponse.ts
@@ -1,13 +1,11 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToExecuteJsJsonResponse
*/
export const testUseEoaSessionSigsToExecuteJsJsonResponse = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts
index c381ded7a8..36dd6fe9dc 100644
--- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigning.ts
@@ -1,14 +1,12 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigning
*/
export const testUseEoaSessionSigsToExecuteJsSigning = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts b/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts
index 0b20018d88..9e1e45a84a 100644
--- a/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToExecuteJsSigningInParallel.ts
@@ -1,14 +1,12 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToExecuteJsSigningInParallel
*/
export const testUseEoaSessionSigsToExecuteJsSigningInParallel = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts b/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts
index d50d5b5513..1b217f3e54 100644
--- a/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts
+++ b/local-tests/tests/testUseEoaSessionSigsToPkpSign.ts
@@ -1,14 +1,12 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getEoaSessionSigs } from 'local-tests/setup/session-sigs/get-eoa-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseEoaSessionSigsToPkpSign
- * ✅ NETWORK=manzano yarn test:local --filter=testUseEoaSessionSigsToPkpSign
- * ✅ NETWORK=localchain yarn test:local --filter=testUseEoaSessionSigsToPkpSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseEoaSessionSigsToPkpSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseEoaSessionSigsToPkpSign
+ * ✅ NETWORK=custom yarn test:local --filter=testUseEoaSessionSigsToPkpSign
*/
export const testUseEoaSessionSigsToPkpSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts b/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts
index 69d6cd36ad..49d5c93a4e 100644
--- a/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts
+++ b/local-tests/tests/testUseInvalidLitActionCodeToGenerateSessionSigs.ts
@@ -1,19 +1,15 @@
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { getInvalidLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs
- * ❌ NOT AVAILABLE IN MANZANO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs
+ * ✅ NETWORK=custom yarn test:local --filter=testUseInvalidLitActionCodeToGenerateSessionSigs
*/
export const testUseInvalidLitActionCodeToGenerateSessionSigs = async (
devEnv: TinnyEnvironment
) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
try {
diff --git a/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts b/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts
index 871009d8e5..fe334401a1 100644
--- a/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts
+++ b/local-tests/tests/testUseInvalidLitActionIpfsCodeToGenerateSessionSigs.ts
@@ -1,13 +1,10 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getInvalidLitActionIpfsSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseInvalidLitActionIpfsCodeToGenerateSessionSigs
- * ❌ NOT AVAILABLE IN MANZANO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseInvalidLitActionIpfsCodeToGenerateSessionSigs
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseInvalidLitActionIpfsCodeToGenerateSessionSigs
+ * ✅ NETWORK=custom yarn test:local --filter=testUseInvalidLitActionIpfsCodeToGenerateSessionSigs
*/
export const testUseInvalidLitActionIpfsCodeToGenerateSessionSigs = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts
index 4b4026eb28..567029e7d8 100644
--- a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptFile.ts
@@ -1,16 +1,17 @@
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToFile } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptFile
*/
export const testUsePkpSessionSigsToEncryptDecryptFile = async (
devEnv: TinnyEnvironment
@@ -26,7 +27,7 @@ export const testUsePkpSessionSigsToEncryptDecryptFile = async (
userAddress: alice.authMethodOwnedPkp.ethAddress,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -62,12 +63,12 @@ export const testUsePkpSessionSigsToEncryptDecryptFile = async (
const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decriptedFile = await LitJsSdk.decryptToFile(
+ const decriptedFile = await decryptToFile(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts
index f5918b1e73..d3508e6c74 100644
--- a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptString.ts
@@ -1,16 +1,17 @@
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToString } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptString
*/
export const testUsePkpSessionSigsToEncryptDecryptString = async (
devEnv: TinnyEnvironment
@@ -21,7 +22,7 @@ export const testUsePkpSessionSigsToEncryptDecryptString = async (
userAddress: alice.authMethodOwnedPkp.ethAddress,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -55,12 +56,12 @@ export const testUsePkpSessionSigsToEncryptDecryptString = async (
const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decryptRes = await LitJsSdk.decryptToString(
+ const decryptRes = await decryptToString(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptZip.ts b/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptZip.ts
deleted file mode 100644
index abdc59ef4e..0000000000
--- a/local-tests/tests/testUsePkpSessionSigsToEncryptDecryptZip.ts
+++ /dev/null
@@ -1,90 +0,0 @@
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
-import { AccessControlConditions } from 'local-tests/setup/accs/accs';
-import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
-import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
-import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
-import { log } from '@lit-protocol/misc';
-
-/**
- * Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptZip
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptZip
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToEncryptDecryptZip
- */
-export const testUsePkpSessionSigsToEncryptDecryptZip = async (
- devEnv: TinnyEnvironment
-) => {
- const alice = await devEnv.createRandomPerson();
-
- const message = 'Hello world';
-
- // set access control conditions for encrypting and decrypting
- const accs = AccessControlConditions.getEmvBasicAccessControlConditions({
- userAddress: alice.authMethodOwnedPkp.ethAddress,
- });
-
- const encryptRes = await LitJsSdk.zipAndEncryptString(
- {
- accessControlConditions: accs,
- dataToEncrypt: message,
- },
- devEnv.litNodeClient as unknown as ILitNodeClient
- );
-
- log('encryptRes:', encryptRes);
-
- // await 5 seconds for the encryption to be mined
-
- // -- Expected output:
- // {
- // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D",
- // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c",
- // }
-
- // -- assertions
- if (!encryptRes.ciphertext) {
- throw new Error(`Expected "ciphertext" in encryptRes`);
- }
-
- if (!encryptRes.dataToEncryptHash) {
- throw new Error(`Expected "dataToEncryptHash" to in encryptRes`);
- }
-
- const accsResourceString =
- await LitAccessControlConditionResource.generateResourceString(
- accs,
- encryptRes.dataToEncryptHash
- );
-
- const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [
- {
- resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
- },
- ]);
-
- // -- Decrypt the encrypted string
- const decryptedZip = await LitJsSdk.decryptToZip(
- {
- accessControlConditions: accs,
- ciphertext: encryptRes.ciphertext,
- dataToEncryptHash: encryptRes.dataToEncryptHash,
- sessionSigs: pkpSessionSigs2,
- chain: 'ethereum',
- },
- devEnv.litNodeClient as unknown as ILitNodeClient
- );
-
- devEnv.releasePrivateKeyFromUser(alice);
-
- const decryptedMessage = await decryptedZip['string.txt'].async('string');
-
- if (message !== decryptedMessage) {
- throw new Error(
- `decryptedMessage should be ${message} but received ${decryptedMessage}`
- );
- }
-
- console.log('decryptedMessage:', decryptedMessage);
-};
diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts
index 3dee2d97d3..d2f3d90048 100644
--- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimKeys.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -15,9 +13,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
* - Note: The key claiming process involves multiple nodes within the Lit network verifying the sessionSigs and collaboratively signing the claim, which results in the generation of a new key pair if successful.
*
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimKeys
*/
export const testUsePkpSessionSigsToExecuteJsClaimKeys = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts
index 6b960c9958..cad0d177c6 100644
--- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToExecuteJsClaimMultipleKeys.ts
@@ -1,5 +1,3 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,9 +11,9 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
* - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results.
* *
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToExecuteJsClaimMultipleKeys
*/
export const testUsePkpSessionSigsToExecuteJsClaimMultipleKeys = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts
index dab300578d..d2714409ba 100644
--- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToExecuteJsConsoleLog.ts
@@ -1,13 +1,11 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToExecuteJsConsoleLog
*/
export const testUsePkpSessionSigsToExecuteJsConsoleLog = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts
index cc4e016d69..68f6f12ef8 100644
--- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToExecuteJsJsonResponse.ts
@@ -1,13 +1,11 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToExecuteJsJsonResponse
*/
export const testUsePkpSessionSigsToExecuteJsJsonResponse = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts
index 0864680c36..b4786f19f5 100644
--- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigning.ts
@@ -1,14 +1,12 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigning
*/
export const testUsePkpSessionSigsToExecuteJsSigning = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts b/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts
index 7469896024..5bf58b524e 100644
--- a/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToExecuteJsSigningInParallel.ts
@@ -1,14 +1,12 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToExecuteJsSigningInParallel
*/
export const testUsePkpSessionSigsToExecuteJsSigningInParallel = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts b/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts
index 658b676a73..27986b20f1 100644
--- a/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts
+++ b/local-tests/tests/testUsePkpSessionSigsToPkpSign.ts
@@ -1,14 +1,12 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUsePkpSessionSigsToPkpSign
- * ✅ NETWORK=manzano yarn test:local --filter=testUsePkpSessionSigsToPkpSign
- * ✅ NETWORK=localchain yarn test:local --filter=testUsePkpSessionSigsToPkpSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUsePkpSessionSigsToPkpSign
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUsePkpSessionSigsToPkpSign
+ * ✅ NETWORK=custom yarn test:local --filter=testUsePkpSessionSigsToPkpSign
*/
export const testUsePkpSessionSigsToPkpSign = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts
index 9481fa4a65..aab71fbd6d 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile.ts
@@ -1,23 +1,22 @@
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_NETWORK } from '@lit-protocol/constants';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
-import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
+import { encryptString, decryptToFile } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
- * ✅ NETWORK=manzano yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=datil-test yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
const alice = await devEnv.createRandomPerson();
const message = 'Hello world';
@@ -29,7 +28,7 @@ export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile =
userAddress: alice.authMethodOwnedPkp.ethAddress,
});
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -65,12 +64,12 @@ export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptFile =
const pkpSessionSigs2 = await getPkpSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decriptedFile = await LitJsSdk.decryptToFile(
+ const decriptedFile = await decryptToFile(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts
index c62bb9f4e9..9d631d7307 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString.ts
@@ -1,24 +1,21 @@
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
+import { LIT_NETWORK } from '@lit-protocol/constants';
+import { LIT_ABILITY } from '@lit-protocol/constants';
+import { ILitNodeClient } from '@lit-protocol/types';
import { AccessControlConditions } from 'local-tests/setup/accs/accs';
import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { log } from '@lit-protocol/misc';
+import { encryptString, decryptToString } from '@lit-protocol/encryption';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
- * ❌ NOT AVAILABLE IN MANZANO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
*
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
// set access control conditions for encrypting and decrypting
const accs = AccessControlConditions.getEmvBasicAccessControlConditions({
@@ -27,7 +24,7 @@ export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice);
- const encryptRes = await LitJsSdk.encryptString(
+ const encryptRes = await encryptString(
{
accessControlConditions: accs,
dataToEncrypt: 'Hello world',
@@ -61,12 +58,12 @@ export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptString
const litActionSessionSigs2 = await getLitActionSessionSigs(devEnv, alice, [
{
resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
]);
// -- Decrypt the encrypted string
- const decryptRes = await LitJsSdk.decryptToString(
+ const decryptRes = await decryptToString(
{
accessControlConditions: accs,
ciphertext: encryptRes.ciphertext,
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip.ts
deleted file mode 100644
index 1ef9ff9e5e..0000000000
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
-import * as LitJsSdk from '@lit-protocol/lit-node-client-nodejs';
-import { ILitNodeClient, LitAbility } from '@lit-protocol/types';
-import { AccessControlConditions } from 'local-tests/setup/accs/accs';
-import { LitAccessControlConditionResource } from '@lit-protocol/auth-helpers';
-import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
-import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
-import { log } from '@lit-protocol/misc';
-
-/**
- * Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip
- * ❌ Not supported in Manzano
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip
- * ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip
- */
-export const testUseValidLitActionCodeGeneratedSessionSigsToEncryptDecryptZip =
- async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
- const alice = await devEnv.createRandomPerson();
-
- const message = 'Hello world';
-
- // set access control conditions for encrypting and decrypting
- const accs = AccessControlConditions.getEmvBasicAccessControlConditions({
- userAddress: alice.authMethodOwnedPkp.ethAddress,
- });
-
- const encryptRes = await LitJsSdk.zipAndEncryptString(
- {
- accessControlConditions: accs,
- dataToEncrypt: message,
- },
- devEnv.litNodeClient as unknown as ILitNodeClient
- );
-
- log('encryptRes:', encryptRes);
-
- // await 5 seconds for the encryption to be mined
-
- // -- Expected output:
- // {
- // ciphertext: "pSP1Rq4xdyLBzSghZ3DtTtHp2UL7/z45U2JDOQho/WXjd2ntr4IS8BJfqJ7TC2U4CmktrvbVT3edoXJgFqsE7vy9uNrBUyUSTuUdHLfDVMIgh4a7fqMxsdQdkWZjHign3JOaVBihtOjAF5VthVena28D",
- // dataToEncryptHash: "64ec88ca00b268e5ba1a35678a1b5316d212f4f366b2477232534a8aeca37f3c",
- // }
-
- // -- assertions
- if (!encryptRes.ciphertext) {
- throw new Error(`Expected "ciphertext" in encryptRes`);
- }
-
- if (!encryptRes.dataToEncryptHash) {
- throw new Error(`Expected "dataToEncryptHash" to in encryptRes`);
- }
-
- const accsResourceString =
- await LitAccessControlConditionResource.generateResourceString(
- accs,
- encryptRes.dataToEncryptHash
- );
-
- const litActionSessionSigs2 = await getLitActionSessionSigs(devEnv, alice, [
- {
- resource: new LitAccessControlConditionResource(accsResourceString),
- ability: LitAbility.AccessControlConditionDecryption,
- },
- ]);
-
- // -- Decrypt the encrypted string
- const decryptedZip = await LitJsSdk.decryptToZip(
- {
- accessControlConditions: accs,
- ciphertext: encryptRes.ciphertext,
- dataToEncryptHash: encryptRes.dataToEncryptHash,
- sessionSigs: litActionSessionSigs2,
- chain: 'ethereum',
- },
- devEnv.litNodeClient as unknown as ILitNodeClient
- );
-
- devEnv.releasePrivateKeyFromUser(alice);
-
- const decryptedMessage = await decryptedZip['string.txt'].async('string');
-
- if (message !== decryptedMessage) {
- throw new Error(
- `decryptedMessage should be ${message} but received ${decryptedMessage}`
- );
- }
-
- console.log('decryptedMessage:', decryptedMessage);
- };
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts
index 9d6fd6e946..d43ff81323 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys.ts
@@ -1,7 +1,5 @@
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LitAbility } from '@lit-protocol/types';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK, LIT_ABILITY } from '@lit-protocol/constants';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -15,24 +13,20 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
* - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results.
* *
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys
- * ❌ Not supported in Manzano
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys
- * ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimKeys =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice, [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
]);
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts
index 2cd2919b8d..efcfa5a819 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys.ts
@@ -1,5 +1,4 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
@@ -13,15 +12,11 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
* - Then: The claim operation should successfully return signatures, derived key IDs, and validate the existence and structure of claimed results.
* *
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys
- * ❌ Not supported in Manzano
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsClaimMultipleKeys =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice);
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts
index 53ffe99766..aa6ca860b7 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog.ts
@@ -1,31 +1,25 @@
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LitAbility } from '@lit-protocol/types';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK, LIT_ABILITY } from '@lit-protocol/constants';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog
- * ❌ Not supported on manzano
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsConsoleLog =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice, [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
]);
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts
index 007c9e448c..da84f7d5db 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse.ts
@@ -1,19 +1,13 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse
- * ❌ Not supported on manzano
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsJsonResponse =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice);
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts
index 92b90b2556..672b2267c0 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning.ts
@@ -1,32 +1,26 @@
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LitAbility } from '@lit-protocol/types';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_ABILITY } from '@lit-protocol/constants';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning
- * ❌ NOT AVAILABLE IN HABANERO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigning =
async (devEnv: TinnyEnvironment) => {
//
- // devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice, [
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
]);
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts
index e57cc6f451..70add1f7ec 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel.ts
@@ -1,20 +1,15 @@
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel
- * ❌ Not available in Habanero
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel
*/
export const testUseValidLitActionCodeGeneratedSessionSigsToExecuteJsSigningInParallel =
async (devEnv: TinnyEnvironment) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice);
diff --git a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts
index b72471a035..9ae59420e8 100644
--- a/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts
+++ b/local-tests/tests/testUseValidLitActionCodeGeneratedSessionSigsToPkpSign.ts
@@ -1,24 +1,17 @@
-import { LitPKPResource } from '@lit-protocol/auth-helpers';
-import { LIT_ENDPOINT_VERSION } from '@lit-protocol/constants';
import { log } from '@lit-protocol/misc';
-import { LitAbility } from '@lit-protocol/types';
-import { LIT_TESTNET } from 'local-tests/setup/tinny-config';
+import { LIT_NETWORK } from '@lit-protocol/constants';
import { getLitActionSessionSigs } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign
- * ❌ NOT AVAILABLE IN HABANERO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign
* ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionCodeGeneratedSessionSigsToPkpSign
*
**/
export const testUseValidLitActionCodeGeneratedSessionSigsToPkpSign = async (
devEnv: TinnyEnvironment
) => {
- devEnv.setUnavailable(LIT_TESTNET.MANZANO);
-
const alice = await devEnv.createRandomPerson();
const litActionSessionSigs = await getLitActionSessionSigs(devEnv, alice);
diff --git a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts b/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts
index 535521bd87..ce40e45291 100644
--- a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts
+++ b/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning.ts
@@ -1,14 +1,13 @@
import { LitActionResource, LitPKPResource } from '@lit-protocol/auth-helpers';
import { log } from '@lit-protocol/misc';
-import { LitAbility } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
import { getLitActionSessionSigsUsingIpfsId } from 'local-tests/setup/session-sigs/get-lit-action-session-sigs';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning
- * ❌ NOT AVAILABLE IN HABANERO
- * ✅ NETWORK=localchain yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning
+ * ✅ NETWORK=custom yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning
*/
export const testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning =
async (devEnv: TinnyEnvironment) => {
@@ -19,11 +18,11 @@ export const testUseValidLitActionIpfsCodeGeneratedSessionSigsToExecuteJsSigning
[
{
resource: new LitPKPResource('*'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('*'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
]
);
diff --git a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts b/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts
index 9d11289b7b..ab59dd5f0d 100644
--- a/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts
+++ b/local-tests/tests/testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign.ts
@@ -4,9 +4,8 @@ import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign
- * ❌ NOT AVAILABLE IN HABANERO
- * ❌ NETWORK=localchain yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign
+ * ❌ NETWORK=custom yarn test:local --filter=testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign
*
**/
export const testUseValidLitActionIpfsCodeGeneratedSessionSigsToPkpSign =
diff --git a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts b/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts
index 711516a3b3..3df75c6de5 100644
--- a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts
+++ b/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionGeneratedKey.ts
@@ -9,9 +9,9 @@ const { signTransactionWithEncryptedKey, generatePrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testEthereumBroadcastTransactionGeneratedKey
*/
export const testEthereumBroadcastTransactionGeneratedKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts b/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts
index 85aae4d90e..c10593c782 100644
--- a/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testEthereumBroadcastTransactionWrappedKey.ts
@@ -9,9 +9,9 @@ const { importPrivateKey, signTransactionWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testEthereumBroadcastTransactionWrappedKey
*/
export const testEthereumBroadcastTransactionWrappedKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts b/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts
index 4c1e7af112..75804f35cb 100644
--- a/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts
+++ b/local-tests/tests/wrapped-keys/testEthereumBroadcastWrappedKeyWithFetchGasParams.ts
@@ -9,9 +9,9 @@ const { importPrivateKey, signTransactionWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams
- * ✅ NETWORK=manzano yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams
- * ✅ NETWORK=localchain yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams
+ * ✅ NETWORK=custom yarn test:local --filter=testEthereumBroadcastWrappedKeyWithFetchGasParams
*/
export const testEthereumBroadcastWrappedKeyWithFetchGasParams = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts b/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts
index a06531dce0..e85336caad 100644
--- a/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts
+++ b/local-tests/tests/wrapped-keys/testEthereumSignMessageGeneratedKey.ts
@@ -8,9 +8,9 @@ const { generatePrivateKey, signMessageWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthereumSignMessageGeneratedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testEthereumSignMessageGeneratedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testEthereumSignMessageGeneratedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthereumSignMessageGeneratedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthereumSignMessageGeneratedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testEthereumSignMessageGeneratedKey
*/
export const testEthereumSignMessageGeneratedKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts b/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts
index 05d692ea0f..08594ace4d 100644
--- a/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testEthereumSignMessageWrappedKey.ts
@@ -8,9 +8,9 @@ const { importPrivateKey, signMessageWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthereumSignMessageWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testEthereumSignMessageWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testEthereumSignMessageWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthereumSignMessageWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthereumSignMessageWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testEthereumSignMessageWrappedKey
*/
export const testEthereumSignMessageWrappedKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts b/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts
index a4b1ace84b..ac6c6bc983 100644
--- a/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testEthereumSignTransactionWrappedKey.ts
@@ -11,9 +11,9 @@ const { importPrivateKey, signTransactionWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testEthereumSignTransactionWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testEthereumSignTransactionWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testEthereumSignTransactionWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testEthereumSignTransactionWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testEthereumSignTransactionWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testEthereumSignTransactionWrappedKey
*/
export const testEthereumSignTransactionWrappedKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testExportWrappedKey.ts b/local-tests/tests/wrapped-keys/testExportWrappedKey.ts
index da390f1eda..50f41c142b 100644
--- a/local-tests/tests/wrapped-keys/testExportWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testExportWrappedKey.ts
@@ -7,9 +7,9 @@ import { randomSolanaPrivateKey } from '../../setup/tinny-utils';
const { exportPrivateKey, importPrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testExportWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testExportWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testExportWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testExportWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testExportWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testExportWrappedKey
*/
export const testExportWrappedKey = async (devEnv: TinnyEnvironment) => {
const alice = await devEnv.createRandomPerson();
diff --git a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts
index 0595610d54..b62bc52c84 100644
--- a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts
+++ b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyInvalidDecryption.ts
@@ -11,9 +11,9 @@ import { getPkpAccessControlCondition } from '../../../packages/wrapped-keys/src
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption
- * ✅ NETWORK=manzano yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption
- * ✅ NETWORK=localchain yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption
+ * ✅ NETWORK=custom yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyInvalidDecryption
*/
export const testFailEthereumSignTransactionWrappedKeyInvalidDecryption =
async (devEnv: TinnyEnvironment) => {
diff --git a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts
index 8aaccca971..88b98abbf5 100644
--- a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts
+++ b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithInvalidParam.ts
@@ -8,9 +8,9 @@ import { getBaseTransactionForNetwork } from './util';
const { importPrivateKey, signTransactionWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam
- * ✅ NETWORK=manzano yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam
- * ✅ NETWORK=localchain yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam
+ * ✅ NETWORK=custom yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithInvalidParam
*/
export const testFailEthereumSignTransactionWrappedKeyWithInvalidParam = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts
index f23c0d6910..adb2b76a35 100644
--- a/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts
+++ b/local-tests/tests/wrapped-keys/testFailEthereumSignTransactionWrappedKeyWithMissingParam.ts
@@ -8,9 +8,9 @@ import { getChainForNetwork } from './util';
const { importPrivateKey, signTransactionWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam
- * ✅ NETWORK=manzano yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam
- * ✅ NETWORK=localchain yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam
+ * ✅ NETWORK=custom yarn test:local --filter=testFailEthereumSignTransactionWrappedKeyWithMissingParam
*/
export const testFailEthereumSignTransactionWrappedKeyWithMissingParam = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts
index 831fc5f04b..801d22e999 100644
--- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts
+++ b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithEoaSessionSig.ts
@@ -7,9 +7,9 @@ const { importPrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig
- * ✅ NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig
- * ✅ NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig
+ * ✅ NETWORK=custom yarn test:local --filter=testFailImportWrappedKeysWithEoaSessionSig
*/
export const testFailImportWrappedKeysWithEoaSessionSig = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts
index 67f5422ef5..1f7ea4319b 100644
--- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts
+++ b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithExpiredSessionSig.ts
@@ -7,9 +7,9 @@ const { importPrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig
- * ✅ NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig
- * ✅ NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig
+ * ✅ NETWORK=custom yarn test:local --filter=testFailImportWrappedKeysWithExpiredSessionSig
*/
export const testFailImportWrappedKeysWithExpiredSessionSig = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts
index 78cc80a53b..f4f088cfc5 100644
--- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts
+++ b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithInvalidSessionSig.ts
@@ -8,9 +8,9 @@ const { importPrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig
- * ✅ NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig
- * ✅ NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig
+ * ✅ NETWORK=custom yarn test:local --filter=testFailImportWrappedKeysWithInvalidSessionSig
*/
export const testFailImportWrappedKeysWithInvalidSessionSig = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts
index 55ab120c21..039f7ad8e3 100644
--- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts
+++ b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithMaxExpirySessionSig.ts
@@ -7,9 +7,9 @@ const { importPrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig
- * ✅ NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig
- * ✅ NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig
+ * ✅ NETWORK=custom yarn test:local --filter=testFailImportWrappedKeysWithMaxExpirySessionSig
*/
export const testFailImportWrappedKeysWithMaxExpirySessionSig = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts
index 3c47591382..b7566c5fea 100644
--- a/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts
+++ b/local-tests/tests/wrapped-keys/testFailImportWrappedKeysWithSamePrivateKey.ts
@@ -5,9 +5,9 @@ import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-sessio
const { importPrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey
- * ✅ NETWORK=manzano yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey
- * ✅ NETWORK=localchain yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey
+ * ✅ NETWORK=custom yarn test:local --filter=testFailImportWrappedKeysWithSamePrivateKey
*/
export const testFailImportWrappedKeysWithSamePrivateKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts b/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts
index 214780fa10..5f0c22aa37 100644
--- a/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testGenerateEthereumWrappedKey.ts
@@ -9,9 +9,9 @@ const { generatePrivateKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testGenerateEthereumWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testGenerateEthereumWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testGenerateEthereumWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testGenerateEthereumWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testGenerateEthereumWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testGenerateEthereumWrappedKey
*/
export const testGenerateEthereumWrappedKey = async (
devEnv: TinnyEnvironment
@@ -24,7 +24,7 @@ export const testGenerateEthereumWrappedKey = async (
alice,
null,
new Date(Date.now() + 1000 * 60 * 10).toISOString()
- ); // 10 mins expiry
+ );
const { pkpAddress, generatedPublicKey, id } = await generatePrivateKey({
pkpSessionSigs,
diff --git a/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts b/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts
index 74bcae620d..1bcb239ce2 100644
--- a/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testGenerateSolanaWrappedKey.ts
@@ -2,18 +2,18 @@ import { log } from '@lit-protocol/misc';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { api } from '@lit-protocol/wrapped-keys';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
-import nacl from 'tweetnacl';
-import bs58 from 'bs58';
import { Keypair } from '@solana/web3.js';
+import { ethers } from 'ethers';
+import nacl from 'tweetnacl';
const { generatePrivateKey, signMessageWithEncryptedKey, exportPrivateKey } =
api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testGenerateSolanaWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testGenerateSolanaWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testGenerateSolanaWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testGenerateSolanaWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testGenerateSolanaWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testGenerateSolanaWrappedKey
*/
export const testGenerateSolanaWrappedKey = async (
devEnv: TinnyEnvironment
@@ -68,8 +68,8 @@ export const testGenerateSolanaWrappedKey = async (
const signatureIsValidForPublicKey = nacl.sign.detached.verify(
Buffer.from(messageToSign),
- bs58.decode(signature),
- bs58.decode(generatedPublicKey)
+ ethers.utils.base58.decode(signature),
+ ethers.utils.base58.decode(generatedPublicKey)
);
if (!signatureIsValidForPublicKey)
diff --git a/local-tests/tests/wrapped-keys/testImportWrappedKey.ts b/local-tests/tests/wrapped-keys/testImportWrappedKey.ts
index 63a8054383..9c2bdfd00c 100644
--- a/local-tests/tests/wrapped-keys/testImportWrappedKey.ts
+++ b/local-tests/tests/wrapped-keys/testImportWrappedKey.ts
@@ -8,9 +8,9 @@ const { importPrivateKey, listEncryptedKeyMetadata } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testImportWrappedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testImportWrappedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testImportWrappedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testImportWrappedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testImportWrappedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testImportWrappedKey
*/
export const testImportWrappedKey = async (devEnv: TinnyEnvironment) => {
const alice = await devEnv.createRandomPerson();
diff --git a/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts b/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts
index 485332c722..b182f3e27d 100644
--- a/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts
+++ b/local-tests/tests/wrapped-keys/testSignMessageWithSolanaEncryptedKey.ts
@@ -2,7 +2,7 @@ import { log } from '@lit-protocol/misc';
import { TinnyEnvironment } from 'local-tests/setup/tinny-environment';
import { api } from '@lit-protocol/wrapped-keys';
import { Keypair } from '@solana/web3.js';
-import bs58 from 'bs58';
+import { ethers } from 'ethers';
import nacl from 'tweetnacl';
import { getPkpSessionSigs } from 'local-tests/setup/session-sigs/get-pkp-session-sigs';
@@ -10,9 +10,9 @@ const { importPrivateKey, signMessageWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testSignMessageWithSolanaEncryptedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testSignMessageWithSolanaEncryptedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testSignMessageWithSolanaEncryptedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testSignMessageWithSolanaEncryptedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testSignMessageWithSolanaEncryptedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testSignMessageWithSolanaEncryptedKey
*/
export const testSignMessageWithSolanaEncryptedKey = async (
devEnv: TinnyEnvironment
@@ -68,7 +68,7 @@ export const testSignMessageWithSolanaEncryptedKey = async (
const signatureIsValidForPublicKey = nacl.sign.detached.verify(
Buffer.from(messageToSign),
- bs58.decode(signature),
+ ethers.utils.base58.decode(signature),
solanaKeypair.publicKey.toBuffer()
);
diff --git a/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts b/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts
index 55f9bfa402..138d2c5b53 100644
--- a/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts
+++ b/local-tests/tests/wrapped-keys/testSignTransactionWithSolanaEncryptedKey.ts
@@ -17,9 +17,9 @@ const { importPrivateKey, signTransactionWithEncryptedKey } = api;
/**
* Test Commands:
- * ✅ NETWORK=cayenne yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey
- * ✅ NETWORK=manzano yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey
- * ✅ NETWORK=localchain yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey
+ * ✅ NETWORK=datil-dev yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey
+ * ✅ NETWORK=datil-test yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey
+ * ✅ NETWORK=custom yarn test:local --filter=testSignTransactionWithSolanaEncryptedKey
*/
export const testSignTransactionWithSolanaEncryptedKey = async (
devEnv: TinnyEnvironment
diff --git a/local-tests/tests/wrapped-keys/util.ts b/local-tests/tests/wrapped-keys/util.ts
index 4f3573fe33..f03f78d420 100644
--- a/local-tests/tests/wrapped-keys/util.ts
+++ b/local-tests/tests/wrapped-keys/util.ts
@@ -51,13 +51,6 @@ export function getChainForNetwork(network: LIT_NETWORKS_KEYS): {
chainId: number;
} {
switch (network) {
- case 'cayenne':
- case 'habanero':
- case 'manzano':
- return {
- chain: 'chronicleTestnet',
- chainId: LIT_CHAINS['chronicleTestnet'].chainId,
- };
case 'datil-dev':
return {
chain: 'yellowstone',
@@ -83,13 +76,6 @@ export function getGasParamsForNetwork(network: LIT_NETWORKS_KEYS): {
gasLimit: number;
} {
switch (network) {
- case 'cayenne':
- case 'habanero':
- case 'manzano':
- return {
- gasPrice: '0.001',
- gasLimit: 30000,
- };
case 'datil-dev':
return { gasLimit: 5000000 };
case 'datil-test':
diff --git a/package.json b/package.json
index 5eb612672f..a9a1c83f28 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,7 @@
"reset": "rm -rf ./dist/packages && yarn reset:dev",
"build": "yarn build:packages",
"build:dev": "yarn tools --remove-local-dev && rm -rf ./dist && yarn tools check --no-empty-directories=true && yarn tools fixTsConfig && yarn tools --match-versions && yarn nx run-many --target=build && yarn tools --setup-local-dev && yarn build:verify",
- "build:packages": "yarn tools --remove-local-dev && rm -rf ./dist && yarn gen:internal-dev && yarn tools check --no-empty-directories=true && yarn tools fixTsConfig && yarn tools --match-versions && yarn nx run-many --target=build && yarn tools --setup-local-dev && yarn gen:readme && yarn build:verify && yarn nx format:write --all",
+ "build:packages": "yarn tools --remove-local-dev && rm -rf ./dist && yarn tools check --no-empty-directories=true && yarn tools fixTsConfig && yarn tools --match-versions && yarn nx run-many --target=build && yarn tools --setup-local-dev && yarn gen:readme && yarn build:verify && yarn nx format:write --all",
"build:target": "yarn node tools/scripts/build.mjs",
"build:setupLocalDev": "yarn tools --setup-local-dev",
"build:verify": "yarn tools --verify",
@@ -25,7 +25,6 @@
"publish:staging": "yarn node ./tools/scripts/pub.mjs --tag staging",
"gen:docs": "node ./tools/scripts/gen-doc.mjs",
"gen:readme": "yarn node ./tools/scripts/gen-readme.mjs",
- "gen:internal-dev": "node ./tools/scripts/gen-internal-dev.mjs",
"update:contracts-sdk": "yarn node ./packages/contracts-sdk/tools.mjs",
"tools": "yarn node ./tools/scripts/tools.mjs",
"graph": "nx graph",
@@ -45,43 +44,36 @@
"@lit-protocol/contracts": "^0.0.63",
"@metamask/eth-sig-util": "5.0.2",
"@mysten/sui.js": "^0.37.1",
+ "@openagenda/verror": "^3.1.4",
"@simplewebauthn/browser": "^7.2.0",
"@simplewebauthn/typescript-types": "^7.0.0",
- "@spruceid/siwe-parser": "2.0.0",
- "@walletconnect/core": "2.9.2",
"@walletconnect/ethereum-provider": "2.9.2",
"@walletconnect/jsonrpc-utils": "1.0.8",
- "@walletconnect/modal": "2.6.1",
"@walletconnect/types": "2.9.2",
"@walletconnect/utils": "2.9.2",
"@walletconnect/web3wallet": "1.8.8",
"ajv": "^8.12.0",
"base64url": "^3.0.1",
- "bitcoinjs-lib": "^6.1.0",
- "bs58": "^5.0.0",
- "cbor-web": "^9.0.1",
- "cross-fetch": "3.1.4",
+ "bech32": "^2.0.0",
+ "cbor-web": "^9.0.2",
+ "cross-fetch": "3.1.8",
"date-and-time": "^2.4.1",
- "dotenv-parse-variables": "^2.0.0",
- "download": "^8.0.0",
+ "depd": "^2.0.0",
"ethers": "^5.7.1",
"jose": "^4.14.4",
- "jszip": "^3.10.1",
"micromodal": "^0.4.10",
"multiformats": "^9.7.1",
- "next": "13.3.0",
- "react": "18.0.0",
- "react-dom": "18.0.0",
- "regenerator-runtime": "0.13.7",
- "secp256k1": "^5.0.0",
- "siwe": "^2.0.5",
+ "pako": "^2.1.0",
+ "siwe": "^2.3.2",
"siwe-recap": "0.0.2-alpha.0",
- "tslib": "^2.3.0",
+ "tslib": "^2.7.0",
"tweetnacl": "^1.0.3",
"tweetnacl-util": "^0.15.1",
"uint8arrays": "^4.0.3"
},
"devDependencies": {
+ "@nrwl/devkit": "19.6.3",
+ "@nrwl/eslint-plugin-nx": "19.6.3",
"@nx/esbuild": "^17.3.0",
"@nx/eslint-plugin": "17.3.0",
"@nx/jest": "17.3.0",
@@ -92,8 +84,8 @@
"@nx/plugin": "17.3.0",
"@nx/react": "17.3.0",
"@nx/web": "17.3.0",
- "@solana/web3.js": "^1.92.2",
- "@swc/core": "1.3.107",
+ "@solana/web3.js": "^1.95.3",
+ "@types/depd": "^1.1.36",
"@types/jest": "27.4.1",
"@types/node": "18.19.18",
"@types/secp256k1": "^4.0.6",
@@ -101,7 +93,6 @@
"@typescript-eslint/parser": "6.21.0",
"axios": "^1.6.0",
"babel-jest": "27.5.1",
- "body-parser": "^1.20.2",
"buffer": "^6.0.3",
"chalk": "^5.3.0",
"cypress": "11.0.1",
@@ -109,18 +100,14 @@
"cypress-metamask-v2": "^1.7.2",
"esbuild": "^0.17.3",
"esbuild-node-builtins": "^0.1.0",
- "esbuild-node-externals": "^1.13.0",
+ "esbuild-node-externals": "^1.14.0",
"esbuild-plugin-tsc": "^0.4.0",
"eslint": "8.48.0",
"eslint-config-next": "12.2.3",
"eslint-config-prettier": "9.1.0",
+ "eslint-import-resolver-typescript": "3.6.3",
"eslint-plugin-import": "^2.29.1",
- "eslint-plugin-jsx-a11y": "6.6.1",
- "eslint-plugin-react": "7.30.1",
- "eslint-plugin-react-hooks": "4.6.0",
- "ethereum-abi-types-generator": "^1.3.2",
- "express": "^4.18.2",
- "form-data": "^4.0.0",
+ "eslint-plugin-jsx-a11y": "6.9.0",
"inquirer": "^9.2.21",
"ipfs-unixfs-importer": "12.0.1",
"jest": "27.5.1",
@@ -131,10 +118,10 @@
"nx": "17.3.0",
"path": "^0.12.7",
"prettier": "^2.6.2",
- "react-router-dom": "6.11.2",
- "ts-jest": "29.1.2",
- "typedoc": "^0.23.10",
- "typescript": "~4.7.2"
+ "ts-jest": "29.2.5",
+ "typedoc": "^0.26.6",
+ "typedoc-theme-hierarchy": "^5.0.0",
+ "typescript": "5.5.4"
},
"workspaces": [
"packages/*"
diff --git a/packages/access-control-conditions/README.md b/packages/access-control-conditions/README.md
index 28dc06d302..0a207960e9 100644
--- a/packages/access-control-conditions/README.md
+++ b/packages/access-control-conditions/README.md
@@ -7,12 +7,3 @@ This submodule provides functionalities for formatting and canonicalizing data,
```
yarn add @lit-protocol/access-control-conditions
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/access-control-conditions/package.json b/packages/access-control-conditions/package.json
index 27ff4f45aa..5e81bb4baf 100644
--- a/packages/access-control-conditions/package.json
+++ b/packages/access-control-conditions/package.json
@@ -21,7 +21,7 @@
"tags": [
"universal"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/access-control-conditions/src/lib/canonicalFormatter.ts b/packages/access-control-conditions/src/lib/canonicalFormatter.ts
index 329a3e96e2..de47e95806 100644
--- a/packages/access-control-conditions/src/lib/canonicalFormatter.ts
+++ b/packages/access-control-conditions/src/lib/canonicalFormatter.ts
@@ -1,5 +1,4 @@
-import { ILitError, LIT_ERROR } from '@lit-protocol/constants';
-
+import { InvalidAccessControlConditions } from '@lit-protocol/constants';
import {
ABIParams,
AccessControlConditions,
@@ -15,8 +14,6 @@ import {
UnifiedAccessControlConditions,
} from '@lit-protocol/types';
-import { throwError } from '@lit-protocol/misc';
-
/** ---------- Local Functions ---------- */
/**
*
@@ -40,7 +37,7 @@ const getOperatorParam = (cond: ConditionItem): AccsOperatorParams => {
* @param { Array } params
* @returns { Array }
*/
-const canonicalAbiParamss = (params: Array): Array => {
+const canonicalAbiParamss = (params: ABIParams[]): ABIParams[] => {
return params.map((param) => ({
name: param.name,
type: param.type,
@@ -88,21 +85,25 @@ export const canonicalUnifiedAccessControlConditionFormatter = (
return canonicalCosmosConditionFormatter(cond as AccsCOSMOSParams);
default:
- throwError({
- message: `You passed an invalid access control condition that is missing or has a wrong "conditionType": ${JSON.stringify(
- cond
- )}`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'You passed an invalid access control condition that is missing or has a wrong "conditionType"'
+ );
}
}
- throwError({
- message: `You passed an invalid access control condition: ${cond}`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'You passed an invalid access control condition'
+ );
};
/**
@@ -134,18 +135,12 @@ export const canonicalUnifiedAccessControlConditionFormatter = (
* @param { object } cond
* @param { boolean } requireV2Conditions
*
-* @returns { any[] | AccsOperatorParams | AccsSOLV2Params | ILitError | any }
+* @returns { any[] | AccsOperatorParams | AccsSOLV2Params | any }
*/
export const canonicalSolRpcConditionFormatter = (
cond: ConditionItem,
requireV2Conditions: boolean = false
-):
- | any[]
- | AccsOperatorParams
- | ConditionItem
- | AccsSOLV2Params
- | ILitError
- | any => {
+): any[] | AccsOperatorParams | ConditionItem | AccsSOLV2Params | any => {
// -- if is array
if (Array.isArray(cond)) {
return cond.map((c: ConditionItem) =>
@@ -181,11 +176,14 @@ export const canonicalSolRpcConditionFormatter = (
!('offset' in _assumedV2Cond.pdaInterface) ||
!('fields' in _assumedV2Cond.pdaInterface)
) {
- throwError({
- message: `Solana RPC Conditions have changed and there are some new fields you must include in your condition. Check the docs here: https://developer.litprotocol.com/AccessControlConditions/solRpcConditions`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'Solana RPC Conditions have changed and there are some new fields you must include in your condition. Check the docs here: https://developer.litprotocol.com/AccessControlConditions/solRpcConditions'
+ );
}
// -- else
@@ -226,11 +224,14 @@ export const canonicalSolRpcConditionFormatter = (
}
// -- else
- throwError({
- message: `You passed an invalid access control condition: ${cond}`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'You passed an invalid access control condition'
+ );
};
/**
@@ -284,11 +285,14 @@ export const canonicalAccessControlConditionFormatter = (
return _return;
}
- throwError({
- message: `You passed an invalid access control condition: ${cond}`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'You passed an invalid access control condition'
+ );
};
/**
@@ -379,11 +383,14 @@ export const canonicalEVMContractConditionFormatter = (
return _return;
}
- throwError({
- message: `You passed an invalid access control condition: ${cond}`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'You passed an invalid access control condition'
+ );
};
/**
@@ -440,11 +447,14 @@ export const canonicalCosmosConditionFormatter = (
};
}
- throwError({
- message: `You passed an invalid access control condition: ${cond}`,
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ cond,
+ },
+ },
+ 'You passed an invalid access control condition'
+ );
};
/**
diff --git a/packages/access-control-conditions/src/lib/hashing.ts b/packages/access-control-conditions/src/lib/hashing.ts
index de3d05846d..47998a84fe 100644
--- a/packages/access-control-conditions/src/lib/hashing.ts
+++ b/packages/access-control-conditions/src/lib/hashing.ts
@@ -1,15 +1,14 @@
-import { LIT_ERROR } from '@lit-protocol/constants';
-
+import { InvalidAccessControlConditions } from '@lit-protocol/constants';
+import { log } from '@lit-protocol/misc';
import {
AccessControlConditions,
- ConditionItem,
EvmContractConditions,
JsonSigningResourceId,
SolRpcConditions,
UnifiedAccessControlConditions,
} from '@lit-protocol/types';
+import { uint8arrayToString } from '@lit-protocol/uint8arrays';
-import { log, throwError } from '@lit-protocol/misc';
import {
canonicalAccessControlConditionFormatter,
canonicalEVMContractConditionFormatter,
@@ -17,7 +16,6 @@ import {
canonicalSolRpcConditionFormatter,
canonicalUnifiedAccessControlConditionFormatter,
} from './canonicalFormatter';
-import { uint8arrayToString } from '@lit-protocol/uint8arrays';
// Same as:
// const unifiedAccs = [
@@ -99,19 +97,25 @@ export const hashUnifiedAccessControlConditions = (
// check if there's any undefined in the conditions
const hasUndefined = conditions.some((c) => c === undefined);
if (hasUndefined) {
- throwError({
- message: 'Invalid access control conditions',
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ conditions,
+ },
+ },
+ 'Invalid access control conditions'
+ );
}
if (conditions.length === 0) {
- throwError({
- message: 'No conditions provided',
- errorKind: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.kind,
- errorCode: LIT_ERROR.INVALID_ACCESS_CONTROL_CONDITIONS.name,
- });
+ throw new InvalidAccessControlConditions(
+ {
+ info: {
+ conditions,
+ },
+ },
+ 'No conditions provided'
+ );
}
const toHash = JSON.stringify(conditions);
diff --git a/packages/access-control-conditions/src/lib/humanizer.ts b/packages/access-control-conditions/src/lib/humanizer.ts
index ce75be86ba..40de46aae7 100644
--- a/packages/access-control-conditions/src/lib/humanizer.ts
+++ b/packages/access-control-conditions/src/lib/humanizer.ts
@@ -1,5 +1,7 @@
-import { LIT_ERROR } from '@lit-protocol/constants';
+import { formatEther, formatUnits } from 'ethers/lib/utils';
+import { InvalidUnifiedConditionType } from '@lit-protocol/constants';
+import { decimalPlaces, log } from '@lit-protocol/misc';
import {
AccessControlConditions,
AccsCOSMOSParams,
@@ -9,9 +11,6 @@ import {
UnifiedAccessControlConditions,
} from '@lit-protocol/types';
-import { decimalPlaces, log, throwError } from '@lit-protocol/misc';
-import { formatEther, formatUnits } from 'ethers/lib/utils';
-
/**
*
* Format SOL number using Ether Units
@@ -47,7 +46,7 @@ export const formatAtom = (amount: number): string => {
* @returns { string } humanized version of the comparator
*/
export const humanizeComparator = (comparator: string): string | undefined => {
- const list: { [key: string]: string } = {
+ const list: Record = {
'>': 'more than',
'>=': 'at least',
'=': 'exactly',
@@ -82,7 +81,7 @@ export const humanizeEvmBasicAccessControlConditions = async ({
myWalletAddress,
}: {
accessControlConditions: AccessControlConditions;
- tokenList?: Array;
+ tokenList?: (any | string)[];
myWalletAddress?: string;
}): Promise => {
log('humanizing evm basic access control conditions');
@@ -217,7 +216,7 @@ export const humanizeEvmBasicAccessControlConditions = async ({
let tokenFromList;
if (tokenList) {
tokenFromList = tokenList.find(
- (t: any) => t.address === acc.contractAddress
+ (t) => t.address === acc.contractAddress
);
}
let decimals, name;
@@ -282,7 +281,7 @@ export const humanizeEvmContractConditions = async ({
myWalletAddress,
}: {
evmContractConditions: EvmContractConditions;
- tokenList?: Array;
+ tokenList?: (any | string)[];
myWalletAddress?: string;
}): Promise => {
log('humanizing evm contract conditions');
@@ -343,7 +342,7 @@ export const humanizeSolRpcConditions = async ({
myWalletAddress,
}: {
solRpcConditions: SolRpcConditions;
- tokenList?: Array;
+ tokenList?: (any | string)[];
myWalletAddress?: string;
}): Promise => {
log('humanizing sol rpc conditions');
@@ -416,8 +415,8 @@ export const humanizeCosmosConditions = async ({
tokenList,
myWalletAddress,
}: {
- cosmosConditions: Array;
- tokenList?: Array;
+ cosmosConditions: (AccsCOSMOSParams | any)[];
+ tokenList?: (any | string)[];
myWalletAddress?: string;
}): Promise => {
log('humanizing cosmos conditions');
@@ -495,7 +494,7 @@ export const humanizeUnifiedAccessControlConditions = async ({
myWalletAddress,
}: {
unifiedAccessControlConditions: UnifiedAccessControlConditions;
- tokenList?: Array;
+ tokenList?: (any | string)[];
myWalletAddress?: string;
}): Promise => {
const promises = await Promise.all(
@@ -543,11 +542,15 @@ export const humanizeUnifiedAccessControlConditions = async ({
myWalletAddress,
});
} else {
- throwError({
- message: `Unrecognized condition type: ${acc.conditionType}`,
- errorKind: LIT_ERROR.INVALID_UNIFIED_CONDITION_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_UNIFIED_CONDITION_TYPE.name,
- });
+ throw new InvalidUnifiedConditionType(
+ {
+ info: {
+ acc,
+ },
+ },
+ 'Unrecognized condition type: %s',
+ acc.conditionType
+ );
}
})
);
diff --git a/packages/access-control-conditions/src/lib/validator.spec.ts b/packages/access-control-conditions/src/lib/validator.spec.ts
index 16659b9cbb..8f677e5ed2 100644
--- a/packages/access-control-conditions/src/lib/validator.spec.ts
+++ b/packages/access-control-conditions/src/lib/validator.spec.ts
@@ -314,8 +314,8 @@ describe('validator.ts', () => {
}
expect(error).toBeDefined();
- expect(error!.errorKind).toBe(LIT_ERROR.INVALID_PARAM_TYPE.kind);
- expect(error!.errorCode).toBe(LIT_ERROR.INVALID_PARAM_TYPE.name);
+ expect(error!.errorKind).toBe(LIT_ERROR['INVALID_PARAM_TYPE'].kind);
+ expect(error!.errorCode).toBe(LIT_ERROR['INVALID_PARAM_TYPE'].name);
});
it('should throw when schema has invalid fields', async () => {
@@ -348,8 +348,8 @@ describe('validator.ts', () => {
}
expect(error).toBeDefined();
- expect(error!.errorKind).toBe(LIT_ERROR.INVALID_PARAM_TYPE.kind);
- expect(error!.errorCode).toBe(LIT_ERROR.INVALID_PARAM_TYPE.name);
+ expect(error!.errorKind).toBe(LIT_ERROR['INVALID_PARAM_TYPE'].kind);
+ expect(error!.errorCode).toBe(LIT_ERROR['INVALID_PARAM_TYPE'].name);
});
it('should throw when schema of a nested ACC does not validate', async () => {
@@ -407,7 +407,7 @@ describe('validator.ts', () => {
}
expect(error).toBeDefined();
- expect(error!.errorKind).toBe(LIT_ERROR.INVALID_PARAM_TYPE.kind);
- expect(error!.errorCode).toBe(LIT_ERROR.INVALID_PARAM_TYPE.name);
+ expect(error!.errorKind).toBe(LIT_ERROR['INVALID_PARAM_TYPE'].kind);
+ expect(error!.errorCode).toBe(LIT_ERROR['INVALID_PARAM_TYPE'].name);
});
});
diff --git a/packages/access-control-conditions/src/lib/validator.ts b/packages/access-control-conditions/src/lib/validator.ts
index ebe9fc9022..f7e88121cf 100644
--- a/packages/access-control-conditions/src/lib/validator.ts
+++ b/packages/access-control-conditions/src/lib/validator.ts
@@ -1,5 +1,8 @@
import { JSONSchemaType } from 'ajv';
-import { LIT_ERROR } from '@lit-protocol/constants';
+
+import { loadSchema } from '@lit-protocol/accs-schemas';
+import { InvalidArgumentException } from '@lit-protocol/constants';
+import { checkSchema } from '@lit-protocol/misc';
import {
AccessControlConditions,
ConditionType,
@@ -7,8 +10,6 @@ import {
SolRpcConditions,
UnifiedAccessControlConditions,
} from '@lit-protocol/types';
-import { checkSchema, throwError } from '@lit-protocol/misc';
-import { loadSchema } from '@lit-protocol/accs-schemas';
const SCHEMA_NAME_MAP: { [K in ConditionType]: string } = {
cosmos: 'LPACC_ATOM',
@@ -24,11 +25,15 @@ async function getSchema(
const schemaName = SCHEMA_NAME_MAP[accType];
return loadSchema(schemaName) as Promise>;
} catch (err) {
- return throwError({
- message: `No schema found for condition type ${accType}`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ accType,
+ },
+ },
+ `No schema found for condition type %s`,
+ accType
+ );
}
}
@@ -164,11 +169,15 @@ export const validateUnifiedAccessControlConditionsSchema = async (
'validateUnifiedAccessControlConditionsSchema'
);
} else {
- throwError({
- message: `Missing schema to validate condition type ${acc.conditionType}`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ acc,
+ },
+ },
+ `Missing schema to validate condition type %s`,
+ acc.conditionType
+ );
}
}
diff --git a/packages/auth-browser/README.md b/packages/auth-browser/README.md
index 273496264c..4daea68c8c 100644
--- a/packages/auth-browser/README.md
+++ b/packages/auth-browser/README.md
@@ -8,15 +8,6 @@ This submodule provides functionalities from various modules within the Lit SDK,
yarn add @lit-protocol/auth-browser
```
-### Vanilla JS (UMD)
-
-```js
-
-
-```
-
## Generate an authSig with long expiration
```
diff --git a/packages/auth-browser/package.json b/packages/auth-browser/package.json
index 892f030ec2..ada66637cb 100644
--- a/packages/auth-browser/package.json
+++ b/packages/auth-browser/package.json
@@ -30,7 +30,7 @@
"tags": [
"browser"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/auth-browser/src/lib/auth-browser.ts b/packages/auth-browser/src/lib/auth-browser.ts
index 813fa41a78..d59b2e3742 100644
--- a/packages/auth-browser/src/lib/auth-browser.ts
+++ b/packages/auth-browser/src/lib/auth-browser.ts
@@ -1,11 +1,13 @@
/**
* FIXME: SessionSigs are only supported for EVM chains at the moment. This will be expanded to other chains in the future.
*/
-import { ALL_LIT_CHAINS, LIT_ERROR, VMTYPE } from '@lit-protocol/constants';
-
+import {
+ ALL_LIT_CHAINS,
+ UnsupportedChainException,
+ VMTYPE,
+} from '@lit-protocol/constants';
import { AuthCallbackParams, AuthSig } from '@lit-protocol/types';
-import { throwError } from '@lit-protocol/misc';
import { checkAndSignCosmosAuthMessage } from './chains/cosmos';
import { checkAndSignEVMAuthMessage } from './chains/eth';
import { checkAndSignSolAuthMessage } from './chains/sol';
@@ -37,13 +39,15 @@ export const checkAndSignAuthMessage = ({
// -- validate: if chain info not found
if (!chainInfo) {
- throwError({
- message: `Unsupported chain selected. Please select one of: ${Object.keys(
- ALL_LIT_CHAINS
- )}`,
- errorKind: LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.kind,
- errorCode: LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.name,
- });
+ throw new UnsupportedChainException(
+ {
+ info: {
+ chain,
+ },
+ },
+ `Unsupported chain selected. Please select one of: %s`,
+ Object.keys(ALL_LIT_CHAINS)
+ );
}
if (!expiration) {
@@ -69,13 +73,17 @@ export const checkAndSignAuthMessage = ({
chain,
walletType: cosmosWalletType || 'keplr',
}); // Keplr is defaulted here, being the Cosmos wallet with the highest market share
- } else {
- return throwError({
- message: `vmType not found for this chain: ${chain}. This should not happen. Unsupported chain selected. Please select one of: ${Object.keys(
- ALL_LIT_CHAINS
- )}`,
- errorKind: LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.kind,
- errorCode: LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.name,
- });
}
+
+ // Else, throw an error
+ throw new UnsupportedChainException(
+ {
+ info: {
+ chain,
+ },
+ },
+ `vmType not found for this chain: %s. This should not happen. Unsupported chain selected. Please select one of: %s`,
+ chain,
+ Object.keys(ALL_LIT_CHAINS)
+ );
};
diff --git a/packages/auth-browser/src/lib/chains/cosmos.ts b/packages/auth-browser/src/lib/chains/cosmos.ts
index 1378971a34..d861696cb4 100644
--- a/packages/auth-browser/src/lib/chains/cosmos.ts
+++ b/packages/auth-browser/src/lib/chains/cosmos.ts
@@ -1,17 +1,15 @@
-import {
- uint8arrayFromString,
- uint8arrayToString,
-} from '@lit-protocol/uint8arrays';
-
import {
AUTH_SIGNATURE_BODY,
LIT_COSMOS_CHAINS,
- LIT_ERROR,
LOCAL_STORAGE_KEYS,
+ NoWalletException,
} from '@lit-protocol/constants';
-
+import { log, sortedObject } from '@lit-protocol/misc';
import { AuthSig, CosmosWalletType } from '@lit-protocol/types';
-import { log, sortedObject, throwError } from '@lit-protocol/misc';
+import {
+ uint8arrayFromString,
+ uint8arrayToString,
+} from '@lit-protocol/uint8arrays';
/** ---------- Declaration ---------- */
declare global {
@@ -68,17 +66,15 @@ const getProvider = (walletType: CosmosWalletType): any => {
}
}
- // -- finally
- const message =
- 'No web3 wallet was found that works with Cosmos. Install a Cosmos wallet or choose another chain';
-
- const error = LIT_ERROR.NO_WALLET_EXCEPTION;
-
- throwError({
- message,
- errorKind: error.kind,
- errorCode: error.name,
- });
+ // no provider found
+ throw new NoWalletException(
+ {
+ info: {
+ walletType,
+ },
+ },
+ 'No web3 wallet was found that works with Cosmos. Install a Cosmos wallet or choose another chain'
+ );
};
/** ---------- Exports ---------- */
@@ -138,19 +134,19 @@ export const checkAndSignCosmosAuthMessage = async ({
const storageKey = LOCAL_STORAGE_KEYS.AUTH_COSMOS_SIGNATURE;
- let authSig: AuthSig | any = localStorage.getItem(storageKey);
+ let authSigString = localStorage.getItem(storageKey);
// -- if not found in local storage
- if (!authSig) {
+ if (!authSigString) {
log('signing auth message because sig is not in local storage');
await signAndSaveAuthMessage(connectedCosmosProvider);
- authSig = localStorage.getItem(storageKey);
+ authSigString = localStorage.getItem(storageKey)!;
}
// -- if found in local storage
- authSig = JSON.parse(authSig);
+ let authSig: AuthSig = JSON.parse(authSigString);
// -- validate
if (connectedCosmosProvider.account != authSig.address) {
@@ -158,8 +154,8 @@ export const checkAndSignCosmosAuthMessage = async ({
'signing auth message because account is not the same as the address in the auth sig'
);
await signAndSaveAuthMessage(connectedCosmosProvider);
- authSig = localStorage.getItem(storageKey);
- authSig = JSON.parse(authSig);
+ authSigString = localStorage.getItem(storageKey)!;
+ authSig = JSON.parse(authSigString);
}
log('authSig', authSig);
@@ -214,7 +210,7 @@ export const signAndSaveAuthMessage = async (
const digest_hex = uint8arrayToString(new Uint8Array(digest), 'base16');
- let authSig: AuthSig = {
+ const authSig: AuthSig = {
sig: signed.signature,
derivedVia: 'cosmos.signArbitrary',
signedMessage: digest_hex,
diff --git a/packages/auth-browser/src/lib/chains/eth.ts b/packages/auth-browser/src/lib/chains/eth.ts
index 339bebea87..faaa2635dd 100644
--- a/packages/auth-browser/src/lib/chains/eth.ts
+++ b/packages/auth-browser/src/lib/chains/eth.ts
@@ -1,47 +1,53 @@
-import {
- ELeft,
- ERight,
- IEither,
- EITHER_TYPE,
- LIT_CHAINS,
- LIT_ERROR,
- LOCAL_STORAGE_KEYS,
-} from '@lit-protocol/constants';
-
-import { AuthSig, AuthCallbackParams } from '@lit-protocol/types';
+import { Buffer as BufferPolyfill } from 'buffer';
+import depd from 'depd';
-import { ethers } from 'ethers';
-// import WalletConnectProvider from '@walletconnect/ethereum-provider';
-import { toUtf8Bytes } from '@ethersproject/strings';
import { hexlify } from '@ethersproject/bytes';
-import { verifyMessage } from '@ethersproject/wallet';
-
-import { EthereumProvider } from '@walletconnect/ethereum-provider';
-
-import LitConnectModal from '../connect-modal/modal';
-
import { Web3Provider, JsonRpcSigner } from '@ethersproject/providers';
+import { toUtf8Bytes } from '@ethersproject/strings';
-import { SiweMessage } from 'siwe';
+// import WalletConnectProvider from '@walletconnect/ethereum-provider';
+import { verifyMessage } from '@ethersproject/wallet';
+import {
+ EthereumProvider,
+ default as WalletConnectProvider,
+} from '@walletconnect/ethereum-provider';
+import { ethers } from 'ethers';
import { getAddress } from 'ethers/lib/utils';
+import { SiweMessage } from 'siwe';
// @ts-ignore: If importing 'nacl' directly, the built files will use .default instead
+import * as nacl from 'tweetnacl';
import * as naclUtil from 'tweetnacl-util';
// @ts-ignore: If importing 'nacl' directly, the built files will use .default instead
-import * as nacl from 'tweetnacl';
-
-import { Buffer as BufferPolyfill } from 'buffer';
-
+import {
+ ELeft,
+ ERight,
+ IEither,
+ EITHER_TYPE,
+ LIT_CHAINS,
+ LOCAL_STORAGE_KEYS,
+ InvalidSignatureError,
+ WrongParamFormat,
+ UnsupportedChainException,
+ UnknownError,
+ RemovedFunctionError,
+ WrongNetworkException,
+ LocalStorageItemNotFoundException,
+} from '@lit-protocol/constants';
import {
isBrowser,
isNode,
log,
numberToHex,
- throwError,
validateSessionSig,
} from '@lit-protocol/misc';
import { getStorageItem } from '@lit-protocol/misc-browser';
+import { AuthSig, AuthCallbackParams } from '@lit-protocol/types';
+
+import LitConnectModal from '../connect-modal/modal';
+
+const deprecated = depd('lit-js-sdk:auth-browser:index');
if (globalThis && typeof globalThis.Buffer === 'undefined') {
globalThis.Buffer = BufferPolyfill;
@@ -68,20 +74,7 @@ interface ConnectWeb3Result {
account: string | any;
}
-interface RPCUrls {
- [chainId: string]: string;
-}
-
-interface Web3ProviderOptions {
- walletconnect: {
- package: any;
- options: {
- infuraId?: string;
- rpc: RPCUrls;
- chainId: number;
- };
- };
-}
+type RPCUrls = Record;
interface signAndSaveAuthParams {
web3: Web3Provider;
@@ -96,23 +89,23 @@ interface signAndSaveAuthParams {
interface IABI {
inputs: any[];
name: string;
- outputs: Array<{
+ outputs: {
internalType: string;
name: string;
type: string;
- }>;
+ }[];
stateMutability: string;
type: string;
}
interface IABIEncode {
- abi: Array;
+ abi: IABI[];
functionName: string;
functionParams: [];
}
interface IABIDecode {
- abi: Array;
+ abi: IABI[];
functionName: string;
data: any;
}
@@ -128,13 +121,18 @@ interface SignedMessage {
address: string;
}
-enum WALLET_ERROR {
- REQUESTED_CHAIN_HAS_NOT_BEEN_ADDED = 4902,
- NO_SUCH_METHOD = -32601,
-}
+const WALLET_ERROR = {
+ REQUESTED_CHAIN_HAS_NOT_BEEN_ADDED: 4902,
+ NO_SUCH_METHOD: -32601,
+} as const;
+export type WALLET_ERROR_TYPE = keyof typeof WALLET_ERROR;
+export type WALLET_ERROR_VALUES =
+ (typeof WALLET_ERROR)[keyof typeof WALLET_ERROR];
/** ---------- Local Helpers ---------- */
+let litWCProvider: WalletConnectProvider | undefined;
+
/**
*
* Convert chain hex id to chain name
@@ -144,34 +142,42 @@ enum WALLET_ERROR {
*/
export const chainHexIdToChainName = (chainHexId: string): void | string => {
// -- setup
- const keys = Object.keys(LIT_CHAINS);
const entries = Object.entries(LIT_CHAINS);
const hexIds = Object.values(LIT_CHAINS).map(
- (chain: any) => '0x' + chain.chainId.toString(16)
+ (chain) => '0x' + chain.chainId.toString(16)
);
// -- validate:: must begin with 0x
if (!chainHexId.startsWith('0x')) {
- throwError({
- message: `${chainHexId} should begin with "0x"`,
- errorKind: LIT_ERROR.WRONG_PARAM_FORMAT.kind,
- errorCode: LIT_ERROR.WRONG_PARAM_FORMAT.name,
- });
+ throw new WrongParamFormat(
+ {
+ info: {
+ param: 'chainHexId',
+ value: chainHexId,
+ },
+ },
+ '%s should begin with "0x"',
+ chainHexId
+ );
}
// -- validate:: hex id must be listed in constants
if (!hexIds.includes(chainHexId)) {
- throwError({
- message: `${chainHexId} cannot be found in LIT_CHAINS`,
- errorKind: LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.kind,
- errorCode: LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.name,
- });
+ throw new UnsupportedChainException(
+ {
+ info: {
+ chainHexId,
+ },
+ },
+ `Unsupported chain selected. Please select one of: %s`,
+ Object.keys(LIT_CHAINS)
+ );
}
// -- search
const chainName =
entries.find(
- (data: any) => '0x' + data[1].chainId.toString(16) === chainHexId
+ (data) => '0x' + data[1].chainId.toString(16) === chainHexId
) || null;
// -- success case
@@ -180,11 +186,15 @@ export const chainHexIdToChainName = (chainHexId: string): void | string => {
}
// -- fail case
- throwError({
- message: `Failed to convert ${chainHexId}`,
- errorKind: LIT_ERROR.UNKNOWN_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_ERROR.name,
- });
+ throw new UnknownError(
+ {
+ info: {
+ chainHexId,
+ },
+ },
+ 'Failed to convert %s',
+ chainHexId
+ );
};
/**
@@ -206,11 +216,17 @@ export const getChainId = async (
// couldn't get chainId. throw the incorrect network error
log('getNetwork threw an exception', e);
- resultOrError = ELeft({
- message: `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`,
- errorKind: LIT_ERROR.WRONG_NETWORK_EXCEPTION.kind,
- errorCode: LIT_ERROR.WRONG_NETWORK_EXCEPTION.name,
- });
+ resultOrError = ELeft(
+ new WrongNetworkException(
+ {
+ info: {
+ chain,
+ },
+ },
+ `Incorrect network selected. Please switch to the %s network in your wallet and try again.`,
+ chain
+ )
+ );
}
return resultOrError;
@@ -276,7 +292,7 @@ export const getMustResign = (authSig: AuthSig, resources: any): boolean => {
};
/**
- *
+ *
* Get RPC Urls in the correct format
* need to make it look like this:
---
@@ -287,16 +303,15 @@ export const getMustResign = (authSig: AuthSig, resources: any): boolean => {
// ...
},
---
- *
+ *
* @returns
*/
export const getRPCUrls = (): RPCUrls => {
const rpcUrls: RPCUrls = {};
- const keys: Array = Object.keys(LIT_CHAINS);
+ const keys: string[] = Object.keys(LIT_CHAINS);
- for (let i = 0; i < keys.length; i++) {
- const chainName = keys[i];
+ for (const chainName of keys) {
const chainId = LIT_CHAINS[chainName].chainId;
const rpcUrl = LIT_CHAINS[chainName].rpcUrls[0];
rpcUrls[chainId.toString()] = rpcUrl;
@@ -308,38 +323,35 @@ export const getRPCUrls = (): RPCUrls => {
/** ---------- Exports ---------- */
/**
* @deprecated
- * (ABI) Encode call data
+ * encodeCallData has been removed.
*
* @param { IABIEncode }
* @returns { string }
*/
-export const encodeCallData = ({
- abi,
- functionName,
- functionParams,
-}: IABIEncode): string => {
- throw new Error('encodeCallData has been removed.');
-};
+export const encodeCallData = deprecated.function(
+ ({ abi, functionName, functionParams }: IABIEncode): string => {
+ throw new RemovedFunctionError({}, 'encodeCallData has been removed.');
+ },
+ 'encodeCallData has been removed.'
+);
/**
* @deprecated
* (ABI) Decode call data
- * TODO: fix "any"
*
* @param { IABIDecode }
* @returns { string }
*/
-export const decodeCallResult = ({
- abi,
- functionName,
- data,
-}: IABIDecode): { answer: string } | any => {
- const _interface = new ethers.utils.Interface(abi);
+export const decodeCallResult = deprecated.function(
+ ({ abi, functionName, data }: IABIDecode): ethers.utils.Result => {
+ const _interface = new ethers.utils.Interface(abi);
- const decoded = _interface.decodeFunctionResult(functionName, data);
+ const decoded = _interface.decodeFunctionResult(functionName, data);
- return decoded;
-};
+ return decoded;
+ },
+ 'decodeCallResult will be removed.'
+);
/**
* @browserOnly
@@ -379,8 +391,7 @@ export const connectWeb3 = async ({
};
if (isBrowser()) {
- // @ts-ignore
- globalThis.litWCProvider = wcProvider;
+ litWCProvider = wcProvider;
}
}
@@ -397,7 +408,7 @@ export const connectWeb3 = async ({
// trigger metamask popup
try {
- log(
+ deprecated(
'@deprecated soon to be removed. - trying to enable provider. this will trigger the metamask popup.'
);
// @ts-ignore
@@ -433,10 +444,9 @@ export const disconnectWeb3 = (): void => {
}
// @ts-ignore
- if (isBrowser() && globalThis.litWCProvider) {
+ if (isBrowser() && litWCProvider) {
try {
- // @ts-ignore
- globalThis.litWCProvider.disconnect();
+ litWCProvider.disconnect();
} catch (err) {
log(
'Attempted to disconnect global WalletConnectProvider for lit-connect-modal',
@@ -486,11 +496,14 @@ export const checkAndSignEVMAuthMessage = async ({
// --- scoped methods ---
const _throwIncorrectNetworkError = (error: any) => {
if (error.code === WALLET_ERROR.NO_SUCH_METHOD) {
- throwError({
- message: `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`,
- errorKind: LIT_ERROR.WRONG_NETWORK_EXCEPTION.kind,
- errorCode: LIT_ERROR.WRONG_NETWORK_EXCEPTION.name,
- });
+ throw new WrongNetworkException(
+ {
+ info: {
+ chain,
+ },
+ },
+ `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`
+ );
} else {
throw error;
}
@@ -511,7 +524,7 @@ export const checkAndSignEVMAuthMessage = async ({
const currentChainIdOrError = await getChainId(chain, web3);
const selectedChainId: number = selectedChain.chainId;
const selectedChainIdHex: string = numberToHex(selectedChainId);
- const authSigOrError = getStorageItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
+ let authSigOrError = getStorageItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
log('currentChainIdOrError:', currentChainIdOrError);
log('selectedChainId:', selectedChainId);
@@ -520,7 +533,15 @@ export const checkAndSignEVMAuthMessage = async ({
// -- 3. check all variables before executing business logic
if (currentChainIdOrError.type === EITHER_TYPE.ERROR) {
- return throwError(currentChainIdOrError.result as any);
+ throw new UnknownError(
+ {
+ info: {
+ chainId: chain,
+ },
+ cause: currentChainIdOrError.result,
+ },
+ 'Unknown error when getting chain id'
+ );
}
log('chainId from web3', currentChainIdOrError);
@@ -531,14 +552,6 @@ export const checkAndSignEVMAuthMessage = async ({
// -- 4. case: (current chain id is NOT equal to selected chain) AND is set to switch chain
if (currentChainIdOrError.result !== selectedChainId && switchChain) {
- // -- validate the provider type
- // if (web3.provider instanceof walletProvider) {
- // return throwError({
- // message: `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`,
- // error: LIT_ERROR.WRONG_NETWORK_EXCEPTION,
- // });
- // }
-
const provider = web3.provider as any;
// -- (case) if able to switch chain id
@@ -596,8 +609,7 @@ export const checkAndSignEVMAuthMessage = async ({
log('signing auth message because sig is not in local storage');
try {
- // @ts-ignore
- authSigOrError.result = await _signAndGetAuth({
+ const authSig = await _signAndGetAuth({
web3,
account,
chainId: selectedChain.chainId,
@@ -606,24 +618,36 @@ export const checkAndSignEVMAuthMessage = async ({
uri,
nonce,
});
+
+ authSigOrError = {
+ type: EITHER_TYPE.SUCCESS,
+ result: JSON.stringify(authSig),
+ };
} catch (e: any) {
- log(e);
- return throwError({
- message: e.message,
- errorKind: LIT_ERROR.UNKNOWN_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_ERROR.name,
- });
+ throw new UnknownError(
+ {
+ info: {
+ account,
+ chainId: selectedChain.chainId,
+ resources,
+ expiration: expirationString,
+ uri,
+ nonce,
+ },
+ cause: e,
+ },
+ 'Could not get authenticated message'
+ );
}
- authSigOrError.type = EITHER_TYPE.SUCCESS;
+
+ // Log new authSig
log('5. authSigOrError:', authSigOrError);
}
// -- 6. case: Lit auth signature IS in the local storage
- // @ts-ignore
- let authSig: AuthSig = authSigOrError.result;
- if (typeof authSig === 'string') {
- authSig = JSON.parse(authSig);
- }
+ const authSigString: string = authSigOrError.result;
+ let authSig = JSON.parse(authSigString);
+
log('6. authSig:', authSig);
// -- 7. case: when we are NOT on the right wallet address
@@ -644,7 +668,7 @@ export const checkAndSignEVMAuthMessage = async ({
// -- 8. case: we are on the right wallet, but need to check the resources of the sig and re-sign if they don't match
} else {
- let mustResign: boolean = getMustResign(authSig, resources);
+ const mustResign: boolean = getMustResign(authSig, resources);
if (mustResign) {
authSig = await _signAndGetAuth({
@@ -708,17 +732,20 @@ const _signAndGetAuth = async ({
nonce,
});
- let authSigOrError = getStorageItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
+ const authSigOrError = getStorageItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
if (authSigOrError.type === 'ERROR') {
- throwError({
- message: 'Failed to get authSig from local storage',
- errorKind: LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION.kind,
- errorCode: LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION.name,
- });
+ throw new LocalStorageItemNotFoundException(
+ {
+ info: {
+ storageKey: LOCAL_STORAGE_KEYS.AUTH_SIGNATURE,
+ },
+ },
+ 'Failed to get authSig from local storage'
+ );
}
- let authSig: AuthSig =
+ const authSig: AuthSig =
typeof authSigOrError.result === 'string'
? JSON.parse(authSigOrError.result)
: authSigOrError.result;
@@ -778,14 +805,14 @@ export const signAndSaveAuthMessage = async ({
const body: string = message.prepareMessage();
const formattedAccount = getAddress(account);
// -- 2. sign the message
- let signedResult: SignedMessage = await signMessage({
+ const signedResult: SignedMessage = await signMessage({
body,
web3,
account: formattedAccount,
});
// -- 3. prepare auth message
- let authSig: AuthSig = {
+ const authSig: AuthSig = {
sig: signedResult.signature,
derivedVia: 'web3.eth.personal.sign',
signedMessage: body,
@@ -840,13 +867,13 @@ export const signMessage = async ({
// -- validate
if (!web3 || !account) {
log(`web3: ${web3} OR ${account} not found. Connecting web3..`);
- let res = await connectWeb3({ chainId: 1 });
+ const res = await connectWeb3({ chainId: 1 });
web3 = res.web3;
account = res.account;
}
log('pausing...');
- await new Promise((resolve: any) => setTimeout(resolve, 500));
+ await new Promise((resolve) => setTimeout(resolve, 500));
log('signing with ', account);
const signature = await signMessageAsync(web3.getSigner(), account, body);
@@ -857,12 +884,19 @@ export const signMessage = async ({
log('recovered address: ', address);
if (address.toLowerCase() !== account.toLowerCase()) {
- const msg = `ruh roh, the user signed with a different address (${address}) then they\'re using with web3 (${account}). this will lead to confusion.`;
- log(msg);
+ const msg = `ruh roh, the user signed with a different address (${address}) then they're using with web3 (${account}). This will lead to confusion.`;
alert(
- 'something seems to be wrong with your wallets message signing. maybe restart your browser or your wallet. your recovered sig address does not match your web3 account address'
+ 'Something seems to be wrong with your wallets message signing. maybe restart your browser or your wallet. Your recovered sig address does not match your web3 account address'
+ );
+ throw new InvalidSignatureError(
+ {
+ info: {
+ address,
+ account,
+ },
+ },
+ msg
);
- throw new Error(msg);
}
return { signature, address };
};
diff --git a/packages/auth-browser/src/lib/chains/sol.ts b/packages/auth-browser/src/lib/chains/sol.ts
index 16e54ba890..6be0f19a15 100644
--- a/packages/auth-browser/src/lib/chains/sol.ts
+++ b/packages/auth-browser/src/lib/chains/sol.ts
@@ -4,12 +4,13 @@ import {
ELeft,
ERight,
IEither,
- LIT_ERROR,
LOCAL_STORAGE_KEYS,
+ NoWalletException,
+ UnknownError,
} from '@lit-protocol/constants';
import { IProvider, AuthSig } from '@lit-protocol/types';
-import { log, throwError } from '@lit-protocol/misc';
+import { log } from '@lit-protocol/misc';
import { getStorageItem } from '@lit-protocol/misc-browser';
// import { toString as uint8arrayToString } from 'uint8arrays';
@@ -34,15 +35,12 @@ const getProvider = (): IEither => {
// @ts-ignore
resultOrError = ERight(window?.solana ?? window?.backpack);
} else {
- // -- finally
- const message =
- 'No web3 wallet was found that works with Solana. Install a Solana wallet or choose another chain';
-
- resultOrError = ELeft({
- message,
- errorKind: LIT_ERROR.NO_WALLET_EXCEPTION.kind,
- errorCode: LIT_ERROR.NO_WALLET_EXCEPTION.name,
- });
+ resultOrError = ELeft(
+ new NoWalletException(
+ {},
+ 'No web3 wallet was found that works with Solana. Install a Solana wallet or choose another chain'
+ )
+ );
}
return resultOrError;
@@ -52,17 +50,23 @@ const getProvider = (): IEither => {
*
* Get Solana provider
*
- * @returns { Promise => {
+export const connectSolProvider = async (): Promise => {
const providerOrError = getProvider();
if (providerOrError.type === 'ERROR') {
- throwError(providerOrError.result);
- return;
+ throw new UnknownError(
+ {
+ info: {
+ provider: providerOrError.result,
+ },
+ },
+ 'Failed to get provider'
+ );
}
- let provider: any = providerOrError.result;
+ const provider = providerOrError.result;
// No need to reconnect if already connected, some wallets such as Backpack throws an error when doing so.
if (!provider.isConnected) {
@@ -93,32 +97,20 @@ export const checkAndSignSolAuthMessage = async (): Promise => {
let authSigOrError = getStorageItem(key);
- // let authSig = localStorage.getItem("lit-auth-sol-signature");
- let authSig: AuthSig;
-
// -- case: if unable to get auth from local storage
if (authSigOrError.type === EITHER_TYPE.ERROR) {
log('signing auth message because sig is not in local storage');
await signAndSaveAuthMessage({ provider });
- authSigOrError.type = EITHER_TYPE.SUCCESS;
- // @ts-ignore
- authSigOrError.result = getStorageItem(key);
+ // Refetch authSigOrError written in previous line
+ authSigOrError = getStorageItem(key);
}
// @ts-ignore
window.test = authSigOrError;
- try {
- // when it's not in local storage, it's a string
- // @ts-ignore
- authSig = JSON.parse(authSigOrError.result.result);
- } catch (e) {
- // when it's in local storage, it's an object
- // @ts-ignore
- authSig = JSON.parse(authSigOrError.result);
- }
+ let authSig: AuthSig = JSON.parse(authSigOrError.result as string);
// -- if the wallet address isn't the same as the address from local storage
if (account !== authSig.address) {
@@ -128,11 +120,8 @@ export const checkAndSignSolAuthMessage = async (): Promise => {
await signAndSaveAuthMessage({ provider });
- authSigOrError.type = EITHER_TYPE.SUCCESS;
- // @ts-ignore
- authSigOrError.result = getStorageItem(key);
- // @ts-ignore
- authSig = JSON.parse(authSigOrError.result);
+ authSigOrError = getStorageItem(key);
+ authSig = JSON.parse(authSigOrError.result as string);
}
log('authSig', authSig);
@@ -152,7 +141,7 @@ export const signAndSaveAuthMessage = async ({
provider,
}: {
provider: any;
-}): Promise => {
+}): Promise => {
const now = new Date().toISOString();
const body = AUTH_SIGNATURE_BODY.replace('{{timestamp}}', now);
diff --git a/packages/auth-browser/src/lib/connect-modal/modal.ts b/packages/auth-browser/src/lib/connect-modal/modal.ts
index b69b89bf3f..8d23d1691a 100644
--- a/packages/auth-browser/src/lib/connect-modal/modal.ts
+++ b/packages/auth-browser/src/lib/connect-modal/modal.ts
@@ -1,5 +1,7 @@
// @ts-nocheck
// node_modules/micromodal/dist/micromodal.es.js
+import { NoWalletException } from '@lit-protocol/constants';
+
function e(e2, t2) {
for (var o2 = 0; o2 < t2.length; o2++) {
var n2 = t2[o2];
@@ -526,8 +528,9 @@ var LitConnectModal = class {
filteredListOfWalletsArray.push(cloneWalletInfo);
}
if (filteredListOfWalletsArray.length === 0) {
- alert('No wallets installed or provided.');
- throw new Error('No wallets installed or provided.');
+ const message = 'No wallets installed or provided.';
+ alert(message);
+ throw new NoWalletException({}, message);
}
this.filteredListOfWalletsArray = filteredListOfWalletsArray;
}
diff --git a/packages/auth-helpers/README.md b/packages/auth-helpers/README.md
index 26afc96f27..440c2d3e23 100644
--- a/packages/auth-helpers/README.md
+++ b/packages/auth-helpers/README.md
@@ -7,12 +7,3 @@ This submodule manages permissions and capabilities related to accessing specifi
```
yarn add @lit-protocol/auth-helpers
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/auth-helpers/package.json b/packages/auth-helpers/package.json
index e9bd1a6432..91e6282f12 100644
--- a/packages/auth-helpers/package.json
+++ b/packages/auth-helpers/package.json
@@ -17,9 +17,6 @@
"access": "public",
"directory": "../../dist/packages/auth-helpers"
},
- "dependencies": {
- "tslib": "2.6.0"
- },
"gitHead": "0d7334c2c55f448e91fe32f29edc5db8f5e09e4b",
"tags": [
"universal"
@@ -28,7 +25,7 @@
"crypto": false,
"stream": false
},
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/auth-helpers/src/lib/models.ts b/packages/auth-helpers/src/lib/models.ts
index 943182d3c5..6a59af56b0 100644
--- a/packages/auth-helpers/src/lib/models.ts
+++ b/packages/auth-helpers/src/lib/models.ts
@@ -1,4 +1,5 @@
-import { SiweMessage } from 'siwe';
+import { LIT_ABILITY_VALUES } from '@lit-protocol/constants';
+import { ILitResource } from '@lit-protocol/types';
// This is here to prevent circular dependency issue
export interface AuthSig {
@@ -18,144 +19,6 @@ export type AttenuationsObject = {
};
export type CID = string;
-/**
- * These are the user-facing abilities that can be granted to a session.
- */
-export enum LitAbility {
- /**
- * This is the ability to process an encryption access control condition.
- * The resource will specify the corresponding hashed key value of the
- * access control condition.
- */
- AccessControlConditionDecryption = 'access-control-condition-decryption',
-
- /**
- * This is the ability to process a signing access control condition.
- * The resource will specify the corresponding hashed key value of the
- * access control condition.
- */
- AccessControlConditionSigning = 'access-control-condition-signing',
-
- /**
- * This is the ability to use a PKP for signing purposes. The resource will specify
- * the corresponding PKP token ID.
- */
- PKPSigning = 'pkp-signing',
-
- /**
- * This is the ability to use a Rate Limit Increase (Capacity Credits NFT) token during
- * authentication with the nodes. The resource will specify the corresponding
- * Capacity Credits NFT token ID.
- */
- RateLimitIncreaseAuth = 'rate-limit-increase-auth',
-
- /**
- * This is the ability to execute a Lit Action. The resource will specify the
- * corresponding Lit Action IPFS CID.
- */
- LitActionExecution = 'lit-action-execution',
-}
-
-/**
- * Prefixes used for identifying various LIT resources.
- *
- * @description These resource prefixes are also used as valid IRI schemes.
- */
-export enum LitResourcePrefix {
- AccessControlCondition = 'lit-accesscontrolcondition',
- PKP = 'lit-pkp',
- RLI = 'lit-ratelimitincrease',
- LitAction = 'lit-litaction',
-}
-
-export interface ISessionCapabilityObject {
- get attenuations(): AttenuationsObject;
- get proofs(): Array;
- get statement(): string;
- addProof(proof: CID): void;
-
- /**
- * Add an arbitrary attenuation to the session capability object.
- *
- * @description We do NOT recommend using this unless with the LIT specific
- * abilities. Use this ONLY if you know what you are doing.
- */
- addAttenuation(
- resource: string,
- namespace?: string,
- name?: string,
- restriction?: { [key: string]: PlainJSON }
- ): void;
- addToSiweMessage(siwe: SiweMessage): SiweMessage;
-
- /**
- * Encode the session capability object as a SIWE resource.
- */
- encodeAsSiweResource(): string;
-
- /** LIT specific methods */
-
- /**
- * Add a LIT-specific capability to the session capability object for the
- * specified resource.
- *
- * @param litResource The LIT-specific resource being added.
- * @param ability The LIT-specific ability being added.
- * @example If the ability is `LitAbility.AccessControlConditionDecryption`,
- * then the resource should be the hashed key value of the access control
- * condition.
- * @example If the ability is `LitAbility.AccessControlConditionSigning`,
- * then the resource should be the hashed key value of the access control
- * condition.
- * @example If the ability is `LitAbility.PKPSigning`, then the resource
- * should be the PKP token ID.
- * @example If the ability is `LitAbility.RateLimitIncreaseAuth`, then the
- * resource should be the RLI token ID.
- * @example If the ability is `LitAbility.LitActionExecution`, then the
- * resource should be the Lit Action IPFS CID.
- * @throws If the ability is not a LIT-specific ability.
- */
- addCapabilityForResource(
- litResource: ILitResource,
- ability: LitAbility,
- data?: any
- ): void;
-
- /**
- * Verify that the session capability object has the specified LIT-specific
- * capability for the specified resource.
- */
- verifyCapabilitiesForResource(
- litResource: ILitResource,
- ability: LitAbility
- ): boolean;
-
- /**
- * Add a wildcard ability to the session capability object for the specified
- * resource.
- */
- addAllCapabilitiesForResource(litResource: ILitResource): void;
-}
-
-export interface ILitResource {
- /**
- * Gets the fully qualified resource key.
- * @returns The fully qualified resource key.
- */
- getResourceKey(): string;
-
- /**
- * Validates that the given LIT ability is valid for this resource.
- * @param litAbility The LIT ability to validate.
- */
- isValidLitAbility(litAbility: LitAbility): boolean;
-
- toString(): string;
-
- readonly resourcePrefix: LitResourcePrefix;
- readonly resource: string;
-}
-
/**
* A LIT resource ability is a combination of a LIT resource and a LIT ability.
* It specifies which LIT specific ability is being requested to be performed
@@ -167,6 +30,6 @@ export interface ILitResource {
*/
export type LitResourceAbilityRequest = {
resource: ILitResource;
- ability: LitAbility;
+ ability: LIT_ABILITY_VALUES;
data?: any;
};
diff --git a/packages/auth-helpers/src/lib/recap/recap-session-capability-object.spec.ts b/packages/auth-helpers/src/lib/recap/recap-session-capability-object.spec.ts
index ee4a5a80ed..b2884d1fc9 100644
--- a/packages/auth-helpers/src/lib/recap/recap-session-capability-object.spec.ts
+++ b/packages/auth-helpers/src/lib/recap/recap-session-capability-object.spec.ts
@@ -1,8 +1,12 @@
import { SiweMessage } from 'siwe';
-import { LitAbility, LitResourcePrefix } from '../models';
+import {
+ LIT_ABILITY,
+ LIT_RESOURCE_PREFIX,
+ LIT_NAMESPACE,
+ LIT_RECAP_ABILITY,
+} from '@lit-protocol/constants';
import { LitAccessControlConditionResource } from '../resources';
import { RecapSessionCapabilityObject } from './recap-session-capability-object';
-import { LitNamespace, LitRecapAbility } from './utils';
const isClass = (v: any) => {
return typeof v === 'function' && /^\s*class\s+/.test(v.toString());
@@ -12,9 +16,6 @@ const dummyCID =
'bafysameboaza4mnsng7t3djdbilbrnliv6ikxh45zsph7kpettjfbp4ad2g2uu2znujlf2afphw25d4y35pq';
describe('recapSessionCapabilityObject', () => {
- // --global
- let recapSessionCapabilityObject;
-
// -- start
it('imported { RecapSessionCapabilityObject } is a class', async () => {
expect(isClass(RecapSessionCapabilityObject)).toBe(true);
@@ -51,7 +52,7 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
const decodedRecapSessionCapabilityObject =
RecapSessionCapabilityObject.decode(
@@ -67,7 +68,7 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
const siweMessage = new SiweMessage({
domain: 'example.com',
@@ -171,7 +172,7 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
const siweMessage = new SiweMessage({
domain: 'example.com',
@@ -188,9 +189,9 @@ describe('recapSessionCapabilityObject', () => {
recapSessionCapabilityObject.addToSiweMessage(siweMessage);
expect(newSiweMessage.statement).toEqual(
`This is some existing statement. I further authorize the stated URI to perform the following actions on my behalf: (1) '${
- LitNamespace.Threshold
+ LIT_NAMESPACE.Threshold
}': '${
- LitRecapAbility.Decryption
+ LIT_RECAP_ABILITY.Decryption
}' for '${litResource.getResourceKey()}'.`
);
expect(newSiweMessage.resources).toEqual([
@@ -203,7 +204,7 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
const siweResource = recapSessionCapabilityObject.encodeAsSiweResource();
@@ -217,12 +218,12 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
expect(recapSessionCapabilityObject.attenuations).toEqual({
- [`${LitResourcePrefix.AccessControlCondition}://someResource`]: {
- [`${LitNamespace.Threshold}/${LitRecapAbility.Decryption}`]: [{}],
+ [`${LIT_RESOURCE_PREFIX.AccessControlCondition}://someResource`]: {
+ [`${LIT_NAMESPACE.Threshold}/${LIT_RECAP_ABILITY.Decryption}`]: [{}],
},
});
});
@@ -232,17 +233,17 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
);
expect(recapSessionCapabilityObject.attenuations).toEqual({
- [`${LitResourcePrefix.AccessControlCondition}://someResource`]: {
- [`${LitNamespace.Threshold}/${LitRecapAbility.Decryption}`]: [{}],
- [`${LitNamespace.Threshold}/${LitRecapAbility.Signing}`]: [{}],
+ [`${LIT_RESOURCE_PREFIX.AccessControlCondition}://someResource`]: {
+ [`${LIT_NAMESPACE.Threshold}/${LIT_RECAP_ABILITY.Decryption}`]: [{}],
+ [`${LIT_NAMESPACE.Threshold}/${LIT_RECAP_ABILITY.Signing}`]: [{}],
},
});
});
@@ -252,12 +253,12 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
});
@@ -267,23 +268,23 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
});
@@ -293,12 +294,12 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('someResource');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
)
).toBe(false);
});
@@ -309,7 +310,7 @@ describe('recapSessionCapabilityObject', () => {
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
)
).toBe(false);
});
@@ -320,26 +321,26 @@ describe('recapSessionCapabilityObject', () => {
recapSessionCapabilityObject.addAllCapabilitiesForResource(litResource);
expect(recapSessionCapabilityObject.attenuations).toEqual({
- [`${LitResourcePrefix.AccessControlCondition}://someResource`]: {
+ [`${LIT_RESOURCE_PREFIX.AccessControlCondition}://someResource`]: {
[`*/*`]: [{}],
},
});
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.PKPSigning
+ LIT_ABILITY.PKPSigning
)
).toBe(false);
});
@@ -349,30 +350,30 @@ describe('recapSessionCapabilityObject', () => {
const litResource = new LitAccessControlConditionResource('*');
recapSessionCapabilityObject.addCapabilityForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
);
expect(recapSessionCapabilityObject.attenuations).toEqual({
- [`${LitResourcePrefix.AccessControlCondition}://*`]: {
- [`${LitNamespace.Threshold}/${LitRecapAbility.Decryption}`]: [{}],
+ [`${LIT_RESOURCE_PREFIX.AccessControlCondition}://*`]: {
+ [`${LIT_NAMESPACE.Threshold}/${LIT_RECAP_ABILITY.Decryption}`]: [{}],
},
});
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
)
).toBe(false);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
new LitAccessControlConditionResource('someResource'),
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
});
@@ -383,32 +384,32 @@ describe('recapSessionCapabilityObject', () => {
recapSessionCapabilityObject.addAllCapabilitiesForResource(litResource);
expect(recapSessionCapabilityObject.attenuations).toEqual({
- [`${LitResourcePrefix.AccessControlCondition}://*`]: {
+ [`${LIT_RESOURCE_PREFIX.AccessControlCondition}://*`]: {
[`*/*`]: [{}],
},
});
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionSigning
+ LIT_ABILITY.AccessControlConditionSigning
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
litResource,
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
new LitAccessControlConditionResource('someResource'),
- LitAbility.AccessControlConditionDecryption
+ LIT_ABILITY.AccessControlConditionDecryption
)
).toBe(true);
expect(
recapSessionCapabilityObject.verifyCapabilitiesForResource(
new LitAccessControlConditionResource('someResource'),
- LitAbility.PKPSigning
+ LIT_ABILITY.PKPSigning
)
).toBe(false);
});
diff --git a/packages/auth-helpers/src/lib/recap/recap-session-capability-object.ts b/packages/auth-helpers/src/lib/recap/recap-session-capability-object.ts
index fea4d29210..b24db237c4 100644
--- a/packages/auth-helpers/src/lib/recap/recap-session-capability-object.ts
+++ b/packages/auth-helpers/src/lib/recap/recap-session-capability-object.ts
@@ -1,16 +1,22 @@
+import {
+ InvalidArgumentException,
+ RemovedFunctionError,
+} from '@lit-protocol/constants';
+import depd from 'depd';
import { SiweMessage } from 'siwe';
import { Recap } from 'siwe-recap';
+import { LIT_ABILITY_VALUES } from '@lit-protocol/constants';
+import { ILitResource, ISessionCapabilityObject } from '@lit-protocol/types';
import {
+ AuthSig,
AttenuationsObject,
CID as CIDString,
- ILitResource,
- ISessionCapabilityObject,
- LitAbility,
PlainJSON,
} from '../models';
import { getRecapNamespaceAndAbility } from './utils';
import { sanitizeSiweMessage } from '../siwe/siwe-helper';
-import { AuthSig } from '../models';
+
+const deprecated = depd('lit-js-sdk:auth-recap:session-capability-object');
export class RecapSessionCapabilityObject implements ISessionCapabilityObject {
private _inner: Recap;
@@ -74,12 +80,18 @@ export class RecapSessionCapabilityObject implements ISessionCapabilityObject {
/** LIT specific methods */
addCapabilityForResource(
litResource: ILitResource,
- ability: LitAbility,
+ ability: LIT_ABILITY_VALUES,
data: any = {}
): void {
// Validate Lit ability is compatible with the Lit resource.
if (!litResource.isValidLitAbility(ability)) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ litResource,
+ ability,
+ },
+ },
`The specified Lit resource does not support the specified ability.`
);
}
@@ -105,7 +117,7 @@ export class RecapSessionCapabilityObject implements ISessionCapabilityObject {
verifyCapabilitiesForResource(
litResource: ILitResource,
- ability: LitAbility
+ ability: LIT_ABILITY_VALUES
): boolean {
// Validate Lit ability is compatible with the Lit resource.
// The only exception is if there's a wildcard resource key in the session capability object.
diff --git a/packages/auth-helpers/src/lib/recap/resource-builder.spec.ts b/packages/auth-helpers/src/lib/recap/resource-builder.spec.ts
index 8c77239b31..dd700d9761 100644
--- a/packages/auth-helpers/src/lib/recap/resource-builder.spec.ts
+++ b/packages/auth-helpers/src/lib/recap/resource-builder.spec.ts
@@ -1,4 +1,4 @@
-import { LitAbility } from '../models';
+import { LIT_ABILITY } from '@lit-protocol/constants';
import {
LitAccessControlConditionResource,
LitActionResource,
@@ -26,11 +26,11 @@ describe('ResourceAbilityRequestBuilder', () => {
JSON.stringify([
{
resource: new LitPKPResource('123'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('456'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
])
);
@@ -49,23 +49,23 @@ describe('ResourceAbilityRequestBuilder', () => {
JSON.stringify([
{
resource: new LitPKPResource('123'),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
},
{
resource: new LitActionResource('456'),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
},
{
resource: new LitAccessControlConditionResource('789'),
- ability: LitAbility.AccessControlConditionSigning,
+ ability: LIT_ABILITY.AccessControlConditionSigning,
},
{
resource: new LitAccessControlConditionResource('abc'),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
},
{
resource: new LitRLIResource('def'),
- ability: LitAbility.RateLimitIncreaseAuth,
+ ability: LIT_ABILITY.RateLimitIncreaseAuth,
},
])
);
diff --git a/packages/auth-helpers/src/lib/recap/resource-builder.ts b/packages/auth-helpers/src/lib/recap/resource-builder.ts
index d13b97b871..4bd6f5b464 100644
--- a/packages/auth-helpers/src/lib/recap/resource-builder.ts
+++ b/packages/auth-helpers/src/lib/recap/resource-builder.ts
@@ -1,4 +1,5 @@
-import { ILitResource, LitAbility } from '../models';
+import { LIT_ABILITY, LIT_ABILITY_VALUES } from '@lit-protocol/constants';
+import { ILitResource } from '@lit-protocol/types';
import {
LitAccessControlConditionResource,
LitActionResource,
@@ -8,7 +9,7 @@ import {
/**
* Lit resrouce ability request builder for creating resource ability requests.
- *
+ *
* @example
* import { ResourceAbilityRequestBuilder } from '@lit-protocol/auth-helpers';
@@ -25,7 +26,10 @@ const requests = builder.build();
*/
export class ResourceAbilityRequestBuilder {
- private requests: Array<{ resource: ILitResource; ability: LitAbility }> = [];
+ private requests: Array<{
+ resource: ILitResource;
+ ability: LIT_ABILITY_VALUES;
+ }> = [];
/**
* Adds a PKP signing request to the builder.
@@ -35,7 +39,7 @@ export class ResourceAbilityRequestBuilder {
addPKPSigningRequest(resourceId: string): this {
this.requests.push({
resource: new LitPKPResource(resourceId),
- ability: LitAbility.PKPSigning,
+ ability: LIT_ABILITY.PKPSigning,
});
return this;
}
@@ -48,7 +52,7 @@ export class ResourceAbilityRequestBuilder {
addLitActionExecutionRequest(resourceId: string): this {
this.requests.push({
resource: new LitActionResource(resourceId),
- ability: LitAbility.LitActionExecution,
+ ability: LIT_ABILITY.LitActionExecution,
});
return this;
}
@@ -61,7 +65,7 @@ export class ResourceAbilityRequestBuilder {
addAccessControlConditionSigningRequest(resourceId: string): this {
this.requests.push({
resource: new LitAccessControlConditionResource(resourceId),
- ability: LitAbility.AccessControlConditionSigning,
+ ability: LIT_ABILITY.AccessControlConditionSigning,
});
return this;
}
@@ -74,7 +78,7 @@ export class ResourceAbilityRequestBuilder {
addAccessControlConditionDecryptionRequest(resourceId: string): this {
this.requests.push({
resource: new LitAccessControlConditionResource(resourceId),
- ability: LitAbility.AccessControlConditionDecryption,
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
});
return this;
}
@@ -87,7 +91,7 @@ export class ResourceAbilityRequestBuilder {
addRateLimitIncreaseAuthRequest(resourceId: string): this {
this.requests.push({
resource: new LitRLIResource(resourceId),
- ability: LitAbility.RateLimitIncreaseAuth,
+ ability: LIT_ABILITY.RateLimitIncreaseAuth,
});
return this;
}
@@ -96,7 +100,7 @@ export class ResourceAbilityRequestBuilder {
* Builds the array of resource ability requests.
* @returns The array of resource ability requests.
*/
- build(): Array<{ resource: ILitResource; ability: LitAbility }> {
+ build(): Array<{ resource: ILitResource; ability: LIT_ABILITY_VALUES }> {
return this.requests;
}
}
diff --git a/packages/auth-helpers/src/lib/recap/utils.ts b/packages/auth-helpers/src/lib/recap/utils.ts
index 7ad5df4c7e..101540ec3d 100644
--- a/packages/auth-helpers/src/lib/recap/utils.ts
+++ b/packages/auth-helpers/src/lib/recap/utils.ts
@@ -1,57 +1,56 @@
-import { LitAbility, LitResourcePrefix } from '../models';
+import {
+ InvalidArgumentException,
+ LIT_ABILITY,
+ LIT_ABILITY_VALUES,
+ LIT_RECAP_ABILITY,
+ LIT_RECAP_ABILITY_VALUES,
+ LIT_NAMESPACE,
+ LIT_NAMESPACE_VALUES,
+} from '@lit-protocol/constants';
/**
* Map from a LitAbility to the Recap namespace and ability.
* @throws Error if the LitAbility is unknown
*/
-export function getRecapNamespaceAndAbility(litAbility: LitAbility): {
- recapNamespace: LitNamespace;
- recapAbility: LitRecapAbility;
+export function getRecapNamespaceAndAbility(litAbility: LIT_ABILITY_VALUES): {
+ recapNamespace: LIT_NAMESPACE_VALUES;
+ recapAbility: LIT_RECAP_ABILITY_VALUES;
} {
switch (litAbility) {
- case LitAbility.AccessControlConditionDecryption:
+ case LIT_ABILITY.AccessControlConditionDecryption:
return {
- recapNamespace: LitNamespace.Threshold,
- recapAbility: LitRecapAbility.Decryption,
+ recapNamespace: LIT_NAMESPACE.Threshold,
+ recapAbility: LIT_RECAP_ABILITY.Decryption,
};
- case LitAbility.AccessControlConditionSigning:
+ case LIT_ABILITY.AccessControlConditionSigning:
return {
- recapNamespace: LitNamespace.Threshold,
- recapAbility: LitRecapAbility.Signing,
+ recapNamespace: LIT_NAMESPACE.Threshold,
+ recapAbility: LIT_RECAP_ABILITY.Signing,
};
- case LitAbility.PKPSigning:
+ case LIT_ABILITY.PKPSigning:
return {
- recapNamespace: LitNamespace.Threshold,
- recapAbility: LitRecapAbility.Signing,
+ recapNamespace: LIT_NAMESPACE.Threshold,
+ recapAbility: LIT_RECAP_ABILITY.Signing,
};
- case LitAbility.RateLimitIncreaseAuth:
+ case LIT_ABILITY.RateLimitIncreaseAuth:
return {
- recapNamespace: LitNamespace.Auth,
- recapAbility: LitRecapAbility.Auth,
+ recapNamespace: LIT_NAMESPACE.Auth,
+ recapAbility: LIT_RECAP_ABILITY.Auth,
};
- case LitAbility.LitActionExecution:
+ case LIT_ABILITY.LitActionExecution:
return {
- recapNamespace: LitNamespace.Threshold,
- recapAbility: LitRecapAbility.Execution,
+ recapNamespace: LIT_NAMESPACE.Threshold,
+ recapAbility: LIT_RECAP_ABILITY.Execution,
};
default:
- throw new Error(`Unknown LitAbility: ${litAbility}`);
+ throw new InvalidArgumentException(
+ {
+ info: {
+ litAbility,
+ },
+ },
+ `Unknown LitAbility`
+ );
}
}
-
-/**
- * LIT specific abilities mapped into the Recap specific terminology
- * of an 'ability'.
- */
-export enum LitRecapAbility {
- Decryption = 'Decryption',
- Signing = 'Signing',
- Auth = 'Auth',
- Execution = 'Execution',
-}
-
-export enum LitNamespace {
- Auth = 'Auth',
- Threshold = 'Threshold',
-}
diff --git a/packages/auth-helpers/src/lib/resources.ts b/packages/auth-helpers/src/lib/resources.ts
index 3babb6ae4d..72ad2b98d5 100644
--- a/packages/auth-helpers/src/lib/resources.ts
+++ b/packages/auth-helpers/src/lib/resources.ts
@@ -1,15 +1,17 @@
-import {
- AccessControlConditions,
- ILitResource,
- LitAbility,
- LitResourcePrefix,
-} from '@lit-protocol/types';
import { hashAccessControlConditions } from '@lit-protocol/access-control-conditions';
+import {
+ InvalidArgumentException,
+ LIT_ABILITY,
+ LIT_ABILITY_VALUES,
+ LIT_RESOURCE_PREFIX,
+ LIT_RESOURCE_PREFIX_VALUES,
+} from '@lit-protocol/constants';
+import { AccessControlConditions, ILitResource } from '@lit-protocol/types';
import { uint8arrayToString } from '@lit-protocol/uint8arrays';
import { formatPKPResource } from './utils';
abstract class LitResourceBase {
- abstract resourcePrefix: LitResourcePrefix;
+ abstract resourcePrefix: LIT_RESOURCE_PREFIX_VALUES;
public readonly resource: string;
constructor(resource: string) {
@@ -29,7 +31,7 @@ export class LitAccessControlConditionResource
extends LitResourceBase
implements ILitResource
{
- public readonly resourcePrefix = LitResourcePrefix.AccessControlCondition;
+ public readonly resourcePrefix = LIT_RESOURCE_PREFIX.AccessControlCondition;
/**
* Creates a new LitAccessControlConditionResource.
@@ -40,10 +42,10 @@ export class LitAccessControlConditionResource
super(resource);
}
- isValidLitAbility(litAbility: LitAbility): boolean {
+ isValidLitAbility(litAbility: LIT_ABILITY_VALUES): boolean {
return (
- litAbility === LitAbility.AccessControlConditionDecryption ||
- litAbility === LitAbility.AccessControlConditionSigning
+ litAbility === LIT_ABILITY.AccessControlConditionDecryption ||
+ litAbility === LIT_ABILITY.AccessControlConditionSigning
);
}
@@ -59,7 +61,13 @@ export class LitAccessControlConditionResource
dataToEncryptHash: string
): Promise {
if (!accs || !dataToEncryptHash) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ accs,
+ dataToEncryptHash,
+ },
+ },
'Invalid input: Access control conditions and data hash are required.'
);
}
@@ -77,7 +85,7 @@ export class LitAccessControlConditionResource
}
export class LitPKPResource extends LitResourceBase implements ILitResource {
- public readonly resourcePrefix = LitResourcePrefix.PKP;
+ public readonly resourcePrefix = LIT_RESOURCE_PREFIX.PKP;
/**
* Creates a new LitPKPResource.
@@ -89,13 +97,13 @@ export class LitPKPResource extends LitResourceBase implements ILitResource {
super(fixedResource);
}
- isValidLitAbility(litAbility: LitAbility): boolean {
- return litAbility === LitAbility.PKPSigning;
+ isValidLitAbility(litAbility: LIT_ABILITY_VALUES): boolean {
+ return litAbility === LIT_ABILITY.PKPSigning;
}
}
export class LitRLIResource extends LitResourceBase implements ILitResource {
- public readonly resourcePrefix = LitResourcePrefix.RLI;
+ public readonly resourcePrefix = LIT_RESOURCE_PREFIX.RLI;
/**
* Creates a new LitRLIResource.
@@ -106,13 +114,13 @@ export class LitRLIResource extends LitResourceBase implements ILitResource {
super(resource);
}
- isValidLitAbility(litAbility: LitAbility): boolean {
- return litAbility === LitAbility.RateLimitIncreaseAuth;
+ isValidLitAbility(litAbility: LIT_ABILITY_VALUES): boolean {
+ return litAbility === LIT_ABILITY.RateLimitIncreaseAuth;
}
}
export class LitActionResource extends LitResourceBase implements ILitResource {
- public readonly resourcePrefix = LitResourcePrefix.LitAction;
+ public readonly resourcePrefix = LIT_RESOURCE_PREFIX.LitAction;
/**
* Creates a new LitActionResource.
@@ -123,30 +131,37 @@ export class LitActionResource extends LitResourceBase implements ILitResource {
super(resource);
}
- isValidLitAbility(litAbility: LitAbility): boolean {
- return litAbility === LitAbility.LitActionExecution;
+ isValidLitAbility(litAbility: LIT_ABILITY_VALUES): boolean {
+ return litAbility === LIT_ABILITY.LitActionExecution;
}
}
export function parseLitResource(resourceKey: string): ILitResource {
- if (resourceKey.startsWith(LitResourcePrefix.AccessControlCondition)) {
+ if (resourceKey.startsWith(LIT_RESOURCE_PREFIX.AccessControlCondition)) {
return new LitAccessControlConditionResource(
resourceKey.substring(
- `${LitResourcePrefix.AccessControlCondition}://`.length
+ `${LIT_RESOURCE_PREFIX.AccessControlCondition}://`.length
)
);
- } else if (resourceKey.startsWith(LitResourcePrefix.PKP)) {
+ } else if (resourceKey.startsWith(LIT_RESOURCE_PREFIX.PKP)) {
return new LitPKPResource(
- resourceKey.substring(`${LitResourcePrefix.PKP}://`.length)
+ resourceKey.substring(`${LIT_RESOURCE_PREFIX.PKP}://`.length)
);
- } else if (resourceKey.startsWith(LitResourcePrefix.RLI)) {
+ } else if (resourceKey.startsWith(LIT_RESOURCE_PREFIX.RLI)) {
return new LitRLIResource(
- resourceKey.substring(`${LitResourcePrefix.RLI}://`.length)
+ resourceKey.substring(`${LIT_RESOURCE_PREFIX.RLI}://`.length)
);
- } else if (resourceKey.startsWith(LitResourcePrefix.LitAction)) {
+ } else if (resourceKey.startsWith(LIT_RESOURCE_PREFIX.LitAction)) {
return new LitActionResource(
- resourceKey.substring(`${LitResourcePrefix.LitAction}://`.length)
+ resourceKey.substring(`${LIT_RESOURCE_PREFIX.LitAction}://`.length)
);
}
- throw new Error(`Invalid resource prefix: ${resourceKey}`);
+ throw new InvalidArgumentException(
+ {
+ info: {
+ resourceKey,
+ },
+ },
+ `Invalid resource prefix`
+ );
}
diff --git a/packages/auth-helpers/src/lib/session-capability-object.ts b/packages/auth-helpers/src/lib/session-capability-object.ts
index 088b75e7e4..babdd3cc75 100644
--- a/packages/auth-helpers/src/lib/session-capability-object.ts
+++ b/packages/auth-helpers/src/lib/session-capability-object.ts
@@ -1,5 +1,6 @@
import { SiweMessage } from 'siwe';
-import { AttenuationsObject, CID, ISessionCapabilityObject } from './models';
+import { ISessionCapabilityObject } from '@lit-protocol/types';
+import { AttenuationsObject, CID } from './models';
import { RecapSessionCapabilityObject } from './recap/recap-session-capability-object';
/**
diff --git a/packages/auth-helpers/src/lib/siwe/create-siwe-message.ts b/packages/auth-helpers/src/lib/siwe/create-siwe-message.ts
index d1e55ff2a4..b20ec67f1e 100644
--- a/packages/auth-helpers/src/lib/siwe/create-siwe-message.ts
+++ b/packages/auth-helpers/src/lib/siwe/create-siwe-message.ts
@@ -1,7 +1,8 @@
import { SiweMessage } from 'siwe';
-import { BaseSiweMessage, CapacityDelegationFields } from '@lit-protocol/types';
+import { LIT_ABILITY } from '@lit-protocol/constants';
import {
- LitAbility,
+ BaseSiweMessage,
+ CapacityDelegationFields,
WithCapacityDelegation,
WithRecap,
} from '@lit-protocol/types';
@@ -30,7 +31,7 @@ export const createSiweMessage = async (
Date.now() + 1000 * 60 * 60 * 24 * 7
).toISOString();
- let siweParams = {
+ const siweParams = {
domain: params?.domain ?? 'localhost',
address: params.walletAddress,
statement:
@@ -59,7 +60,7 @@ export const createSiweMessage = async (
params.resources = [
{
resource: new LitRLIResource(ccParams.capacityTokenId ?? '*'),
- ability: LitAbility.RateLimitIncreaseAuth,
+ ability: LIT_ABILITY.RateLimitIncreaseAuth,
data: capabilities,
},
];
diff --git a/packages/bls-sdk/.eslintrc.json b/packages/bls-sdk/.eslintrc.json
deleted file mode 100644
index 9d9c0db55b..0000000000
--- a/packages/bls-sdk/.eslintrc.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "extends": ["../../.eslintrc.json"],
- "ignorePatterns": ["!**/*"],
- "overrides": [
- {
- "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
- "rules": {}
- },
- {
- "files": ["*.ts", "*.tsx"],
- "rules": {}
- },
- {
- "files": ["*.js", "*.jsx"],
- "rules": {}
- }
- ]
-}
diff --git a/packages/bls-sdk/README.md b/packages/bls-sdk/README.md
deleted file mode 100644
index 2ca8c7d66e..0000000000
--- a/packages/bls-sdk/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# BLS-SDK
-
-Read more about it here
-
-https://github.com/LIT-Protocol/threshold_crypto_ui
-
-# Installation
-
-```
-yarn add @lit-protocol/bls-sdk
-```
-
-# Usage
-
-```js
-import { initWasmBlsSdk } from '@lit-protocol/bls-sdk';
-
-initWasmBlsSdk().then((exports) => {
- globalThis.wasmExports = exports;
- log(
- `✅ [BLS SDK] wasmExports loaded. ${
- Object.keys(exports).length
- } functions available. Run 'wasmExports' in the console to see them.`
- );
-});
-```
-
-# Then
-
-```js
-// set decryption shares bytes in wasm
-decryptionShares.forEach((s: any, idx: any) => {
- wasmExports.set_share_indexes(idx, s.shareIndex);
-
- const shareAsBytes = uint8arrayFromString(s.decryptionShare, 'base16');
-
- for (let i = 0; i < shareAsBytes.length; i++) {
- wasmExports.set_decryption_shares_byte(i, idx, shareAsBytes[i]);
- }
-});
-```
diff --git a/packages/bls-sdk/package.json b/packages/bls-sdk/package.json
deleted file mode 100644
index ce67bc15f0..0000000000
--- a/packages/bls-sdk/package.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
- "name": "@lit-protocol/bls-sdk",
- "license": "MIT",
- "homepage": "https://github.com/Lit-Protocol/js-sdk",
- "repository": {
- "type": "git",
- "url": "https://github.com/LIT-Protocol/js-sdk"
- },
- "keywords": [
- "library"
- ],
- "bugs": {
- "url": "https://github.com/LIT-Protocol/js-sdk/issues"
- },
- "type": "commonjs",
- "publishConfig": {
- "access": "public",
- "directory": "../../dist/packages/bls-sdk"
- },
- "gitHead": "0d7334c2c55f448e91fe32f29edc5db8f5e09e4b",
- "peerDependencies": {
- "pako": "^2.1.0"
- },
- "tags": [
- "universal"
- ],
- "buildOptions": {
- "genReact": false
- },
- "version": "6.11.0",
- "main": "./dist/src/index.js",
- "typings": "./dist/src/index.d.ts"
-}
diff --git a/packages/bls-sdk/project.json b/packages/bls-sdk/project.json
deleted file mode 100644
index 52e123647b..0000000000
--- a/packages/bls-sdk/project.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "bls-sdk",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "sourceRoot": "packages/bls-sdk/src",
- "projectType": "library",
- "targets": {
- "build": {
- "executor": "@nx/js:tsc",
- "outputs": ["{options.outputPath}"],
- "options": {
- "outputPath": "dist/packages/bls-sdk",
- "main": "packages/bls-sdk/src/index.ts",
- "tsConfig": "packages/bls-sdk/tsconfig.lib.json",
- "assets": ["packages/bls-sdk/*.md"],
- "updateBuildableProjectDepsInPackageJson": true
- }
- },
- "test": {
- "executor": "@nx/jest:jest",
- "outputs": ["{workspaceRoot}/coverage/packages/bls-sdk"],
- "options": {
- "jestConfig": "packages/bls-sdk/jest.config.ts",
- "passWithNoTests": true
- }
- }
- },
- "tags": []
-}
diff --git a/packages/bls-sdk/src/index.d.ts b/packages/bls-sdk/src/index.d.ts
deleted file mode 100644
index 5f95c75068..0000000000
--- a/packages/bls-sdk/src/index.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './lib/bls-sdk.d.ts';
diff --git a/packages/bls-sdk/src/index.ts b/packages/bls-sdk/src/index.ts
deleted file mode 100644
index 4740ba28a0..0000000000
--- a/packages/bls-sdk/src/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './lib/bls-sdk';
diff --git a/packages/bls-sdk/src/lib/bls-sdk.d.ts b/packages/bls-sdk/src/lib/bls-sdk.d.ts
deleted file mode 100644
index d9584f0c64..0000000000
--- a/packages/bls-sdk/src/lib/bls-sdk.d.ts
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- *Initialize function for the wasm library
- */
-export function initWasmBlsSdk(): void;
-/**
- *Encrypts the data to the public key and identity. All inputs are hex encoded strings.
- * @param {string} public_key
- * @param {string} message
- * @param {string} identity
- * @returns {string}
- */
-export function encrypt(
- public_key: string,
- message: string,
- identity: string
-): string;
-/**
- *Verifies the decryption shares are valid and decrypts the data.
- * @param {string} public_key
- * @param {string} identity
- * @param {string} ciphertext
- * @param {any} shares
- * @returns {string}
- */
-export function verify_and_decrypt_with_signature_shares(
- public_key: string,
- identity: string,
- ciphertext: string,
- shares: any
-): string;
-/**
- *Decrypts the data with signature shares.
- * @param {string} ciphertext
- * @param {any} shares
- * @returns {string}
- */
-export function decrypt_with_signature_shares(
- ciphertext: string,
- shares: any
-): string;
-
-/**
- *Combines the signature shares into a single signature.
- * @param {any} shares
- * @returns {string}
- */
-export function combine_signature_shares(shares: any): string;
-
-/**
- *Verifies the signature.
- * @param {string} public_key
- * @param {string} message
- * @param {string} signature
- */
-export function verify_signature(public_key, message, signature): void;
diff --git a/packages/bls-sdk/src/lib/bls-sdk.spec.ts b/packages/bls-sdk/src/lib/bls-sdk.spec.ts
deleted file mode 100644
index 706c448ddd..0000000000
--- a/packages/bls-sdk/src/lib/bls-sdk.spec.ts
+++ /dev/null
@@ -1,153 +0,0 @@
-// @ts-nocheck
-import { TextEncoder, TextDecoder } from 'util';
-global.TextEncoder = TextEncoder;
-// @ts-ignore
-global.TextDecoder = TextDecoder;
-
-import * as blsSdk from './bls-sdk';
-
-const publicKey =
- '8e29447d7b0666fe41c357dbbdbdac0ac8ac973f88439a07f85fa31fa6fa3cea87c2eaa8b367e1c97764800fb5636892';
-const secretMessage = new Uint8Array([
- 240, 23, 185, 6, 87, 33, 173, 216, 53, 84, 80, 135, 190, 16, 58, 85, 97, 75,
- 3, 192, 215, 82, 217, 5, 40, 65, 2, 214, 40, 177, 53, 150,
-]);
-const identityParam = new Uint8Array([
- 101, 110, 99, 114, 121, 112, 116, 95, 100, 101, 99, 114, 121, 112, 116, 95,
- 119, 111, 114, 107, 115,
-]);
-
-describe('imported functions', () => {
- it('should be non-zero', () => {
- const OUTPUT = Object.keys(blsSdk).length;
-
- expect(OUTPUT).toBeGreaterThan(0);
- });
-});
-
-describe('blsSdk', () => {
- beforeAll(async () => {
- await blsSdk.initWasmBlsSdk();
- });
-
- it('should encrypt a message', async () => {
- // execute
- const ciphertext = blsSdk.encrypt(
- publicKey,
- byteArrayToHex(secretMessage),
- byteArrayToHex(identityParam)
- );
-
- // assert
- expect(ciphertext.length).toBeGreaterThan(0);
- });
-
- it('should decrypt', async () => {
- // prepare
- const ciphertext =
- 'l9a/01WDJB/euKxtbWcuQ8ez/c9eZ+jQryTHZVLN0kfd7XHoLs6FeWUVmk89ovQGkQJnnFDKjq6kgJxvIIrxXd9DaGuRBozLdA1G9Nk413YhTEqsENuHU0nSa4i6F912KltE15sbWKpDfPnZF6CA2UKBAw==';
- const signatureShares = [
- '01b2b44a0bf7184f19efacad98e213818edd3f8909dd798129ef169b877d68d77ba630005609f48b80203717d82092a45b06a9de0e61a97b2672b38b31f9ae43e64383d0375a51c75db8972613cc6b099b95c189fd8549ed973ee94b08749f4cac',
- '02a8343d5602f523286c4c59356fdcfc51953290495d98cb91a56b59bd1a837ea969cc521382164e85787128ce7f944de303d8e0b5fc4becede0c894bec1adc490fdc133939cca70fb3f504b9bf7b156527b681d9f0619828cd8050c819e46fdb1',
- '03b1594ab0cb56f47437b3720dc181661481ca0e36078b79c9a4acc50042f076bf66b68fbd12a1d55021a668555f0eed0a08dfe74455f557b30f1a9c32435a81479ca8843f5b74b176a8d10c5845a84213441eaaaf2ba57e32581584393541c5aa',
- ];
-
- // execute
- const plaintext = blsSdk.decrypt_with_signature_shares(
- ciphertext,
- signatureShares.slice(0, 2).map((s) =>
- JSON.stringify({
- ProofOfPossession: s,
- })
- )
- );
-
- // assert
- expect(new Uint8Array(base64ToArrayBuffer(plaintext))).toEqual(
- secretMessage
- );
- });
-
- it('should verify + decrypt', async () => {
- // prepare
- const ciphertext =
- 'l9a/01WDJB/euKxtbWcuQ8ez/c9eZ+jQryTHZVLN0kfd7XHoLs6FeWUVmk89ovQGkQJnnFDKjq6kgJxvIIrxXd9DaGuRBozLdA1G9Nk413YhTEqsENuHU0nSa4i6F912KltE15sbWKpDfPnZF6CA2UKBAw==';
- const signatureShares = [
- '01b2b44a0bf7184f19efacad98e213818edd3f8909dd798129ef169b877d68d77ba630005609f48b80203717d82092a45b06a9de0e61a97b2672b38b31f9ae43e64383d0375a51c75db8972613cc6b099b95c189fd8549ed973ee94b08749f4cac',
- '02a8343d5602f523286c4c59356fdcfc51953290495d98cb91a56b59bd1a837ea969cc521382164e85787128ce7f944de303d8e0b5fc4becede0c894bec1adc490fdc133939cca70fb3f504b9bf7b156527b681d9f0619828cd8050c819e46fdb1',
- '03b1594ab0cb56f47437b3720dc181661481ca0e36078b79c9a4acc50042f076bf66b68fbd12a1d55021a668555f0eed0a08dfe74455f557b30f1a9c32435a81479ca8843f5b74b176a8d10c5845a84213441eaaaf2ba57e32581584393541c5aa',
- ];
-
- // execute
- const plaintext = blsSdk.verify_and_decrypt_with_signature_shares(
- publicKey,
- arrayBufferToBase64(identityParam),
- ciphertext,
- signatureShares.slice(0, 2).map((s) =>
- JSON.stringify({
- ProofOfPossession: s,
- })
- )
- );
-
- // assert
- expect(new Uint8Array(base64ToArrayBuffer(plaintext))).toEqual(
- secretMessage
- );
- });
-
- it('should combine signature shares', async () => {
- const signatureShares = [
- '01b2b44a0bf7184f19efacad98e213818edd3f8909dd798129ef169b877d68d77ba630005609f48b80203717d82092a45b06a9de0e61a97b2672b38b31f9ae43e64383d0375a51c75db8972613cc6b099b95c189fd8549ed973ee94b08749f4cac',
- '02a8343d5602f523286c4c59356fdcfc51953290495d98cb91a56b59bd1a837ea969cc521382164e85787128ce7f944de303d8e0b5fc4becede0c894bec1adc490fdc133939cca70fb3f504b9bf7b156527b681d9f0619828cd8050c819e46fdb1',
- '03b1594ab0cb56f47437b3720dc181661481ca0e36078b79c9a4acc50042f076bf66b68fbd12a1d55021a668555f0eed0a08dfe74455f557b30f1a9c32435a81479ca8843f5b74b176a8d10c5845a84213441eaaaf2ba57e32581584393541c5aa',
- ].map((s) => ({
- ProofOfPossession: s,
- }));
-
- // execute
- const combinedSignature = blsSdk.combine_signature_shares(
- signatureShares.map((s) => JSON.stringify(s))
- );
-
- // assert
- expect(combinedSignature.length).toEqual(192);
- });
-
- it('should verify signature', async () => {
- const publicKey =
- 'ad1bd6c66f849ccbcc20fa08c26108f3df7db0068df032cc184779cc967159da4dd5669de563af7252b540f0759aee5a';
-
- // execute
- blsSdk.verify_signature(
- publicKey,
- 'ZXlKaGJHY2lPaUpDVEZNeE1pMHpPREVpTENKMGVYQWlPaUpLVjFRaWZRLmV5SnBjM01pT2lKTVNWUWlMQ0p6ZFdJaU9pSXdlRFF5TlRsbE5EUTJOekF3TlRNME9URmxOMkkwWm1VMFlURXlNR00zTUdKbE1XVmhaRFkwTm1JaUxDSmphR0ZwYmlJNkltVjBhR1Z5WlhWdElpd2lhV0YwSWpveE5qZzNOVFl5TWpjMUxDSmxlSEFpT2pFMk9EYzJNRFUwTnpVc0ltRmpZMlZ6YzBOdmJuUnliMnhEYjI1a2FYUnBiMjV6SWpwYmV5SmpiMjUwY21GamRFRmtaSEpsYzNNaU9pSWlMQ0pqYUdGcGJpSTZJbVYwYUdWeVpYVnRJaXdpYzNSaGJtUmhjbVJEYjI1MGNtRmpkRlI1Y0dVaU9pSWlMQ0p0WlhSb2IyUWlPaUlpTENKd1lYSmhiV1YwWlhKeklqcGJJanAxYzJWeVFXUmtjbVZ6Y3lKZExDSnlaWFIxY201V1lXeDFaVlJsYzNRaU9uc2lZMjl0Y0dGeVlYUnZjaUk2SWowaUxDSjJZV3gxWlNJNklqQjROREkxT1VVME5EWTNNREExTXpRNU1VVTNZalJHUlRSQk1USXdRemN3WW1VeFpVRkVOalEyWWlKOWZWMHNJbVYyYlVOdmJuUnlZV04wUTI5dVpHbDBhVzl1Y3lJNmJuVnNiQ3dpYzI5c1VuQmpRMjl1WkdsMGFXOXVjeUk2Ym5Wc2JDd2lkVzVwWm1sbFpFRmpZMlZ6YzBOdmJuUnliMnhEYjI1a2FYUnBiMjV6SWpwdWRXeHNmUQ==',
- 'trkIFY8XLxWAHvErjc5sEMfyEMjDVW0m4zSEiO8Ladb+F2vsaUmBMPIR4axyHdayDJ7/qdxUsxM1Xt/AUMcYRCVbUqNZZmkAGtOFGODAjieGdv9Q3aPnsrQXkDzW0ITP'
- );
- });
-});
-
-function base64ToArrayBuffer(base64) {
- var binaryString = atob(base64);
- var bytes = new Uint8Array(binaryString.length);
- for (var i = 0; i < binaryString.length; i++) {
- bytes[i] = binaryString.charCodeAt(i);
- }
- return bytes.buffer;
-}
-
-function arrayBufferToBase64(buffer) {
- var binary = '';
- var bytes = new Uint8Array(buffer);
- var len = bytes.byteLength;
- for (var i = 0; i < len; i++) {
- binary += String.fromCharCode(bytes[i]);
- }
- return btoa(binary);
-}
-
-function byteArrayToHex(byteArray: Uint8Array) {
- return Array.from(byteArray, function (byte: any) {
- return ('0' + (byte & 0xff).toString(16)).slice(-2);
- }).join('');
-}
diff --git a/packages/bls-sdk/src/lib/bls-sdk.ts b/packages/bls-sdk/src/lib/bls-sdk.ts
deleted file mode 100644
index 5f45c8b981..0000000000
--- a/packages/bls-sdk/src/lib/bls-sdk.ts
+++ /dev/null
@@ -1,5190 +0,0 @@
-// @ts-nocheck
-import * as pako from 'pako';
-
-// Encoding conversions
-
-// modified from https://stackoverflow.com/a/11058858
-function asciiToUint8Array(a) {
- let b = new Uint8Array(a.length);
- for (let i = 0; i < a.length; i++) {
- b[i] = a.charCodeAt(i);
- }
- return b;
-}
-// https://stackoverflow.com/a/19102224
-// TODO resolve RangeError possibility here, see SO comments
-function uint8ArrayToAscii(a) {
- return String.fromCharCode.apply(null, a);
-}
-// https://stackoverflow.com/a/50868276
-function hexToUint8Array(h) {
- if (h.length == 0) {
- return new Uint8Array();
- }
- return new Uint8Array(h.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
-}
-function uint8ArrayToHex(a) {
- return a.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
-}
-function uint8ArrayToByteStr(a) {
- return '[' + a.join(', ') + ']';
-}
-
-//https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727
-/*
-MIT License
-Copyright (c) 2020 Egor Nepomnyaschih
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/*
-// This constant can also be computed with the following algorithm:
-const base64abc = [],
- A = "A".charCodeAt(0),
- a = "a".charCodeAt(0),
- n = "0".charCodeAt(0);
-for (let i = 0; i < 26; ++i) {
- base64abc.push(String.fromCharCode(A + i));
-}
-for (let i = 0; i < 26; ++i) {
- base64abc.push(String.fromCharCode(a + i));
-}
-for (let i = 0; i < 10; ++i) {
- base64abc.push(String.fromCharCode(n + i));
-}
-base64abc.push("+");
-base64abc.push("/");
-*/
-const base64abc = [
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
- 'a',
- 'b',
- 'c',
- 'd',
- 'e',
- 'f',
- 'g',
- 'h',
- 'i',
- 'j',
- 'k',
- 'l',
- 'm',
- 'n',
- 'o',
- 'p',
- 'q',
- 'r',
- 's',
- 't',
- 'u',
- 'v',
- 'w',
- 'x',
- 'y',
- 'z',
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '+',
- '/',
-];
-
-/*
-// This constant can also be computed with the following algorithm:
-const l = 256, base64codes = new Uint8Array(l);
-for (let i = 0; i < l; ++i) {
- base64codes[i] = 255; // invalid character
-}
-base64abc.forEach((char, index) => {
- base64codes[char.charCodeAt(0)] = index;
-});
-base64codes["=".charCodeAt(0)] = 0; // ignored anyway, so we just need to prevent an error
-*/
-const base64codes = [
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,
- 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255,
- 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
-];
-
-function getBase64Code(charCode) {
- if (charCode >= base64codes.length) {
- throw new Error('Unable to parse base64 string.');
- }
- const code = base64codes[charCode];
- if (code === 255) {
- throw new Error('Unable to parse base64 string.');
- }
- return code;
-}
-
-export function uint8ArrayToBase64(bytes) {
- let result = '',
- i,
- l = bytes.length;
- for (i = 2; i < l; i += 3) {
- result += base64abc[bytes[i - 2] >> 2];
- result += base64abc[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];
- result += base64abc[((bytes[i - 1] & 0x0f) << 2) | (bytes[i] >> 6)];
- result += base64abc[bytes[i] & 0x3f];
- }
- if (i === l + 1) {
- // 1 octet yet to write
- result += base64abc[bytes[i - 2] >> 2];
- result += base64abc[(bytes[i - 2] & 0x03) << 4];
- result += '==';
- }
- if (i === l) {
- // 2 octets yet to write
- result += base64abc[bytes[i - 2] >> 2];
- result += base64abc[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];
- result += base64abc[(bytes[i - 1] & 0x0f) << 2];
- result += '=';
- }
- return result;
-}
-
-export function base64ToUint8Array(str) {
- if (str.length % 4 !== 0) {
- throw new Error('Unable to parse base64 string.');
- }
- const index = str.indexOf('=');
- if (index !== -1 && index < str.length - 2) {
- throw new Error('Unable to parse base64 string.');
- }
- let missingOctets = str.endsWith('==') ? 2 : str.endsWith('=') ? 1 : 0,
- n = str.length,
- result = new Uint8Array(3 * (n / 4)),
- buffer;
- for (let i = 0, j = 0; i < n; i += 4, j += 3) {
- buffer =
- (getBase64Code(str.charCodeAt(i)) << 18) |
- (getBase64Code(str.charCodeAt(i + 1)) << 12) |
- (getBase64Code(str.charCodeAt(i + 2)) << 6) |
- getBase64Code(str.charCodeAt(i + 3));
- result[j] = buffer >> 16;
- result[j + 1] = (buffer >> 8) & 0xff;
- result[j + 2] = buffer & 0xff;
- }
- return result.subarray(0, result.length - missingOctets);
-}
-
-// export function base64encode(str, encoder = new TextEncoder()) {
-// return bytesToBase64(encoder.encode(str));
-// }
-
-// export function base64decode(str, decoder = new TextDecoder()) {
-// return decoder.decode(base64ToBytes(str));
-// }
-
-// https://stackoverflow.com/a/12713326
-// function uint8ArrayToBase64(a) {
-// return btoa(String.fromCharCode.apply(null, a));
-// }
-// function base64ToUint8Array(b) {
-// return new Uint8Array(atob(b).split("").map(function(c) {
-// return c.charCodeAt(0);
-// }));
-// }
-let wasm;
-
-const heap = new Array(128).fill(undefined);
-
-heap.push(undefined, null, true, false);
-
-function getObject(idx) {
- return heap[idx];
-}
-
-let heap_next = heap.length;
-
-function dropObject(idx) {
- if (idx < 132) return;
- heap[idx] = heap_next;
- heap_next = idx;
-}
-
-function takeObject(idx) {
- const ret = getObject(idx);
- dropObject(idx);
- return ret;
-}
-
-const cachedTextDecoder =
- typeof TextDecoder !== 'undefined'
- ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true })
- : {
- decode: () => {
- throw Error('TextDecoder not available');
- },
- };
-
-if (typeof TextDecoder !== 'undefined') {
- cachedTextDecoder.decode();
-}
-
-let cachedUint8Memory0 = null;
-
-function getUint8Memory0() {
- if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
- cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
- }
- return cachedUint8Memory0;
-}
-
-function getStringFromWasm0(ptr, len) {
- ptr = ptr >>> 0;
- return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
-}
-
-function addHeapObject(obj) {
- if (heap_next === heap.length) heap.push(heap.length + 1);
- const idx = heap_next;
- heap_next = heap[idx];
-
- heap[idx] = obj;
- return idx;
-}
-
-let WASM_VECTOR_LEN = 0;
-
-const cachedTextEncoder =
- typeof TextEncoder !== 'undefined'
- ? new TextEncoder('utf-8')
- : {
- encode: () => {
- throw Error('TextEncoder not available');
- },
- };
-
-const encodeString =
- typeof cachedTextEncoder.encodeInto === 'function'
- ? function (arg, view) {
- return cachedTextEncoder.encodeInto(arg, view);
- }
- : function (arg, view) {
- const buf = cachedTextEncoder.encode(arg);
- view.set(buf);
- return {
- read: arg.length,
- written: buf.length,
- };
- };
-
-function passStringToWasm0(arg, malloc, realloc) {
- if (realloc === undefined) {
- const buf = cachedTextEncoder.encode(arg);
- const ptr = malloc(buf.length, 1) >>> 0;
- getUint8Memory0()
- .subarray(ptr, ptr + buf.length)
- .set(buf);
- WASM_VECTOR_LEN = buf.length;
- return ptr;
- }
-
- let len = arg.length;
- let ptr = malloc(len, 1) >>> 0;
-
- const mem = getUint8Memory0();
-
- let offset = 0;
-
- for (; offset < len; offset++) {
- const code = arg.charCodeAt(offset);
- if (code > 0x7f) break;
- mem[ptr + offset] = code;
- }
-
- if (offset !== len) {
- if (offset !== 0) {
- arg = arg.slice(offset);
- }
- ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0;
- const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
- const ret = encodeString(arg, view);
-
- offset += ret.written;
- ptr = realloc(ptr, len, offset, 1) >>> 0;
- }
-
- WASM_VECTOR_LEN = offset;
- return ptr;
-}
-
-function isLikeNone(x) {
- return x === undefined || x === null;
-}
-
-let cachedInt32Memory0 = null;
-
-function getInt32Memory0() {
- if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
- cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
- }
- return cachedInt32Memory0;
-}
-
-let cachedFloat64Memory0 = null;
-
-function getFloat64Memory0() {
- if (cachedFloat64Memory0 === null || cachedFloat64Memory0.byteLength === 0) {
- cachedFloat64Memory0 = new Float64Array(wasm.memory.buffer);
- }
- return cachedFloat64Memory0;
-}
-
-function debugString(val) {
- // primitive types
- const type = typeof val;
- if (type == 'number' || type == 'boolean' || val == null) {
- return `${val}`;
- }
- if (type == 'string') {
- return `"${val}"`;
- }
- if (type == 'symbol') {
- const description = val.description;
- if (description == null) {
- return 'Symbol';
- } else {
- return `Symbol(${description})`;
- }
- }
- if (type == 'function') {
- const name = val.name;
- if (typeof name == 'string' && name.length > 0) {
- return `Function(${name})`;
- } else {
- return 'Function';
- }
- }
- // objects
- if (Array.isArray(val)) {
- const length = val.length;
- let debug = '[';
- if (length > 0) {
- debug += debugString(val[0]);
- }
- for (let i = 1; i < length; i++) {
- debug += ', ' + debugString(val[i]);
- }
- debug += ']';
- return debug;
- }
- // Test for built-in
- const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
- let className;
- if (builtInMatches.length > 1) {
- className = builtInMatches[1];
- } else {
- // Failed to match the standard '[object ClassName]'
- return toString.call(val);
- }
- if (className == 'Object') {
- // we're a user defined class or Object
- // JSON.stringify avoids problems with cycles, and is generally much
- // easier than looping through ownProperties of `val`.
- try {
- return 'Object(' + JSON.stringify(val) + ')';
- } catch (_) {
- return 'Object';
- }
- }
- // errors
- if (val instanceof Error) {
- return `${val.name}: ${val.message}\n${val.stack}`;
- }
- // TODO we could test for more things here, like `Set`s and `Map`s.
- return className;
-}
-/**
- * @private
- *Initialize function for the wasm library
- */
-export function initialize() {
- wasm.initialize();
-}
-
-/**
- * @private
- *Encrypts the data to the public key and identity. All inputs are hex encoded strings.
- * @param {string} public_key
- * @param {string} message
- * @param {string} identity
- * @returns {string}
- */
-export function encrypt(public_key, message, identity) {
- let deferred5_0;
- let deferred5_1;
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- const ptr0 = passStringToWasm0(
- public_key,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len0 = WASM_VECTOR_LEN;
- const ptr1 = passStringToWasm0(
- message,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len1 = WASM_VECTOR_LEN;
- const ptr2 = passStringToWasm0(
- identity,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len2 = WASM_VECTOR_LEN;
- wasm.encrypt(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- var r2 = getInt32Memory0()[retptr / 4 + 2];
- var r3 = getInt32Memory0()[retptr / 4 + 3];
- var ptr4 = r0;
- var len4 = r1;
- if (r3) {
- ptr4 = 0;
- len4 = 0;
- throw takeObject(r2);
- }
- deferred5_0 = ptr4;
- deferred5_1 = len4;
- return getStringFromWasm0(ptr4, len4);
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
- }
-}
-
-/**
- * @private
- *Verifies the decryption shares are valid and decrypts the data.
- * @param {string} public_key
- * @param {string} identity
- * @param {string} ciphertext
- * @param {any} shares
- * @returns {string}
- */
-export function verify_and_decrypt_with_signature_shares(
- public_key,
- identity,
- ciphertext,
- shares
-) {
- let deferred5_0;
- let deferred5_1;
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- const ptr0 = passStringToWasm0(
- public_key,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len0 = WASM_VECTOR_LEN;
- const ptr1 = passStringToWasm0(
- identity,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len1 = WASM_VECTOR_LEN;
- const ptr2 = passStringToWasm0(
- ciphertext,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len2 = WASM_VECTOR_LEN;
- wasm.verify_and_decrypt_with_signature_shares(
- retptr,
- ptr0,
- len0,
- ptr1,
- len1,
- ptr2,
- len2,
- addHeapObject(shares)
- );
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- var r2 = getInt32Memory0()[retptr / 4 + 2];
- var r3 = getInt32Memory0()[retptr / 4 + 3];
- var ptr4 = r0;
- var len4 = r1;
- if (r3) {
- ptr4 = 0;
- len4 = 0;
- throw takeObject(r2);
- }
- deferred5_0 = ptr4;
- deferred5_1 = len4;
- return getStringFromWasm0(ptr4, len4);
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- wasm.__wbindgen_free(deferred5_0, deferred5_1, 1);
- }
-}
-
-/**
- * @private
- *Decrypts the data with signature shares.
- * @param {string} ciphertext
- * @param {any} shares
- * @returns {string}
- */
-export function decrypt_with_signature_shares(ciphertext, shares) {
- let deferred3_0;
- let deferred3_1;
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- const ptr0 = passStringToWasm0(
- ciphertext,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len0 = WASM_VECTOR_LEN;
- wasm.decrypt_with_signature_shares(
- retptr,
- ptr0,
- len0,
- addHeapObject(shares)
- );
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- var r2 = getInt32Memory0()[retptr / 4 + 2];
- var r3 = getInt32Memory0()[retptr / 4 + 3];
- var ptr2 = r0;
- var len2 = r1;
- if (r3) {
- ptr2 = 0;
- len2 = 0;
- throw takeObject(r2);
- }
- deferred3_0 = ptr2;
- deferred3_1 = len2;
- return getStringFromWasm0(ptr2, len2);
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
- }
-}
-
-/**
- * @private
- *Combines the signature shares into a single signature.
- * @param {any} shares
- * @returns {string}
- */
-export function combine_signature_shares(shares) {
- let deferred2_0;
- let deferred2_1;
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- wasm.combine_signature_shares(retptr, addHeapObject(shares));
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- var r2 = getInt32Memory0()[retptr / 4 + 2];
- var r3 = getInt32Memory0()[retptr / 4 + 3];
- var ptr1 = r0;
- var len1 = r1;
- if (r3) {
- ptr1 = 0;
- len1 = 0;
- throw takeObject(r2);
- }
- deferred2_0 = ptr1;
- deferred2_1 = len1;
- return getStringFromWasm0(ptr1, len1);
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- wasm.__wbindgen_free(deferred2_0, deferred2_1, 1);
- }
-}
-
-/**
- * @private
- *Verifies the signature.
- * @param {string} public_key
- * @param {string} message
- * @param {string} signature
- */
-export function verify_signature(public_key, message, signature) {
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- const ptr0 = passStringToWasm0(
- public_key,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len0 = WASM_VECTOR_LEN;
- const ptr1 = passStringToWasm0(
- message,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len1 = WASM_VECTOR_LEN;
- const ptr2 = passStringToWasm0(
- signature,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len2 = WASM_VECTOR_LEN;
- wasm.verify_signature(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- if (r1) {
- throw takeObject(r0);
- }
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- }
-}
-
-function handleError(f, args) {
- try {
- return f.apply(this, args);
- } catch (e) {
- wasm.__wbindgen_exn_store(addHeapObject(e));
- }
-}
-
-async function __wbg_load(module, imports) {
- if (typeof Response === 'function' && module instanceof Response) {
- if (typeof WebAssembly.instantiateStreaming === 'function') {
- try {
- return await WebAssembly.instantiateStreaming(module, imports);
- } catch (e) {
- if (module.headers.get('Content-Type') != 'application/wasm') {
- console.warn(
- '`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n',
- e
- );
- } else {
- throw e;
- }
- }
- }
-
- const bytes = await module.arrayBuffer();
- return await WebAssembly.instantiate(bytes, imports);
- } else {
- const instance = await WebAssembly.instantiate(module, imports);
-
- if (instance instanceof WebAssembly.Instance) {
- return { instance, module };
- } else {
- return instance;
- }
- }
-}
-
-function __wbg_get_imports() {
- const imports = {};
- imports.wbg = {};
- imports.wbg.__wbindgen_object_drop_ref = function (arg0) {
- takeObject(arg0);
- };
- imports.wbg.__wbindgen_string_new = function (arg0, arg1) {
- const ret = getStringFromWasm0(arg0, arg1);
- return addHeapObject(ret);
- };
- imports.wbg.__wbindgen_string_get = function (arg0, arg1) {
- const obj = getObject(arg1);
- const ret = typeof obj === 'string' ? obj : undefined;
- var ptr1 = isLikeNone(ret)
- ? 0
- : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
- var len1 = WASM_VECTOR_LEN;
- getInt32Memory0()[arg0 / 4 + 1] = len1;
- getInt32Memory0()[arg0 / 4 + 0] = ptr1;
- };
- imports.wbg.__wbindgen_number_get = function (arg0, arg1) {
- const obj = getObject(arg1);
- const ret = typeof obj === 'number' ? obj : undefined;
- getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
- getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
- };
- imports.wbg.__wbindgen_object_clone_ref = function (arg0) {
- const ret = getObject(arg0);
- return addHeapObject(ret);
- };
- imports.wbg.__wbindgen_is_object = function (arg0) {
- const val = getObject(arg0);
- const ret = typeof val === 'object' && val !== null;
- return ret;
- };
- imports.wbg.__wbindgen_jsval_loose_eq = function (arg0, arg1) {
- const ret = getObject(arg0) == getObject(arg1);
- return ret;
- };
- imports.wbg.__wbindgen_boolean_get = function (arg0) {
- const v = getObject(arg0);
- const ret = typeof v === 'boolean' ? (v ? 1 : 0) : 2;
- return ret;
- };
- imports.wbg.__wbindgen_error_new = function (arg0, arg1) {
- const ret = new Error(getStringFromWasm0(arg0, arg1));
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_new_abda76e883ba8a5f = function () {
- const ret = new Error();
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_stack_658279fe44541cf6 = function (arg0, arg1) {
- const ret = getObject(arg1).stack;
- const ptr1 = passStringToWasm0(
- ret,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len1 = WASM_VECTOR_LEN;
- getInt32Memory0()[arg0 / 4 + 1] = len1;
- getInt32Memory0()[arg0 / 4 + 0] = ptr1;
- };
- imports.wbg.__wbg_error_f851667af71bcfc6 = function (arg0, arg1) {
- let deferred0_0;
- let deferred0_1;
- try {
- deferred0_0 = arg0;
- deferred0_1 = arg1;
- console.error(getStringFromWasm0(arg0, arg1));
- } finally {
- wasm.__wbindgen_free(deferred0_0, deferred0_1, 1);
- }
- };
- imports.wbg.__wbg_crypto_1d1f22824a6a080c = function (arg0) {
- const ret = getObject(arg0).crypto;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_process_4a72847cc503995b = function (arg0) {
- const ret = getObject(arg0).process;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_versions_f686565e586dd935 = function (arg0) {
- const ret = getObject(arg0).versions;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_node_104a2ff8d6ea03a2 = function (arg0) {
- const ret = getObject(arg0).node;
- return addHeapObject(ret);
- };
- imports.wbg.__wbindgen_is_string = function (arg0) {
- const ret = typeof getObject(arg0) === 'string';
- return ret;
- };
- imports.wbg.__wbg_require_cca90b1a94a0255b = function () {
- return handleError(function () {
- const ret = module.require;
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_msCrypto_eb05e62b530a1508 = function (arg0) {
- const ret = getObject(arg0).msCrypto;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_randomFillSync_5c9c955aa56b6049 = function () {
- return handleError(function (arg0, arg1) {
- getObject(arg0).randomFillSync(takeObject(arg1));
- }, arguments);
- };
- imports.wbg.__wbg_getRandomValues_3aa56aa6edec874c = function () {
- return handleError(function (arg0, arg1) {
- getObject(arg0).getRandomValues(getObject(arg1));
- }, arguments);
- };
- imports.wbg.__wbg_length_cd7af8117672b8b8 = function (arg0) {
- const ret = getObject(arg0).length;
- return ret;
- };
- imports.wbg.__wbg_newnoargs_e258087cd0daa0ea = function (arg0, arg1) {
- const ret = new Function(getStringFromWasm0(arg0, arg1));
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_next_40fc327bfc8770e6 = function (arg0) {
- const ret = getObject(arg0).next;
- return addHeapObject(ret);
- };
- imports.wbg.__wbindgen_is_function = function (arg0) {
- const ret = typeof getObject(arg0) === 'function';
- return ret;
- };
- imports.wbg.__wbg_value_d93c65011f51a456 = function (arg0) {
- const ret = getObject(arg0).value;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_iterator_2cee6dadfd956dfa = function () {
- const ret = Symbol.iterator;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_self_ce0dbfc45cf2f5be = function () {
- return handleError(function () {
- const ret = self.self;
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_window_c6fb939a7f436783 = function () {
- return handleError(function () {
- const ret = window.window;
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_globalThis_d1e6af4856ba331b = function () {
- return handleError(function () {
- const ret = globalThis.globalThis;
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_global_207b558942527489 = function () {
- return handleError(function () {
- const ret = global.global;
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbindgen_is_undefined = function (arg0) {
- const ret = getObject(arg0) === undefined;
- return ret;
- };
- imports.wbg.__wbg_get_bd8e338fbd5f5cc8 = function (arg0, arg1) {
- const ret = getObject(arg0)[arg1 >>> 0];
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_isArray_2ab64d95e09ea0ae = function (arg0) {
- const ret = Array.isArray(getObject(arg0));
- return ret;
- };
- imports.wbg.__wbg_instanceof_ArrayBuffer_836825be07d4c9d2 = function (arg0) {
- let result;
- try {
- result = getObject(arg0) instanceof ArrayBuffer;
- } catch (_) {
- result = false;
- }
- const ret = result;
- return ret;
- };
- imports.wbg.__wbg_call_27c0f87801dedf93 = function () {
- return handleError(function (arg0, arg1) {
- const ret = getObject(arg0).call(getObject(arg1));
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_call_b3ca7c6051f9bec1 = function () {
- return handleError(function (arg0, arg1, arg2) {
- const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_next_196c84450b364254 = function () {
- return handleError(function (arg0) {
- const ret = getObject(arg0).next();
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbg_done_298b57d23c0fc80c = function (arg0) {
- const ret = getObject(arg0).done;
- return ret;
- };
- imports.wbg.__wbg_buffer_12d079cc21e14bdb = function (arg0) {
- const ret = getObject(arg0).buffer;
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_newwithbyteoffsetandlength_aa4a17c33a06e5cb = function (
- arg0,
- arg1,
- arg2
- ) {
- const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_new_63b92bc8671ed464 = function (arg0) {
- const ret = new Uint8Array(getObject(arg0));
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_instanceof_Uint8Array_2b3bbecd033d19f6 = function (arg0) {
- let result;
- try {
- result = getObject(arg0) instanceof Uint8Array;
- } catch (_) {
- result = false;
- }
- const ret = result;
- return ret;
- };
- imports.wbg.__wbg_newwithlength_e9b4878cebadb3d3 = function (arg0) {
- const ret = new Uint8Array(arg0 >>> 0);
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_subarray_a1f73cd4b5b42fe1 = function (arg0, arg1, arg2) {
- const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_length_c20a40f15020d68a = function (arg0) {
- const ret = getObject(arg0).length;
- return ret;
- };
- imports.wbg.__wbg_set_a47bac70306a19a7 = function (arg0, arg1, arg2) {
- getObject(arg0).set(getObject(arg1), arg2 >>> 0);
- };
- imports.wbg.__wbg_get_e3c254076557e348 = function () {
- return handleError(function (arg0, arg1) {
- const ret = Reflect.get(getObject(arg0), getObject(arg1));
- return addHeapObject(ret);
- }, arguments);
- };
- imports.wbg.__wbindgen_debug_string = function (arg0, arg1) {
- const ret = debugString(getObject(arg1));
- const ptr1 = passStringToWasm0(
- ret,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len1 = WASM_VECTOR_LEN;
- getInt32Memory0()[arg0 / 4 + 1] = len1;
- getInt32Memory0()[arg0 / 4 + 0] = ptr1;
- };
- imports.wbg.__wbindgen_throw = function (arg0, arg1) {
- throw new Error(getStringFromWasm0(arg0, arg1));
- };
- imports.wbg.__wbindgen_memory = function () {
- const ret = wasm.memory;
- return addHeapObject(ret);
- };
-
- return imports;
-}
-
-function __wbg_init_memory(imports, maybe_memory) {}
-
-function __wbg_finalize_init(instance, module) {
- wasm = instance.exports;
- __wbg_init.__wbindgen_wasm_module = module;
- cachedFloat64Memory0 = null;
- cachedInt32Memory0 = null;
- cachedUint8Memory0 = null;
-
- return wasm;
-}
-
-function initSync(module) {
- if (wasm !== undefined) return wasm;
-
- const imports = __wbg_get_imports();
-
- __wbg_init_memory(imports);
-
- if (!(module instanceof WebAssembly.Module)) {
- module = new WebAssembly.Module(module);
- }
-
- const instance = new WebAssembly.Instance(module, imports);
-
- return __wbg_finalize_init(instance, module);
-}
-
-async function __wbg_init(input) {
- if (wasm !== undefined) return wasm;
- const imports = __wbg_get_imports();
-
- __wbg_init_memory(imports);
-
- const { instance, module } = await __wbg_load(await input, imports);
-
- return __wbg_finalize_init(instance, module);
-}
-
-export { initSync };
-export default __wbg_init;
-
-export async function initWasmBlsSdk() {
- var b = '';
-
- b +=
- 'eNrsvQtgXFWZOH7vuXdm7mRmksmjTdr0ce5tgRRayHMmLQi9sS1UQFBZ1n1Z8iowwZY+AP3/Cx2';
- b +=
- 'gYFhRglYMLrpBcYk81qyiWxU1IkJWQaPCblT8md3FNSq6QdBfVLS/73HuYya3FHal7mqK5txz7r';
- b +=
- 'nn8b3Pd75zRuve82Zd0zT9Od2+SOzfr+Efff9Fxn58xr+Q0fmPdpG5n4pj+znVoDi+f3+4EEo0V';
- b +=
- 'Q8esewaeKcqQUliv1c/yQ/XXHON5pdix9dQYu33K2JjUEdgQ/T2GhgXfmVw29fwp9dgDe7zGv7s';
- b +=
- 'GjWsqzl7tcru4ywm4teZNuOqnouXbtt2Vc+lO/ou7t+xbWdPob9377a+3Tsv37a7f7sWwwqLQhX';
- b +=
- '27N196Y6Lt+3ov0rTj/Du4v69mlb+bscVb+7p3x28a5zfae9lO3f0U68m1qgL1bh0j6rEr5aEXh';
- b +=
- 'X2XNl92bbLdu7c07+tfxcPanHofc/OnZf1d++gnue12797987dwWQIEjS5bd09fd35XH9nZ1tPd';
- b +=
- '2d3x3bNwgrLuMKevd29A9tyHZ2t+fXb+9vbO9pberfneGKqCre8vbOjJZfLd2/Pt/T0bu9VVZZz';
- b +=
- 'ld7db718785tLX0t21tbO1vbu3PdzZ3NvTzKFVzn8t07e/v37NnW3p1v7WzP9/Z2NLetX9/Rw5V';
- b +=
- 'WcqUr+3fvuXTnjj3btuc6cx25jv6Ozlxf3/q2Dq7VqGa1s69/W0tze3fr9u2dfbn+7ua27tZIUD';
- b +=
- 'MeS8axu3/XFZfu7t/W29u9vrmnpXt9e3dzaweMwwqN4817Xs1T6u9p7ujPtfZ0tDV3t3Q0d3JTx';
- b +=
- '6mmunf07Xzzlksvu+wNb93Ru62jd33v+o6O7u6OXE+uuX09g+h4rgtIez1Vv7D7siv692xrw2rd';
- b +=
- '3bn+vv7eznx7bwk8L+vfcfHeS7b19gG8O1ta8rl8a09nj+pc+qjdsbN798V7tvW3dnQ2d+Z7+5r';
- b +=
- '7urub+7uZAjxY9b9l77b25u29ba35nu3QVb65P8cNLS6F1fYrdvTuBeDzS4X8K3G02wADvbmO5p';
- b +=
- 'aW7R0t3e0duRKcXbq3f3f3XiCR1t7+/lxfd9/2vvUdub7t3QxRNY49/Zdt39bb39wHg2jv6N3eu';
- b +=
- 'r2jp59rqElfBUPZedW23tz2nvVt67vz29vbcvnONq5jKyhetrOn+7ILLoHh9rX057q3t3cCsLvb';
- b +=
- '2lp6Striettam/M9HR2d69tbO1rz7Z3ruU596byv2NHXv/3SHf19PKulPr629fR19re1dW7v6ev';
- b +=
- 'Y3tHb28mAVXR06R539+7ut25r7e7JtcOM+5vXAyF293Mr61SlHcBgO3r7d27fRrW7rti+HWRHZ1';
- b +=
- 'uusxXm35zva+9d39daQt293ZfByPO9zds7853NLX39fdvXt5XglGr0tPV253tzzR0t29f39Pe2a';
- b +=
- 'EY51lvW53o7gaWbe9pyAIH2kl76UEK1ru/s6cj3tbZBZ70+wyoY9vBYW1r7mvPre3tbW/pb2nv6';
- b +=
- 'FL+2+ER41aV7L+l5616Y4vY9/TDZPkW83d3t3S353ra27uZcf0dvD48vJJdybT3rW3t6O3P5lv6';
- b +=
- '+9pwa3tp5gPuTS3fs7VSw7mnrgbn2Nbe19bWs367ocHXJWFT3/et72gF+vf093X09bX1tJSS754';
- b +=
- 'qebmqwu2V7vq23r72no6e9dXu/AmIZF7Y2dwMDAfe3NvflOrtLyASmvK27Pd/T3ZtvbmvOdbcA4';
- b +=
- 'WqijI7623oB/M35XEdHvr+tXdFRmAz7+nuuuNiTViQJsqG3ey/ZvfMqLq4OFb+5/807d78VaPoD';
- b +=
- '5h2mZppCCM3UNEi1BKRaPK4JYejwfyOuwWOlgMIYFBhQUxdxwzB0TWgZTcsKsB2SWjKZhLxWUR3';
- b +=
- 'X9IwuajRdxzahkgFP2IQQCU0khKit0kQ8IbSqmKbVQZW4ZmbierwinoSWtUXwWVx9EE8kdOgdxg';
- b +=
- 'NNGADfhKEF/6CyYYh4PJ7QFmtavajQYnrciMdxDtiboSUS8UQcmk5qcROaFA00M/5Y01JxfDQpn';
- b +=
- '6BCkx6FbsSS0JtIwrciFotBTwk9Aa3FcEzxeIUeg8+X6DC2lEZjE/GYSOv4D7MxHT7BHmCWIg7/';
- b +=
- 'g+e4MGM87Ji+FNpM8BBh8NBpJc9XTzcmKpavhM/hn6nH4tASzDGmw7fwBBUNM6Zr0DkMJAb9Adq';
- b +=
- 'wN2hC5ynr0LsGvQPYYRLYimliDZ0awH8xgX+hJr7QUzhiXTcQm94/D7zwqaWlYmZCv1x/D/wHyN';
- b +=
- 'eq40mwA91icVxLJW4X6TiTkdAqLt1x6d5Luy+79P/r1x43E/07SKtrH9SbQCtfuh2YZUcfECqVb';
- b +=
- 'kNO27bn0ot3dO+9ApTpnku6d/fv0e7Ul794ha/oDb073wwE3D//3XN6VnXkv9I+opcQPMi9nb3a';
- b +=
- 'E6ImVLi7n0vnxMpQaXdf3zZQ32zeXL4TREj/bu09ZlWoyvbd/f3aT4wSI+otaPrthI6vM5P3Ayp';
- b +=
- 'cPXVQ/6r5K/FV87fGR8yvmr+Gp5v074jPw/Nj9N9XzX+E/79gfNX8NKRfNR80P2t+xnzW+Ktbze';
- b +=
- 'v0w1B8yPyUeZs5aL7PHDFvhwp/Q9VeEPj3/eaP9GeNh/UPwPt3QUd3mp+Fvx+ENx8yfwjf/sj4O';
- b +=
- '3guGlj3h/DFtfD0Tv0rxrvNB4xx/d36v4t74c139U8b9+A34mvGb4w7oc71xi3mP5mTxpeNd4vP';
- b +=
- 'Gp81Pmc8SH8/b4wbH6fWfiSuNW8X/2w8Ig7o90P+l9D6Q8YNMM1/Ma43f2M8Km40v2B8TP8xjOe';
- b +=
- 'A+c/GhPgH8++h3kfNIZjc28yfGrcKfPNV86C5/SHxMbPi8Kcq7zAPX6r/+f5Vmjv2qDbgiNWaFK';
- b +=
- '5VcJql7o6b2QfMpZAfX1dwYpB2FrK36JAOQT4JFZq997mCY0E6rHsVoADTGa3gVyqeWnBSkM55l';
- b +=
- 'SY3FJw4pBN6UGkwWXAqnOWuBiWfpJJpKEl3feGd7/zQkzcPzjXkDRzgFBQu7vrGnV/4wMz933vB';
- b +=
- '4MJJKFzS9YH3/vgd0/9y/XfeuZ9LJ6B0add7/vHgHb95cujQlMal41Da2PWNr3zyt/86MfHkd7m';
- b +=
- '069npRz8+8eDPrj03bxxKQq2x1oJTJXW5PPslGHDXp//6Xfc+e/d3flaXN8bgddfMyE9v++1ND2';
- b +=
- 'J+FPN3jYw8/+izj9z4Qeh6BAvue+EnB/795usenoT2h7Hgya/cdvDjX5745Yl5YwjzX3z7k9jhj';
- b +=
- 'TfBF4PY46FkQc0dodhWcBwZV927ky0Fx5RJd1rzILqm4BgIDeFBtKngJCAdFR5EEWuHDHqNzQ8a';
- b +=
- '3gvExLBJLxAHM/6LCh/2ZVAvg3c5pMthfHTozgKRpGFYxwi6al72YgRUvuDUe5DVZcKHaddHD9/';
- b +=
- '68OivP/O2auj1VMjf9Nnr7//cLw/ccTJ0ivnJr3/ohrve+4N3uNAn5g/e/YP7Hvr0h+86D/rE/D';
- b +=
- 'O//PC/ff4do3ciEAax4JH73vuDJ558368/BoMoYsGPH//J2379hcFfWnljbgPkH7/j3p98+DdPP';
- b +=
- '7ssb8xi/qffnL3t3m/9+P4PwQczWHDLl54afPz2W55/LxRMY8G7b7xn9N6f/csDW/LGFOa/P/qD';
- b +=
- '4Xvv+fCBRN6Y3IBkeyoS0biOs12F5JAqOOtgmvHsVrlcmu6IoMkacjGiPyGXBzwKBF+BlFFBlIF';
- b +=
- 'EOAOccpaqgDw+x6+Q3CYqCs5W9SoeYtnRU5E7y1h25FTkzjKWHT4VmbOcZYdOReYsZ9lBKF32Yk';
- b +=
- 'SF0HVnQTRlYeDxeURFwA4RFQE7TFQE7DBREbBDREXADhMVQDsVsOvkyQVnNYH5S8htAVG546sLT';
- b +=
- 'jUyasqTj6tRFq5TsEMePpQuMDJgoumC85oQxIczPsRn4NXZ8yBeBusyKJfDtxyyR4NpFQzqGEHT';
- b +=
- 'Y9GTpePB0QQIRzHnTK6UOadzpcw5lStlzslcGXNO5MqYczxXypyHcqXMOZYrY87RXBlzjuRKmXM';
- b +=
- '4V8qcQzmZ9hnzOCTW0wpOHUxRB8aMg2RXjFktT0aEpwDFgRSfBvLPsxxf5YlqJC1ootPj1SHInK';
- b +=
- 'Re6iGGnAFJu6KcIaeh8PhyhpyCwhPmMeQklDbNY8gJKF3zYsSDEHXHQEllYND6PBIiAIdIiAAcJ';
- b +=
- 'iECcJiECMAhEiIAh0kIIGyF9OeJBefVBN4vIWelQppTFpwWFEqvKjjrle5cidqoTkEPubV4esHZ';
- b +=
- 'wIiA11Dz1BDcp+HlaR7cxyDzqnlwL4N4GazLoVwO36NBNgvDOkYw9diyQa72oJkESo7Uma1lOrO';
- b +=
- '1TGe2lunM1nKd2VquM1vLdGZLmc5sKdeZLeU6s6VMZ7aU6cwWWeWz5YmIzs6CsxamaAJbonGg2L';
- b +=
- 'JFNiDC077hi3J7BCyJc1hyHxfi1iI0cS5za70qNsMaEvTs6fM0JBSeMU9DQuHG+RoSSt35GhJKu';
- b +=
- '15Umrei0AHdUwPDNefL9JYymd5SLtNbymV6S5lMbymX6S2+QYlMdByaF0nuOhUiIXe8seDUIlsB';
- b +=
- '3F6rdGQjLirWKught46vLzjnMQrgNWTOD0F8BFYTr/Ps3Fl4+fp5cC+DeBmsy6FcDt+jQTYDwzp';
- b +=
- 'GMPUYskq+2oNmAgRfpJ5cV6Yn15XpyXVlenJduZ5cV64n15XpyXVlenJduZ5cV64n15XpyXVlen';
- b +=
- 'KdzPoMSSQLC6FNMMUkMCQaBIoha2UVItwCFAdSe7q1wDL7xBCXjrcp68pRhcmwdgSTceU87QiFl';
- b +=
- 'fO0IxSeMl87Qqmcrx2hdNGLyvB1KGpAEW2GwSbnS/J1ZZJ8XbkkX1cuydeVSfJ15ZJ8nYyFtKNd';
- b +=
- 'cLYQUL+EHGWFtGM9L/dH2r115WI0qjcp2CGfFjsKDHp42V4IQXq6w7djxzoK86BdBucyCJfDthy';
- b +=
- 'qR4NnDQzoGEHSY8FTwBpQMEwB1UbqxDVlOnFNmU5cU6YT15TrxDXlOnFNmU5sKtOJTeU6salcJz';
- b +=
- 'aV6cSmMp3YJDMeCyIqTyk4bTDBBDAgqn7FgDF5CiI7CwgOSGMElkFvYOJoDVtT0MQFzJmrVXEir';
- b +=
- 'BHXRDDhyJoIJhxeg4w1TyNCqT1fI0Jp+4vK7TVyMww0MV9uN5XJ7aZyud1ULrebyuR2U7ncbpKG';
- b +=
- 'x35bCJjEeNmQFqwpIAsBpP5E6cAaEC2yLaTmxpsLzoUMdHgNmT8Ng76l4LzR48tZePln8yD94gx';
- b +=
- 'YDtdyiB4NljUwrGMES48BbWBAhcCUlH9ADBhiv5l4QTEf6BUTGMVnwVWaO9sw4BirNaAtC62r5u';
- b +=
- 'y1OjxPmrjsaoZqBecvuGgshWI9k32/wIxAK7BCxrLPCyAswx0y8APDnYW0EqEJj/GC00Evp+HTR';
- b +=
- 'dlRAx5HEgUoWpR9vw5JTfaD2NhkAtgMsh3ZTxmQVHLpGIwnR3Xpw2kr/CGMg/oYSmIfUA0/hS4h';
- b +=
- 'uwjefVBQJTWQyQpsaRFXqgBLK4fl0BH0yBUW4+BxNoeolaqCc6bE2aAqq1QDzxagqNLrv131X4N';
- b +=
- 'wOJO/zMCEPkegqoNhAAKAmj5JC75F2No6baw+ez/OsML/PF2AjBrFLGVobFTXrsQhBe62yg3aqJ';
- b +=
- 'DYLhRhuzXQbgUM6X4aNDA/NLgI/85oBa94shYLZql4QlfFZ8qaQAY3w6i30ti/jR+M1WPVyWyBs';
- b +=
- '0MNmB2rVtnJTEH+BQB4Kw5xVNgVcjkMkTz9smKDNm5iZw0FoCcywUwaJ0qb5VKs0yYyjoH9o/MC';
- b +=
- '+zlLUrYeZRH0s5Wz6FCGNuQ6zqILcnJJQb6Gsyfht0sL8mzOSlhOqakIhLuMe1lLrpQyO0EGSAZ';
- b +=
- 'J2/J2JGxZy0aGpeRbFQq/Zb7PcrbRszwaUPMs9/1nk8uCrYbJDYVj5EFrPYb+yJM9DRPliST7eH';
- b +=
- 'nB82mMLS84hoKHjbplhW+7Da0IQ3BkpQ/B2RW/DwieeOx9kLE/WB/kcf7aqlZGeh9jpd7HU2SZ3';
- b +=
- '7FKKo/jST4pDOUKx8jvdew8iQ0eK0X5EFvkevZEBB5D5Ss81YeS8g++6vcApdYF7+Dvzjt4os8w';
- b +=
- 'lTLCL2gFW+WWrMjegQrQyr4BqtR5VUxZh+q3EvQWJI6sx0QPVN1ab1fOPg4MAr85WJVn7yVPGTS';
- b +=
- 'XgDdpVIew4MTSldDXvQjrlZyksGf0JNzLW7qzJxacaq8DXVZjl7VyFSb18iRM4sEc6jwtjILW6z';
- b +=
- '6OGhZ7BFnA0zKC9oyo9iz/vZpOJtweaHBsBhTNQxpviBUrvQ0xLLEdsO5CGn260tfoY5VhfTRe5';
- b +=
- 'eujoarfhz6Cfr+koZP42Cn2kOdmFvuu8bQTAOdhDS17I7SQPAMdNgJtXgXfMzhCY9YHF4G/ml4j';
- b +=
- 'SsBeDAF4utoHMFiOvwcAV8KgjrHCl2GFb/0hKfxaX37hMsZT+P7CJAtWNvkM4j6ip5GiTmS9H/u';
- b +=
- 'fofeBdlFGrIPxHHMDACj/i9D3yZ5+M0q8pY/CqwbpbSM+ouFORkZBKMtWgfU/wypYi7rq2FoFdb';
- b +=
- 'DIVVCLASH+AVkFlSGr4DiYHFsFvoZsAJUPiK71dwur5TksbBepghPlucxf9YGAbSkco90qYKczC';
- b +=
- 'jCYY7ULWBXipXGtQPD6EjJGQBPu9Bfghdr9G4Nnp97fU22Q5zE0z/eB9zoG3ut/D8BbBwM55lt9';
- b +=
- 'J3swA3srko8GN5fyUXFzKR/NbSrlo9lNZXw0s6mMj6Y3lfLR1KZSPprcVMZHE5vK+Gh8UykfHdp';
- b +=
- 'Uykdjm+Ran4/q5SaYXIw2+XxLsgJMY2U/JsHwBfuxmncdDH/XoUq+gWWqt99QJy9g82X178F0qT';
- b +=
- '+GRqH0uMq3BmPS9ogjK/+EdU+bL4EuZMD9qQ+nNzKc/uyPwsT7gzXwFvkstDrKwEsGS7A0rBaJh';
- b +=
- 'VqYEtLh5ZZUy63NPnnASsJWK4Etf9isNI+ReFmllqYBS8GayvG3vmftktXUqmA15RRCMJxeFaym';
- b +=
- 'Vv2RrKaMgNlIM/Ma9A+J6VZ7TLfU5znCqaKcYHVllK6ujrSsYjD9PpZWx3JNVecxmr+YsgNZrFZ';
- b +=
- 'RR18+Max+H0uo+mO+hFr6h7+CWhpaQNke46TDflByq6ZlEpNmeEjRvqDaktQ3aGAL6a5+prkRiE';
- b +=
- 'HLiUFUeT/8xRc0udx9BpLsz4WWkny0KTjWNAYr99Va6j2vEn+1f9k1qzR3Ojbg6Ks1sVFqTaIoH';
- b +=
- 'FB/2taMJjX3PlFoEhqsZjU8XOMYmGmVxhpDc97UZexzLrrbbpNv6hL7nG1326fBk77PedPd9qvk';
- b +=
- 'RV1y8G47LrdRmoA3mC6C0c6aBRsPUU1DWg3pJKSLcc56ASxh3R2DlDZHIbUhHYIUZKpbhHQVpBs';
- b +=
- 'HQNvD4rJgHweJLNjHQ5It2Ce4z3/52m/F7dPdj3178CsJ+wz3pxPX3m7YTe73Z7/w9ri90a2wz4';
- b +=
- 'SqD0A7F0B6F6R/AulBSC+E9ACkfwrpg5C+EdL7IP0zSO+A9M8hvRnSv0AADQKAbBcgcjMBxzHsd';
- b +=
- 'sgMcabC7oLMQc6k7FdLYTdIw66RFXatTNlrIH8i5E+C/FrIr4PKw1w5bW+CzB2cydgdErfLKVNp';
- b +=
- 'L4HMXZxZaptqQjE1wc1qwlsUAM5S77eq969R789W789R789V71+r3p+n3p8v0/bJMmOfIivtRrn';
- b +=
- 'UBrqzc5AHwrWXQT4PgxnjwVTZr4PMA5xZab9eVjmWnZUrneX2CmOjRLrU3ef1gtMp4zmhQeZpyK';
- b +=
- 'yXCc48AZkNchFnHobMqbIOMxfIFkz+RJ6CyYWyA5M/lRmu+LyGoRMnqfYgc5KsUe1B5g2yXbWnY';
- b +=
- 'XCGwZn2gvOXsomfVxecv5Kb+bkOwxBfw89zOp7Ly3JmRkdPssWZKR29yK/jzISOh82qOHNIR4/0';
- b +=
- 'Ms6MQuYU2ciZYR1D7ZdwZhAyTbJS9aNh0MZa1Q9kKmWt6kfDc3ddqh9yqFVwprPgNMoz+Lmp4Cy';
- b +=
- 'TW/i5AQ9SnM3PL0AnS+QKzjwDmRVyOWeegsxy+XrOPKZjqMlKzLxR5jH5M9mMyZ9LE5O/kEtVez';
- b +=
- 'CApXKdak/D8Js1qj3IrJGvVu3RhkCKM6cVnDPk6fy8tuCcLs/i52UYc3kOPcu2nJhFq/C0nJjG9';
- b +=
- 'FU5MYlpa06MY5rLiTFMT86JEUw35cQQpumcKGJ6Yk5cDklDTlwEiZsT56OJmQPppcuNOdEMSSwn';
- b +=
- 'QITIrTmRheRc7ve1OQH6RJ6XE6DK5Pk5wZIWz3yuBoGn9m8mDDxcuBqDihrWCNKFsJ6mp3EDUQk';
- b +=
- 'fCKmvMSx+BU/wqogtg4wy8agitAqNxLJfFXjWjMKT/JYWey0JeQK+OdF/cwI9QUMngNpTH1djlZ';
- b +=
- 'RfpTr4+Hh8s85/c7z38fHBx0mskvarJIOPj8M3J/tvjvM+Ps77OEETlAmY2w0gz93sVQhCS9ZBg';
- b +=
- 'bSo9CKvNCuXYWmWSrd5pXHZiKVxKu32ShexHlC5Uwl4+Gdch25Cb5az/lC5DVgli38moV74zQrW';
- b +=
- 'Lyq3HqtI/DMN9cJvlsjuUK4TqzTjn1moF36jSzVZIkQ1RSJONTEiWDUdIOJmWe9RDnqn8PywD9X';
- b +=
- '6AN6r8E3Of7PKg/eqAFmRFOLgd3n/jeN95wTfRRKHjd+1+m9s7zs7+C6SLiR+1+a/kd530vuuVj';
- b +=
- 'Yhxmo9ukgT1KpkC5ZWeXTBpZXyFCyt9OiCSzOyBkszHl1w6VpFF5xrR9QUibU2enTBb9YouuDcG';
- b +=
- '7DGENU736MLfrNS0QXnTsIaI1TvIo8u+M1SRRec68AaY1Tvco8u0gFd4ONGJgt8PJ+pAh8vYqLA';
- b +=
- 'x8tZpgQSxZARYuQIAuTFqeHFRUUkIby4gIikgZcjFqxIsWBFigUrUixYJWLBOqJYsErEgnVEsWC';
- b +=
- 'ViAXriGLBKhEL1hHFghWg3wqJBSskFqyQWLBYLDAJhERDpFT4LwiE/4Is+C+IgReTAItwBXCaXI';
- b +=
- '7Jq+QKTDbKJZi4RAZ2gfBuDxCi7ctIYNhvIpFhbydBYV9EosK+mASEvY1EhH0JCQa7m0SDfalMY';
- b +=
- 'Jtd0sLk1TKLySYiDPvNRIX2DkK/vZOwa19OyLN3kdCwd5NMsPcQy9t7iaPtK1is2D0sNuxeFgt2';
- b +=
- 'H7O93c8kZ1/JJGVfxSRjv4VJwn4r0EscxsG08tY8EdomprC35Ik8X810eVWeiLqLqflKzNXIfjr';
- b +=
- 'pIfswaZG9tAiXPeTmkv3yihuc/rvdhJKR3fLSG5xLiQITSjRd6j2ulH1y7w1On5evlNvkJTc4l4';
- b +=
- 'RqnyQv8R7XyF655wan18tXyYvkxTc4F4dqv0Fe7D2ulT1y9w1Oj5evlW+S229wtodqt8vt3mOjv';
- b +=
- 'Iy8cHIAkzpZYKJxlX23scy+O03xT3eehKzcliehLC/KkxCXb8qT0Jf9fm9o5vX5OZSyvX4OxW+P';
- b +=
- 'n0O5vCuP3CsvzyOzy515lA1yR95Aa+/NNLQ/Hsm8YLBFG2x/wJJ5wTZbsM0WbLM/ZtvsTFcfsM8';
- b +=
- 'kJnbepNi4gPrRXsfc41yk+GeASk8iKeBsU3LgMipcwwzpdCuWJG1v15AYcXqUICGDAcwy4nGnV3';
- b +=
- 'E5GR12O8khp09JIrJb7BSLDadfCY43U6khB5QGt9fKgvd4ovTsDbtWXuY9NkjPwgGr0DNfwOh8s';
- b +=
- '/dYIT2DyRbK/ZxXbucWpiW7WbmjT2E7wjbZgrA72Oawl7K1YWfkFrQ3z5F1mJwtN2PyGnk6JmfJ';
- b +=
- 'ZZhskX+FyWZ5Biany0ZMzpB/iUkTW8lVbMPWyVPZa0428+vYol0kN4QsaIvt24Rcz9Y12dNZMjb';
- b +=
- 'tuOzEpE3qTSJtn4+JZZ+HiWm/FhPNPheTrL0VE2nHMGkGqxwSsGZXYgrW7OsxBWt2OaZgza4AXr';
- b +=
- 'GXAfPYOeAOuxHYxT5Z9t5tL5E9d4Op3X+3XSn77rbTaT2GGwN0cm4xdlfNLl+nHjNJqa0xRgVY+';
- b +=
- 'Lr7oCh4vr9D8KjclVDV87zeB4/KITgKj8qHeRc8KnfsHfB4jvKfwqNybB6ER/bRok05JtjBNyLY';
- b +=
- 'wzck2Jt3s2Dn3qBgX98Bwa6/okBfJjShPJlz8Kicr8/Do/IjPwOPyrs5A4/KIfs0PCrf8lPwqDy';
- b +=
- 'eU/ConLRPwCP7m9EtOSvYLzkt2AyexDSVE49hWpETE5gaOfGwYI/lOA7tQaPAblgdbyzzfMkPwG';
- b +=
- 'OLgho8NiuowaPyL98Fj6coqMGjqaAGj8rnfBAeO3ho6FE1lEfVUB5VTJcC1DCtBKhhmgGoGcrTi';
- b +=
- 'r7OF6AJ5U+eg0flGn8eHpU3/xl4VD7mGXhU7vKn4VF5+J+CR+V3noJH5UJ/Ah4XBc5gQzmDDbVY';
- b +=
- 'wHQlQA3TKoAapnUANUM5iQ1/hwWY3tt5ARHj7cjYaX+7BFjZ20YBcva2V4DRaR8HWBTSYYFM4j4';
- b +=
- 'IaiGpIB483uE91nOyWFZjQjtjIF3MfaTcTsciedHpYhQxSztj204XY+gKfgAaqL6/S94Iwhelz4';
- b +=
- 'E8Ky3aMztdjGCdu6AOvpMX+W91ejuEbw+Wv4WB3IwmCYxk0FQLJ1P5spGiijA0yOF+nUQ0FtGln';
- b +=
- 'f0EER0VjFPBs5jVuYaJBfd4NUT2XuFqIJ5BVJzvNGByjiMGnBoXF7IN5zaCqIKyTVK45t6CTRWa';
- b +=
- 'sbEm0QlDoMIazC3jwtVeYS3nswXIOfSoFVDjgEyTomCfCJ3GjY0yQftGwzEM1FyD31oFT+25o1R';
- b +=
- '6Il74FCo9RKW1BWdtuHSCSmsKzrpw6RSVNhSck0OlUtDTEEhPeRI9juDjWnocw0e218bxke2wSX';
- b +=
- 'jswq2zR//+9qEfa7TQ7MKttf94x+1Dbf6C08FzMkPQp446Og7Y2ZIRQC1xtY8wYeY1i63OcXjUW';
- b +=
- 'FSkWXJYzI0mc4JGZ25GvLaE21DwWsA93mwh3EiGG6nkRpZyIyu9RsaCRppKGpEljcAMsKI7GStw';
- b +=
- '5c4Cm8dUt7nAFjJkEmh7JKSBO7EGzHLjgB1P66kUYFSkjRQ8PHYtmFzvMtV+tF4gyYyPYi/yJO4';
- b +=
- 'Ixxa2pRe2pRe2pRe2pRe2pRe2pRe8nAvb0gvb0guuzwXX54Lrc2FbemFbemFbemFbemFbemFbes';
- b +=
- 'E2W7DNFmyzhW3phW3phW3phW3phW3phW3phW3phW3phW3p/+K29APvfGnb0l/ZoB+PPxc5ZAw4J';
- b +=
- '6zW5Al4iFvjKx/wYH4c6KgJ+XaZvQqTBns1JnXAxBqqQYlJ2j4OE8s+HhO8xF1DvncMXCQ04b6k';
- b +=
- '0VUs4g+e5sU5yAK4fDCgn5zYRByxETrPibOgDJ4EtOtYm82N7thdD2nuEncYkuw/CS3lZiW8NKW';
- b +=
- '1w0HoZM9rhOnYlThr6ErIyi3YVZM4DUQNJJ2g1SFpBx1qoJKuwWQtsAUkTWApQLIabAMD9fhiTJ';
- b +=
- 'bZ9Zg04CYyznEJJlmQXwbOcQUmFuhuA+e4TNL2/HIY//Gkiwx5XE48j+nqnJjDdFVOvIDpShL8Y';
- b +=
- 'HiT4DekTYLfkA4JfkMud4e/N3oQb3jPEXiWubfe9N2bEgXHJJjIRvcfBl/4ujngxBheK9zvTIx+';
- b +=
- 'TB9w4gzHaYG7moY7K/BnOg2SQIJhaWU/jDIHPrwMLw3JiUsggW768K4wXK7BJKYFyG1InxZgokE';
- b +=
- '6I8CqgfQZAebQ0Ucf50HHeKwmDzHDC0QB1I/3WBZoGGAJCTBhIH0ebyqHdE6AIoH0BQFahJoigM';
- b +=
- 'UUAE0F0IwCcFoNJaWGUqGGklRDWep+58B3vmz4gFziPvuhh78W8wHZ4D71q2t/GvcBWe/e+9A77';
- b +=
- '44pQFbygH2I7eMRvYUHsJfHc/lLgNjRhnl0iM0eK4gtdmfu+dfPg7JREFvkXvvJdxzUfYjVuZ97';
- b +=
- '+yN3Al0piNW6X/z1P4BSiIbYzToPaVDnIRzQeUhF/ZhAragfI6jVuM9/+pfvSfh0Vu1ed8cNv0w';
- b +=
- 'MeFDLut/62S13BnRW5d78/qHnjCPQ2R0KasMKagcV1IY8qJkKajEFtbiCWuIlDDXBI4zzwNR4zD';
- b +=
- 'DUhl4q1MD0fAahAzbzDKZgGj+N6QoywQ1UegTVJQqqDQqq9Qqqi9VQF6mh1qmh1npQVcBUMFSgY';
- b +=
- 'xE3KTDAwoPc39BwJwXL4icEC+MpgdK4STxFdIYzp+HE1XBiajjmS0Ryxv38fe/6jk5IPYek9K9m';
- b +=
- 'b7xOJ6SeRVL6kc/c+FuNWGETSenHvvgx/H2OxDwkQ437dB7SqELuXQr5I8cGySMvFclLFZKXKCQ';
- b +=
- '3KCTXKyQvVlBdpKBap6Baq6Bao4ZarYaaVUOt8qCqgKlgqECHQ41Ab71Cb4NC7xKF3qW/A/Qudf';
- b +=
- '9z6q7/FAUPvUvce276xjfNgode0BXffOj7MR+99e63b/2Pf0wcAb0PKvQeUuh9QKF37Nigd+ylo';
- b +=
- 'nexQu8ihd46hd5ahd4aBdVqBdWsgmqVgmpGDXW5GuoyNdRGD6oKmAqGCnRHQG+tQm+dQu8ihd7F';
- b +=
- 'vwP0Lnb//rs3fi7uc+8i993PHfpczOfeOvfQ2HOHzQEPvbXup4rvuwHykeh9TKF3QqH3YYXe8WO';
- b +=
- 'D3vGXit4ahd5qhd6sQm+VQm9GQXW5guoyBdVGBdWlaqhL1FAb1FDrPagqYCoYKtAdAb1VCr1Zhd';
- b +=
- '5qhd6a3wF6a9x3zByeMHz0Vruf+u6/fkP46M26X3/kIzmfeavcH3zjrjv1IzDvUwq7Uwq7TyjsT';
- b +=
- 'h4b7E6+VOxmFHaXK+wuU9htfMUV8DFXvTe856nPBrJ5uXvooWdmRSFQvS985x9+aIZU77vfN317';
- b +=
- '7AjofUahd0ah92mF3uljg97pBdU7T/U+8R8fGY2HVO9n3jP68URI9X7jJ88/mxgIVO+v/+4fn4k';
- b +=
- 'fQTa/oNA7p9D7vELv7LFB7+yC6p2ner/398UfxUKq9xMfv+3zYdU79MOv/8QIqd7vPvXVh40joP';
- b +=
- 'dmwUMaVEM4oIZUFMcEvUWxoHrLVe8PPvrAcyKkep967m++Ela9vz746Pe0gUD3zo7fc/2RdO8dC';
- b +=
- 'r3DaggH1ZCGjg16h8SC7i3Xvbdd9+7H9ZDuHZz67rN6SPc+9tM7Py1CuvcTv3zow8aRlr0KvaNq';
- b +=
- 'CHepIY0cG/SOiAXdW657P377LJ668HXvl5/4t1+El71fO/jcU+Fl73Pf+9QX4kda9ir0HlJDeEA';
- b +=
- 'NaezYoHdMLOject370xs+d1eiEOje/3zkPV8KTKs695lb/s+3EiHdO/frf789caRlr0LvhBrCw2';
- b +=
- 'pI48cGveMLunee7r2xeOBXYAl76sJ9z9997rtgWnl6w73p0O2D5oDjKRD3ne/89GNgWilNEkJvV';
- b +=
- 'sGsSsGsRsGsmmFGU1mhplKlppJVU6l+CUOt5hFmeWBVaucKh1EtV+HZ0qxcXbBXyyp5HJ4tXSGP';
- b +=
- 'p7OlhPpKhXaA1cqCvZIxLiWeVCUikDYeViW6kA6eVz3B1tNGDHfTC9hEoUnTHMtt2Cstt/hbY5d';
- b +=
- 'r7d0Nj9aVlIOnhit378a9WeGaBVuk9ZQG/+FW6aqcWAbJ6pxogGRlTtRBIvFgm4bbe2lIjsctXg';
- b +=
- '23wUxIHGyGfm55tZZ6txT6/nPwjO9Y0vsVZ4x/ExiiFaPdW8fM/l/1g85YbDmWVCXTXJJ14l7JL';
- b +=
- 'Jc0OAmvpBijEukkvZIhLmlyKrwS2rDGljFOjduBEhPwTpnxeIF+hoG/TmAmoQZAmSRnxizMVKgM';
- b +=
- 'N5kNmizGQ01OhpscCTc5G25yPNzkODfZEDQ5FG5yOtzkWLjJohVqcjLc5CQ3KYMmR8JNzoabHA8';
- b +=
- '3ORRucjrc5DQ32RQ0ORZuspgINTkZbnIk3ORsCSwBqQZu+Ttm128OP3f4a4cP//Km/dc4sa57n/';
- b +=
- 'zt4cOHP3/4U/tVG1Az1nX48Nf++seHDz+5Qn1uYOFdz3zxE7c88cDwDzQ1HYGln//wwTu+NvuNz';
- b +=
- 'zytSid1LP2Xb/39+57+xQ/f8RVVOo0/19T1vscPf+VDn324uFSBAEflHjILGG9q4gDHTCe2T8Yu';
- b +=
- 'uH8fECTkR8x9Dr0YiQE9QjppAhUa+APm8M0+p2Kfk97nWEeZUzFqTrORc5o2IudkRM1p3IiY04h';
- b +=
- 'BqLrwfnge9WYWhwntw19GhxkaakazMQe0iTvFdZKy4kKYdCW+mYZJVxEAMBIG3yZk+kJsgUAwFt';
- b +=
- 'vnZPchGNYYRagKuskd5lagZAggKC2G4dEhM2REQKYYCZnZSGxPiyjITIoIyIDdhL9tegFCZjA86';
- b +=
- '31ONQHEwLkA/RLsDhkKdhmaSA2RryDYuTP8daWsQphV0cemgsh4HEgCf3WUWplj+MVlCltRRFWM';
- b +=
- 'Ey4woIiBmw2AO87Ard2HyAFoGoQTDMpT8B0xXg58R0QEfIdEFHyLkfCdjeYmPQK+4zrCt5LgO8z';
- b +=
- 'jTclKmlodTZvmUiFTDBmuUSGraSKLiPAUBmqpxoRQGKgJMDCpMwbmPPxVIavWUvMxD2YJxElcpm';
- b +=
- 'kkE3FVkyhYIWmSkJRA3CIxxBWSMhcGSBpSSJqIQNIkdLV4n1O/z2kAbBFWBBERxqQqPI2Jl4OnM';
- b +=
- 'T0CTyN6FJ6G9Cg8FSPxNBsl9SY1xFM1TX2Ux5uV1TS7JTRzmkslThiBYyhar6OJLCViF4zJBqox';
- b +=
- '42FyUYDJSYXJeqoxpZdgsh5rXMSIHIwpQqlFRDZQ/zEF1OkEYp1wjCSVUDWrGEuE65ESXE9F4Xq';
- b +=
- '6BNfDUbgeUbie8nC9OMD1NOO6cZ+zbJ+zXNHamE40jfc0KHSP6y8H3RsH5mO7OQrZMgrX2QhUz0';
- b +=
- 'fzBKEF7Uj3EE0aDVt3jh8llhJA0aR05/jRwVKLHlfRpCwwVZG1LLBVMZ8AYxXzCfsEwrKwmxBsR';
- b +=
- 'ET2GqQFfjwRMcttnoRD4ce1WMrNr8NSfjyZWrLsUwj3lt1M+YTdQtDX8SoYvCkDq7YR8el2Ow6Z';
- b +=
- 'izqwTe40h0PhnvKIaW6+E0v5cT21aNkbCOeWfSqml9unYWsa1XgVzU63T8dWuYMzaFi6jfEYw1z';
- b +=
- 'kIuPwYxc+cuuvxnHy4yYap2Vvplts7C3whl+ciQVZG0P+GqhgKxZI+zVQ0EQFZ2NBsw2LCLeTCs';
- b +=
- '4F3Bp4a4citPMDOnNeiwUb92EJsidijwmyVtYFcncEiBX4XUnVYeb4arnkAp/ji4rjl7NkForjl';
- b +=
- 'wYcP604fhnzcwTHjxvKEogpidLgM/SYhWyTQu5HGCVUhRrmQGL12RJWH41i9bESVp+JYvXZElYf';
- b +=
- 'jWL1McXqM+WsbspGlmaaklX1rLFNT9QrCZA3itCXPEdulO2yCW3fC+53zpMnyOPlcXI1TAsEmVw';
- b +=
- 'FGGgg2DSgmOOpO6E5B7O1Q9MMJihDMwvmtCKYzAqcTwWOHn9DnREB00AcVJLUPdFDIMwXcVdN88';
- b +=
- 't5iAeEI1IswmgX0w+WWkg0MUUJEwyLmHwtv1yUNwZx8q+Rp8tWGMt5MCaydABGskU2y1MAHqg28';
- b +=
- 'HexeP71SJ08/3XB/E0cPc9/bdn803IFNHBSMP8aRG4Fzluuwd+PvzA8U1BbskNm2MwgWzyDP8cK';
- b +=
- '7bpM8VhaiURWJxdB3XNxplxanTeGcDJnydOgs8XwSUIm2Zo4VW7A805QtB5/2ZYmUocTiZPx0ok';
- b +=
- 'WtT8RCxbzMC2ZL5kIIgcmINtKhpzkocozYJoKkbiCYP0rz2alSyjLG8M4uC3QZW0A5Uq5WQ1sEw';
- b +=
- 'yMNXIV8z8O7NVs+ashmGzeylfhxC70sBvnruVWHiANLG+MYGcmGW/cBDSv7DRL0UAV0YCybM+E1';
- b +=
- 'KKCvDGalLjkLyYL2X1oyiTRKXAtOgW2LDgFFpwCf5ROgdT/GqdAutwpkHnpToHUH61TIE0TqX05';
- b +=
- 'ToHUfKdApswpkH5xp0CNcuH8L3cKZKKcApkop8DisFOgptQpUBtgINopUOM5BTJhp0Cq1CmQKnM';
- b +=
- 'KpNDVVeoUSJc5BdIv4hRYtOAUKHcKLA4weQSnQO2RnAIZ8hdEOAVqy50CGc/yyoSdAqlSp0CqzC';
- b +=
- 'kQ4Ho4CtcjCte+U2BRqVNgUcgpUPO/xSmglsor1UJaBgtpO1i9O4H3YFXgPVgdeA+OC7wHxwfeg';
- b +=
- 'xMC70GT8h6sUd6DE5X34CTlPVirvAfrAu/ByYHL4JTAZdAcuAxaApdBq3IZtCmXQbtyGXQol0FO';
- b +=
- 'LePzwTK+M1izr1Ar+vXBin5D4GM4NfAinBZ4EV4VeBFOV16EM5QXYSN7EVxe2nf5S/tX89J+k7+';
- b +=
- '038xL+y3+0v5Mf4mFHoHyNXyNWsNv9dbwMVjR1Pzu1/AhBj3KGr4G+Ky2dA1fW7aGry1fw5dy5l';
- b +=
- 'gJZ85EceZsCWeORnHmmOLMmXLOPNIaflFoAW8qn0ld4FWx2K8CjEpLGn+NvwWWf7zaWgHrn630b';
- b +=
- 'gXiQQLol9HK20cBrgPX8VCcRbCoPQkW4GtwwQtfN+GBZvZhI44YiCeEoBfA7fgQwAJQHReCUQCd';
- b +=
- '1QFYGnjBiYJ1lYdSf42MMHECbwB7M9JIC3VELWfBJNWauE4t8DfBajYHzS8Klp6LYJ3dDsvZLCm';
- b +=
- 'JVqRFb0qmmlJLMKU40gRPqblsSinSEKcEU6rlBf5i8huULvAtmpIN6RLfPZECXODKegOkK7g0xq';
- b +=
- 'RfRwvTtOcMqFQL/C7pQmeLggV+ndwIK3Baw8vTg/0Fnkj2Alwxx72FeBwHV0W+s9NKJpJWZuOpZ';
- b +=
- 'UOOEcY6eUXuD7mSoLYZ3lb7g6MFfpqYnhCKbfKgPEeiPza2Ji2kvaQyldjrCANN+oRh+pYsuzOD';
- b +=
- 'kRHbaMgitCMjXx0anr/4T9PiP86L/2Tk4j+h1hBe34kLX7ILQKzGwAN0AfDaH+/00BwD1ZIgFwA';
- b +=
- 't1EG7csm0qdbZMa9k1lTL5LhXUvRWuZZXMuQtUpNeCboANGzZYKeAIBeAwYtTQS4Agxe0glwABq';
- b +=
- '9hBbkADF7dCnIBGLyGFeQC0HBofpPFeKjJyXCTI+EmZ8NNjoebHOcmG4Imh8JNToebHAs3WbRCT';
- b +=
- 'U6Gm5zkJmXQ5Ei4ydlwk+PhJofCTU6Hm5zmJpuCJsfCTRYToSYnw02OhJucLYEl+3XGTccosY7M';
- b +=
- 'MutIkAvALDWPBLkAzDL7SJALwCwzkAS5AMwyC0mQC8AstZIEuQCE5wIwcIBjpmPukyYyaQzz6AK';
- b +=
- 'gFyMxoEdBLgALvvFcAEnyAiSOMqdi1JxmI+c0bUTOyYia07gRMSd0ARi0ABWeC8BQhmmKZmioGc';
- b +=
- '3GQA4JzwVgkXwB7S3YBVBJAPBcAHG1VCYQoAugCvWgYBdAEuopF4AgF4ApEwzDo0NmyIiATDESM';
- b +=
- 'rOR2J4WUZCZFBGQQRcAaQZ4HgzPGnWYYBcASkiLYKdcAAbv6INNJNgFALDzXAC8wAX9KtgFQBBB';
- b +=
- 'FwBqhzi1olwAMXYkKKIqkukjPBdAnLUNA3ecgVuNSkKwCyCDeDA8+I4YLwe+IyICvkMiCr7FSPj';
- b +=
- 'ORnOTHgFfdAHw/oXwXADK+w1mj2AXQIb9/QgZQxmFWbW3JNgFgBiophrKBWD4cQGCXQCIgTkPf5';
- b +=
- 'XIqtXUfMyDWQJxEiMVKTwXgOWpSELSJCGJjS7huQBinqokJA0pJE1EIAldAHWehVVFWBFERJ4LQ';
- b +=
- 'JAL4GXgaUyPwNOIHoWnIT0KT8VIPM1GST10ASTI/hGeC6BKOTgaaOY0F7KBEDieM6dWrUEEuwAQ';
- b +=
- 'k/VUY8bD5KIAk5MKk4uphnIBeJhcjDUuYkQqF0CaPEFOPfUfU0DluAD2KgnPBeCbfYTrkRJcT0X';
- b +=
- 'heroE18NRuB5RuJ7ycF0X4Hqacb3UW1cQraELoBaJQ/fQPa6/HHRvHJiP7eYoZMsoXGcjUD0fzc';
- b +=
- 'oFsIIQhne3Cc8FIBFpQnkDhOcCcJB848obIDwXwGosTShvgPBcAMdjqaW8AYJcAE3Eg+gKEOQCO';
- b +=
- 'JHy6AoQ5AJYi/AVKihAeC6Ak7F/zxsgPBdAM5Z63gBBLoBWogx0BQhyAbQTbnS7g7pBV4DwXAB5';
- b +=
- 'pGt+XE5f6XYnYl5XwQHCcwFswCEllDdAeC6A07DU8wYIcgGcTkSCrgCBLoCNtGllu3RpEkcH4A4';
- b +=
- 'V/kCLcgFswoJmezNdcsShAcJzAZwp8YLNWqJG5QJQO5jOWdQPeTmzSggOi9ASXTFoUTHoMhakQj';
- b +=
- 'HokoBBpxWDNjL7RTDouKEUd0wJgHqf/9AFUA18VkNDVC6AKm9LlzhztoQzR6M4c6yEM2eiOHO2h';
- b +=
- 'DNHozhzTHHmTDlnGnIpCx8VMOGthVksM7eSmbOROXXKWykJdAEAoyYIFsvIBSBgxdaJayMYyHJY';
- b +=
- 'G53F7gHEw0oAPUJxRYACXF6t5aHAEpMdAE0AoGpa7VerfeRqxBED8fgQ9AK4HRcCWACq1SEYBdB';
- b +=
- 'ZFYClnheHi2mxn/QCAuK857yUVtEZbxW9iICRQlqoJWo5EyP71WqcXAAClog5WPHTJjNbLbhuRg';
- b +=
- 'dAK2oFtdqv9qZkqCk1B1Miac1TOqVsSuypODmYUg1iPkk79OuCJS0NniI0pIS0IeTVMGl3Gt0zy';
- b +=
- '/0wDSR9XKdvgUVuxt9GH8LJuLDiZ/cab1sD6s+ApT8YwLQ/bpROBL0Wp+Gi158ITINcb6eWTCSl';
- b +=
- 'zMYNZUM2CWP5MscAuxY2cYREsMcvOPZNhYhiqAsNSnguAG9sbE1avMpnU2nUW51bPmEYviWrXAD';
- b +=
- '+yIhtNPYTZSjmIxgeuQAE27Tc/z61XSg8FwDFBgT7/8L1+o6HXQBCuQCEcgE8slok9+voAsgOOB';
- b +=
- 'b++lf4P6m5P9fPMzF9/PD/f14mAQ+pgqO5b9llx9xnDnwR71Nzkpszpgs9DdiG2I8PYJFuzWhL3';
- b +=
- 'ZXwCNozcTZk4DEOX1tXXuxoA1e6+i7I6HsH3NMLKSfhir3u5LVf1OgXpHS8Yk2ztbTAe+OwuSV4';
- b +=
- 'sdyVAy5eMLfyzMa9tmng4PD2UxgJACyGv1MGyQDKl/PgWbeFjDtGRuMLDKExM0U/9IQdxPHePbz';
- b +=
- 'M2V1+pWvuKoBapn7PbMQXjdClCUOzTalntFRaT7kzaqKgwAkA0CmmWxudmGtc6WhXOrpr7DJpTO';
- b +=
- '7+PTS5ApbtBVBNXwfzQm+KO3OdmiHeSecYdP8cHrFBp5KRE5bXFSDnGqlftSsn8Jo8wCNMAW/Gg';
- b +=
- '+bgz24+4KEDGuhWO1fHknQiBYCa5YGemzEIewRJD0va5gxM/JJSUDMECXUIMw+sWUfLaD688Fng';
- b +=
- '9XMJalVgJu1oeKmdcOvw8jv8BS3qxGzkdjO6wiDWtRxdanxIRedpSnVRodmIqJSmDegAUNXhPXE';
- b +=
- 'a3WBIrcBbyGIPutcuQCTuagSZBJAdD2aZPymckYaATbhZtw6v3oXRbWksSPq9BgBBjAhBZTMGQc';
- b +=
- 'cDEUAdGyPAYzXNh45DF2RKYyuOCZEhYERAYpqtp/GIjtjoQmavg2xgDuzGDvbuuuR3RQGAWA/re';
- b +=
- 'ABSUQIOSyGfyIEuf/UowDGwaRg8d27r7hy/sAWwqEfPMRd3nIwr9zrGLiQV6hqkC51B0hFPeCdn';
- b +=
- 'iq9cxONFBiZpnD0nOGaPRKkHuhKWBkHDSeNbPF3WIOn2RB1FCX6cZRw0pIh2mOvppwbrCvha814';
- b +=
- 'TwRluFmWQ8OEgEA64DcmzBxAW6Cfe/NnHN2d0oBN/+po/fb1s+nGafjyYPshLmr5GZErTjyvCRa';
- b +=
- 'HB12lqnMQVNdORORSLHppEGXMCWuc8mDB0DEKtIMil48QQu1nuCSClBJINtACklNyFnGuUca6Nd';
- b +=
- 'AGTTBkbiRoVqWLoD8nArU6iEW9lJqBvJgFOYLZptKgAY1sdDUnYkGiSJUD0IWXryOwpqIPY8OWJ';
- b +=
- 'o2GMK0r483b9j5UF4mXLAgPH5MsC/ciyQKRCKjGAin62idnnPSCdR9mPFs2CWyzu24Xq4sqNqME';
- b +=
- 's10R1oNElrC4pYXgP09m/xRGNdCcrYtvN7pWCLna2AJ2eHjTSFSksSNtxt3jDF+klyA56xptzHR';
- b +=
- 'y/ewBy9If0lMSLiMVWbAvH7L7gKTBocRI4wtboClRGExGPkyjQhbTYNpIAKt+bVXNEilI/txEHh';
- b +=
- 'IXEoil3CPs8jJfJuk9d5/H+E9cp6qaOqKb7DDwRJ2LmeczMqMxM+M0LmJlVmdlwtQPXQ2ZOZebC';
- b +=
- '1W7GN8XrOVMMVzuImUH1ZjBc7Q7MDKnMULjaXZgZVpnhcLX7MDOiMiPhaqPhNw9gZlRlxsKZBzE';
- b +=
- 'zpjKHwpmHMXNIZcbDmccwM64yE+HME5iZUJnJcOYpzEyqzFQ48zRmplRmOpx5BjPTKvM8ZmZUZi';
- b +=
- 'b85gXMzKrMbLjaAeScOZWZC1e7Gd8UDyj8hKsdxMygejMYrnYHZoZUZihc7S7MDKvMcLjafZgZU';
- b +=
- 'ZmRcLUHMDOqMqPhag9iZkxlxsLVHsbMIZU5FK72GGbGVWY8XO0JzEyozES42lOYmVSZyXC1pzEz';
- b +=
- 'pTJT4WrIsSAVqtDWBAa0BhxBaAt/8DwpErdpAH9tEpRFAX+4j6SZQON6N1/2DNKoCZ7cQeTWYrG';
- b +=
- 'oK70spLkV9fq5uzOkq9JoTaB4h+RKGd+SMVgCBGIAO5H6Vr56XhoF21TCBGUMim4SKChxlRjRQY';
- b +=
- 'qkuO0Et51QbYNC9OQQaRGWRChAWRzhj6uKszNKBdsaXSI9HyZmKRiSZWAwQ2BIRoAB/TmuHEA7A';
- b +=
- 'RrTlCYCs950USrTENfQ/fImlLtTnM1TyxV5YR1F7GF9+NIq0FjcZQUSu5qb4LvjTTQSEltRjQEu';
- b +=
- 'tmQwOsJEPX7NLjZy4P8wKjUDU+kpWFuxMaRl36GTfRWy8kLGDWARXqFxowXGDQyj3LbTPNtOK7P';
- b +=
- 'tUFvhqoInI9meAayzuiIkEFn6VpkZFBpsomkDeAODp32AoqThGWJbMnRHg0krJ1enC7KhWUCsnr';
- b +=
- '0af9qhgD9hIQ36tWkTzRZ8zZBBy0T3DWK8rIDXnLRQlTGESxxXQ0eES2y+zTsPLiZbBhYDXtkrm';
- b +=
- 'JgIl1iKyU6jxYHHsL6eJUNdMIXpwVg9+5CtPivlW6Ua3S4BTQm36lwYFJa7mmcsuox5WbL403n5';
- b +=
- '69uXZFWSjJhTA6PLNpBURXiVILgtNRbPeGdEgx2I6C2bi2I43RdCOHPP6kEMUcvMdnr5nCOlj6F';
- b +=
- '4WZvXWkw1oXlN+KZzAI3ZI9XlCephy9pAF4IRmGgydm5G/PdRJ/7by5ojLGo0f1GDkOXfrTZ80j';
- b +=
- 'aQtEWqZGFXRtrGf5u0X8J6xgMv2KUgF/HkSOr6RqHvPx39SOOJslASjOygiJJYSSiJf0DDDyXBw';
- b +=
- 'JFYSSiJBDUQKwklaXIsP3KDTooYQciHH3aCwRp+nAqGWfjhJ7NULRQUkgiHc1jhqImEFxsxTm/i';
- b +=
- 'QaCH5cVTYDBLzJ8ERa0YQSSH6bWG8SZxP8SEmg4FZFh+CAtHWgzFnHjJJpQRGWlhzNsbpsJ5e8N';
- b +=
- 'UOm9vGGlr/t4wlZbvORoFf7MB9x0oFMTq0m8MxVmYQSwGR2LAorLr6uv3SYMco0ebzrgRMR0MBJ';
- b +=
- 'g/Hdy+jpiOFjGd+VPBWBTaQOF9jumYU6ECQzKhwJAEzE1aXWcMHkCvcowD0pIcIIHeX1MFCPinN';
- b +=
- 'GIXeGfYYsGWDe2kIhw8IJhHw2kUEIaMSJwakUAQkTgVETjF8BsOSKjiQIpgn4bi03in1wswociA';
- b +=
- 'UIBJnKNq9hEVyARDKuHFlFSoADY/siQUPEr7iQzDGG/xG6VBFmmG4SEfhmMIQ/OlwnBMRMBwJJK';
- b +=
- 'QhkQUDIuRMJzVo/hCL6hggRqYMbv7eZfUmzFvCEzrOOGk2k0bNMNhf+HolQTug/EGO25qJ4JgFT';
- b +=
- '6FwtvXswRhFcqTDof5WLy9FiLeWtpTs4JgFA/qo0ZJzCBuNsWCqA2Klnk5UB/XI6A+pkdBfSSSf';
- b +=
- 'Yf0KKgXo6COwWC8Z1+PAZK8Q6l7N1kEG62XM9DrogJW6oKAlQRtR/k7mAkVap0N4lT4oEsQp5Lw';
- b +=
- 'Qn0q1TlgPxjIP6xZwTFagB9ERtxHxhLFOhhNUyUztJfmx9tY3oaY5QWlBPhSoSkxDsLw8TXlhzB';
- b +=
- 'M6i8HX5NaBL42DkSgqzkKWzIKWdkIXPFO/FI/usNu9CN27GV+zIba6Y9zuMNYHMMdcBu8PNZhTk';
- b +=
- 'TFOgz7sQ4Yv4WBDrg5bRsqdOL4IHTiBN5/x2gHL8Bijb9LjzEPKt6Iwx6m4xT2oEIp1qlQhZODU';
- b +=
- 'IVTVHxCcxCf0MIxABjw4EUxtPmRAhj2oPbSVeRDwl7M0Qg5Pxohz9EInX40wnqORtjgRyOcShvj';
- b +=
- 'FOkw4V2IIHhn/HSO7XbO8MKkaoIgnQRT8UYvBCoL1MoRAP45KbVpmvDC3CqDGDhF2U4F0nOa6Tk';
- b +=
- 'N7LSkNIhInU9Pqm3Maj8+QG10prz94ZQXiYSn26suCMUqxb0d3bgXzhQwigp4KmUUDOcJGEUF9c';
- b +=
- 'S8UwV1zCj+YQMMXvKiROms/BBMV54mW2WTlGp/vFHWyDPUeaeVcoWKt1oOwN0YXBfA0FsWAhsAD';
- b +=
- 'KFTwdCpwGA5jhdPUXTBUiio9sPAa9SZcQd3lv3T4FkFjRNDYGAAoBhrD80c5xxTYJnybgA4/QLv';
- b +=
- '0PwwzmqDbJbHqyPuajC1+FtQeOz3QoxW8M7/E5BWeVMB6QHTqPSUegVHlyxivV5DtyEkvfiBJN+';
- b +=
- 'jhPBZA2+z/kwq1Uza5s2kmnbzrdDu/wgOtlOeDF0hSEhRYm8JFWtgcAg7wGytwvNJ/sH67D4Qbz';
- b +=
- 'Bck4dbzTcZpCmaw7+dwMR5xAlhLd51RwRDDLuoovMB/ihTeWMUx5NTMR1s3MFoFssOvDSQUIo9G';
- b +=
- 'tyjoQ5Z4HGDmIq9P4UhHLpEgQMhLG+fP5E3xrCTcBd4GSQH7SXCUTHEbf6Wft6/1SBvHEqQt2oo';
- b +=
- 'wZv54wnczP/RYiH2L6Z4/pi3CDvkxfPHjhLZNhoV6jxsRsW2DZpRwW1zkaHOM1GhzlNsiY+auJs';
- b +=
- 'JK0RSmrheZFKGV4fMgFFf/Ow5WZHl5/LIFpt3MI9shXkn80hAzTuah/qr/HQeWaY4ugmDzeFh06';
- b +=
- 'FfXM6iODKVjTdmhiOvifRTvLrypdCU8dJnNxo1u2EjanaDRuTsRNTsZkTE9CZ4YTBqsBEzaPJFE';
- b +=
- 'A3M6BZNb8QzYa2QWT8lGAIs8Ce9u8UyfoxTPa/zfAgcOiIEEvMggD8jmyiHwCgVlkNgmErLITBI';
- b +=
- 'peUQmMOo53mUyWb9IcEInjMYwRLFV1IZfEMenaYvDPTZjB4G0rSnrJIhpThsMJDqmUy84331fhB';
- b +=
- 'TBa97fSBNiCMBKT6fCWDg8XIgHaLCciCNUmk5kIaptBxIg1RaBqQZtsIndDa2Zwxm4yaU/Cml0Y';
- b +=
- 'semVR5BxCh5lvQLPDAOOvZ7d41MkRyBuqpmEdrRikYyXQfFRgJ6XHbuFBgzPgnzRazoyDgNv2l0';
- b +=
- '9qUFkFrE1oUrXVGkVpTFKU1RBDaOJuFS3iFio/1vLTHxyoyqfGJaQuvE0bg4HXDCAHdJuvnLLuC';
- b +=
- '7XmsmWFD8I1AsHwInNw8LIkqg6hoi68aqqEKRT18jlwhaY7OqdaqxdOQoc661oawNCwYS4uYkhk';
- b +=
- 'FdXzKU2HpkM5YWswSgTta7JmACkuzIcvskhCS8rDWgung8cIkBvTRfFLBRII5VAWDb0A242HXB+';
- b +=
- 'OtYi8OjnRJMMQUH+XjwU1r4ZumqPtB7L6SzkGSZ2UeGOd0jubkUPshb+HfEGZ3HS0PvveHFsRMy';
- b +=
- 'mrRTQjs5EhJ5IdMwAgm/QKtUGf8yCuhIvku8Psf1AOLg9bVPAPFJyS7mvjALbPJxoGSKF7oYpi7';
- b +=
- 'YLNjSJ/fRQP2QLdn0VIwcAXx9yMx2qJiy1uGPwcjKsYONfbbOgadOdTc5uwnzaVMprN4pUwnmm7';
- b +=
- 'F3xrXdzXdeAAfiy8kru9qoNJica7q+i7rxgP4whpUBfDcMMj1sLxpkD6Hp87BAwcO5I05jAqyeP';
- b +=
- 'mOOxbu8Ace0rIfNbjTmVesU1ppuRjdYbmj4S6nX8Euh/wuD4W7nHoFuxz2u5wIdzn5CnY54nc5F';
- b +=
- 'e5y4hXsctTvckZ1ibswzdkHkHpxqwFs7b+pFTrb2iO4j7Qad6HQg0+HZku1jCjTMjo58EWpltH5';
- b +=
- 'TGOZlqEf5YbSUjWjkwNflOkZnRz4olTR6OTA19FPD6sVjeQ/Ts2/PUknh72ARQRxvnjRVYKuTi6';
- b +=
- 'WjXwy4liaro6azRu5Nn+VoJevEHTy1evkq09hStcTaWRox/EqdhA6enBIUlmi5NLTfQ88fjdpvP';
- b +=
- 'SpjURNbciImlrRiJxaxIlGXZ1zLJseeuB18sBbmBZNPm7dQLc7oBTFXz43SwK42RBF/zlCIElVJ';
- b +=
- 'jzfi7q82ECdq/v+c0LuESEQmweBsfnXDunqLqJyCAxFXDukq8uIyiEwO//aIZ385zr5zwnBswYj';
- b +=
- 'WKLySpDS0j1vuelprSTWRId6AKQpTzcnLgiAhO5uBNIiJhPPiFwUuhFQ993dRGbiSEAy5nPAfHe';
- b +=
- '3Hunu1iPd3Xqku1uPcnfr5O7Wyd29mKZuMA83sf8tQ9Ob87z5yqdSiTUvx/WKB0blIE96YMwSyR';
- b +=
- 'lo5ZkerRmlYKwh6iQrz+O2Q96SJuWf56hDBOghbtNfOq1NahG0RhfslEOxOYrSZBShZSPoTLlf6';
- b +=
- '3GSbGcjhyhvcgaFPD0xaeHPeOjkJiY6GtFtWthstIlgNGWR61iGt7zSURMEsHfimP2kvN2NOKLT';
- b +=
- 'mdidFrp5zMPRLLk32YzVPQ9oyBTXvTud6AImJGRRborr/oFGOjqjex7QOu9QlUKS8oASki4K4Sg';
- b +=
- 'PdhhMByOb0dfH80kGEwnmkAkGvxi5jIe9KBhvBlmORxqyvpO0qFWD812V6i4TQepWh24XMxjFfD';
- b +=
- 'DO0pm6BJmpunLce/s0HrfrfPFnkqqw5z18dRtUaSZ7m9ghFfCBoGWGrjyiutopwIiJoP8i9c+Hw';
- b +=
- 'nXl6YdswvNks28g5nNJZ3g7jroY5C5SPIGILrK0gU6GtM5+f76iRH0/FKNfHzHpdUP4c7LhdQ6z';
- b +=
- 'wIgJsLJ12p4XXfc8CeZOcaS4ilDdpV/t4G+f6GQ28VF4cjoC/939pZ8fPnxP1dW0eQQVu854m1d';
- b +=
- '3srTuT2/6wIfnnvz+xx/T9kVUniqtfOdPfv4PU4/e9m+PR1aeLq384/ve+46P/fr5R46LGsVMad';
- b +=
- '3H/+Pw97/+gQ8WM1z3blcvuPqu7DNG9jmMEBsh4+xwBowzh4wz07vbtCjU3aZmKBqFb9UTfLFJL';
- b +=
- 'Lh8T91tGguuIKS7TS2vROlvC1dIoXsO/Rs10RHn37VJGSu44lDdmmKGrk30PhwLfzgd/nBaqBgZ';
- b +=
- '/8Oh8Ifj4Q9nwx/S7jXKNAfdQ4cP70Tb51qgjsuDSwHNrt/+4y8Pf7T4w//zzdB1dWbXDWNve7x';
- b +=
- '47S/uaPPvPzO7Jn7188c+9qMf/uK50MWddMki3w41JPCyF8WpdMdGjO/8oovZPB6L8/VmwZI/em';
- b +=
- 'zjkWMbixobH7kvHxxqVVJq/vVhCLIL/Ws1h9SwhkXolKu6o45cmuravIrgYkOOCFHTQnOs0rtCk';
- b +=
- 'nb6/Wvz6NpDILb4i0+R7eHyKfKlJ2VTnNSipthcCC5N1EviD6q8O+9SfL+wf5uaus1I3Qq2kUEQ';
- b +=
- '7K/xhjddhqimNkKaIObdXSTKjwSrayIr/MvioC47S2LevWY1tAdOkL2cL8cc9OFUfAlwklFgys6';
- b +=
- 'HUgSE1GZsnX/BJf60mTKS8dfN1IrBrufLLO0GvmnNplvbzseft1OqC3/gUOlS/I1D7/z9cv82Rb';
- b +=
- '65btbg6/v4En/Lu7wP93od//K5VRgshhFuq/kwbHCtXIpdRM5x3rVyZnBDZdILR1CXNabwqCnfw';
- b +=
- '2ZEXLc+VoK3QSMCb0MKbzN+kIHCW8L7kQ/PO5a9wLsLLaFugqxS+2r+dVb+Nd+VfId7Z8DszQ4g';
- b +=
- 'mL1LNaB38dSWI5dCf2BdAB0ukQ28jAHrIRUc9o2r+S0uuW09paa0KJhLWjmrYMh1kB53QWDqV5J';
- b +=
- 'HelngilaHffmmviY18NUXeDuSgzg2iSMLdgAr5UplYeAN79XBtd4c+rO85Po3NKYs2kr2L/umgf';
- b +=
- 'Cx3lUlx3qHTDqBxdd6I3iCm72MeTd70far1yZof5Pv9DIL7tTIuJZ9r7qIGRTgrxYU4IICXFCAC';
- b +=
- 'wpwQQEuKMA/AgWYvS3QfQfToPuW01EEw4uCKYrSowjxIApYHUWIB9HCSsvEQ3cV+ocJSMkZQcR1';
- b +=
- 'zD8yIEJB/hR17V+CaYTOArDOigWBxRxDHPNY3ghY3ot2L+V5jjw2SpneC8ItZXyOwvXiR3lTErR';
- b +=
- 'ggoL3415wsunHSHLQpIOXUgfB+9EjG4kemTZ/ZBGjGuJpj+gqQlpwtAkozrQfnFkeXR4PxeFP6i';
- b +=
- 'qG/MJQ+K/6tQTliPIvaKIYQZxSEB0bNZ9i5HxmI+ZDmmn+nMAyoBhR4OSEF1HvOasq1A2xItCyK';
- b +=
- 'jhQhfrGvCsKS88eCFapFUo++hG/pRH156tDCRza7VkXlSXAGPaBMVQWKhwFjOYoWMgIUGSjIMHi';
- b +=
- 'via4NKyWwz1B/XhxnjZdZHURBsB62qTejxMF7eNH+y7h4HWO581SLHGDF0qMkbLL/EjZ5bwr2Oy';
- b +=
- 's8GPtJ/SwtFch3IazMogljYXwMCk4/sY3cthIipVQIe/e+3doahzwkgkHYpYi5/IwcgY95GRLkD';
- b +=
- 'MRCoLYGBiE2TxYHTCrZSD76d5/mAFJcJD6CblS0VSd0gS16L6lsgoVwxlTgbocp4Dyle6v8sMfE';
- b +=
- '2rkDWVXV8dV8IinutQNzpV5YxSHgxqrmm6cspSlCKrLVFGboWDMOF/TRAMwFU/Uswz3r2zikyIh';
- b +=
- '3YGhkQaFFWRY9eA9R3F1umLY87LTfhiF2vpaodG/YylvHKILWnAJglqBws5AK4ymRMV+/RqxUZq';
- b +=
- 'b+TBdTnTy0bdmqbnaBq0SkmvFqXqaj8JaUuvS8gae3jutQEcw8SyibqdKr0hSt0KYdIYVXie5Vh';
- b +=
- 'z+nzA2InYKGPR1XkbIhJ3Gg38yXlinaXQTmkVP1la8OEImCq6O554rBmw8tRjDk3ig/s+kZkHNw';
- b +=
- 'ls7gS9k2q7AXugcLH4BqNzixBvhDbyX8UaZhpopahKd8njEWA0pCd9bODRsh4ZnFTCA+ryMETG8';
- b +=
- 'DD1lzi4ZnjVArajhZXh4ydLhWWXDSx5teLLCjpFIlxisY53txBqd9NaMIHc9PIO9XkCTbGvGoLt';
- b +=
- 'LMqbYL+nX2gsynf2ECSPEeJ70gBM/G2BlusYu22K0DLjGVrpII4EjNt19u+wKzBkbu3RqAC9xKr';
- b +=
- 'Ro2o2Qj2Eqqw7gIwwec/ws+PmAXQWMlsCz24kz6aYUi04uJwoIzlADUA8bgDkDuAcci+pifGCqk';
- b +=
- 'QG13waGBUTvZ3qxEHKEJM1O0Vn6OF5GW2Do47UuMu7u30MAOy8DQIIMXnuTwlPvUJIsQ12SnpJI';
- b +=
- 'WRnEAnQ8wJ0w3pJ4TL8ChxJXPYOctFMhvMWR+LY4ScQb1JHJRiBlO45LKevMDJ7HLx11Mjzqyqh';
- b +=
- 'RV/ijTg4w0aWOTHCVPIZkyagzkaNOzh91xht1pnzUuBUDNAUiZ2vjADKzTPA9K0i7yFaAXSAebL';
- b +=
- '8CX7omU4/Fr4B6iIcU9Vgvm3qSfBuMxdQTx+PB2MwRySeO5BOnymYK8mWCC0+/N0FSkROrWW5JS';
- b +=
- 'QfGl3knlGE9xT8Xn+afi6/KGxbei8C3CZzG90alk7iQMt3hHz2kZW/EA9SZkhwwlzv3Q8i9jW7b';
- b +=
- 'gcEN4rtBzIEJzDl6B5h2R/3vgDbdQ36u9F2m5J3mtvPh9FQxJRr5SrpZzbPfwSShW2pq+WqJKvf';
- b +=
- 'Q4+Oam8y6IREsmkTzZrqHqJOuOsJLal+FBGVjNNrTfG9SHKtdhGGV7un0DoV0Ai8j2JwRTI3nEU';
- b +=
- 'fjJRV4vYIhU4W1muZ+fv85mQRnHZB1A0io+jje+HUWkrp7xi6QSGlX0Atz3NHdja+lFyt30clrr';
- b +=
- '4Ixr0KVXwFem/jaTexy43t3p/w/eP9BzD2s78rgHlex+DDenyD2u/spcIDu2rsGH7P0eLW7j2qZ';
- b +=
- 'WxtTeE2HAXwSo3vKcPKXYHym+zDfQwaEh2tI4T7D+cQAGmUAIbRjB+x64CCQ99V45Bk5aGuj04A';
- b +=
- 'FKbZ36EIptmDw0eQlgAf7AOLuE/xI5lynvczAux4t3EcHUd8ol+A9SJUgFwfAbEQjR5eVjY5ONe';
- b +=
- 'B9AfUS/wcfYmh6Am+YiIMYBIQtw3MZyF6DXfr15yP+K2R9ARRSjU1H3isBjbEUfapDP/R+cQGGn';
- b +=
- 'QaySEG9RXYGFeHmDFDr5gxutkLLcWQ/vL0iiQneK5ItgPmZAeSQPKXIAR2bWQpFW0iDSRNv0atE';
- b +=
- 'DWUT6SRkzbmZGF01aBRQpuEtJHStBV4HgA3r2F4M/pyZEXjFCeqWAbzEIO5OPTauOKMCIC5xl7N';
- b +=
- 'AzVNJdcErSRspMOES7qhfHy81OxTKJdwJP5dQF9YxNeEFYrBsToLYtHVjI4cvYyDbyNfgg/cIZq';
- b +=
- 'q1JiVNSJjNA/idW7EVv6RFAcW9cXWsJZEKmsRq1zrP3O9+AbkU5YqV/YwRc7UUXtOFIReOiQIP2';
- b +=
- '8fgaJTd4+Eul3GXDeVdkqURk1VbM3FeftBFju4kfvsUL12AbgTd9NUk6rLvg8w6rTlDXN9OpGjh';
- b +=
- 'R6CZ3Gn1EdW36B6z8voxVGtAX1VnQ4mxGZ/Ow1va8C5WXyjQXRB0eR9dOoJCm26rmQGgu83uMIA';
- b +=
- 'g+0+ECSIYAj/OI8Uh5HijBPCGurUHr5cxmnEtA1PJ/l/Dfce1X9QACktxQKZNY9VsvAfNzP7ccE';
- b +=
- 'y+MIdvX+Erb1xy0DairMfnOD2jbUQ32NGaFiSqWZVyTbcuO2bCwOgaNfSg4VB/ZmipfwNb+ZrEf';
- b +=
- 'tw9EANOGuqnVfQuiD7g+65P//W77n327u/8rA7t4zQyfdfMyE9v++1ND3pFIBK67hoZef7RZx+5';
- b +=
- '8YP7uWzjQNd9L/zkwL/ffN3DkxoXdRa6nvzKbQc//uWJX57IJbBu7/rGLb/43ne++733VHLRGBS';
- b +=
- '9f+7Tn/zhfbd9fR0XwTq36+6PfPObvxka/P7ruGgEip79zae/feNnPnTgFC6CZW/XCy/80xPvmv';
- b +=
- 'q/b/9LKur64tuf/PjEgz+78ab9COd017f/9uYnP/z8D3/waxjQEAiFronP3vTMo997+kepvDGI+';
- b +=
- 'U/963P//qt/+uaD+JNDmB9+YXzi69/78j+/Cxp4C+Q/9tPB7wzefuvBzrxxOWSvv/7GT07dPfjl';
- b +=
- 'h6C9SyD/9U/87J5vv/2f33t63rjID4HBKCMvbD8UWWRSBBQ+GV4kiU0hO8022L/o4nFQ7HAcahq';
- b +=
- 'dNk5l1/4ujeLk0Y0GS4wD+K9Le32jE4cX4fMNF95/NToarnaSQdQVrPeuZ1AVRYFOuGCYCgWGQ/';
- b +=
- 'V9GIUhpAHfhYKycGUbV18NwldZL04dfT0XqK9ABl7thMNWKURHfTUEX1VzH2TDm95XprSudsKhc';
- b +=
- 'fuge++rYfiqhvtAdxou++grWXF1EPO1z6suwydkZOJqKJ3F66sysFz4UigurIKD9zxMKE+5ycF7';
- b +=
- 'HirUAV/BwXv4mJAZDs9T2Pgd4eHlYuDlwv7lQv2/DW/ylgHMMWW4qyC8Co4h9eCuTmSbHEPqwX0';
- b +=
- 'ugPusB3eNXJ0Uhqlgr2G93w38NXLJzp8K37tVOCJ2EiXY8aCt0cGzGJ+gOAqGEv43tB/Lv0P6Er';
- b +=
- 'Gk0bG3l4opdHGv1lJjSWHur0Qre1J4Vvacrs6KJjy/YDzsF5wh2JQ7BqeotMwzyKfRyl2Dh9jxO';
- b +=
- '6Nz1LPFF9kXRXDB+5we7JL422CJ8CBG6dTevEHQCa2yQVhYVj6GYR7DqM4OwSndqVBBeCl2Mgcn';
- b +=
- '04ITuzzQcc9/R8ebIgZqhQeKJ+eseQPFo6ZW+UBnqLB8pBN8ym5Q55v7JxTUGvjX5vmkpTrmVuE';
- b +=
- '50Ojgzxv5dgqey5ge2jfjudQEJ4bifFApYi4V4bmAnVIxbypNWFg2kwYsK58InzJDP7A61EbHzC';
- b +=
- '7hs21NeKSNjxfZ1ezE7XQq1E+g+wfHLBUTaqkjbAiByvDhLX/jLaPOGSIE+HcQ1Nkm/9r7BPviJ';
- b +=
- '7UAAmeFAJA3xgTdkZtSg8gGve8j934l+Vv9HlMkj9WxRz5nVeEfe88bhwTdIM+/2jLr/Z5hNphO';
- b +=
- 'g7+/IauDUH74chy/jKsDWNI7dcsnrCaEOtdKO0+Owa7OCXg02WtJG1egNlTmEGR0lcGE5khHCvP';
- b +=
- 'GqFCHpkaxJddyR4qhgzZDXAOsdqzljoXfDfO7mHo3Hn43wu9M9W5SvdOQRkyYS17T+H7fmJ+xWP';
- b +=
- 'xQhjfG8JF23UBi/WdKGPstimnRPYnViaqg0wVLe+pvof1vizK3LJjLp7nWFl5OdK5RvoBm/KoZv';
- b +=
- 'pvjj8jad9E/RE4ErBZnAtfdJrThR/xqa7EaPTVhtQQvgnRXQsVDQbXVWM2gBRFWs5g1dLcBKk4F';
- b +=
- '1ZZhNVowNWC1JC9qdDcLFeeCanVYLUbrGqxWwbINzydl3eE7/WpprEZLFwurpegGOw2PhwV1TKy';
- b +=
- 'ToGUE1kmzoPKoZCh4HPYfMSniTl4Kz1ulgvNWqeC8VarkvFUqdN4qFTpvlfLPW6W881aXY1g2tl';
- b +=
- 'sRtFsRtFtR0m5FqN2KULsVfrsVXruXIAtju8mg3WTQbrKk3WSo3WSo3aTfbtJr9yKM9MZ2raBdK';
- b +=
- '2jXKmnXCrVrhdq1/HYtr903os7HdhNBu4mg3URJu4lQu4lQuwm/3YTX7vkoQrDdeNBuPGg3XtJu';
- b +=
- 'PNRuPNRu3G837rV7FtpA2G4saDcWtBsraTcWajcWajfmtxvz2sUbEdPYbjpoNx20my5pNx1qNx1';
- b +=
- 'qN+23m/bafQuGA+jqoB7JaccATZk3mtA7s8Y4P29IfjorbzTw08a8keWnTvSZ0lNzniN2UJBAYt';
- b +=
- 'lxjmuhiJAG2+KfFE5y5SbEqy6TiAZdWgg1XSbydPc2yPdOvPMTl6G0ksDQBJBM7ugdwKydvNTAU';
- b +=
- 'D137gNUQGH/2ferI0gk/UYwhZX8t4Yf0tyTaFbugdvheQbl2s90LeLV4MgRX40e+dXEkV/NHPnV';
- b +=
- '4J1H7uvIrya8Vwcq9OR+V9pxwN10esAx0XGBettJgFib0Ok0sYn2rJPM3owukIacGEaVM2Eov6+';
- b +=
- 'JPvBJvO8ePkwW4NlgzQB2JN7/mXDlubi7RVcVQx3QJ0l65T54/biWvRlATj/vBcoD/5wG4vsxfP';
- b +=
- 'F3Bmab8U87Sf+nsBTUWwzUgR3jxvDeR3gnE9l34KCeiit/KHw0Fbd1TJ+IA+VAOhm30U2GJp/q/';
- b +=
- '4XrVP9N4iz8cw76YN2bVTcmBVUmXT37tzp7/Eb1HTCbUf0yJ1awLfoxFNo9GKXfb+H6QHxU38Rw';
- b +=
- 'BdXPHcF0NuKfTbgD597H/dCW3AZtwlCzYejj+UdaeRFM6Syfyo6k0P9m4s+Juh/xCkmNQl/mOm0';
- b +=
- 'iDR8/40N2Io2OWuh0LUOlifYk43SNvrYBVD9uftjxkFcNfVownjT9egv2Fiu4K7Gmic0/mgZbc/';
- b +=
- 'cGSOHtVLqAsqFY1PnC5mROPIHlozpQATrEYjnxWFpBxnQfSxfUfEx3OFXIvkvgiGYNh/D0jOHEB';
- b +=
- 'xwYFbLseby5ZOx1aNTwPSPzadzK4plMg8mzxU76XusYzCmJzs+4jKMdp4PyvQFFiXIzo0/URjRC';
- b +=
- 'ElcThbFw58Op7LjJD0jSOGA8+YQcoMAeKzgVxAE4qWF2W4IEyv41MQPtryF9Ad0lFd0lcZzIHAg';
- b +=
- 'Cnn5OjAAp4dSAJi38BY0Yos0CLlEkRPeY4i7ufQcQhSGijimiTiiiTjFRQwWwjmBZ7j6IX7zdkP';
- b +=
- 'RC4p/V7mMHiMiYWRq43guqnkmGENZrwD/L3JtvgBdPCv7hHnTwmmgX3XED84OOW2hJ/NGCcSgBc';
- b +=
- 'UJQcp/BzMyN4yxPeAoO7mXEaG6KY9ynrouejqKxtJpMIjus40YB2O/Zt5uwOrCA/4Z1uuIbd62h';
- b +=
- 'LfepAzxMaoFAnnaf4XnS/EYZZzH0/wJNAi3H6Qc8MAZOz/6dznjP/jNCYDqNZu/vVQreNXQEKfj';
- b +=
- 'AUJQUfHjoxaTgLS9fCj59S5QUfP6Wcik48jKl4EiZFDwwFCUFDw69clLwiaEFKfi/XAoevBVQ+M';
- b +=
- '6XIwXvunW+FHzg1vlS8OlbjyAFn781SgoeeFe5FBx9V0gKPoGZyXcfTQo+fEv0dOZJwdvnS8HbS';
- b +=
- '6Xgw7fOl4JP3PrfkYIPJ0X8GrFfBQVYq/FHdTpB4vm3yli8qsfl7hRa0N8KuQLwJ3Pa2Q1g4TOu';
- b +=
- '8B2BqwwRrDJEsMoQJasMEVpliNAqQ/irDMGrDMfA9aHFrI5r8zkeCHa5lt0L1H3TK9S9icsNi/0';
- b +=
- 'R6EEYfr/f/Wp2W1D38hXqPobLHCvwcxwKul/G7hDqvuEV6j6OyyuL/SfojZkKuq9jNwt1n32Fuq';
- b +=
- 'dlncV+GfQZzQXdp9l9Q91br1D3ApeTSV48/i0GQCZpdwTeP3kPOnLHi49o/llw9P0lcP8Aj7GHL';
- b +=
- '6K5mk5Zq/PX5H2kXQauFWxxzKsWw2oxrhbsasyrZmI1k6sFGxnzqhlYzeBq/v4F1wqOe2/QmgHc';
- b +=
- 'tJsdrIAt9z+1glqW3lG2wAy9G3z/kd+Nvsi7iRd5N/Mi7wY/oN59MqEv36/sOD6UN5kqsBPbqVD';
- b +=
- 'bWQZKW/bFOSmvDD38uPbH005OhnKj+GsqsxUF3phwsv7n4xUFZwXvYjjVfil2UYnXNXAz2Drdnc';
- b +=
- 'btjIFGaCT/g1OTveX/sfc+UHpV5b3wOfuc877n/TdzJpmEIRPkvMe0Tiq5BMoldGhLziwBU5oL7';
- b +=
- 'eJ6XXd13fJ9q+trv3e4Lifkpn63CTMIYlCUqU01WtBoUaKFdqzYBgs6gVSjoMaKEjTKiBGCRo2K';
- b +=
- 'Niqa7/n9nr3Pe97JJATFrra3YTHv2fvss8/e++w/z9/fwwLVTrbcSiEWa9YRyTpDdXHZoGZNyXN';
- b +=
- 'LCp10wPAIKs1YqvMvADSpiiyyIWbBqyifanbUWqPZ7TWsQpBp0/tkKTVdJVNCkfTr4xU0V5J9mo';
- b +=
- 'Tn1pwkW5qEsHlaBkXhmmC9wVefmS5Jw2S9Ojdmy0othkfHoiIFX42lRQrOiIu7fZPUUJECWtOgT';
- b +=
- 'YVps0CH4mth9NPnmlt1LYf9eOCaWXMtrlkXxWVs4HDK8V+ecszPSLvjXLTZjuzpaTGeYeomT5Tq';
- b +=
- 'lIFao/v+Zvf9/d3395WGKMSs0iEKUzfr6t3ONLuVmW5lfd3K+kudCZ9zZ5YVvcFgJkVn3PStFB2';
- b +=
- 'sFq2Li7lSS0uzCFFhio89o9PMfeoIDXuB3PHSM2WSSnZmNdSaWlZol20ysNTHW2MTTQZUlgZu5S';
- b +=
- 'YdITaEpBHig3ZMuxn/j55gcmM3bqizXL7vY7uBCkbJIW0G9pYz9kvGbCkD4vZXwuHN5V0BRTBZj';
- b +=
- 'sr5ZjpgahpxmGath2hGhJC8sin5IOzuLppgPDCTr50AGb93z27SXXSvS0OwCaDbj7ge7jVW0E+n';
- b +=
- 'Xne5q7i02iI6yLm7c93L/T0F9xn1deU63GlIckMjLwT50yDvwruy2tiFkJPXbgRK9lhw4w3ZqYj';
- b +=
- 'o4Q3UFaX3l0TpZ84X/R+F/wC9XcEXTfnoMbr/tJExuzmgRyKNVuUo2Y/BuSVAKKomgmEi2Bgt4W';
- b +=
- 'Ctp9yXAW9inPWWH9Gq/IKJ/AJGb8V+Qg3XUfzmh4rBvhmOXsnTQZMmdpJCxFZJ68fLTDF51I2yV';
- b +=
- 'MdRW4d8QimPp6Ud1NHdEHTGduAwZwyyABZfzxj27Qj6dpQdeNq0fZ0xyJuyL9TaU4VOSr7to+QM';
- b +=
- '2Dr5vTPIQoSeomRc2Dpm3g7a22zs6KhsD4glKVc7hAe8usNQnf7FafViaw9nNKDq0EZE4vppMJH';
- b +=
- 'HGzdAL7iJKbka2rRhA6cv9iY2KRcu9GO2qzSGlKEO8b4QDGRI/o+u53mqvYHu7AE3vtvZJ3Vt05';
- b +=
- 'nICCoWD1ZzdjJnbzdHfXrXBFhFWMCpbUma3/pRVtwMGjSPpGet4Sq6U+/Qyg/PzLqFs49+JU9X/';
- b +=
- 'HjSrNUIdnU1Tw42MBZ0ACZJqoAkwsub4Klo+w/2ksaPUTtARDxhLa0Z+CUtA7+Gs2AOn3swD67A';
- b +=
- '+JFnnt/hVFrlwVJYNtpKfuYEOfDfp+wmr2xMaxtY0riS2AuEEIQBMcq/Et4ANSna3KgFAxaM8kU';
- b +=
- 'b86mpI94EngmKZzZIG9TUGKMVdhp0MA3G5dukeudSG+GPLfe03cJ2/xep8qp1+PyvXMfpQWPT49';
- b +=
- '9iW4iW226hZRs22Lf6Gv03xNjIpFiv0VA1Vp6vwcEDxjeEJebal8Ii1W9TWCNTVkPb+riQ/Dr4e';
- b +=
- 'BiQ0ynEaOgtrK/fbnOBGhdqlVatwQSi22I2qum/LDSKIyRn8wSNQpkTMGSdzNUsVFvQ3+pwUykl';
- b +=
- 'TDkRFAlpNz6cHLoVdQOo6kyp0A0A22W5pPoB6DxBaVqp02dI9ozxdoj2uHDtq7xUyvUZz4c4ge0';
- b +=
- 'M1e3F39QOdM+Tq7DBCdVWdbzy+ogVjFDHwi4xTmGAF8Iqnka2kdwd8L2L6UrUz/CwvoYlB/kvu+';
- b +=
- 'dA4IUydTk6ZpK+IAG/1LLiVb3V8AXSsnWNfkZ5HGRVtj1a4QlvNB7XVceweZ6MbI5wuykkA+s4k';
- b +=
- 'vG4TN6QUeH5OXNEfmao5EuyWsvTmJPwTKFzUJNxlH2Gq8uC4pMF5Y8ZlD9mUP6YkFbIcyG/ZK1F';
- b +=
- '24Vx9he7GSs2pcIGo2FYOQLUI0AmxDYhPVFadGSV3nQyzz6j3x7rS77RWbJMWA8yTZFpbCYsec0';
- b +=
- 'mgNYhgGLAcMoenEzAI0DqJj+XI7xlMEEZmtlovaSe8Scy6wdjNCZzlZs/fF0Y5pyKWUZiNohwX9';
- b +=
- '1EgmNDft2rb4gnQDGFnZPcjE92s3nCmzx2E5ycNesuAxv7ih0wWEFsyo9d90x1Qi7528mvmwqvz';
- b +=
- 'pNNdHuglKohG6rtjYal9u2L/O6LMvrryGgu06DI4UKFeIBzzJfZ+Ka2jNctk/qyS/rarOWSWqhV';
- b +=
- 'dPbgUPfDJly+BD697zYbo84gdqMx3A4YgM8vZp9fnpd+eV768zcZnKiZ0cHjRoqq+DVl6yqVtM4';
- b +=
- 'McJezEzlo3FcxodrbHPFJ9EIqnVcukbaPee2+fG6LBuwmGURPcyyfyMKZa+RZvc6qXYiSyDnfVr';
- b +=
- 's4K5GDEK92QUsih/hQ7cKERA7tvdoFCYmcxy7z+gp8CiI0wG+QxmIQJjTlvwKoASgccIElNgjuw';
- b +=
- 'gx+HiRHNa0zEglu19N6Fz2EuClyu8YYUrgNhzKHs6GoFfCUhIEXb8fk/HYVt2dwu0WoUxqdafCu';
- b +=
- 'mkbZ4V8FMKHZWbuP6peCIoKXfeukMPYEqpmHYk+clPkg9kQVmQ9iT9pnPoh9MB/Bvs8he9AaYt5';
- b +=
- 'ABw6oENgKvaPsACcCje5YHmEHl0GwjN7RLVA4YJYxb2gdOElKbJUrstZmxX6U0Y11dC1gTc164t';
- b +=
- 'fVxi5rqMd0u9lVPPhO8RCkzTXBIfS7sUb4GUhg1gT78VsTLoeuf2uCvfhtrQlmfRKHwooR6PwIz';
- b +=
- 'DKedfnsmFx4+ViDRi4fve5dPnZ69yyfI97xy+eod/zysXj/Pctnq/8fy+c/ls+/uuXztYrpUy/Q';
- b +=
- 'lKtHyM2WM+kczJp5RpNKHOj9CMHbJ1Ql6TrfUjGg+JSSkUYllowJVREJkieLwa3UlcuK0XJI0cB';
- b +=
- 'swZ04jS2fhcwzwYDVlc+qgFsJwU/FcvAqcR1bTiskpyWjmwdaGxmuqjwDhovVVrpcUAjnNnmqqr';
- b +=
- 'xWreC14B+sFDo8pUE7JP+VPRcmKZQlTFZrldePP33qHMc8ocMvawUYIct3rlcm5xJ6QPLkt5xSC';
- b +=
- 'B4i0lKRloqKUlHh2RYqA0Y8BEhMzHjar/Q3WiCjT9ispnNfA3ctpNMArOYG7mC7pgiKMOWDWTIY';
- b +=
- 'vCmfUpNV3rKMHOrw5a0Ik0TGf1ToqkZev7xV1SXUoPDI0Lcbgkf1bwvAnhgVNiWw0DZpn2UoULK';
- b +=
- 'udcM4ur5+uK3vQFA7aDzWDbfrpGPrwmdDZkF4ArzXpA0GJCfXD+V1Vd7RTCtwz3TVN5pVoSVzoU';
- b +=
- 'Wdy63BpbrcyrdCQl1uhfQ2cIuOx8EBgGlOwCkHsi6khfn0DwufZ+We8v1P3q+Od44RRa/J25S/Y';
- b +=
- 'dj9hvg6ASwehNHwG+4L+aXPgwWClrdbDW5TK2R997s3+vle98avV/1wslhkUnRQ5p6kk/EsWuGp';
- b +=
- 'XCPOyBaGl5OVD200elx2ki8bZS8pKqOpQsdGlkaIburcRz0KGRAo2kwuAJ0hn2gQS3dBXA25uUT';
- b +=
- '4lW95431x1ff92K/VvQZ5lsclL4okr0KldiZjJD9nYwmF+QFZSoyU3VTnd3Qs+YlpLgIXnyVPyP';
- b +=
- '7QHMD1AU8TCRJn63U/A1zrdR+um3rdwnVdr5u4bul1A9c1va7zpZ3US2Zkezvbb7ZC7cjZfp90Z';
- b +=
- 'OpoMCGH/NRMcClHc2pXALW0Dz5b2tjb2Bb6NTXzEeEzjt1y7+T6Vk2FfoPIljkIYxmZgBTAwQNd';
- b +=
- '7T6WMFXZJBuqpAZz02Zry0WWMtXclM+xiHugqCEP2uwVGiI9udvoR+LPEo6tn/qtCBbmYfJO221';
- b +=
- 'P50pkp8C8Zz199vse+u23AvsowApSk1yhFQApofSsjuCguimPmCH645/tL8UArpWd71gwgQFd14';
- b +=
- 'Ihw5QccczCoOyz13l94waM+hTDwXCHhYvZTHANE+P51PS9k+usDDMqBuA0sEf5ok1yFi00Pkt5u';
- b +=
- '1keMOGzm4AHyPt7P2G1t1un9d6tuFErxmxegYgdT7D2A8juB+UY9CB8mXty1kveFFKMMm/WaAB3';
- b +=
- 'HcEfyHxxG0Dj3bEZUi3GnOfsyIgUwWgpU8kaTiyYD7ACP8nl28DAK0sACxAi+vpytSaamj3mXd8';
- b +=
- '+A3d/Ty1DLshOG28PpcvpP3TLVde3XwBImPH26ZKVbr2jPYBCL28vwc+VaiFzBUizEfOS9iCtyt';
- b +=
- 'Q2Z4XaQqXtZYHuAMvwcc4Y8363Bba1KsxqLbR7Q1pbzw9XU0EkdFqO/cWU6QPyDFzj/95tr1Xgi';
- b +=
- 'VBEiKLQp6SUU1U6gM+ABUu7H8AfOHG4x6SdrAUao5HKTyinLMBOEKuJH8xLGwBzqM8KFdHymG1c';
- b +=
- 'NqmHQKmHSH4e8wsxbbBBgUZQPnDlSUEEpCDw1BF/nZ2ToB2K4iGLlyS2DSdLJRXRllXUDyyQUH4';
- b +=
- 'qKDqAc1hqGsj9a+Qb1LKgHWE20SQHS4AWOsNZYMkPORPbAzzmgu4xF5SPucAdczXYGlFaPnDX2D';
- b +=
- 'H/+rH0xvQFN7SXp4OUjSbyH9BYknXD6SAQHhYNZ/3kIvrlIB6mb/oiPZFPT2XbgAF89XKCcADTo';
- b +=
- 'a8H0yGStJzm/U7SSQHGMHbOhGIuGTKlzjzUCVCsptTXjrnxUZCZNoFxFACcJsZ78NmX4HiCHrPj';
- b +=
- 'QBwiYEfE6SIhQoaElCX+R9RB+YDQH+0WH7MiTaJBdB9NxiHgwdOyH6VLO0zp0m3mR//OnfqwYNz';
- b +=
- '69y4FK6z+TobDUwgUubW9uIVOsDrACUAEzcEOsbL9dDEYxsXjssLVcSrMlztCTL7pSjNIez/weD';
- b +=
- 'CQ4FOIhYDnIvtcJd/5d7B4YMukf+3FfMM/VEw0aa6lUKo6kYGaVDpAuLIgX8l5SQgtbB47QNfI6';
- b +=
- 'Wc25ge/fL/X+c/Go+7Px/aMHTgjlRURUweydTwOAgcUUv6MFKlifaikS6g0eT6Nr4V1SvU3AYlA';
- b +=
- 'yWoaumzZSoo78QnvNE9wB5d02UogWhT6RYgcJRzBV+WzPyxAbMK1J2xO27h6utA8FC1X78gMROD';
- b +=
- '5iy5rKUdjNiqkDaeL0LkNjlf5bfjOHOh4wm5qx40z9RJB41nGdIy+0fPH1eUWnRmbuv+RsxccXn';
- b +=
- 'dnwRFe6GbzxDd/pnFeoGkLDTWHmeoyjLM5fpzbgQXkoE1wnkxwqk49KDPdJFciK9WsrcgKNWvW0';
- b +=
- '7ztyKtq3pSveXcjr8/mGc07jLxhyeuf9zG/Efp9oKdnW9ZF0RkTZIocqcYxhb2B2u5UrIFMo5sN';
- b +=
- 'M5WqRl/K+rrZU0GHwYvwG3az5yRZ0wBgWX+pkga9ioTQ+riv8XUBR1y6D4tZ1NqEIY7Llv3BT+4';
- b +=
- 'J6Edvkl0B7TIjXADBNcQFTfk0R3ZezelLG/oa2ASF5dfMVSA7L14QIO6ybVG1Q+zdbotkyjW6Rd';
- b +=
- 'UyChxUS1sUaUMi+kLJBQx8+/X9tbSmOdJjzcG+tE8q9GHjZGhqJd8Q9k9spA6QexXU2336XDWt4';
- b +=
- 'qLqXoKd0paqQM6iTQHY6y782BEwMFLKFCHUNb4GAVv3U9c73Zqg+bWXMKHtPtME0+/MUTgD5JK4';
- b +=
- 'tIFes6oWCLrPRqYpO7X1iFX+DdfJ34UAL3M+sHZPiZQAWXl5i6A31O8QWYl22ZGiGkXQCQHKrQ5';
- b +=
- 'V0kZVIlXAcbcZqucS8iBhp63sM1RNUB9WqQHKGm2fSixZpXe1kzEEMq1hI5BsjzX5+QiOXpAn2D';
- b +=
- 'o2pwF22OTazVk/Fn0/Vns/9WnEgqBSwr6uim0EClBYMd2RBbLVGpzmrBIGcj73gQD7AA7gBpUm0';
- b +=
- 'AUKuRGnDQu9Q32cdKNKZSjeAkYVrW/7NGpWJQgEBnxQD12/vMbnpeyQYkDpT8txJNEvw9dnO163';
- b +=
- 'CrUKaVjZ+WgW03dJK9LeQsBB24AAw6ljnME+oMbhrLnhbMq9BhQ2IFCppR3By7sDWjnJgFpFbEV';
- b +=
- 'fWMOA1ooBrXBAsWOgyogCRQxoxQ6oHCzcTgI7oBFVWfO2P+l1eX/vTfWW9ITK3QE78DTGXs0UJv';
- b +=
- 'U7G340qRKIYMWCYoHU7xuJYvvPD+LYxAv8q+BPlV8LDGtAViyfCi/060T29MF7HjjkX+h7C986y';
- b +=
- 'FuVhW4d4K1ooVu7eCtc6Nach1skl4SEnqBNwnGF9rCQYSEzQZXdcWU+xTJ+o7vEc5xVBnBwjY1t';
- b +=
- 'k7fbFfk/Mnq6yuG5CboFLOj89h/dTzA2KZhVwYtXiGcitGdGsMEO7Seqlw1nVLUSbFOtPCjeDRt';
- b +=
- 'mElIc8Ebr6Q9hNgolUtS6ZBMMePJUOLL8kagd5WeqY0M7nz3anSM7S8XhThJeDDsBLLxGTxuFjP';
- b +=
- 'EmGiq2pTZz8pqOii2lcVV5AZGyHonWD7cdYhssHrTXEPIxmuePpTah0nEqVUGaRSr5o1pUpjHH2';
- b +=
- 'p9Q8ewjUb7PNRQWKJOkztJ1FFCBLfLzY946aorJB7V8FpiaimlSks98rDme7/vQi9fJ9YPvketo';
- b +=
- '3Qa5fPvTjfH88QZyv/KIXL5jaN0G5F87kb/9SB0yiXfdJtl9ktvCxnfVRD73yfqlKvXz81u/KeT';
- b +=
- 'GWfnT+Nnj57u+Lb/3B8mk3IXVVv6hb9XH80rRLAg2jly/cR3MNCTjR9+V4iP5J74nP+8w+VPfl9';
- b +=
- '+/MQmRRwHJ5iuaZIiZBms5sixC/KlQT46UC31YC/1Ekv2UfPRP5A9/RQcVsLnICjf15raYG8/Lb';
- b +=
- 'TrBSU9ug7nJvNw6cwfn5YLK8Tf8YW425WZc9v4Gdj9hfoGHJyTWj+Tbne15F9Juz3TyZyTN58AV';
- b +=
- 'BSv9SgE0EeR9nbN9lvTy+qhKY+WtSmr/n9p5zpd6PoVd+jV61JVTAaW4jccivzqJ3YZs4IhZ3o7';
- b +=
- 'zVe06aQhMqherZAF3sliWVuYPA/BJTusG5SpxLrtfWdAdqEWWUBnJb6vaxnI+llsSRocAt85Iwm';
- b +=
- 'Zvnmg3czVOgchKiMlGYQrRKBtJNMpGEo1e451mD5xvTa3Nqh0Cgwo1UyppT2hAQvLcbKjJVqXhG';
- b +=
- 'DfvYoIh04ZkUIXmQxnQYNCxx40KqVSWTm+yZy0bky9U0yycKKsJ4brKS6XffDaXr5ZqFbFWUStV';
- b +=
- 'Ad3TOIkoi38JAASs9zhfndZ6LbpYX0wI5prVImBfaLJ+QMgmbtxRKT5jYXGWoeK+wPM9dK/tO3M';
- b +=
- '5nDtWLYirioNALIzOqtqz2BqdzWskaLHqAo0kpL7ro6dojiiomo9iPlQuKWxs9KW91fFFaWUdCv';
- b +=
- 'TTsiilDRzNy/4x9OugQWacnwaNBS9Q94tY/SSq6sAQMRtsSsUydzXn0ME7dOOgz+ltzlyb0R41C';
- b +=
- 'VeKJtwBWRbMHsjCWG/uM2SG5CZ9NMjzQYSpd2fo/yh0mibB+tHTV99Kvj4WFkXfGmpZW9ORUG3G';
- b +=
- 'bU1qM29cTfskqUzgBdbDA3paWxMcRXDq+lrTnL0bWK+SKvlQlwT/SWdPW3FD32M0Ca4TEinftpG';
- b +=
- '8YMUl4WyCHthGgTFsMkkU+kgHsKitVA84PtOtR5myqv18M7UOceebBNSIi24o5yYDcoH6j2SG43';
- b +=
- '4B1hwNgW0b6zRGE073AnW+gT8Th1z9CIqCM3Qb+HhkKipwnykQiwY7yVvBO52nvzh4r6SU4BA3+';
- b +=
- 'Sy4K4thIY/AollNzeRjmsmfCuJMrWQmXyuZydeON5N/OY+YkZKRvFGk3vPN1QowFOWzKlLJn7GQ';
- b +=
- 'DQAZUgjlmFRWhRRg2UlZmSo1kw8KM3mFSowVqC2P85utRzxxhwszeaYQqwNm8sTKysLkplBB30p';
- b +=
- 'P32qfBnsOA3ka6v+RIg6X7OMN5JO/1+3Vy9HuK9ucMzL855urbIgPhY/rmsZLsWlfcWRv9rNgHC';
- b +=
- 'DPIDkvH1Zw2xt8ZY0UjvVV0ILjYsqnZTytLgvLeGs0+eyW8a+kSIENysN8183Ow11GNbTsKRUVl';
- b +=
- 'usyecpeAHrkOnW2xdxCLvhZIj0dvm62C7ll8rM6K70u6pbJV3TTMdLLi3RqVnqDCr01Q56s8e9n';
- b +=
- 'Kh+cfn6n8tPTP89UvuFP/91P5Zm3nfpU3vPGE0zlh9/4/E3lmX/jU1nn8e13zNJz6fmax3ff8fP';
- b +=
- 'M4z13/Lufx/vf+6zzWCetncrvfv5m7E8iP5pESaGM5SccR/uD/FUTmddpm66tjLBaVIwElC2xl9';
- b +=
- 'KAThtDFYBhPHrDA2BTLB4i3ADyAJKaI5KfWgxy3rh2AvIAMhgbcGV4F7Sy0HZbGs4QL5RWmAkNu';
- b +=
- 'vCMrRvoiMWLIDdM2VKTbKGHhdC0rlKY5ulbi5b1NKZfDRnmt6V4jDI2gygxcjN5A/gOP59+zQMe';
- b +=
- '/9DbajxTjahUu//VzMu80LIZHWW+4swDL6cPHjuTk+7YmeuH2QD2CruBlz8tV/yDTUnWgTbctcp';
- b +=
- '1IKXFG7pAezVm566xW7VZWbBe+BQ7XlRmqXuKq10m98p1krlPWkxXHKPeZRENsMg+ypS5jMjz3f';
- b +=
- 'b/DP3Dcr28pe3KJ9FImIjJ18rnpDJMrcn8kG2TTC542mzamHnk3Q/xK6XBBs4a7hXyrkbb090zV';
- b +=
- 'pkSIGqM/sggxDKgR4sB5SAdOdGAlj7zmyO/AW5stdNxrOiwBsz0Ue8smLfAioWmUSNwl4BZhzWU';
- b +=
- '4k/T2Z0RQjNr6IRVvxPvYkX9jLm0go2Qk3tO1QrTSqjgFXU/gOZP/VywywaAcFEzN1yvsBwoBHY';
- b +=
- 'jbFyz8IuBcWrhyYUVjyUJ9apsYZdazSi2D9sg7AoRlAmuIRd12xHrZt/bHL+nOX65OQFNGCC6hy';
- b +=
- 'sNLQSW84xZrjKls5gY0jsjzh1Ho+Hk1mJWNdTqvwjnMqNRcjbC9w12MflNPsBNWvTPkmfBp9Pso';
- b +=
- 'Qp5RYAIM003FN0ae6oLbXXVbnVVW12I6uoNrWcI6jZ8WHDbHDB8s2zBEYd9pg9sJTviTeJSZZEN';
- b +=
- '3MQNjBI0jBxpjZiV6YSUm6VxvJjRJ1RiSjGAbMyHIuNP+pt1ZpqFrRsX0F5AJoeOD/gmCKNKNa7';
- b +=
- 'VG81WX38yAANQ3JZzP+aZMObrqWnQY5PPved+DyNq8k/I71k8NUc6GBRD2oAfkGr35NsBzRtTb2';
- b +=
- 'UQA7xygdqeKWp78BRqS065todOoTbsMy8OYmoRj6vq1jtcVZ/E4sUh8GvBSFHPUFF3XKqxr6HbZ';
- b +=
- 'KhhLo6rdFdR6adOoX0t7a0J18yrzdfa9hW1hc9eWRP00H55Iq8nBwLYVfr540WyjuRhJJtI1pA8';
- b +=
- 'egdNDiQZI3njTknGSFaRfCOSAZIUqf3pTtoxSDJC8s93uqqoOngnkv1IkiybQbKFJEW99+10LyK';
- b +=
- 'AGie9jUgimQ2KuGSm/zR0+AfThaJ5pIAASIuroTIWQKJb8XnYYFZ5a7PI0tDeL5qGJq5q2fMflO';
- b +=
- 'Vvq98/TD24EecPPbibjCBd/z11/QcB7XUJaCzTttdDQEclAvoC9drHT37gQeeY/hAI18Lx/yEcb';
- b +=
- 'ExbDIew7Pi/1S9VcdhW4ZVpaFB1e7zj3P5/nf1a3UEosACharSjiWSstT4uAaPLSB8Kf/9Xqrv/';
- b +=
- '1ZnXSz9L3h9IOSWfJfFyIZ85IFeRevZ6qOfgVKnnK+jwy7ZAoPHp3QtQz7AQb3sFF6g++fmBj7u';
- b +=
- 'xnLYE8N7Qj61OuIp9VmnPEBL01NOtm4p8FVsvaxSne6CUbkyDlObVOEOrOfD2glLoxrN9PYiMr5';
- b +=
- 'blqNvhebjzUFgIEkCHn7jfoywBb4phirEWqpdZ7zJ3jF+MI1cLkoPk8zxBZPdQFwu8gdamanrQL';
- b +=
- 'SFUG40zz/ZNG6cXZyE9H2I2dnJ+kylyR03UsspjQqcdomohzMEoTn/KWzfcjmTtIwaYZNSFXM5N';
- b +=
- 'jsE9qLdYQdhp6FetrFMgSMbcoy1ZlN/5ZBH4jQxoh0ocWURK+atLq1pocf+rv0JaUb96PF+9Qdr';
- b +=
- 'fsL61sCcZt6ZoAY2zswqK1vP6K7Uk1bI437sPy0MHvVfQ6x/vvgT7uVRysfWb1vb0DKGMC3a6UO';
- b +=
- '3TNMxezqZTdXV0xAxNhtzJQocjl3TaLZ1cja7BgbpiaDxPeevr7r2nfhmtPB73rpbueS+VRAN6Q';
- b +=
- 'nBEXzNpA7MM4IYw1K2BgG2pTVqDL5axTL5poMWQ4oy6FOekU+M0Xhkka3B0yASVrx4jqANCriH2';
- b +=
- 'gdDCsJC1zdG89mmEVGsvkTZPVcezQenEUjRLWcF0KQbhca/dz6Huh61+f7oEy61fsjttScBw1Xe';
- b +=
- 'Gq6eNBdizT8NRhiiH6g1SXwEDDaGbAh2aVnlopLqskS4Zl/peIZ3mQJEHqOU/3fExDlQt/4oMlK';
- b +=
- '8D1dKB8jFQLQyU4UAFGCEoPGq0MZk/UL4OVF2OXwD9oUw9rYMEMYPFZpADxL5oC8xIBjvZABbWA';
- b +=
- 'F80flm4Vgv3SY/60KOW9lD9WwjyIVNF1m8e4hmyOhtBmWODvAyB6GS3Wg+v+WPSt3W0b5C+EVAg';
- b +=
- 'UHgLaduQQmn4IAKw0KQEKO0IVcrADuJmrJgiEcRNH/QJmyCNl5+YtSRKH6OiAUZllJ8meEsAuL2';
- b +=
- 'q3WTIRJ1ZTTUDp19PHyAW+xC+7I5AOshpnlbTAaFextKbQMBIgkRJqKpOH0AYKgXByOEwW1LYQo';
- b +=
- 'HckbaDUTHdcW0qkkHErsNmJ+RUQgolYemfNbkoOed1saWDeFsT3a5Z0+SmfD81Ta5r4wdx7Br8N';
- b +=
- 'Ns+8JVkVS5b4ekXW7QCIYjIRi7SkLzL4D3ebqWLyDxhuNiPsL0YRnCyGBJ+1MW5uZyffdY4RwdH';
- b +=
- 'mgBS013F7splpJ18x9/MetbOrpgm/HTt2vF7xGJM/Vg3wMX5Ew+9NcDUXyyvLaY+94hYpz73iIB';
- b +=
- 'TvwZDNbghLF5gj4jd1I8w9Rs69SMEysDUpzvcYs6irI5vWCf32p3oAys8fvB2VXvQzzHxafydBT';
- b +=
- 'rR8WDWpxOdOCmliQ4Qnatpg/ak9Gid8ESc632Y6/3FXO/PY8z1fplyUhxzvR+16lzvJ61FXDCd6';
- b +=
- '/0qpuzXud5v5zoHrq42e3VYmrm5zoCtHKGqGqD163TBmsYfzvUBneuyUyyWMfel5YzWWGUz7Kig';
- b +=
- 'bSoArMIXU++DDJmlWeWsofQuMjY4Y5Wf1JYjBeeKLmtoeEbMwgS9a9gpnch30Slt1yNrld/F3CU';
- b +=
- 'AZ3ZBp326/MwZbL4JHeradVyEmQ+oGSq+GZZaPuw6YAAhCnCxxaV2SsGa0Mc6tJtwH07Vqi4Mhn';
- b +=
- 'sB3m1bvSmzhvO5VKKtz9oS9aXBuBR9RVpZ31LLVh0gO95NPVJBIyWPBbQu4RB13Q/s0pa3X0qXG';
- b +=
- '9n3kW9j6MK3qOaE6lvf5ZYSrT90WWgEzHYfd5M+jecL49Y+Lj5jgef2h5189vZZAKBlZ2Bt1mVn';
- b +=
- '6OS7bNYLNGuvZM3YrOWatdMmh9cEs3DBPRp2UlsBcOnsg4fkUh9IpeBcSJPMGs0qibjBMKLUSOP';
- b +=
- '4mQs7ycdQ2Q46qTSSj+KYmaKavA7duhzpv0m6BR0xyV/B9Bh2wv83gBpdp6z1SB8HtA80SqN4Cw';
- b +=
- 'If9SVv8fVl6UByu6vZyGXDfl2DL4vgq/go4zJvMfANHq58N1/TUqKxDp32CppytfLrYmt4mCC8p';
- b +=
- 'dzfb2Q67jed5OHA+gdJocq8Qv1aRv72d5K5IE1WyXPwuFnlPQqL3lZOBqsFyyHSXKen/St9b43v';
- b +=
- 'pafDOXhAFu1Qp8hJYBqAhV/kxBhN7BQ2J8FTfbBU4nacQFgjn6VIjqCGAZdMT+dVoq1sR9DnRF0';
- b +=
- 'r6DnwWO2hwpBU2b8hycetxxTrjcwfyU7k793t+A5O8aF8a4BeDCV/G/BBNHdglbfDINb7tVrhgB';
- b +=
- '33MT8a8xrEshb2ZGhlcNUVPNNrMjaUG+nxP0RAQH1EqFKM35A0G6971uFNOOUCDHNhFK7LheJMn';
- b +=
- 'MRCJacJyEkAOkDxULPIZ1V6VBcJaUlfkUhLluV1TDDYKmO+VXnaj1vkBKAH3fm3LpDsYkndihT5';
- b +=
- 'gsQJIRNGGEq57SZPBOSIpCMXAnc6kQMaHV3kiAPGpJLRWrbK20nyFkJGOeL5B7hv5V7mngLj8JD';
- b +=
- 'wG9h5l2FPUBpiF0ZuED0ezPeYzkpjN4TBdHCluddgO0iEwk2w7OXJ02TZy9e3lG8z2cODaBCLT0';
- b +=
- '7BQbCh4Qb5nZ3XiHQpaKVzPK89LLVRnGBvoMZAKR6tTaaglz/zgBuvQSHVOzyHhdzf548Fvwu7L';
- b +=
- 'qlkJ58njEA+JQs+tjHd1jBMWIwIdWuCowHxrVUIFYPIHAGa+NtnPfgtxrnQzzcT3zjfCg/Bs3h5';
- b +=
- 'FJiD55utKtGRjBWyp4OqfihIPfacn4fkU4ukX4nEoa9hBleNWvJ4YBmPlgUzUUoaTiOyyb0GROf';
- b +=
- 'NcAXA5u87egvorckTfpfLXuXF+MbyW+NvHp1vNjKw+NNeJ/mOoWE6p3yFJz+jNqN4XQiSTMEWf+';
- b +=
- 'ypk3f9WR6tNCxQeG0FkJCbaMuHuoqy2iqvKZXSBRtmcIQogwAgAAsDk7T5FQYNVpMFyQ9MWpE5i';
- b +=
- 'yp4YOd0zPA3KF28DC6IWPKeBqxHZTphYVdrnkMt/glr8Z9DLeZEtaAOgidDItFMm6u8IbpJjnpD';
- b +=
- 'aaCxoQMZtK8EOsjcXjGgIEeqOqDbugNaLQ0obOxIPBYjWtURjXREo2JEq+yFTLCv+tw1q7Yf0fx';
- b +=
- '+RKUxpalf75g+h3r8E9bjP6d6zInqQS02xPIqbyMn6yKYn8jDjztvHx3sDoY6ZPhMLBSU3++3+E';
- b +=
- 'V13j/q6zoJMNkr0F4k3wW/TMCFVd4X/Pwn1OTyK6nlvrzLvib3VLBTdw/rWmEFDdvlkGaPcgKCz';
- b +=
- 'tb5js/CvFeV8ozNO+CXMqmzGTr5OkSROb/jGKa0b5V3MzvVl/8KzvJKeViSvzFZQFmBDw8om23J';
- b +=
- 'mWbyeQqwW2B0p9mOVtGO4qTUd2JnkuK4IJSM5a4A07LPdyEAHpY6uKsKd7Yk+b5PbPY2f5qZyb9';
- b +=
- 'x26xnFfImb3Xyo+W0PPK9bpobbXJDQM1+voTqZiwQo664qgvldovgCJ8C5Igcs6ZjLbPjtA6bbf';
- b +=
- '8hX5slNL787veFzIsx5LI1Y+cG6ZF/Vsckzn9I+a5Ljpg0W0po/UscC1hZ4WkYjSYR+QkSGSk3u';
- b +=
- 'Iin0NJ0KbiEfuUGQxX+CTcoBBkDng9nBP0Unqo/f/2999TXtWsUH10ND+w0wkdcVLCCi1TssUjm';
- b +=
- '+eMq9lhEGSdZwUXk/6XSRZYVXARWMMJPzFqUFeznjEr7GcQceMGOFeT+1I8v3kQ26AeyWRXQbxX';
- b +=
- 'LClbsJwZwwNIGBYL6MZeraAzjF58tg3whVQKt82l33zjfAzPYd74XEN8RK96a/fd3dJiLQWbdGL';
- b +=
- 'KlkNqZvDlOZ1soEkG2+lb1zuOUkmJ5KygguT0dEg+skDwiqPqpSx537rpvUCWP5/6iBY9TVvAIg';
- b +=
- '5f5gkfJKwsegYOtgsdze+SO5y4odjz3+ZU6njtf6Ljt6HcHVeh4zr+szPHcX7TI8c+lZypyPOfZ';
- b +=
- 'JI7n/NsVOJ5Tljee2yNuPEeljediDzvn+ZU1zphnkTVu908oazwSHCdrnPGfq6xx+q9noVH9WWS';
- b +=
- 'Nr//SoUhljTP+v21Zo7Sf5OLN0qNTkDVK8X+1skZp24Kyxhl8YljzPbuskUWfi6yRNoLSpHN6RI';
- b +=
- '3g1n5mUSO7cTJR44x/yqLGGb8katTxObGokSP0HESNO6Iicv0Ot5KsqBGrYiFRI/AyKWrUZSc5u';
- b +=
- '8xxokbIHuaJGneak4kad0BcB1mZk1WaQtS415RFjbNmYVEj/HVw6swaK2qEs08hapwzKmokCIAV';
- b +=
- 'NaIjJnmvEzX+N4oabacKUSMGtCRqxFtKokZ5mRM1quBSRY0zfo+oUba1+aJG+5pC1LgjOrGoca8';
- b +=
- 'v03Gv/+yiRilTFjXu9VUW9nH/X5Woca+vvPCc6YoaVy8saVwtN46XM64+Xsy411cx4/shZlxtpY';
- b +=
- 'zTfo+UUYf8OCnj6hNIGS9wE7wQMs4ZK2Q8+cBSS2GFjKyhWCgUMp7z88gYiyVnZYwzvsoYz/nZR';
- b +=
- 'IyyxI8XMR4JekSMO/1CxLjdny9i3OF3evq4oIhxxljSYaffFTHe7c8TMd7pP5uI8QErYpw1vSLG';
- b +=
- 'mXmNWEDEaG+URYwPLChiZEQKFTG+sith3O53JYzTpqN0flnC+Ko1wVbzrALGWxk+Lt9uCgHjVkM';
- b +=
- 'B43bzvAgYwWC0rIXZ8QLGA54KGKeem4DxJZRO7PlZBIwnfZQCxrWdf0n54jnPh3jxnOdDunjOqQ';
- b +=
- 'gX146fkmxxj5Utylj+QkSLj59IlHfOc5IsPms1pyZYfNZqTipXxJBivr6kR6x47kJSxaNeV6r4q';
- b +=
- 'rJQ8f8rZIovWUCm+L8XFimeO0+i+BIrUdzzXCSKL11Aorh5AYHiydYd8VB7BYq/N1+eeO6C4sRz';
- b +=
- 'TyhNvOpUhYnT84SJr3SyxI3nG+6fz4MoUbbUUxYlfss7gSjxajZKBYmvUjni5rIY8YVWivhxShF';
- b +=
- 'f+C8jRHzvrvsGVYh47rPJEM/91ydCPNdJEK9+TgJEGWE3vs9ZfniuEx/uAAXS+DMLSTC7tAxJ8I';
- b +=
- '8Wxx/u/BaEQMEHQr0FuIHYosvVLNpcQ28BbAC8ElHMFF2gSlBeJgEn0AQPaushgICFgQsscJxwc';
- b +=
- 'IRCI0ZAFYeAfbaCdoTCvTA5W1Xcgop9b6xYBLF9b00L26rgiR8SmkCfratjvq1KAQXkvlYFBAFi';
- b +=
- 'ydv3NtlJi14HjLSM0dHss31alU1O9eNunO//qlDjOoz9GKtIMe/k8QQtQZK17RhA+Vqp/NQiDHu';
- b +=
- 'l+AqLOgTf4Mh7iLNlm7HYISZo9we1CzGLWdQAO6xTS3BPWDNb4xK0ONaBs5EJi9YtxaT4UujXrF';
- b +=
- '10aDdFF4tMYUNCEtjNbpid6HxnKx1nRpG6ffrxKao3pyF9q4gyUlOAjjpSy/N4QvbTOsI9InpY0';
- b +=
- '9joTIAdkd79vsznoAjYFPQGbIJlMwL3EK8kX82AaAQzIQIxBHwHPn4/RRxVeCoKVwXvofXD8EMC';
- b +=
- 'qJwi1DWvhnSl68xVNtwmYKS8T6GzaFqt8nMDpBvZl7pm0ZGaRYOChmy0rii3OcgI2EQjvDjsx9t';
- b +=
- 'GwyjhUwAHhECfxINKqwrsD87YtoVx2oDLWQChBIxBYN0A/E025BPjcDVcECgHhGLDbjHKEtHnLq';
- b +=
- 'ZTIzcnB1hSDC7HO0x+X102KrikvbZh2C3CNTLsln3HvGr4AmnSugbej9jbwHeRQz3heLR5xqvcp';
- b +=
- 'fHprtm9SibpjhM5tGi4AQevyOpwmyj5N0G6xIt6HkBjMXlNajoISValP+f6FiFBdaYH9K72EX8q';
- b +=
- '37lLUb+Sjxgazlc2ypSfl53v/ND9Xv6+DxGxFu4vtkIbTyu8jHD5oYYO0NeEJ3kNY0htBP7Sxg1';
- b +=
- '5fdOC98ON+ZH52flvyA9ejwL3fsgBm/U2pkJEYkDMFwVwRmCLXtdSz+LD3TuS2r6rnLqz595DRQ';
- b +=
- 'q9AZQb+0iah1dV7W3MoAVyf35X4PgQb8Q2faLOQmxf2wAwq+Pv1AB1bjbOGwW6ciAWmvWA9iCeD';
- b +=
- 'NcY69UcdWNDKPx/45sNE6sObCp02hCLJWws/UXXgPUaPzGfu0gxK2H0C4HfdGA3OvWzyiqd5NZQ';
- b +=
- 'Vt56laOeT9WDUb1Dl6i8oJO8DlvMiHDau2ddoFVK4LeW00OdfKqUhqB+NWjpWZuXcGXkez4y6+U';
- b +=
- 'DybRfeNvDo9tBFUg+iKZxIvMK7WSafqRUK7Z9PG8jr4b50z7RBsJ8m9ELBL5pg/o9pN8Uu7P05m';
- b +=
- '6eF3dlLXhPNeE41Ze26DjV6jpOtbqOU60ex6lmyXGqWXKcahaOU33OcWqXIfwlhCY15z+FgbsbP';
- b +=
- 'P9DRpnuGtxfAFifP32fQmmEGjw1pHOqDZ5a6Qme6iLDRAT/ch5UNA7I8cZdDHx6w4edh/1DQkrV';
- b +=
- 'rA8VUzh64UMVEhSpAgiCEOZ5pae32aflbXSfog/XIXBKe0zZf4onzr2m27FdbPrdpq1525A3a/R';
- b +=
- 'VWjtnm7pRSckjJiPzcthkUOQSyDy+HAiEknnQWGRVgtnvNxljJIyYOZPVr1atVuXitKG+VCGIQi';
- b +=
- '+rwZeq1vWlqhW+VDXrS7UPm0pdmyRH2KFZ7aoFeGDAmBglON0Q6g1zK0+1N3mab7vXjewh9ulmA';
- b +=
- '7iBrKnzfo55N2heS/P2M+8Zn3l9zJP56T3tZ/2M8lu1vklp/xoPyGgIyL2GzkoDnbSlV6cLD8qr';
- b +=
- 'NDzbm/Iv9NqS+ULU+2rf8iwN/JOMaYrtIhgCyiGKcCey+s/s5NEm2WGwsQlnhzW9wZLTckKPerg';
- b +=
- 'zIlMj+Yy0h6gUMFz0km1+HqujETePkY7FeMXq3AZFeqwBfWMN6EvlqZwCgf0CmzZc6O80tm7dfO';
- b +=
- 'ToMPro0Z2y+H1cRyq/Msm7AUcVJLcaRullpGDc94kcYfn67YrynPx3xLXzbZuxLlKt9odFtadaI';
- b +=
- '6KRa323MrZwkK+wd/YHjKjHT6eqon3M2VnK2cucHd0c2bm97f4aM8uYnkIHMTg2Qk78v0q1/ZHi';
- b +=
- 'vf9BM9IIuXbHNo3S3q1XEEJP0eThz0O/MalkKCPjem1FLADscEA3M6teQqTOQE9uoJYWCv8QYTx';
- b +=
- 'jjTujQT49RirCSTNO1/3cs/j/EWZUXgfihGeDaxLfkyzsOFSRpFgRPZZOa5DhHf+wBicuHkYxBt';
- b +=
- 'WUGQPFFOGDESIpq1rP+1r+um0793nXMP7juCzYyWsm6LkuJXruVHFnQz4lqVdNEPk1hmcooCB4c';
- b +=
- 'lZcswL3Dm0S4fIDCxyIlnlFy2jNEBJPQ+OHyn57ORHxfH34UiJLRAgEi0CghJ4l4kND3QGNNCDO';
- b +=
- 'AkTKQZwneUbe1sjnDt5v1bZKuoPmiDsad3OcyAA1hhyKLw0npVVVWZzj2tgorVHdEABwGbdcJRc';
- b +=
- 'zhoGPaEStxj+FJiyH9qImhLALioBQofxDrtYpE9PUOEJg461jrqz8UY8BXUmQB6u8hOLbwU7yY9';
- b +=
- '9CSq7yBrJQ5bphvkp/nkD0GYLXfsvTnKch8GXOF22OEwGv1tBa9ctbMRuYERcieUfIsGxjwe8AQ';
- b +=
- 'poM2U0GXtsBgDQTjSGF3C/4DB+RN+bnAmwY8jWwSPf+7Sxcuff7Gd3JPRv8KvOSI+DyqnjWcw9W';
- b +=
- 'Sg9+ZP6DlZ4Hp8yFfunJqPTk/XgyLD0Z9Tzp9TwYugfdAHjlAfC7AxDYgtwkYo1d5mkcpD+B9iv';
- b +=
- 'MDSXsK2X1o48RRyWtriFGR3dwgoZ6Ynv2aojhbjC4bCzLJt8xjeTDMqGL0FZe473VoDLpb+asOq';
- b +=
- 'LRbcoKueto2EFMmOv8pNLWwGXJl50WzlBnn1dJyOay21vElaQK05xLEK0kGAbVfSmVz5Hl7HqnM';
- b +=
- 'J9J6FGeUPMfvDgY+rUgJta7d+lda2y0v3adlBQEKi8OYhSoIjye53ojdGB8B7R/Mh1fHCTtWh5w';
- b +=
- '94lUvhUlRqW5XCsMGYwdNpqngKxIwc8akr9dHWTytULviJg9OTi5V0G3z7g/Yb6W0EIVFRKEK80';
- b +=
- 'Fa4KhPJK3Y7uQJ5YrRbbHamO6GN2M48T+/8pwFtnwIJqRSUbLZ8hwedn5xn7QEChTHzaUMJbDyF';
- b +=
- 'UYRm6Nsu8BjJW8ZKWivdDT5mSPyO0vBw6m1kwyuhCCReHFurrPUpXjapnv3NBCeOjbatjjl6wJR';
- b +=
- 'vKKlUYDDD3cwCfSDqG0DnhWSRbmxAgTuulBKMmuQKXA6AqBefBHpCQPKcQVqVavk3zFzwcaVFZo';
- b +=
- 'e4Chbj8A4rirHABHB0B0Knd9pF1joKJfC16ulV6J0NCj3u8gYtGod4XCjngrCBllAXNUYjzYGTP';
- b +=
- 'KhJ3VyYc1jyA8Xv70J2a5Pr18ORR7njYNEklFCtBFBiQY/br+CsXGz1THJ31Qky342idCciafI3';
- b +=
- 'ox1yChItKYwzzSkTsNim0wjEyEahjd+GoA9GAFlZmqr6NSVui8qBT+JORzEK8QYDwFhMA46fOo0';
- b +=
- '03je6xcR6DeKuOn4WAONRyAguRwcmhRozVoMKB8UjFgfERngnw0vVxnLARCUKusH5bXAKShoS1i';
- b +=
- 'TL+U+kWOtuQQnopB2RGIJMCJ7AJNcw0BYEFetQlgthATvGi9PkxQfX4po7gSiFTQg4zfi5MfllP';
- b +=
- '51+UqP0MzPq4u+b2hZAzRLbLqZTwQpXsamQBDBiKGEiYzjkEyuqKEf9jIqAMgUDdtsCsNQ1+1wq';
- b +=
- 'h1lkRhRINMgcXkIRtqyA1GPlluyfvqZome8XP3GLXS8Vd5sz7iayWHA34Q4d/Gvvv3R9/+5oeP/';
- b +=
- 'DmNGhjfZOybf/69d77udZ9//R9q1lHh3j700R98/PBNj9z+Q0/zjoCje+TPHvvLN3zj8zdOap5w';
- b +=
- 'NmMHHvjM/nd95abPDWmWMDZjX5p704/vetNH5u6yxYSxGfvaB69/+sn3H9ttaxOmauxdD9772sf';
- b +=
- '++utPVTVrr2Q99qYPHnnzfd/853+wT85K3hc++t59n7jrnd+zbduFrF1f+M73H/jwhx/V2rBEp2';
- b +=
- 'U2jH1i+7tffeNj99/zkOTPCBU/9r0vXv8Xb9n9uo8PrAlA1Y997HWfn/72O//hi2O0HzJjTz5x4';
- b +=
- '/v2PnrXG4bXBNuRvvHIW7e98YHH9l+4JphG+oHdH3ziix94/773TVJfLwUO3/KdR9945OF3S8YU';
- b +=
- 'Mh754f1vu/1vD85Ga4Kj8tnHvnH45gfef/ibH/i2NOEIMp760nc/85kPvOcT2ycZndWMTT34V9/';
- b +=
- '57A9uf/idkwzTasbeduc/3Xfo4E9/9IFJxms1Y9Pb9m3b8fRf/vB/MW4rYwJVyIns8ztpf/IQ+N';
- b +=
- '3Zt8t1JTlmHPhyPvVWBvqUT4CgxcKL0hEUoCcMaUMgaUz7XVHHFsIjMN9aYqvWWrsRT44EHdWX7';
- b +=
- 'fVtzi7cJ8jaRfatk/LOsampV8ueumPqKexcF03chRhi7dNkZSQWsOK0O9qJiob3gStL3o3TLUlP';
- b +=
- 'u6LlWePsJomHqUVO01JR/UnyLmO1LQOSBf1JQ3UvemPWVx2J1a9AobK0G/6lq1AoqTaAyKyV1lT';
- b +=
- '3MACdQYSwOlbrIC9pkRn8RwfyXKcqRVULIYyY6loFdDLVtM8GsaFOZpELZaM6mcXpIlUtwKC3oo';
- b +=
- 'GIbEVVPOui7FBFMyjPup7UYBy1SPUQ0NS8C/xpmC5GafSogQvV+DCnphFxbO9itv8ehOaJpXXs4';
- b +=
- 'FIdhRBcgn1nA10LncIJqp1YmrnYdryJntqgQ620rvWAFtKhbyn49YCtqw8P2+8FRU+d+iY+MZgO';
- b +=
- '2hHp12fqyG+68EGq6EEzvhAwDhHiYVAn1qQCpvQ9pxZRh5gfCqBr32+khKrqCC1eTHGZZDLFZKd';
- b +=
- 'ckm/lFE/7Rz25wry/h+XnAtXirO04kzLinDkxe6L0nIFqmbRxpOZkoJhlwfhq0g5EIJ9wQFBxnk';
- b +=
- 'eAJoJ8m/yZe2VT/h3JWU5K8Cz8WZ3/RHOj5PMKkcTfEbMCsg5qK6AIjR0zbqUp8v0h4QYiUupfz';
- b +=
- 'kirhlegdwJeYUxjRicj01ahlYNKqAO1zItUZJ0/8yENbJA3N+IL9WQt2rghTzYlT0CkU2RWNoJQ';
- b +=
- 'KtJtnH6/QSMb4KBvyGM8AHb9N9SaJwE4TGMDM60kUiPhWGm1UI1JIa0OHAiex5HSYYHJBaLnYUu';
- b +=
- '7r3si+zTLKmUYuoKWMjAW+YzLOGJUebsj7kYFA5J8cqGCyAcOx9wqbx2iuiF8fMQpyKTuMbFDmk';
- b +=
- '8uwM7oq3HJhTagVqX7tIKoWwB2Q/D2SreyHbT0q7jkPos+H7HWKW41xtUEtHkGK+RNBZvvNtLCy';
- b +=
- '9vkrArGZA0x7paizSNK1gU25liVK1dfGqmGJtaXWjh5IK8XkO4MICZferXd96eriOGw2gbIquQ7';
- b +=
- 'v7Tbk+7vDZM5oyHEZE0dDIXIVPasyuDhMfECpSGRUmcYV/nWjCtjkREv1yjEJG6t/OXF432BL6U';
- b +=
- 'gKoqpbmOEz0G16UGgMbVU6tr0yG+rhVkbnU9FaBVCie/STwUGPQ2N2lAYdNDyRp7ps/IGWTf1y6';
- b +=
- 'nNaPU8v9BjPsAsa/hBAIlKWlvHMBuQxjfUIDuta4QfxtJ2b6hB4+m7WNCBtF3t5ihSy8/8X8qTX';
- b +=
- 'JOSunsptH6/dc2wZT0780rIzZey2DXDjeRuxqzQgA/gIQfl9kNv/cAT3qVpLa9eBpCwB5H8rQk1';
- b +=
- 'fqpfDTN4cLWNrpLRg0U6DsArhtVeM7EyIQv3iKCDaWXdsEYea7ZjDeeeVi5VgXqpp66fL/HsP3c';
- b +=
- 'xlZphYbtzChl8rucMliZqdh7lfZad0hDXtHCy9qCR83bRiLo/DGBcyhDzxrEvwMTtweFV+NTUBq';
- b +=
- 'EIMMgnxeH1j8Ph9Rj3RXF4fctAewUQ76lC8QZlKF5PfZD8MtiqZR/nQ/H686F4u80pHtPYiGSiZ';
- b +=
- 'FG8wWfYjRPiyPrEkfW7OLL+8TiyvmIOx4oc21S2q2mtoBwwr3ccMK/fydwqcW2c36F5wLwOk9Y7';
- b +=
- 'DpN2gbqK/jY+Y1Q3vq/qfBAOMe6hD6pD2IwndntqCmKcXY7e0CCMRs1usA1+2O3r2Pbej1He/pX';
- b +=
- 'dXvI2HD+7ntyN7/yNINmG5PZDcuMv8FhgabD8KLK0JiUSXejIMN//lN5yUSONFkBL/iIogkZau5';
- b +=
- 'xIduuNDIkRwCZ/R5QFyV0otTNCe1GOGWjxRvBulaLBfvIoToJHg2vA2Pls3RcIBS63tgXWyKUI8';
- b +=
- 'khDFvaxG/RwH7ARGk8bP+yBUJWXxi+jpUW8JY1fTkEthMqVLVfi75h/o2TL3/8+oQ4t8ctaFLpK';
- b +=
- 'T9e1aB4Aq6R4S1bZklZe1qrYG1Shp367YeMI1y6h6yCdWuD2IAcdDj9sJL9GX8V6ygSMK8EO1Ma';
- b +=
- 'JU8cgeTTpZ0ggcDcwKZ7Mz0mDizUU1zmj2IwgdLhEM1g6sKXz1UpL7AZbsPu3aT6woRWq/RidhR';
- b +=
- 'hGzkJhFxf4KgceK4LqwQKhSBk0y1OLgSJTJuKFfqxBUZ2YqKiw8ZrAP81FLA04kWVitBs6bRjQc';
- b +=
- 'AchtzhJ2306n9v9aqgWbIQpEA7odqJkentA+ZT2IqXi24uVF2oPKjsjDB55n/ZSZZnapyn70x5S';
- b +=
- '3qp9ukaUjNRgvG6V7BFjJq0i4cwTPF7lXbUBEy60jBDN20IbWxPztZ4f+omsgDthH3bM8TEEhpd';
- b +=
- '5K1N5CE4Oerk0PU04J14qJxKnS+D7iIzFwjI09XJAmKCGXiKuuOVNE9ro2dipNdcGawNAb74IWk';
- b +=
- 'afk0WRsbsttZE8G40njR/J5M8/eexPcsrg8mT9cOaNp/564kEniO3XkT0Vv+uGs7ADAfaoxsKlS';
- b +=
- 'pP6EI11rQeB37YmULC1UKpHHpcp0oFodnwCejFDOa0s4nG8j1ilkjlOw9uAsaegNKBN4sSG3Nhd';
- b +=
- 'kM5JlOrrvogNLSKesy1kj5eeQuBXXmHpFk/PQnfOMmp6w52fPg9OjyeINZpYbwM9+T3NCNWiLwS';
- b +=
- 'caWDzaCtgym8Nk1c0FAIaouHGfqPc1lR/OUIviHHuzwrz4yLfcmOOnBGhsRGabBRa3VgrqTOwjO';
- b +=
- 'x2r4GZuts9xP/ObNARwIE7HEDy1pxZosbKrZMm/0cXIDcsvT5WAj7oBpxVg4d7Ag03y8I1+2wdh';
- b +=
- 'avKvWowYKW09b1NR2pro5saKti33W6VQtUaMNRwQ3NBaeVgOigHU4SD6SvopfDYsEa0R+KcPRJ9';
- b +=
- 'uU+EZ4vGBGvMUe8qaf33gjaW6yGOtZ9vfZdsVZ/wVR6U2dPN0C8qctaehnr4CqP7UgxBUV5yC+4';
- b +=
- 'citBaxx/sx5Dnu1DnFxgqOPmUNuNIoAdjEehYWrMv1OYEKo+EEEYf1QGuogVxvv0vtYH49BVtjS';
- b +=
- '97z6i3vUKzKVTyZkj2bU85ZmS2IMuR8/RQoOcpTtt3wYPKR6NQYXeUcSxNuFoxL0P5km/mh+Xx+';
- b +=
- 'IbA96H3IR9OKnc9glnm5kLf2cMHuyF3/i2GCSBIhgVaDaAYtmWH9Kep3hIxPUkxFuOZUQp3eYcH';
- b +=
- 'pCYGO8p1gPDNb/gKbTTzgNRZSP4/NeOqii4q91h5brTy1/CZ0L6m+4aiUmHhxmF+WqqWhnfYm6w';
- b +=
- '5XUVZ9qLu1NadAC3WjFN3A1pSuKSelqRF45cXjbe1rFDDEDi952FbuSHdQCKlCQ9/6X4vb+fTc1';
- b +=
- 'bQnu+Qq/zMfNZlHDPKYZZsb9d2oe1D3Zh91eoYRDCsMlCrjWBoFDN3uQZS3jzRjnON0x4okn08r';
- b +=
- 'r+J/R3ir+nIP2oxUjwYqxGKBbSvqpkEYPQZMdlVZvSJWIMo+xpEueEsgskw0Hu8Iq2+GKDl6yYI';
- b +=
- 'N+FvZGhUAt9T/6jUOQvnb7juAeDY08o0+X5gPc1D1f6GqTUn5vcO8+m992M3+D1AIB+R6/xXJbO';
- b +=
- '/k9/+cbl+SP4k3/W9AoLBqD869KDGK8QzFi5ZKyQT9lkj68Gqe+mqoN77FWUb6DCCMAEGOq1Kfv';
- b +=
- 'tX76dYrYKJudyqT9Wv6SGvk7/OV13RntI1YtcEa3gZIGyNLFVW8nK5er0PkRscFi9g2JoK/QfON';
- b +=
- 'y/lFbAP1uoXXt1he9GVADWNaFdcWjsZpPZ1ob7u4VIr5rfuZnsdapO2HXy2Jl1RNEkbBy3fWnW2';
- b +=
- 'HCKAeIXBdqLkW4i1AY4We3gfB1W5y2RnSLctbDzJHbymQnemYY8yefgnzDBC2b921kv+tyT2tUr';
- b +=
- 'Oi2hKptyJTe+jVrGazwQ2Y4rOjjZJrVXybmz+bzbu5VRjkmn3AAigfkTQCZwJ2WhF4R3gzyEkxB';
- b +=
- 'tfX7jVwNIrf3M5fVonf3c5LdvQ27tpWeZdVrPQrnIr0W+a2td5+jpQLI/c1Pu6x8rpoU7+7Zt6X';
- b +=
- '/fkTaXXpSd6HV4214fJ/pYFv8sdpe+yc+HvsgPqcupXtsl3uQ+p2WYJuK74MMWHOpUPc/vP/mFu';
- b +=
- 'fGvvSL3xrb0f5ra39o7Um9/6c32YT7+l93WPvKX3wzz5lt7XPfaW5/Zhrg/8+rWI7+DBpxawCNC';
- b +=
- 'o4xJk4V69hIhx7TiuAsYNwJVBMLHVNHsCf6zxuJxU0+dV5knZsckxj6qTSFmXG/BvzPvd4awyBi';
- b +=
- 'vlv/rcT48dO/aRY/dMvuyuLXDh2ZLVx44d+/TrvnHs2OdesDlrXI+NRnaMUsk03HI9jJs9aRWAA';
- b +=
- '152F5S9aVVq2Dx20Wtx8m7JwrHbDz/wwVsevnv7k95mGI5rRegT9DTyDE3dr7TPCPmzJTNjH3n3';
- b +=
- 'tls/feSf/uGgPBMWz+yjm0soz0AwELlnIjDnwdgjj/712w7+4Kk3PCjPmOKZ/XxG6ge9ncb2mbS';
- b +=
- '2Zextnzz24F/et2dq2WYt3Lg50LN4dWGPEqxVH5dID2MQYpXLELbe18CzEWM9hGl8CYmlymUtEE';
- b +=
- 'uhGkXQmrKTHKBZk3SV3gO1fO5rs9Q7XKyKECs1jKlMqOUHaD9WU4szva2WUMkClRr1XLMqCnpH5';
- b +=
- 'Tuk+uQTHNMRKH1GzGDyg6BUVSEANrR2CV2o6qKGGVsDzYziNcr9FA97henNUPeR2fJLh/Bnee9L';
- b +=
- 'fZ7IV2QhnUd0oavaP3SBcPoRTKeST3/NeqIfMn7rWvR4ZTAC+h4gGeHY594HZ7zZqY/KR66l4ZV';
- b +=
- '3jflbMlq3SluzCF9e5sXm1HQn7xZoICRPSuqsZOEkq3CaaOHuHN0CW+vjSg9lVZSuaunu7NySNR';
- b +=
- 'conWYxSsdaujsvt2St3tIUpm7OgpdJwaA7IdEjmbGbsz70LrheKvHSPsm9/oY1wQiZ6Vgy0xbSK';
- b +=
- 'dNVpJtIDzFdQbqBNO3d0gjpOtIU4aQh0jWkvcaPITGjiaSVPxdSWFjOBSqSTg2NSPNByBWgAzEU';
- b +=
- 'ow9r5Ch1HWq6WGI2XJfG8CK9pxHrwmFdMNjKMoSqyjS+jfUYYxg+vsF39Sqlzb0SxGGq8cDhRLJ';
- b +=
- 'PaEf1eLRqunxQp7x3ybDlERBFQ5UJmpRWHoZo9rCKZvNrWdkfTzhhOMOcpTQx9FwPbMAxCJid9D';
- b +=
- 'm/lrJnPqcibZCE8HEjtAR7nehLhxqFPaqnIpZBG6zO09uN1wYmUhOXtR2oLnIC7MBVLmzRfy5S/';
- b +=
- 'zkvq2gg9FDFlLKu8ydhYntQ/qS1Ybqe1YZJjpUc5liQKhq5GOrJze/G4/NuBNb1esD3FE6oVrzt';
- b +=
- 'KRQPFnrBcmi16L0+LD/ndfK9B++3CFAVIg01aQ813KE2B3myrazAL6wYZVcG/UjjtQSoEBG8j9J';
- b +=
- 'R79ehj11DNDI4AWVSbHXKaE3J/9OC94h2gIlAGULbdMmIoJ0+rD2U6/O0vW2YzaKhsO+uqvE/He';
- b +=
- 'K9xufAiQEwz6LntShSEv6lA7NzZ9XPAOpCr7RbtBUxkG1WwUjLfO7QXtmnk5hu343LZMrCVLUJg';
- b +=
- 'LdLWhqoXkXS61XTtI6DXu2o2x4wDayO2SfQnQbga4E3g8U0zLzk2fzmbwq7sxWrAq4rTFFIW7xL';
- b +=
- 'mTnadUYMLolmCxPP1zCEHJWWaKuZRRyf/0ITcRqHymii+XITG/gxj/4kdIQzqmjLnzksL3xTSD8';
- b +=
- 'yM+6Aw2q5fw2AFVLLSkp6ovGXbbN8MqYJV0AkXSiwAwdd6II+xQXaWVygncX4AUKIuqzGhDEZzl';
- b +=
- 'fkqfwkv1VYCc16jNEON2vgiuRzn97tvK8IVZLvL2dslYx9pQy8ZAdcePe6zCmCGBLiBDoGP/lsY';
- b +=
- 'N9zKTEM2RyQxnDTzr/uXTNafCge4jEBn3tasWt+K2YWaMXenlbsRIpOI6V2ACaURgIj1vl+H7U0';
- b +=
- 'bG6RN8JQ5UIs2fRRD4ZTu1WiBMpSoVwgb4a/THRcl86f3yOVLN6ML7z/Y7thv87rrRSl1Vx9NSL';
- b +=
- 'dGQhFjbX5lM2CN7OIVlKxftiIMrm6S0Do2bQJ/OyCiOmI33H3D3Uv54pL/OxXM8t9RDCIgIGbBc';
- b +=
- 'n/gGMudG4u7BECQqX5vTYslp+nxPgAB121bjQ+H4KJWdN+D7q5ALDRpmYkFbsUUO12+WuC7T53n';
- b +=
- 'e0Yu+QOdUKJAL9LRIco/476xRC0K8qfKlIQa32lSNFn5lEf3bbI10QwQUM5x+UVAfCbMMuvZbrK';
- b +=
- 'aLml+VVldKz95Qyhrsvzq4rhugr5Lm8tkUAgydHpHdjpja0IxpmlqW21SJgIVXgg9r766PxXH1n';
- b +=
- 'g1Vv98rv/SBIQ2vr29fKzy+/O6qp+PzbQZkUKYaRTesyLepp5/rxWajOIGIxP5V3B2JwQHKIaty';
- b +=
- '4M6VdMS7SJToaJ/eQWU0NnA2Mn6xfnvJkyFvfwvZAz3f4pWQ6LdfLld35SErskh4IomFKgX90XK';
- b +=
- 'sYXFsquoJMt05lco1HMsEvslMRym+DWFJALqWGt5nOy+JJPGkVAU6HhIAGqSKsM5lN7d1NqNZjT';
- b +=
- '0YYLMovpaxPYWFWKeiRL47/ZBQyUsvYSYJIpk9mW27IU2ksBz5W24f33VAD9Wgh3r/YZ6svYfoF';
- b +=
- '6/LUJPu1BXxcS1exMOUEb+er2Imn0ohDgHkvsRFiKAV8CgDWXTpBOuukY6dimETk0PdNtXO0+CA';
- b +=
- 'CJ7VZUECLwnWQk3YwpZsRFRtpeE8xCPp5yuYbok9x5FRS0E4phAz60Tya/vOlWG8sPDgzEmsGf3';
- b +=
- '5bN407ceA9dVCnxe0k6UNpSQmwpW2WCMbyoussvkm1nEf5ePpydPt6GCeXpspvmcbs/rbSbAdza';
- b +=
- 'SUWU5L39aj8TUEO8M6Dx/1GY1e/V672Qph8C6Ekrv+hSaxPPtktGt+0JqaAh+lnkfrntCf4MwjV';
- b +=
- 'X5pJftB/YNu2G+ipM02FT76Pe8WSajqfbDdxNRsytRj04thl4GI+YaUPj+rhox4FP7HbevPRdba';
- b +=
- 'aweTz8CTdUh6j065N1/yNsnhdNtEE5zjJKXsCNsrJJboFhZo1Ca3yi6ICNeYdSaydgvnWzdgGlG';
- b +=
- '/gG2gOYFHBfsgdTSGVav4NM3Q+zM5fYFxQnEV21MdbwO3T3jwbF5ZGgDL56CCKIIdujppwgXFU7';
- b +=
- 'AL6XSo/nTQ/JfwFL7w30kAqx7IsTJsSOwM1KU7OS6i8mcbhSmiUUQUBMI/k46Rly3gBp6VBwMQG';
- b +=
- 'ST8OqcOcJ0OOKgwfgbzYRpqfxai8USKdL60/Pt31K2zhg3+EpDGuxDQ5QslAkhmyrPDquyB4C1M';
- b +=
- '9UGBaG7xMeoAkXIv547cUnmsA6sYQpbwB6ttWCKIO7KT0+jp/QKSf0CP6cJd+8NKFT/FmRLpZcN';
- b +=
- '9qNtCX0umJMYTIvBrKlncQyeRt2Mi+2kziyk7iuHk7HT+IL8OfXOeV6JrGdwg15tcxhoGbqHNab';
- b +=
- 'aJGbx5Dds956eSqvxp/zWBBTud6dyk3FSpJpzhndD6V8v0XODBUFPPcI/bdCgxPLZFEgYt+BLY2';
- b +=
- 'AdpWdMp+bEjr9UdOjVhIu66ycAiu5GpEZ0c4ozgeBLQ9NXcdHcHNFHl+qDF6KYm2yfgD+loI7us';
- b +=
- 'WWo5iykSiWphWsD2gJsrELbpQ/BbpA1kUXyHrQBbKxeKtDF8jGhgp0gWxsxKILZA5dYLXU20a97';
- b +=
- 'W697W697Z5626V626V620W97W6410qaot60W2/arTftqTct1ZuW6k2LelNX71rKxkGW56vz2e6o';
- b +=
- 'DWLUAvK87hsQ/TCVgnPdYk0UCyn8tt8AvJKUmnp1USZEGfX9Kn2AP/oFDdTLf0Ef9opf0Ae4CkJ';
- b +=
- 'FMjdQo+Xbj8k6u0iuhU6lgmIHBvIiijFBRuv9rkumWRnE7RemVfyswM9Q+5eROdR+EVJJ+5eQSu';
- b +=
- 'QDBkh7WRtpb3OW0hczfWG6YnP2wjRN2xDopWvoyJmlv7RZCsq9K++SWy+UW7wHZ9ZfTl+0WeiuX';
- b +=
- '+IdPLQZMj3g7r/Zd76dFQVshvP5rp8K0fli7WN+EIkjU1YVusC96etOfG/mJPf2neTekZPcm361';
- b +=
- 'vZeC7JWT1x5qw5LaV6SWS2pvkaoBC3Y2AO1rLewlvSNQcT6QYnFY2rKUKpKELjIILrKzWxsOf0i';
- b +=
- 'X863/yNZxw8zvRmJur6XV/9TZnFQKa56yHY9vjXusaY7CoRXmNFMVLROp/Qwsc2hgwnJ+1+Knpl';
- b +=
- 'Ybau8DGxC/bOkTOgub2bAwAFXnOdjF+2oED9P7iHYft9HyyeJ40Y7liCumxi63OVwwB2wG/B1co';
- b +=
- 'G3qzkMjznsCCwoGI557rPEQAk0EfjhZBKVX3IWgHH8eChGvLwgBmyVEP6yqjr73fi+vJgcCCGph';
- b +=
- '1Qc4Bk+RtkOYIRpVp0c0yT72XkrvpHTY0Ajry2Gu817VsBs4yK6AVSdZGkNkLoLeUYhqTcHgFfr';
- b +=
- 'tAMDgapkQQXYWYRaMtz01xAZfB40fmLoV1qfVQBWPt825t6FErO0LUzV0UPmve23xMjUiYV3d2P';
- b +=
- 'A9LZ9X1wI1uJDoadhvjdbpgZvvYhVwse1TbcuDO2n3UnKjlUyANdCoIVZl5PT77rdu0rGQ7V7yI';
- b +=
- 'fkiDwcFpluF3rddr4Wq81pwLgrUMSr4YQ0O4uA4uyi0MOoVGlkeuoxKLtrGZw1MjCY9AVqwkA9T';
- b +=
- '9c5u6YepwOT9O8f7G1SsN28ajWtk6Ao8HE72RNSwpYVSSjfkXwOuQuF1IGvubnr7d9P/E7W28ui';
- b +=
- 'yNBh76weegOfAQ6f/7gZJbXepl6mum6CX6l8AOG4pUb82bd41dsy/frOVd9g3O/eBao/7QHXdsF';
- b +=
- 'C+6j5QuDdJNoEf7DDVnBNBbX2Pum/QqvtO0KOe9P+EIFeNVW4O/Wiy7DE/qdoan+yTAqtJMoFQW';
- b +=
- 'X6nYCbEreiiCSm0YdTrY6q5KZ9DqslUZVNxu5UT0bT8RP/8MkUVxUPMWLQpr07kR1htHhbqFIVA';
- b +=
- 'UDDQtLBxotMybZvy2Co3gPgZURccrRvOCMy1fjiL8slr8jM3QS+lgQHCAuozRJiF5epBPwTfdof';
- b +=
- 'zGWrAEti1D3aSB/wyspS6XkeFAiZUoL/rFMDAV7G/GosCMQAmRDQoIhui22Dcpt+EcRpRcKSQyV';
- b +=
- 'ocm/LYtdzYzeqwGDgkqCuHHR2EwEj1vNntd2u3dQbqHWSV+bRvjR0uQe41XlM1y1R1NF1zMdU4B';
- b +=
- 'WyIhaoaowFRPZ/6Zznv1Fw4v4ghGWgEeJyzq3HOrtkZd2BsJy5uGYjk9lkLVJh5OLNjX+OywGxx';
- b +=
- 'Ij3jCioy3E1rCh7RExGG3P3WgDuxBtwD1nB7kTXYJkdGU3DIR2EKjoUJU/AlilPUhhssTMFPw28';
- b +=
- 'A0VPEmk6HAKHeaS9TWXIbOiiYgi+nm2VHEbU8Zf1ixnFoAqAG51espuCMWl93puBwLcQh3KJJuA';
- b +=
- 'WKasHrND9qTcHrMAWPaDmrFhU1mGUuRzQMvVwmFM4ivYysU+rpwmUz47R0KE30ckm6VLh3Xra69';
- b +=
- 't+D3TiskM7YNjRxpjUZnQXSmogSEqtdL7XUmYIrYrSzwoHTsCui4XTk6J/ARwod2McOin520J2n';
- b +=
- 'eLtPHwzreiGDrkmSC/gmSJo0LKJblmKA0pweJ1zXTJ2SjdDJeGuq89c2+trGuDt74Ddt7fHU2zs';
- b +=
- 'Lk3XWYbpOe+zv0QopVA+S25CYq6jpsq/38Hl8+ubywYaSaZXkaT7Yck6NLAs/Xty7zdB5xUehuB';
- b +=
- 'gTZ8IEX93cb1BNDSUdKYxZ4zS4qznh8xcRmdgbm/6UdyW1alCBU+1W68DoPczDcSiyUWAqi/Fz7';
- b +=
- 'ZY7ZAuEgi4/6L0CR/TG/Pav3e91AMVMcYsZh9OK3L16XMvNK2HRFryxY7sfOftladz2qIOL75DX';
- b +=
- 'fdVTHAdEm2ArOsyHcs+9MTxhzYS3V3fCnhrCeeUsRGm5wOoOgbxgGw9g1txzQ5C/KA3Gk5dJElR';
- b +=
- 'Q4y5rBDsTczISXWIquISBYLiZz/f0wbJWjLoAmgSS53bW7SVEopLP+V4avpvu3Z34oA5Ed6v6nw';
- b +=
- 'KMwOS7vr4bgEZHcONQoBDIu765G/BIzNtL71ST7/92txy8mhDJZv93XZ7MKLhiBXTjMurZ5BH+V';
- b +=
- '99YKTCW1UUdCL4fpr0yS/KGLX28h1MgA4Th+gfjB5PdKAYFYK8PAwEhd63/XkqAsP8Mfwrp8Y2+';
- b +=
- 'PZO9tmeNhOWtnfwY7MXyR0B99k9kgdByw/KBSqiLQm2sA9G5qe2QX4FCibdDue0LxTn9NWrZWR3';
- b +=
- '0Q/KofFwSMSd43Zrn/W0Fpjtdkqb8fJsUS15Dx6We5FPW3lf5GtPjKeYYG+IBV30ThFGlykYMFc';
- b +=
- 'Q+bTtMvn3fbh61Jv8NRLkwJMthvGDIGoCsxNVZHZht+UQCFsofqF0LVDbzs1VWgfn1Lnk2HxAuC';
- b +=
- 'pSyn38cyRaSIZKfR3IISfio5t9CchhJWMXkN31Gki9C0l+wXXs/87O0yzE3jUeNUqsOkYCIQFLH';
- b +=
- 'SIcs2iF1v6djiuRJvc4PFdJSgPZRoNry1dwMkmjeyO+9XhFDuTcUVm5wVsON9wSlYDlo1IHrHaQ';
- b +=
- 'nnfaNGpypTUzyBmwTv95RY0955II24RHOg0PaiFlNuIG0ePMzr7ZvhuwZMAcUG91sXxDISICZSD';
- b +=
- '7IMbhogueE1W3gHlpT2cTbaj6ntd7abbbazrEgxMJhfqfWTUN2wCcqmMAvbGhvnz7B0N49vdDQ7';
- b +=
- 'pk+ydDe8pyG9uAtCw3t07f8fEN7w/SJh3bb9IJD+8UTDO0+T8d22v8Zx9ZpNI4bW6fR6B1bp9FY';
- b +=
- 'cGynn9PYOn1G79g6fUYxtj86+dj+aN7YOm3GQmNbaDM4ttO+G9y/U1PDMQ+AJOqkD2NDYqefCZn';
- b +=
- 'QsWPVy9TJFb768aY/zILxTcKGgLTYOJ7/ZqeRWXGLMwEEZqWz6EPgiNRszAI6hSMTHPQGhWXzCp';
- b +=
- 'vTIWeG5Sv8Hd0LXzUBnUig/il+fjq2wU3jOF7yMy8d3kjDRSh/ztiUhxMdUKuUphBkHbQQRg1uO';
- b +=
- 'FpX6qsNlFFzSK9rTKg2tEPzXdHl2LcNDNRs0Dms45nGrq6bkHE2gnriDwrp9iIaodMoL8kitX8z';
- b +=
- 'FqfQJP8VcxOGElMEAySetNCyPlHw8YmnFGUJIYw8/DQAxGJSdVWG7Vv98hZ9yTjxfcaMomsnG4w';
- b +=
- 'Ow+WKulGCnKSRA5s3jbyuFYOIr68fbusLVKaaBgBgIGJrhcw3bY4Q4aeOYbmEPta0qlMntxgWcU';
- b +=
- 'Xd1Fe/iOl2VcV84IB5/tfzaQchJiNXv1ZmHOzfaUpcsxa6atYbqS1woPbDxpoZ/yzW8fGC1vH4o';
- b +=
- 'M/FND6hg+qpm8UPqY/fKZvEpyx/CubwI40PmUIC/FzOGLcLpmb9wvvgnvtOcMY8fN9CZ8zB+44/';
- b +=
- 'Y7pb2w33zT82IErcdt9xxwa2TZpVwhrSf06HyO33nfgQufu++YcISZ89xoHT2mPEU290bHk+rHp';
- b +=
- 'jbHKUocNOQ3g/mvXm3JCsYe93YNgbwbBXVtQwrT1KdrcQv4RYfLB3pVtj6fnvqt3rcY/gXYhUGq';
- b +=
- 'itblC21QVyvNrqYtzUVpd5tNWFgxnRSCuKDhVaW90AZgi01SUM63I+3JSHV+dc4TDKNc4od5liR';
- b +=
- 'lmr3KCwym2MejFhYPyOAidZk9ztRt2VdNdTK3SpvEfqaU4g9TQ9Uk/TI/U0C0o9TY/U08yXepr5';
- b +=
- 'Uk9zYqlnYKWekwRYeS2TsbCaKtpTYWHqJPYQ4SiotD+v9rLkMPlh4Da53Gu8yXIxSUk7A6hSB1E';
- b +=
- 'ebygNTTFodO3XYfPseHkYr8vpH+v1dNbrGS9vwfHy0DRf2+71tN0rt905AJQH18PQHVmw+uLt3f';
- b +=
- 'eFjeQy6/M/mHql027A99yoNO5+3vcrIDu/R9b3LQtsVjfcsdBmte2OhTcr7BSupp6das97ns+d6';
- b +=
- 'uH3nHinOvieBXeqN//HGltojTXeIxSXdT8SAlEO+2PH+nHoBvNcjoLN1llHKKCf/v0Pj/3N1FNf';
- b +=
- '/qy3BfNpAZ+jcunXzLz2k1PX/eDWX90CxccCLkflwnt/9P2H/vbrT/3ge1J17Epn1TFoLl55PUR';
- b +=
- 'Nm7PAuuil1VJLroefE1WaL7uLRbDTVrsvx7PRZiIkVK4EFRHSGCFQUqRaevH1abwZehXSGpE1TG';
- b +=
- 'i80fixHSd8E5hLZOEWpasAuAVjiEzojKy6BaB9V4IQ0pdsUcKG4xLSiCID/aIep1vQ+4i9L4oNa';
- b +=
- 'bGhrOqKVVmsqs5SgRuMOuF6NmcVHY+gZzTitEbaKa3jmYr1hyqPR82Nh7Qao/IyjEdoHal6xqO6';
- b +=
- 'GUCcLFWMx05LqR+xoX2JOYGI1RXdpatcsAAcI9l7sQakJBtHY3Qveb1MsrGd6Iu/BpFAuJHNGd2';
- b +=
- 'TAsbZsLgWyQxm8E6/o4Q8YBdD/Iwoeo86363QvStOw+SfNY5wVoOWK9Dodwo0DqzBjWoyMUeto7';
- b +=
- '4oj/OjN8q28TlDPbCiCoDB2fpabiYKTokDfq+fzIYKzWh7Iu0qXH310noTBADelRX2722k5v5so';
- b +=
- 'ZE68mc//0gd840RapJuSYowjTjLfqMMFuFwBj3Zzxvl+F/OjQN50DRTUlGTbV39jYxFAQH6TQ0I';
- b +=
- '1MFdY/Vrs2gs3XpHK3QOSA73Mo3uyFTjcnnLhe8Avn+wtrca917aMyNkTWCbZEGgFbOHLhr91iP';
- b +=
- 'LL2J/+JpR3PEa3/T9gPu8Qw23brl53x/L0Xf6H18DyIpN13RoKRoKNd3/x7BFkPxKXpd84Ag29X';
- b +=
- 'ka3hAGCg9X+XC1+zBECP2otMVK+XCkjtv8plXrqoiHfT7s24ePe6lFF7KkAdzWPTzl8SnPPnXc2';
- b +=
- '+Dq+AUr4E8dKBy8H1yU4klw0FRky2+N4HyR9TfUqAYW/a6pIJFeD9ojZorWUHcuxgYRcnZ8QGbp';
- b +=
- 'H5LEQvwFXxE41DVTldB/gjoTwLqSVYdnKNmPQVV2pUp7pQ7sPVFUFLAASjpEoPF99eOQF267U17';
- b +=
- '4BZ/zIoZKzGLnc2L4qmyn7IQWzuiO7MgNixtlUQLYSYRwOL6fKZ8etLOM7qNGwRb/2Tf+ZPPaLp';
- b +=
- '2Ig6sdqp1fhJ8R2DTjp4kUwhdCYADsMlj91XkSAcEMVn8VHl9kjPSg47G3GeGNPD3IcNjEaT8O3';
- b +=
- '1iN/+R83qzgpTw54u75AgP4vs0MBwkJQEh/Y94bIhpZazNd0OvdEyeLwNLD7Lm5GQ4n5OsrehbR';
- b +=
- 'UTjZ7Ai91xu/0rUIUhuMCWEZp6b2WFdPajU3ITbFdS7PWbWAt3y1ZtKMK7qMmCcx44IC0LNG2Uz';
- b +=
- 'yLcVpkMWF0jBwVRx5IAcZuHU2ZQBjwuThgeoCDwQsltbzcOMGddWC12E3TlzhjIT4ik/vcnHL8R';
- b +=
- '6Q5fe4jAp37YaaexBUXxFPSN3dYgfDcufzjh7dBuDOUlUMAMUFVSxlnDUXKEzyWdAB+vBKDfR0A';
- b +=
- 'dLjeTbEBAl66eGbjJ433EBSBPsKc8ohL6c0TE6TjCXAMCjhrlA7WFo4+zw6HdIK2HCSIYKW9xo1';
- b +=
- 'dpQx0SjmZBBipxWlpRcPGnuOKAJxPvuaWZhAooH5YVwfwukOC8j/Qwdk55u6A/Iwrvf9mR2QVw+';
- b +=
- 'Zikpw9nnOW3VIA8x81mgg3uUQRY/o9RB6uoLeq7SkdGUGs5p6LcfYPesMeq9gC5WiTDNrAFWH13';
- b +=
- 'HWRPDqOD+vQ58t+R7qsnUeDFKqyZz6GcJ5QNZMNyQJ3RRwUq3Q6wtw5KXYQiAtlzW0juGIRjppM';
- b +=
- '20k40Q/ryXjVnEx5ynO/qyvUYuSTt4HEBRIedRyahBWIe8ogZxUOvl7umnIfGCzaKPG+CpQMgoe';
- b +=
- '5sBm0Sx1I/p1tcY5S52IVrdbJbw3Q+Kuqjr9V5sCYlT283t5Esz6yZ8GXcjaOYZ+lHlwKCCu5Oq';
- b +=
- 'OBWnz860W5D/tw25YBRh3jRFtrkL5uSDr0/hDJp9WxbyFhjJa3ZpgK6wAHuLG8nQgh5YLI7AXGO';
- b +=
- '5F4T76rPKhrRU6nBHZlMa7MuB1GfBPsuVbZcfUgT5Edx9jgz2YlQYPzgVUwubLMPQ8YSP8LJeev';
- b +=
- 'Pa2XryZd0jaGn4Qb+Ytt/Xi09zSTdeSh7rRYlpkcOcY662ZtpI3UmExHZXD23BoMJQj5pCG2NhW';
- b +=
- 'wQgclhG43YVN2FNF1q1RpzRkZlu0xtwLObfMw134lTk4XdER2qrxHrayKvnCyd8g+XAVtMURfOV';
- b +=
- 'dchmoVdqIebg0t3W0TH6g2inCCvF1D1ftmO2tUsh4UI6O5A+kvs+zV3tdHS3fWgEP2IHFuW10Ts';
- b +=
- '/OG7i9t/UC+eyTdBGNW+b4wPw5XiGss0YZkjbtra7hnEe8dQDS6vDkHnCfES8+tFzAnBAxD1c1F';
- b +=
- 'sWZtlmxfm/AG73ztl44o13zmvX+ec1+bzkcvAxq8kWj7T1zfnuj0poMbGMOSmM41dNuY1JtDID8';
- b +=
- 'D93a25hjt/Y25uitvY05cmupMfLBEYv+WRtjZ8XnNb4eFmQpjLRdkJnOIzWL1Br61nS7o5GeSlX';
- b +=
- 'qq+7iKbUjuGGNkoHEQSS9c9L9CDaVuh/tD3Q/ko2H+9HOit2PDgT6KZPp0n60s2L3o5kK96MRTn';
- b +=
- 'hA0ufbTXc/Ssv70f+F8jsr3f1IofF79qMZ2SH2Y7Y/DLY2v1c24BvcakSM0Z79aNboQ/sD4gpUN';
- b +=
- 'fCMekFjP3qI33h/4Pajmcq8/QgP7qzosllWLJvILZvndz/aWXH70Rs4oofiefvRzoruRzKkaNNB';
- b +=
- '7gd3ywjc7Xbk27mvPB337EeH4zXm1oruR9sruh9hw8AI7adykWEuOTbJXyN5Q63Yj7ZXSvvRDbX';
- b +=
- 'yfjTDl91cm7cf3VCzY3Y05n50Z6VnPzoa9+xHcXc/inU/av4C9qOjcWk/mqqdcD/aKc/dADRVt/';
- b +=
- '49/djhz7sZyYg+t83ozgoD5/IkPPP4k/Dn2ozwnU9xM5KJUWxGjJLauxnNVDKdRD/nZkQz2AbpO';
- b +=
- '0wTxjzj7/JO8hYKu5WcA6EZ5kstUeYpUYaP86kyUdbXyQ+8o7f/n++mWfmXbfeXnoxY89WKXpHw';
- b +=
- 'QgXeC3WC/vW8+v/uHb07wUff0fs9PjyPSExP8l7X7QZd8Ely7wFORPIZIJ+c1dHfFfyFQ9w+yDK';
- b +=
- 'EaH7JxWQJNAYfIqyNmJe2Qxgp5F6zAB5Fht5rONzo42D5VGgRw9hHPsunzjJnTRrHA9RXwIe3yw';
- b +=
- 'PUEZbU8gC8HsqqoL/rJR6A+YMApl2t1wm8P86SMl0egPlN7CMv1WvLA9TBA/gFMBTRK4B5Jh0fJ';
- b +=
- '6ZuBofwygmI+Cg/Dx8v0hEB8Hl++O3C4JyHaD8hpTr5eZTQEBfVgm2r9EW/DI8nuwaIlxKpV8T5';
- b +=
- 'NtKviXGKRfCbBvZS+c4g/HSBnEvUoNXKyswU8BM7GMe4agl8AklkPHlv52zbWSLwGfSajh9CAJj';
- b +=
- '2ryroQQjBqCPvw/RXITyp6LrZGSJElSnhvGIbBJJGqIGrs0FOv+JuwLtzxoaTVzeKIwjLpYyQRb';
- b +=
- 'SswuWyXUPr5Q0JjF4WpQmWRkvd3pfgJ24vzXfsmaX8+rQuPLh0pFGC2ZSduA4YgPdhEp8H+xb52';
- b +=
- '8+/ffw7wL9D/Hu6FperZcXVcHG1vLg6o7h6QXF1ZnGVFlft4iorrl5YXK0orn6puPrl4upFxdVI';
- b +=
- 'cbWyuPqV4urFxdVZxdWq4uo/FVdnF1eri6tziqtzKb3n9aj3bZzf545638LvOaPeN/G7etQ7jN+';
- b +=
- 'zR71v4Pc/jXpfx++qUe8p/J416h3C74tHvSfx+yuj3hP4XTnqfQ2/I6PeQfy+aNT7Kn5/edR7HL';
- b +=
- '+/NOp9Bb8rRr05/L5w1HsMv9mo92X8tke9L+E3HfUO4PfMUe+L+H3BqPcF/J4x6j2K3+Wj3n78D';
- b +=
- 'o96j+B32aj3efyePup9Dr9Do97D+B0Y9T5LPmnU+yf89o96n8FvPOrtUyIs6weZV4GLxAdumvWS';
- b +=
- 'H8Ot89MQICwSsul1cL2JXVhvA2EBJhKihvYnH4Uk5ABJlocRdc6eYfmOekd4EL72fMNmyjYlrxu';
- b +=
- 'Qmr/tnF/7+Docvi/Hn99LpvCqhlsVjFcCisdz/rYaZwkhxrs5+5lzqJuDE/SqNQH7BvvuBr1U3w';
- b +=
- 'vhH1xiTgMOsDSw2em+CRiYFjzWEOQDQFs+sH0DggV3WzTTwvbbp9XZ7s/2SVX/P3XvAmbHVZ2J1';
- b +=
- 't5Vdd5HqpZaD6tlXOegR8u27IYYydjmURosWSPADvF1HCYzQ8hMPnLa4SLZcTJ39OjEslHAgG7i';
- b +=
- 'DIKIoICDNCAlzcQQhZjQUkyiEGMLMEGTGJDBDiI4GSVxEsFV8F3/v/auqnO6W24DyZ1rf+pTtat';
- b +=
- 'qV9Wu/ViPf/1LWuT3HVDtDHzN7SMy7iGiPzOPDPjgYk2+gvdDm36bQtv5eUqBrbk99ROEamlnxZ';
- b +=
- 'NNsoeLdDdPT082atPqgxRPtY9Fp+Z5Ng55CZacLJXsYcmJokTaKZgSOWOiAQ4uDAUoIVqhPDQFS';
- b +=
- '3xUzNIhRaRn5LvDJ87j6hfnY9ExzsfsKTGW1XIC7tbJhqyTLlzWr/sUTGsqmIZlauJwgIo4HKAi';
- b +=
- 'Dgeoi+s+Z+8kWMPIhltX1vg6qP8imIOdiZ4pACwdfaet3DUXuquI8iaVmMzmT2IhsJiQma8jLTX';
- b +=
- 'zKWo5S4u+d5IFSVFwwmoKyHJfDKgxVYp7wA0Fa5MsLfYBo0Nj0mhMVa2nhFWw9/8QyaYQ+D9pul';
- b +=
- 'cpN7cc/yFl5XYF+ds30xY+WYI/Vc1uT3eMLHInrdy0MOetCQ8YLHZYDMmw8zQjkQ6b3AQTZfsjF';
- b +=
- 'D1u+xIPP2bX2/scafreSB0qZ6yukVzjklKkYC2t+vSAfAv5MnpGfUXA3CRKuthy9OjNFQHDz7pW';
- b +=
- '3uNYpC6UthS2RSDabTXMg6LImDLyaVxB2u5pklqZrZJ9ET06TcToMgK6qfl84ZWFd1A+gYz6FlD';
- b +=
- 'WyZ9ZltRkVz51ct5wt5U9CDY21GSZmd4ikNal37aawqfqON8r+rH8aq/0zj6BtLK6R9TDm4w/03';
- b +=
- 'zWB4xPaB2lCyFRGOp5Nm/jA4bSBDIaU2iRxhY1L1H5Y2+E0Ui5Mx3Wq8tEPrj2tO0T5UMV5W12r';
- b +=
- 'KyqyDh9tLwvQ+pP9pdEeZGZoEibXJanHGdzn5vLNaZ+HbnBk8g3HKlYf2Uu1ivZZ/bLUrOUimRY';
- b +=
- 'VQEHWhKrvjKvuqpVV0oiIiU5pjjkTMR2jETO8/YVFelw3+z0e2loZ+XZvb8mO6f2O0u75mT4/uV';
- b +=
- 'LGJBVvpy0Kl+qwSbKJmInXz5ANeaoLQw2sjsRO/lyT1zIl3vjnjfX9MuXp6qzyJcn0XR74lnkyw';
- b +=
- 'kkVp+s+sEn1Xv50kUXVqGcUr48Wb2wfHlfSb48MFTIl4dK8uXeZi5fvoTy5UsoX76E8uVLKF++h';
- b +=
- 'PLlSyhfyumytSzfGsm3ludbF+dbL8i3Lsm30nyrk291860X5lsr8q2V+daqfGt1vjWab63Jty7N';
- b +=
- 'ty7Lty7Pt9bmW1fkW1fmW2P51ovyLZUvuX1N8GxV5cvvVlW+/Oeqypfnqypf/j9VlS+/U1X58tt';
- b +=
- 'VlS/PVVW+/Keqypf/WFX58h+qKl8+U1X58u+rKl/+XVXly7+tqnx5tqry5f+qqnz5N1WVL/+6qv';
- b +=
- 'Ll01WVL79VVfnyr6oqX36zqvLlmarKl9+oqnz5l1WVL5+qqnz5ZFXly69XVb78WlXlyyeqKl+er';
- b +=
- 'hby5ekq5MuPvNvLlye9fPn2meXLHysErKer0+RLEY3WWd5e5Es+pkxLcrsB+RK3my5f5hmbz1UH';
- b +=
- '5cuz1UH58kx1ZvmS71bIlx8p5MsDNpcv3Z365MsDoZcv74d8iaQHxRNBloR8+ZGSfHk6UfnyQSd';
- b +=
- 'f7hly8uXEEPwnQyo0TgxNky/3D/XLl/gEZfnyZNvJl/uG9PRkkx/e+ijFc53gOnsuKeTJKZacLZ';
- b +=
- 'UcZcmZpE/CPJ2sDyfbkMlEWnKVySPPIF3eN+SlSzmeS5f7h7x0uW+oLF3uH3LS5f6h55IuS/kVw';
- b +=
- 'oF8CuFAPoVwIP9CLl1O2eeSLg8M5dLlRDwoXU5ZJ13ujildTlmVLoueGPU0WXvRE1kyWSo5w5JD';
- b +=
- 'tq8nHrDSFSOKl+4mEC+R8xzi5UNWR8aULYmXJ+yAeDlln0u8nLL94uVktSReno0GxMtJq+LlUSV';
- b +=
- 'wvDfGovegzS3qUfZwFUXnoz7x8plIHriq4uVUVcXLPbEukVzivkfx8qQZEC//EOLl6aCQLz9oSv';
- b +=
- 'Ll6WBOAubpQCXMk2YGCfOA7ZMwYRrOJcyH7b+ohDlp+yXMo3ZAwpy0lCe8hAlHYSFhTlX7JcyiR';
- b +=
- '0b6ZfEpfgASpkhNz0vC3B2vsxSCnlvCFBFnrhLmpJ0uYRYePBXqcN9CwpTKByTMpmd5b9CebGE/';
- b +=
- 'bjh7csPZk8EZQHtyw9mTG4U9uXEBe3JjDvbkhrMn/5NRxCv4sdW1mBBAlZ386rEAAMop061qwlS';
- b +=
- 'w04XlRHDMLS4aV3YOeV2/xAm2pRC8muaHJ2XBK8eT65gPbizb8zUfQBrK3ukg2/e1/MpIr0QPre';
- b +=
- 'UXHMovsGuDt2QyZsezqWDrNoXLv0W68d+HSl6Q/DFzzDHTmjvXjGfpVp4WFFlardIlNx8zNlJDe';
- b +=
- 'urpRpYSWwT/GvBl2d2ITaS3BXg/c3kAwFFwQ57d5MiGZ4O7lI0++TWbc+Q7kGlWBd6nAixQbTfk';
- b +=
- '3TUisFd3E8JGPwxZnYrLAwUI0wggVzicOHaqyJChY0tmJca/RySVyxbBb6b5m5WFr/m4MRXmbSb';
- b +=
- 'NLf5YRaUuA6RzESGd1Z8DypNo1aoudjUp3ppWbyfLG1BOHpyqX0RLA3Uwy5i9Hbk261tvl4d/wc';
- b +=
- '/Jn4U/h80Gqu26XHNMqyt3AHSZuQJv33o78KjLgEddRDwqHqMburyhBjUZ1mRQE2OKI94owpXM2';
- b +=
- 'tf8G6OBIUpqQlYK+BMwsSdKgk4GMjgiGMwJ8he4PXrJ2+lvGO3yZ0UXlCDMDhreOKKuiOVIYx1i';
- b +=
- 'a5gJrUNNRxgy44H8uV0+Zox+XYGwQfLvCmQNKUviFBxi0pC9lDluiexKXK7wxHcMhQmWOewD1Sh';
- b +=
- '9Iriyrqn4yPe7uO88fIgcSqHPgCinXp6lzHHKYNZUXsYQ1EageqtHjgtDvq2Q+fT0YzLlbGUT3s';
- b +=
- 'PBzAOEzAXy3E1AnUNmHVcGDDRSdVM3GkFTGE0THIKuVd/ucrzPuKY3dMA2ZXTN0k1tB25GP9jU1';
- b +=
- 'u5sW+tzLDVgxz3mDsLCxX1IcKJX5/tgZpGPqfs6AALytzgA6TfDHOOrQ7gflRw6VHKoqOTQo5LD';
- b +=
- 'ApUc5qhkF5yTo3XpZw9LqOQQIOG9RCW7iOwSLjks45IVz59kdpOji+laF+sWMjqaEEIZlGd+T5a';
- b +=
- 'EOPn90KWpz/4aBQulgHxtcTbxiSkwaegJVv1uSgYZa/R2pJjoq3rZC9RHvDynE7TkwsjOf2wq0F';
- b +=
- '54CWkyQDN4HaTlT6D8aqpFCD1byi0k2BvjFsgGR1Xq/zwjtmSxUj++UiMCHU9PNID/WaDbwMw3M';
- b +=
- 'wRPBtr4baOhCtZlds8B0OQmY+QXPo5W4Snmkj+IdCl3n5oz29m2D1+F41MFusLxWYUA7Ryf3F4K';
- b +=
- 'kOMKCjje8cnyYTg7x3TbgR+rJccny1sALb5Kt2vo5chM4Byf5Z7WkHrH2UGJmJnZ6Rmq0zPMeRE';
- b +=
- 'GnZ5XKV1W5OgjfS4rtBqZE5JOg/1FkafLO7UyKSgBrTEYRR0wcTJyQKDD1Gcm+4GJk5EDAh2NOg';
- b +=
- 'o/V3bPApbYBLA7hmRTw4sQy//5EGI3Q+1VkYqAqzEnEYobhMQpBU0oTtlXeeb8XvY5n/q1ti74i';
- b +=
- '5D1Bl8IiY8GvXmU/A+3pp8IuzV6skSz3USc0dGoRxY1rUB6czgJo3Fd0yNU0kbyWaNvc7LAChEP';
- b +=
- 'CS7XEl7oJPBCqHFZjh+p6AoWlcFC0QBYKBoAC0UDYKEYEmilhJsxuXBNgpu0ojJjVMJVRDmU5AH';
- b +=
- '5zidDxwA6CGKKylCSaABKEg1ASaJpUBJpWRVhL+nrUrHODIdKUDYZyZNQ5b9a6WX7fw3GDnSc7J';
- b +=
- 'xsJv9gvVK8OleKNao7O4yOuxodF4xRq/UujiwzcgotqVr9zDp7D57Me/DpSHuwh7Idta4HP8m7n';
- b +=
- 'on6oGxHrevBU7bowSdsrwCylXvwmHbg78YzduDz8bQO/PaK68Cdov++taL999mY/fc8MjknH3X9';
- b +=
- '92yM/vvbpf4LUFuce3/Qf4/a/v77sOu/5+Mce0sdfXelr/+ej6mj/+/Vfx+UCep8/C/Tf6VlL9B';
- b +=
- '/T0d9/fcoPuxvF/0X+Yx+EP13klTDnNWp5ElF+sv4HySAUfBP1SlrVaesIdRd1ourShYcJvKoKi';
- b +=
- 'fOOrU3rLFXgX/dJF8OOzZzvCWW2LdINTSXO0ee4buxbeyKdrpwRMYwJe8J1VzhUlVBCKipegcIf';
- b +=
- 'yfOI7QYRh5kz3z0OAzzQ1HQDSNNm9ytaLxUrCpXrLg6IkSxOnXqPrgGtoy4mVO7ir77YiyGjBdK';
- b +=
- 'VquKIOseCHKeJVm0bt040q0koxjyaDqH7dJfGhvqMgIWyqp9INQeFTnZg6w3ZHi4XjNXMsQGcef';
- b +=
- 'MwNdLnnQRi7qdvQPt3Al9rkhk+cLjN/DcfAXkLUvrYJyBessHnLB8usuBikpk/a4mw+wq+cO08o';
- b +=
- 'ep4ZzhtKqiWfkpVEeuykA6bP1zVuUFy0+ngtNXwmyPe0rbzKY+cjzI/ijQ6LY9h2XnzGFPRc5HD';
- b +=
- '31EGCh/GLeBCVIj4lTUfihwfGi0RVwHfutjxyjGmexqhLVADRhDGmRuXU5pDnlZs8ePiyKNPMiE';
- b +=
- 'xCGrDiPKgk5Lo83aGjU2LzslFSa/b6VTPu62ItYA3Vfaj6q/Ud+vWknOWG+BgQNQ05EYOr2bugl';
- b +=
- '39zzdhKO7zc20Rf82UrpwLEPnOapTuHEhpmeMDVXiO9D0i0XBGSsP+ArSBVFMV9JYSFuv2HrkHp';
- b +=
- 'm4djMl5+vuQh9CZ98QvE6njilOtX2cokShdh2zqAVRq3Km6+4UERATFe4G3vrazyxqQeVJoj9Pl';
- b +=
- 'm6THyENqeO3JUFnfNP1ylCQ7A+VmFI6BmzQ71tuO7vCneXYmuUwHTKlK9Mk+QkAQ77mbF1O3QBJ';
- b +=
- '9XfMIGfg8/sfKm6LDNRrgzbHvtT7LplRdx+QGfWvNSbS6NqJW7c0qeA86rPD+UOgbLjNn0VK/TK';
- b +=
- 'XWhZzNl7eV8tyDQK+GLXYOdXyAgQ+ylxcrmUF6JrWBitRSzinWlaBPptsFkUtlyPmeG2wFrVEc6';
- b +=
- 'rlCtKXX9VXy1XtGD8vQS3xnGpZx5zL1/XVcl27gp+XoZbKnGp5OcJDMXGUq3lVmwkir0c11TlVs';
- b +=
- 'xHzBcyP5Wpe3a7h5zWopjanal6L+QYOnHI1N7fr+Pk/UE19TtXcgvkqe7y/mh9vN/Dz71FNY07V';
- b +=
- '/IfOPDnvyf5q/lObx/4zqmnOqZqf6szHlNhfzW3tFn5+BtW05lTNmzuJnPdMfzV3tNv4+VlU055';
- b +=
- 'TNXd2huS88/3VbG/Pw88OVDNvTtXs7CyQ83abvmp2m/Z8/N5tUNH8OVV0j+kslBPv7a/pXtNO8P';
- b +=
- 'sO1pTMqaZ3ms6wnHhff033mfYQfn+VNQ3Nqab/ZjqL5MT9/TXtN+0F+H0fa1owp5p+3XQWy4n39';
- b +=
- '9d0v2kvxO9vsqaFc6rpQ6azRE483F/TYdMexu8R1jQ8p5p+y3SWyokP9Nf0gGkvwu/HWNOiOdX0';
- b +=
- 'cdO5SE58sL+mB017MX4/yZoWz6mmPzAdrOwP9df0kGkvwe+nWdOSOdX0R6Yzgqmov6aHTXspfj/';
- b +=
- 'LmpbOqaZHTGc5ZqP+mh4z7Yvw+0XWdNGcavoz07kYE1J/TY+b9jL8fpk1LZtTTV8xnRdgTuqv6U';
- b +=
- 'nTHsHvU6xpZE41/aXpgL7y6f6anjbt5fj9a9a0fE41/Y3ppJiZ+mt6xrQvxu8/sKaL51TTP5pOB';
- b +=
- '5NTf03nTfsF+P1n1vSCOdX0XdPpYn6yhQS0izOUdWLM3dgggWepMuVbCmHkpukA05NVQ/clPUBd';
- b +=
- 'sPWCHsAu2Lq4l6a6JdLJJbo10gPkBVvLegC9YOuiHmAvgWr4I7q1pAfoC7YW9wB+wdaiHuAvLuX';
- b +=
- '2Et1a2EsX69aCXrpIt4Z66fA1Pv/nQt2a30sXXOOcpADPYKvdSxPdEkFwvm41e4DUYEvk1rZuiU';
- b +=
- 'DbusanEG3qVrWHbG7YqvTSum7FPcBvAqaHQSpqhr730opuwa7hnAIw3nbIfbbHNqd9oUtIakU2v';
- b +=
- 'sgdar3AlS0tlV3sytJS2XJXNloqG3FlY6WyZa7s6lLZRa7slaWypa7shlLZEld2U6lssSu7tVS2';
- b +=
- 'yJW9oVQ27MreVCpb6MreUipb4Mp+vlQ25MomTKkwcYV7yoXzXeHecuE8V7ivXNh2hQfKhS1XeKh';
- b +=
- 'c2HSFk+XChis8Wi6su8KpcmHNFZ4oF1Zd4clyYcUVnioXxq7wdLkwcoVnyoWhKzxbLrSu8Fy50P';
- b +=
- 'j2tEUhJLa9lnlRADMRTULpiYBaWBtcom4nKK9XBhdf66xQ8udyWN66L9RUlyCKEekdJSu0hPjL6';
- b +=
- '5g+hx0dtgS6rbor9YTUueWDrONp3jArrMjdWi/MHVordSuG1swtU/J+RDoa1PfhQs6a/wyuJbqq';
- b +=
- 'k4JdP9fcXPqfPCUQWPBcFqW1dFlfobFXnw42yt+ngo3b2ra5wcCWCKqlUPlTIs3tkwXJXYrQwDF';
- b +=
- 'NbkoP7QYwufWf+DPuPDP9vLC5IeiApzYEIVzwI6Kb206Ffo1PfFIZOvDfrrsdywssEFW8f9WR1i';
- b +=
- 'pvrxKjfKVqmkzFEDp2HFntpba+VoD1aF5obBAB7GI3MoNnWqHTb69RdL2zyWYGMAE9rjbbWU8hV';
- b +=
- '+Isx2C545aekh364zzgo0l/Kwq532XyuTQ3N4gURHANVc0Tuglo0d4hfb9KcjACrEFzBAJEK3vE';
- b +=
- 'NrQQWEKCm4o3MIfZoXoJMhjClAyqXQcczAzsYsi/3iCVI7GDDzdxSkNzmAAfGGZPN8HlgTxuUbK';
- b +=
- 'JievpXp5oOUKVZL0954gjQxmazS4t+s80u3HyIZfLk9QpGfmcyf9IQhXDNKVn3600ZLWCBTK5nz';
- b +=
- '6xfbU2nWIHasxaY5h8CP467zIz6kPGc8HmAwewtATYHAN1fuawFhfReq5Je23b2YrVLyv/018XZ';
- b +=
- '3v3yaN8xqpbIso5NIe7xt0SjAdwXTCs0aiTLq+Vrnc0Cu593oXTntOcHzD7AJ4KU78hPJXfClCQ';
- b +=
- 'sz5Zxu4Ww/aBUs3uJ3zm/pZLfBa6r1BbZ/fDxFpdJ43C0ocBWt3H5gFINcwmUYuCVOVJDxHocbg';
- b +=
- 'FmGqgmJyJljc50+d+rqkmwzJmNMzOzoOfxaRVoEajogshj80ncZuTLRiy8DJvRGNLP0wtumHa2u';
- b +=
- 'o+gXpZiICS/j7kHT+45/7aensmKshspHmyJ7EzsW/KJyNHjkQZ3w+78e3z/lDDeB7j+4CLnnEvM';
- b +=
- 'NP4nuUU9o9ZjpXHt5ySHT2RN56ObxRyv8sMQFh3HGceNC8/vo+afHyfbvvxfciNbyYO0tE+bXzn';
- b +=
- '3+loA7l48+E+bXw3dXzXOb5/sxjfdT5RD/Fl/eN741zGd32u4xv3PfdL/1uMbzzKvrfNdXw3v5f';
- b +=
- 'x/SjGN5Afb7vg+L71BzC+GeT4vMZ3OeYw4sj+7whKbyT/lxvNVb7yj2KdlV53wdF8uj3DaM65uj';
- b +=
- 'Caz2Nnz9uK0czkWs1vGM1b6vMBKrNhrHgzZFS8Ub07SrEVpfFrXMrCAJ6UGkCMTLYUbVRayWsNi';
- b +=
- 'biuNVYlw6qjCJSzXaoxq4kNs7PfmApchsNnXTdtua5D+FPyZavYFcJyoyy6I633OpGjwQTbSHby';
- b +=
- 'KU/VRr8gYD3RQBU+2V3zmENOng5djA+xKEigxCiCqkvQikgXFk4ofwpTsNZ94QGGBcWae13mgkN';
- b +=
- 'A05I6RT4bE6pWNAkrY2GxEaOvYyPSZK6EnkhdMSdupk7VjE1V7GAaKFI3sZSXMgFt81zuYXEpVf';
- b +=
- 'EZHA7YSZFU7i7P2RCtny1WMN1ONvXJ43AM/vgy1acj58RzHuwV4AJcqkjaUL3KMUkmzBo6HU2Bx';
- b +=
- 'aZPLeSpXc8xQ2hVkL3jF/4Q/CLwxsdAQrYymT7CLo0FUdZiRkS0vQiR6z1uN/TjI3tg6nhQmkBc';
- b +=
- 'HqCzJqezNExz2lIBfiCb7DwbkLq0bbJ7PzZFT21HlZG2Mpx3CVwN1Dvv0nSIbh8kd3JbNmTWUTc';
- b +=
- 'OBwJ4xHWiYwKO5eraW6oeneEmZXikfCiCywwaaxjv7dvBN0DQ1wDKGpmDCW3ehpoksvl5USK2e1';
- b +=
- 'ptwKfCTyj5fylPaJRd8rMAg9bGu7XsY+Rni18VuP9+oo2OQ/xrlD1ggW6NX3XgxLfu/vuHn9j1w';
- b +=
- 'U6McYSXrmXhHdnZR2UsXhYCseCukSH/Qc2vKlsf6MbvcRWf3fXGNoMM5vmBhlSAyd/ZnDSGgMr3';
- b +=
- 'pnbkpYDBNtVFziH4JZMThUeq8alKpPzgN7RhE8Ly4lB4VJM0Y2dN+cqD5FuahFPx6C2HvAo4mmx';
- b +=
- 'yJkT3V1Q39p+yZfB6EysJc2WGHpFLrEJGPUmRhO5jOFAXeT/LZcaXNR2M16k8f2eUSx9QN5f8uZ';
- b +=
- 'SthfiH0WIsItDtoaCXnfydKR2kmcznr8aIVKhfABoP/lylP5otK4Wf2Gr2FQ7y5FnFGcrq3jWEB';
- b +=
- 'ZaZi5ALfIY+SPUPxKN518spohTHkILU8Iw8WrZeYSMHHpDt8w+4hSPvwZ81weDXcyjO/i9o+Ix0';
- b +=
- 'L3YARizNDyIA/UOYf0OT6TekncCfb6ed35QaXbbbvo/jWFqV8delZdWPVXw2lxiY5xSXMbbncyZ';
- b +=
- 'Ph6BY5YDQYiYSKKXA4MKrnzWWpwQFfKxVx2SolDn9/zYywcTgKaWNMws2uanneqQokvkBWSyATe';
- b +=
- '4YpVAF2DaGI7dNYXp5Fm1tM+Me8nA8g0wXpshX4PJwaCKD7MQT0482iUyWXvlpN9x80lwsSQz62';
- b +=
- 'sykucSIW02ay8wvm0e6BNC8Rn5d0tzYh6uUk+bavqS5pi9pbkwq7OFe8jGXNDfmeGUNmh861JnW';
- b +=
- 'ry+YNpg7V4lWdWgqhkgT5jZ32/w1KiuC7GHpDvzjE1HLqeyIVXTCINt3N7uL26KRKbsPW/jDxHw';
- b +=
- '9jauJrwkuxnJ9TYCsq0iZpME2wyIbnecqlEBK+iTzaWcPujtavQt2XQJf3cke0hOiXWlFAf3JUI';
- b +=
- 'DbVIhyb/njUmWrl53QHfmEcpKvOzPj0qcwr+ijE/wWtTXu7TNuBTwdF4hWkfYfhQB6LtB875+OK';
- b +=
- 'JpMRRB30SNzQfdTMSVfEXRheIN3IE0+RPl6QjbB15vLil+NHbHroVxWpFy7vWsc8ktnDYQ++H1i';
- b +=
- 'qZNiH0BfwFZ8uN25wIGyTsf4orO8y8mZ3+Xts7zLj836LrkWi3chJ+uBff9S73KfI9r2ySB1rMv';
- b +=
- 'Hey2xIzp7T8+LuPvIcZcX8X/q4nDBNI1k3XaS3u0i283bQrxXpCxbyFaWPfg/jmusEaNN/Q5FcJ';
- b +=
- 'dEPnKpthRaZjQmNJo9deP+/BEvdqkb55638bAXtm3BP87Peq0LTIoJfOpWWfBKZHyVbwwJGo9/6';
- b +=
- 'jeOB8mXaLdMTkDbRkKvqzUUSCQdaWwX0aQhSzUSWj2qMnUlWa8BlczF+y6SwBgQqRo5EDCfs/Qj';
- b +=
- '+JTeAOwQkUsfCE28i/l2uUIj467x0qHIVpaZdieOf+nKia78/sGhk/N3bj8obb73Eaa9lZ+3dGP';
- b +=
- 'mwEUOcpkyjuU5dQ0S9ZLU4ZHgNkSxlNLlTju1Mg5hqz+Nbv8ZViub7Qzp3gdJtW/HIRsDuZi965';
- b +=
- 'GAieOzr/MXfiFaW2KeRtwZ38NkZz+66zaEjM34dLa48eARpA22Ti0zzMDnXtHM/qC0hNf1gcw4O';
- b +=
- '4N3EfCpBs9vfquIJXJJZmReZU4V/hfc9alcQP1JlYqWlzs08+18+LgLrXjUdeV86GlEheO//1+h';
- b +=
- 'iwrNApeGRqU4V2HmfJxzrNSJa1Lvh6M2c9cpciu798PIYSXjr63Z8PzgScPmnxYrd+jS3Wt8VNd';
- b +=
- 'sKRLec+2OeCSStRtNj7U7cmu38Wt3mK/doa7doa7dYZHwXiNxOPg04T3R4GqA0YT3UYkcn5lf84';
- b +=
- 'T3hnIL1ez+hPcuEuT/45f53R/oy/wWxMTZtBZbSL1A5DpUvTc1nIGoS82XgmBJTVaxdlA3GRBqn';
- b +=
- '59+4sXaIwvDoV3xTrPdaSf1ImExcsgFWTg+LzYybPCOdZmJWZsLBq5zkK0Pr5YjVyNS6t+3GMdc';
- b +=
- '63WGWNSR+1wW1jpLVXCezwVwae4xOifDsrT9uuiVet486eRLP9ld6Idv9a7OcLqQfqe0ma2FxGY';
- b +=
- '6rSZzUmNeXrjhqj0Hs2fnbxX9JR2+aau6CO3mdHhD8LptImIO+7vUdqfDaTAiVdt7WKe5q7OEa+';
- b +=
- 'fHauPZwz+HY07BXZidvu+Yugbv/sCP3JYN3ylbuzaNdxk2G90xzijUj/7Pj+26LVt45zgRWvPSe';
- b +=
- 'RRykzO2syidBzfYQvwEncV8IFG5hzeICHDkng277r7rpuul8OVbtrWNRmEhTvvYmei2bAFuFW4Z';
- b +=
- '532yib8S3RuzK2KTHv3QZwLcr5f983PcL8wW34jQ8nT44LjcNZ44mP3X22BsW0LY6mIps7tlXfx';
- b +=
- 'AeGRHZzEV+SPyVOnwdhZej6fqVKj8igYxzMJ2uKwpX3DxhieDie4SaT78Dt+K1pLWXNxZon7PRQ';
- b +=
- 'fTRTy06GC2X9aM7EVbOjJtNztVWXGWbGjg2mH8LLyFuHqQ/utFDV5zp1wSySWolevGcLroh1O7D';
- b +=
- 'RbDZtpCsu49nzrmAyTg/83eJvsuHGThhldIbwilTpy/OF0iryfr5pKbtsrrALgrD7EYd1osp8rP';
- b +=
- '8C1MNCEXoqFw941ypn8sS8abNEJ+tP5HlOcb7izUEMm0ImM2fKWrRKvFSXBXzLUisldUrk+XHNw';
- b +=
- 'mXWHRD28VVTqW88xdN40Qe2y2jnDdkHqyeOMIf6Mt25rwaaTVHoVKpn8cShel9ohcuJ1j6K7vfu';
- b +=
- 'grTwzdgkklSVHwng/91W9/3bBgPgvO3PXRryzm/jzsf+ozf7/7g5b7bey//77ffMfF3G1h99G/+';
- b +=
- 'MNn9GgTu3/82wdWcq+BvV/51uMh9+rYO/alK7lTw87hr0XcqcrOp3a/jNsV2X7/OyrcjmVbpBFu';
- b +=
- 'R7L9jSo3Q9n8upYiT+XCDfVbRppdZnQZugFjXVmWkPtHFFtmRkauhXhz22pvoYU4j+ipZE+5qKG';
- b +=
- 'FB1WqkM4h52V2mwzt5BGTBj31oS+UYvA2gGFERNFe8iljFZ8eiVSpHRFMMnIH+kEYM9vG8oHAYB';
- b +=
- 'p/5BmgkmzfijgG2Qi3dmvjKdTdNuDiMXlZEL0MBT/QXCQoR56WLUxkxExjsN9t39pNxqXedq/bl';
- b +=
- 'nqkiiQLXi3v2EY6C9FD0GnbOC2mwIWEF+MoDVxMSAjCgWgcnuM0uEMlfREn79ymxp2IQc1pY7Nm';
- b +=
- '1dXaDa3xPFZcbnODUN81VEIq8s6YfVVCCvQh8NY9ZGXRI6nVFy+/M4IuQra01pa/ON8o6TEFEJ5';
- b +=
- 'F3rR4edjB5eUreE1kPdaX7/HlK+PaJMXLI279zvy97/DvjfHXQDh1Iw3di2jt8uz62uU3HjwbJC';
- b +=
- 'Ah7hOk8pQWIxguMjg/Ar6k9VFq6qdwLxn4Zq6hdWh2a6fyfdsQVMab8tHYQWzRQUr1oNUDf3tYX';
- b +=
- 'Fq9XnaFA9ssRJ/FLZpwqHQD6bUp8+Lw6grPk6bSQYCeH8r8We751k2yYTb5OCZYZHlFyhOcxxk8';
- b +=
- '4qQ9pogWA8OxTnEtE/sx00sDN2LkkTix+QPgxpAngk4WpbUbRuQbS6W70io5f1hpFW9YdQ2GSvU';
- b +=
- 'V5Rmz3zqdT/nNJiAm8zSqZj70xwVwwkXpgpSm1/lqBp4PM7B80fmZLKYqVQQ/1g1HOK3k8sVN3W';
- b +=
- 'AE187Pzn5zKsj+/pvw1Y1k/4RfHGF1gVYX4esMqYFqKA30Mg2FynWKukZn1zVqu54dekSjtutpn';
- b +=
- 'Vb9MWwxsmeUW16/qKt+oarlUbkogwIOmUpjyD7gLCMTobeMnCUUZQyz4ZgzgIz10giaLdwvKOt6';
- b +=
- 'p3jfWaepZdt8H5gWf5Rc5clrpRQ+qcjVs4zsTb38moB3Utc5T56gF+pTfZoY4I+qHp24fypQS4N';
- b +=
- 'ZG6RQ2eejb9MvyNglTa/j7Sl+39tb/L63x3g+pDEXqIOGX17oXQ98vD9Ovi8sPnLB8PN72YMfn1';
- b +=
- 'JvVbbvd1204W8apWmYjP0bnAnVmSWtkfyBcfFGUYk7Bc3A8OdIuVW0cZ0D0bIVK+pAZJFCEdRuV';
- b +=
- 'fCYAJqZ7wJ1dhqkNPdzKUH1ybfC5GEGhdOydNA95sQCTyeB+23W78GPht/YPW2FRxDMxKwpyd9j';
- b +=
- 'KjpdgXcKjmruImwKk0VVa2nSdSWP8AwOTrX1YKS7p+fjaJS8z2q6b9QQOOBEjnWYWIAHfZtRVoe';
- b +=
- '808r9PmCLLqg72tNi7YnyuIdC17sRyk/XaaQeU9WWjjrMBk19H8AHML7tcN77vOMUZqPfC/POed';
- b +=
- 'jYWF2kU8YPoaMfOB7otVTcx3rMGG81AVUFFh7YaDu17BVcR+Js18a2f3zc6wNq+9AakIotRtTaH';
- b +=
- 'ghuahpX/zGtlvjmVfegTbfYU/Jrlklt2BrytB9OfIaoMc+RUOvnSGiBoWXUcxvUlCNhWObNcvDZ';
- b +=
- 'mHqoi8ROY2VmMpfMKcYwiTTtU4W5ADDFrfCJneoITHWcCABLZk++X4bL55nC0mTfIUeCyf7cZXd';
- b +=
- 'aWmR3WqruteUXzu5k8+xONifu95bJcnYnUJkzqUrd0SZoGN05DlDmOYHqvSY8F3YbG8LX8aEmjd';
- b +=
- 'oT90RlJ2w4EZFPwAWZ3RvlyU4M8ynnpzZAzckrDhlNk1dL60gjApxtpZxGhPdFfNaonYgYv6YxG';
- b +=
- '7ujnPTMIMsTIIOVPofwg5X19ulQ/R1nQg3anjR680PGpzrjRIgsIiZ7DKlDkEXEaOoiTaY8ah+r';
- b +=
- 'lB4H/L8IY6gUWUR4t8cq6+VBgVbUFDjnNasRCbAACe6PJvdZRIxybRml0ytlEQkHsoiEA1lEbJ5';
- b +=
- 'FxObIAVvKIoJcxHLT9fzWDIE8WZmWRQRmGCKGQzKKG42iNxrtTExKmH3uff0Uf98souj5TE8MPP';
- b +=
- 'P/LGcVkRZFFhE+7LLBh41LHZGNMsmvoT2qG5b6VLfhWCpa+cWN9fnFuDRnVBjszlN5dwYxoHbnN';
- b +=
- '2h3nrJFdz4baXc+afu68wm7PjwT+WjHx2yeS8yQ+LbcnZfqFWcizeyI7vxOfvmz4UB3nrLanU9Y';
- b +=
- 'dudn2J8etjlFtGFWHJOdD/u68zMhs+IYlxWH3flspDc/E7E7n4l0nUeSLoNEO747IylO3p0f6Ov';
- b +=
- 'OJ7i6PDjYnR+ouNjjQ9qdH7J93flQf3dOiu6caHce/hfozofK3Xly9u48JQLiAxUdZcvyURb7Uf';
- b +=
- 'Z99egHnlePPssPop2q1KNP2K5+tAv06KmKyzAz5jLLrOjLLHMVYAukh1icc/aFPtnL80oucx2JB';
- b +=
- '2xOFzjbWmEc8XGaZxgMfYbB7yO5jM2Ty8xyX//meXIZkEkovQTWbHL/yTq9gnmmZZxqjIGUjJLt';
- b +=
- 'z3jqP6M8gO4YQs0DBYwMYihDBc8od5ZVKQuw+moRVKAYMDM+zxp8rKoPeO9aJ6zlSPjU5Wwgy1q';
- b +=
- 'U/eZ7ZH3/L/iIxTW1wWtwP0u/O9OedkFzoNIf5D3jsBJIJIMG+NVQmdYoESnV23mQJWY57TZ0oz';
- b +=
- 'ukWKNmRRr6NnC1EYL7yyAoEK3dsZ7EahOGHKREVnwbonIt1aeskN0NNCGTcO7+F02SVYHrT6ffu';
- b +=
- 'TfFX7ACgJoU4fyNOTf1Xsf1rwEDOSjZ1Y9S1H/k7VL/z/um1mtqg9eAN8EMNHX+EWC672vqX8mb';
- b +=
- 'esy19MPTW/pVUqyR5GMXaOhXaUMr+GegofGMRUMfBSLg531DHzClhp5bQ3ydFRQNfR9UyZTOcvn';
- b +=
- 'Bogfjv+Pco22pKXV+PXg1fS31V7ts02rVC7JL7pQT59OlMuiU5EG7zR2EMzJ0l2k4zHRHptFrwl';
- b +=
- '7z1+WpdqYBwmFI+rgDy/GacLTLFM+jd9+VRndrbmRkddbS9O401vJUy5dq+dK8fKmWJ1qe5OWJg';
- b +=
- 'wJqeS0vrxFIB725y5zSgdw3Rora5nv6FXDEU3aU0AYdVJ2fo70yhbx1FPKp90amveSfHIWKEign';
- b +=
- '50LFhQUy9WeBhwTMVEmSqkKdfLlgcPV+//c7VTDxj1brkd1FV6bkoIUvxuUfJ8KLWnWdKxTdZtR';
- b +=
- 'XFIK8qa1RZHDiHSR5U6CnG7IeYkU0W33YJW0EJk8mjHzpUL66UUFNRDXsvz9vIOmpP/0egKR4XU';
- b +=
- 'Djz7kFP9QQr+dEk8qrbnAY0OZxhJFROcQ85OjjvnwsGBhrOkfIm/8i2J8mvqmA7Ei5S5wGzXO7Y';
- b +=
- 'XIbRTMPOXcKLEKZjJNMqen/KFs9j47Ya3T132D2ePS1rzb5JfYaf3Y3h7MHboAX71BQ4B198lgw';
- b +=
- 'MDHrZDHbO8Co4Y0yYXI738FNL6V3OGDL7/BGPlUewXXATn8HV23yNv8O+kx5yE2gknzzHd4m5ww';
- b +=
- 'KzJwQhAqny54NetlY9iV0pflbu1HW2DySRr2yITdLNiOg8c5OcH1bM9TAbCt/t9CNOWGy+546Hi';
- b +=
- 'R3q6wlTfkUcAFau5wKSs/x5BZYOPgh7p3D46z/V3ua+4yneQTTttpbJu46HtCE6M0tMZ8uhpAfw';
- b +=
- '9wC4tdONXuFfmVvbhmDDS1MroVxXS+vIM6kz9YiknTyfhI4I5V7ybBSsnrKU+1xYE4HOSBDMJ78';
- b +=
- 'enXXwHydHLWgsmwpjVZCWipiMA1+yb4REFSv/MDafC7zdx0myEDhBX+ntKSgKi2V5XiB+/C13Bz';
- b +=
- 'QJ0d0HcRVtKW2UVIxwmMd7JyOl7bFCTqhcJ5Kw3G4IGzHKyJ5MbvyjR1pTAVXbB7pkMEzKhGVBV';
- b +=
- '6qbb7dtY9L1e4zKPqYnWFHSgpq2uxFWnZ1r4wMCGH4RvjTk5+dcnyqL4YxKXSIgbFUKdhgoQ0xu';
- b +=
- '42yAAbxVInGPm9cCvUf4MPsfuQH8zAlJS3qqFFNvsaWtpK3t6leMddCGm9sG9X1bO/yQN7hBiih';
- b +=
- 'IXuRniM/m/w5Ic/51K5/S00VAGJKW38XKi5RvrrH1FvyJ98VmkoRAUCwcJWQKawnHDyiRWyCZ40';
- b +=
- '+KRJUkRnY+W2yKzY5fxfsikWInvQbGc3bt8LmvbFNgy09UHzLkW50PSnrpT6OXDw3kCJXgGs+cg';
- b +=
- '4uVEz8pQxnaRmrAkNtXGnNm7wMdoyMFpTstx4/+rf2dhF6f+EXd8NBmu26fSttFv5I7I7EOLItm';
- b +=
- '5C9n99KUyOBg+Fr4AvLmFE2jWQicTfQ54LQoI+rMUd4+260ie4zC2BVRbW4iuKKYUrNzEYFHMeA';
- b +=
- 'wYjEs2nbNUHEyZS63OOhD1p43NowJx7XFWyJTIPrnOChBGrM2FFThrbY+y+YaBgCEIY20Xjxhme';
- b +=
- 'DW9LKhuB1aeWmEYWBLYQfW36yhz5/zAczZQsdhXEvjQ8qd7poBRteeo/UUN2zm7fgtFSR3U4F05';
- b +=
- 'JUsDB7rKiC117nhGmR+odv1LtlT+Kct9qgWfQGnYmcVwqIpgKcZIi5Rz4EW4KSOoMtkVGAn2tIi';
- b +=
- '1UXmuUEptTONJjnhPZRSatV5rzm+9xq5jgLzQzymOmXx0DS72ZLJ4+ZXB4zJXkM9It36tzMR/Hh';
- b +=
- 'hJHjWdenszPS7edBY78xzzZ1ectzTgCGJU9VV2VK7550RgDf0tOME3yVNzpIFuWxUVGOe8+IKVe';
- b +=
- 'yuFIsV/RKF5LFl9aQOxnRN44oOvCLHyZSH783jiRnjEaHDPsEdLblIoOA0PXckpGH3LF6uWWlYK';
- b +=
- 'Q0XdKMV3HLBoZFtJmZTBoO1246FYX1d6rkq+w20wbeoqmcozUA+4l947CpQY1IMQ7jLGhy8WZ3q';
- b +=
- 'bqz89wVtTbTdeUspmoqRegapeUW795iGIHIA0/RwjNc2AnBAmuHVWmlBry8lDmD4QZLNR7jF9wN';
- b +=
- 'mi6SgMnoC6ifI6O9vC9qZkW3DVWtfbCcrLsFCNbvOIgrbJrfCB3oTskcFE1owZbuQHi41ahi8/J';
- b +=
- 'MHsRIvzvKYZ6GDYLTiahzXUF5Q5fJ0lSoUexr0agLD+vW0KuuxFToqTCVuhf2LU0RUANTNghMEa';
- b +=
- 'vYGFELFpvfgNDXFiNrqU5CCfyWT1v9AMNdpa+kCRV+o9GUYVjUVlaocgOvShexjsesxh1GWl/te';
- b +=
- 'j8MNA4q0n4eF1FfaIZuNXmnqnroe8mSLunR42Qpp2X5XGQg9YwSqXFUn2SXvX6dDfK3UVWxeNwA';
- b +=
- 'Ct8oKSRDoHcjFScQxP0VBMt+JQTdSYiAq0ijhgMlJLUogG0dp9iZS8KiPp0qV+hT4qO4DX7Yekn';
- b +=
- 'aS+siYyJbz/g8K3NYs9whFOwpdavw45QXWYquCbxOqLaUAGOdc8YKNdrW1tvlbqyDt7ATbwg67X';
- b +=
- 'yFKlPOYuyWiEioYuqob8j8DrZGLh96CmxPnLJWdkKmpUHnguUHlMu0AyGtdMCQ6jBtsV9V8mEdq';
- b +=
- 'RE2UAZWpDIBo4tO6MkqYneTi1z+E0wxgHnaJiMO+bnVNlpxh5oD04frCjUf48r5FTOQS5GHU3WK';
- b +=
- '0QbuuGER9bMS1Gi/CyxnID9BYNZY50iTMelEmHSsOg4m8ulijV3aaWOGacM6HnMmp9ijPtC+6kJ';
- b +=
- 'icB07rAHNcIEwBqrCFCzDdHFchWlntG/aIcVmPu3AyZNPO+h5+bQjVy/Ppx3PsFTqZcYnRKd14S';
- b +=
- 'tQniHp5h/duAlGyuf3sinkS3gTzEmD/dTNV02ejHo0nxFMPs9zBT/1me9pBVdzyvNfw99jVYo+7';
- b +=
- 'YMzkXAjKikcmJCAkdhvlDWh1a04rVCUVFAegEr3RQSCwGlXlf0XJb/uTtakGclnw25FwQBANMhx';
- b +=
- 'UUc1Wk4dRx0NSnUxDqwbwq1jJzLsLqqCePvY5QpVt1cGa9U4CTfw2uBKVebHesrGoMuQppS4FDy';
- b +=
- '3lzrbRaSqXlasR2MFUZF1evIHXdMAK6FN83igbXM21+bn0jhPBH2tI7sXbp4ngu+tfc4GvaKBfj';
- b +=
- 'xvoH9fbqD/mL/gQAs9GfSyP8eN9e/MjfSGciMpSOOd3uCSxzLtc6Cp04SKn/3zY4xWiny00jXBm';
- b +=
- 'IKxwiJUiUlaACAyCFRSf9HV+pg6I+iukmnsBeblgyF1QlATS61/avNMSL9XxFPkscaJF7htPtF1';
- b +=
- 'jWqqungCUMK5jSmbGPj1FGfIYT/DORFmuAhJLwtWxVxhFbElc8Xkc88VjlbbS/v3MN2RI77qhjk';
- b +=
- 'ZFjXPzSOdSGWJWHO0pVGRok1NxY4jq5LVRSPOlmwR3aN6R/YrExPR1uu3tXX5lG8DUJ7L2EPuQB';
- b +=
- 'dKSSIxkOM1t+ZTlvXuHdWCal4L+v0vVLZwsj73HnMbQwYoMcpiXMPy4CjHVS3Ko1ZNIZrMd8oRz';
- b +=
- 'oZyNOsdI3/HD3/xw18M9J6t/jtGz+uOkbvjXYUp3sdYMjsQqTswI2cTT+XcKz48BiT3qvSTVJrD';
- b +=
- 'FYb3rLGxW+H3cemDFOyqbOqAcObKnZKn6Odvwlhpd5Xy4GxgNImlAQdiwVg58BBveF1Xw96xfbX';
- b +=
- 'mtnEhlH+tcVWw9aC37/u4i05UvgtCmYrYxDwiUcbkF0OXDqf5rpw/I70gf8by6fwZwxw9ffwZyT';
- b +=
- 'T+jGHwZ9Rm4M+YgdaC4+G/Trd8DavlC5aqQK1aK3ID2HW9bESb10U+PcxkQUtl62K0WsmqxU8Ao';
- b +=
- 'nnl80dLAmBQsnT969/7d/J736NRVNJSx4JxxjlU1DzxhN/drJISIyZlv3GjzvWuCVHm4/h/ceIh';
- b +=
- 'T60j8vlAkcnWj89U+qUAxc3JIuhfKWGYgC/SvF3UfmilPfCh40F2UbZHfpI/UQON2l3tm8lMI7K';
- b +=
- 'oz5wlz2/vZHQAdSVGYy0vUK45zYlHuWoKSEpxbitijrFhRV3qvIhWdUwT/1XnESzYiv1zGFXIub';
- b +=
- 'AH0sQ+EcKirrhEonR6nDqBTnRGQsBSXb6G5L2hmyujHGCpK998kD1E2al/cEalX6BtNFA9JNDou';
- b +=
- '9KTk4xqxrfzb9+N8hKHAi6kWLAtYDiNA/B4uTL4pHY8i+7s8vgWaYXR5kRhK1aWBsImckIGqkxx';
- b +=
- 'yikizjtvjM77NqOJ2vjUcXb0yePsvXH2doPuGzOHGxo6Jn0Cum9MAwO6b0xGSeZjOF3RyObUO+Q';
- b +=
- 'jlzo8BxMjlYLxYEyZxk7ZbgnlxJnttNW35M7jVpVWYoygXgOP6Zg+VvSyZwocZsXhMCsOh2lzHK';
- b +=
- 'bVdD32OXGYYY7DDHOMS6hzd5jjMK36YgBo/Yk0hLS1JhxTeJq+XkVEII9qjpk+gcnkfyUsWcAAT';
- b +=
- 'cgOfVoe/rc0nZ3U9qB1kkHmuKqk4qvX896tHmdph6PK04KWHuUNszzKITvDo/zqwKOcDrLDn/g+';
- b +=
- 'nqXJj+FQT+6zcXnKYU+lxDXPD/aEV/R5VxT2NNunMSpQ5dmPE73f9wl7CnPY0yz39a/OdFGApmv';
- b +=
- 'GxlABT0jBqOlnmKNmaQcaACVHFdtqWmpgE4SmVpspx2lVBycXxY8Za9Tg7vMocv5Aas0g+SejrH';
- b +=
- 'cwgvjdUebgDDWooMssnOl26QnBzUe2d9Rt8spx5O3sIn0Jo0cNeXA05ygykBBeLhvdeM9uWqzjP';
- b +=
- 'R2vUtMB2Yk2BB3olGlEl1NKe3+oNyb04SdybqMBCa/Psq4dBibzuUt03sB+smLafvJv0cxTRDDI';
- b +=
- 'ElTJzv2arFP75E+iMla37RgXzgCgzsNpm8dUg1H2hROET2PvfUZzVCNcjV5cV6IMaNkJrTnUW7w';
- b +=
- 'LDqwweT9Iy4BkFSXl3cricK3mr+42uHe1jD5e8H6QzNT1lhF9vQgvMDqOu3DS1HkybpM2ZFM0wu';
- b +=
- 'TXIY/tCcHL1pBLYXnCIYjVrK+WTb7XkUVkR3kaar3axXTMQ1puPLKcd+a9fHrc1rUBYyXgUeYJr';
- b +=
- 'D1k7fNSkIk2k3drLGawSbSyLl+vyju/GxEO+2RP/tyukR7YkRapMvjh3aTTSb4OfThM/odNW1yK';
- b +=
- 'jVRcSa5Wfa/qXNYu2iNt+WAeZx8CYMOfQ02TBt6xXqfu3AaTteLbFy73Zfq1RSw4EItYoKK2D++';
- b +=
- 'RzkCf4VmS9Um7VvCR1JaWTaKKVjJBRbPGLpGdfauUNbXsBNPK862kqSv4Ynw34Lom7pXzEj3vTE';
- b +=
- 'W/AtoddUz8sj+WX72vqoEVcnUlbUhDXw2Pf49tiy8zWZMWid09nS8JbHyqLaPevmgmDMCOF2IUO';
- b +=
- 'tANym3MSJFyGxmn2r/RRDsxCTFQbP5d0Ej9ZrSTg8JuSPd07c4uHdLYruzc3pWNe7Z3Q5fzN41v';
- b +=
- 'PoLFeycWmpuPyDGeuXv7dpkiEMVjy/yK5XnBFvMCVrbrHWuWnx6w5ueqd/6pDX1y38qzN1OLr5U';
- b +=
- 'mbWcbhzDaBOkUZ5d+Us6ZZpet+XNWaCmO1LwCQ8VfSn8mYRyEMhc0o4A+ErJV3DSGURAoMWicX+';
- b +=
- 'ksK2Q7PBPC5+osxnHzzvKM6fFryL2uTJI5zbZKretyryIUx48TEFZzTABUUuvXTKPndm6D3KBDE';
- b +=
- 'fotIkIXUC9ZMMBVq9bJQNFuXBxgIvl3rAb+4ZAZcT2lWeGjg9UyGIrVpBKp5UV6ZPLvQDoqfwL5';
- b +=
- '898iW8udiLGqnQC3xJoGLVCzR435Sp2rf1f5o9+txpWIgW3JZNjxr1J+C6vZ3Mah42dvxRU3jPi';
- b +=
- '3AiB9xhdhrGxNkxSG7kU8fRtfpIZ3sO5FQKJzRPp0YVSoOkc3krh5EwMIQEN6xZ2HorHh2eBWfq';
- b +=
- 'fGjSQpD3tp4zrYFPC1EGONIyPkEgWOSUQEtfvYllKC9XheB11rX0QatSZT0WaNTUqZIfXlXnJ3a';
- b +=
- 'gOO8QYd4w35f/dhTxQqV2XPfMTvuRx3tqtei07gINrAZNc19rOubCFV12u9ryt2rGYUE0I3pB1I';
- b +=
- '0BlJKnzgDuYkBqgTceXZ2dKgORmpheZAjd0CJsbIq3WXQTxybg34R4pkbtROz1u1ip6zylQqf8+';
- b +=
- 'BJR+B8XLefwYKZEJUdTTk0U+7rPb32l72JHb2fdqzYbGw6yrpIimSi07EPbuwOCZ30YQozcsjMA';
- b +=
- 'X/RUiR+l7Ty0vVFKrHIoQlUUic0PDD5P+UbSU/tclbFZ+HotPKRqdFiEN8I/So+TmML3nMuCDHq';
- b +=
- 'uz8G8Q71TVX2+0ywx575zs/+MV795xbuj48I3LOhs//xrFfP3Pkq+dlWj6N/V9/97fecfpLd/3F';
- b +=
- 'O3etD0+h4Fd/9779//zFvUdPSd88ySv+9OPffeLEiS9+WQpOoOBvT//x75x48O9+4TXrwykkbzr';
- b +=
- 'b7uUWXMb1kKbKMFSyAm1aNqsEsteZbU4elprvVKPnVekKeX3fiENNPHtFX2oqF4DeCB1cGu7DzH';
- b +=
- 'wu535Y7b4WGwZhmGzKA1gSm29W7becX3w2pFRhrIEd5/DHPDJquUNGeUtNPywKPj+aacYcDr7SZ';
- b +=
- '22gwRrLa6ShrlxXi6hM6Gpx8lKC0lPdUBNEyG2iwJOXosKkFNLKrlGTlvmo6XNFuBhb7QCkw40Y';
- b +=
- 'bcusrhCP6oghtbyXSBvvc8ThTkyo6tnseIzIdJfH/h2WeQO/C5u1nro3RC7BboWUYQyblW9M3l6';
- b +=
- 'ZKOUZlc+5HDl72oXVxrp7YJ72+gtGzk6p19TJIT1dCeGh8ladMRp1skTNaVtGCKMO6UIZ87HHV3';
- b +=
- 'tzDlGWVuVDRh2L3JwbdcacTUddPj9PxL2sBFDG1gaxQmyDTfMZmKJCCBcUx0TppAA4Cv7Xk4SCA';
- b +=
- 'jWgTJNdetiJvMbxv3FUlfnxjipQdKQ3fyoHXucJucFFRlwOLK6xWlzBXx3SAIYOLVL3k9ZFBH8b';
- b +=
- 'w+VJ64hby4Taw9rrqT3+WWjqMFI9JBJzTdEwbjn/T105RSZEuytTgncghpXzWhriTTLJyM9Pd+u';
- b +=
- 'bVfxYZ/9TSq6C3jXBm+QrvgcfAmGBAQJKeQPpJDKrw7GUvJ3i2pTpkq38qOlpDuVJGN86dGg9JJ';
- b +=
- 'vKCBIpFDaSp2lz1COKudkjbi9t4Pf2gnvBQU5TNMXnGIcu6v99FLXkoa8JJpXoijGwIhfex0Dq5';
- b +=
- 'DchbQfJfutOcIfiMvk5hmOcvF5WJ+L8DxnPcVhhEnbEd+QFpDHfVxRIqwd7zXrN905wNTStzVg7';
- b +=
- 'U/n/1CG3wDIriTR9hyCLS17jiAdrPrUzQfw9NLXDJyuuzb90dsZX1PwZRxmZO3HH1Ae398+PkTX';
- b +=
- '1DV1SACJk/TpN9Qz1PhyHxr8NW6DwxwBJXgYC9fEsBczQyQw55YF3jP7MwETruqZRo0jfRHtx30';
- b +=
- 'S7/8xxN9FerBNtaYZ1tASca1M3AmhTHLyb3sbd9EJ32/312e/mYa5R7znuNud3e/AH8W5zvtvZ7';
- b +=
- '+VuO0IjkjbZzsoKlxOSi9gtspbFiumhCvfSsEZGNVBs0e6l5ZGIuxSdfbktypvOjfvnxvu7Xll2';
- b +=
- '8hGebQBZsIqNscrOmZu+wgKr4FWTbQMcxFzfY13fiVFpqZG7JgP3HRGd77JgvyOHQCzViQsROjH';
- b +=
- 'dCDXd8k4GdQfDoTDsSYLfnCPlYz5zuJkuhGEAW2mTUwt7dvRulSDi7PDdyryh6DtNUtxvvmI948';
- b +=
- '7OJ+K5XsfpeWt+u6i4XZTfLtLbRfntovx2DDB9+hengrne0dEHz/UFD/yyf8H7fvlf4QX97aL8d';
- b +=
- 'nzBx971vF9wrne8/7PH3B33ccvd8eHPHHu+dxzP70jK28wQqrOHxNY2v7HVG9vs4SeOOx70x/+E';
- b +=
- 'ZJmO29p7gBTH+OO4WiEZUpUHTzXf6gH5CTkVs7N/dgy+uFPyo744VafT6M3wopQ8bku9N0o9m8/';
- b +=
- 'LBaeup1BdTxFcT2nzKat0LEpDTX0vORwxk8Yw00dQfo9plx+qBgVkmMwdhNcy1xfBnpFWVKP0oc';
- b +=
- 'e68WsomxAolsbXkyU8s3fIzAFkLgBVaUMRAxCaYT+jdSWLdE/+NUAFHCffNqRIXwYIncOBmpxmu';
- b +=
- '6kCIvVK/dA1NrSmAvDfrqbfrpYd+ph+u1q2+2NKdApMYXZedrTTAOyIP63kIHmMKNdSYKiusbSV';
- b +=
- 'V4oIUkQZVhTmFWAjKHg45Rp+769Phy1IhzhEOJEz+Mhv3cObrUOUyjl/aRQXRHpVq4mxwa3v8QD';
- b +=
- 'DveRvmUNIjs3LrtHgHoiY9Ds6yLPzf1X6L1KUX+I7Zdc6qdhBHlzGu0BXEzW2qQEqdLhVPZRD0n';
- b +=
- '4iDzKJXJAJrop2uVCTSINLok39wSV54EikhEQaOIJgIVkbmv2hIz+FHo7s68kjjiknO617TCLD9';
- b +=
- 'CLZ1LlyCRMkfdtfMYF4r++Uj4u6np0uSvCv+R/4+ZITYTGeZMdd4AZcUeCcvkUBHDkAz+YFoz1F';
- b +=
- 'OmpB86lIU02lBTtOJ5yWVw+r2jiAOm9muggZIFyzY6WOCza7MJIM2remhKh1a7SLhvBGRZo2yEN';
- b +=
- 'M87gGnM64hirUk5aqJ1Xp1lRPCpBt6e7k5lGkNu9SH99Sxtw35OwG3qFZosNFGqRUNMgYZLjaF0';
- b +=
- 'kjjQxROLJ5pAtHdPQa+ZU36tQddN5sxuTQJjdlPy8ucuAsZRRdeAexGi7dn6fGbad1jVP7mKPGr';
- b +=
- 'dDax0qUoz9WaJ62iiL0lKO/Au64uBQDoFpX2sAIb+gsIK+o4K8asAzRhvSXIIfU+A0UpRspXkJh';
- b +=
- 'nOyzm5zFEbyodyCaOSo1K3KXkGrP2TmIVT0T9BTdKqf0mB8LfYNqRNfSzhaVog7YO1v5hFN1OmN';
- b +=
- 'V55w3BSqhBiuC7F6NfKEO6JFJgYKOgmz3pxR0FCglOmcAYBUCBzvCllKiI7A4O/wpP0sGalB5Qy';
- b +=
- '7fKVQWT67RidjZ2DZelv289UZETHryOnBVYkonjYRpeoEvj+1zE8stxu6kw9P5OaH7bsAMCd9md';
- b +=
- 'A+cDVjZ4NHczXiL6B6NJTR6zj2dcINX2517A5LuT+WWeuPCSdBGGGupc5PSFJ5ab1nGV0z2ww0z';
- b +=
- 'YW/0vCwut8j9fzAVMBf5/F526lOy/cCnnDnyJwZ0PJd9CXrbWTgsc3uP8xxqkiRTtkIF3rzjkJW';
- b +=
- '5qUf1ut+tmHm0aFnOKCUXKuI9u2FWvRP+PGgdlTszwyxvFUR3+p06/KG2DO0MszHoldnRx2Vq/O';
- b +=
- '1Qdc9zNrtk6zXyQwMQsrmcYhRWQV1/SDGkevpYt01YKECflbTGybDusszJq56ItqqX0WZ76FcNp';
- b +=
- 'fsXNHKg1ZGTO/RO0796NQxS3hF6wPEJncADvs8wMn7KYVa9mzQnAFSHMV1177bd1jXBvsghK+aX';
- b +=
- 'efdZ5fx0XtpSOGusTPtnAs0AEicvS+vwjOKoyW1QFejgfLuOkgTlZHiRT2t2Gg1YuSY4xUxoYF8';
- b +=
- 'F9BXdtjmeNmCmiTAk3nT71jS6HYYZK9OZtOABo9cfgA/WeCOHd65WtfnRvFWmH2C6tbSK+upygz';
- b +=
- '5X+oFISee+a50fG43yBeO85vB5f8E4j7u86C+pMdx9D2yeQztf7fzRpELyx0Kps8xMlzrOwG5MU';
- b +=
- '94YPq0hR2CvW2MRtprqHNVz9jqmQXhL4QeXviEPC+97N2ZvQU+Qfdd34M9+t+aNk2rc5jbnsnbm';
- b +=
- 'T99IgX8N8FRqa75JmmuKoOODVR04pyOKv0CIN2YYOPXywKmWBw78zPsqfZhoFRACjJ2voTsyCJy';
- b +=
- 'ClgKTT3ytNKL2VTii9lU031HEYVWujOLHGIA+p/prU4KL7IyvjbYy44blBO1mpZ7NFHCxgrVv6L';
- b +=
- 'J765csn4VBE2nSqbXBaaOjl4gCWXDcSAKxY1UbUj5CPpa/FeZjGSgIzDQnTDGW91bKY/kDdKgbP';
- b +=
- '5rJNXmypsP5HN7nKN7nTBVDOE7ugF28oSPVE1dmk3U/VIE+r4G+Ev3jz3HhCeuH6x/LM3K8Hgkd';
- b +=
- 'XIqPVEVnqpcG7JTJByyrc4MWlJNVGbTQgmoctA/ng7YG0LuO2hPGDdsTRkftpDaGDgQ2g8yRDzO';
- b +=
- 'B7wNhbzRglC0MKMFHw3XBnxgqWW6mOIHGONtQdWMfvFdo8QpzguA5KuDElTofto59QodcNXnW5s';
- b +=
- 'ySYfJvcut/mDxmHIllnh6Qy09cJAls5GtSXQvVdaHEn3GRItA4ZD/Pqss3p0NAfnSM2r4xKnqbF';
- b +=
- '7JBwaibboxGSmupVJ4co1VtJ7wgXi9vC5k1mM/xQZePZm/kAYp74XzEgLUl52JLnYs15dEC70Ph';
- b +=
- 'XHzaORfPwA14nkCLM3Qu1ujwo3PxvFHn4n2/55yLSJ88hZ17jxbORcxWrpJ+52JC56LxzsWp3Fm';
- b +=
- 'WXM/+J8MwLyQeRsojeQN1hp3VRIrJPxqCXeluIXfrPxqXCe5H+whBYszYxj2NUdIS8JL+qGcGQS';
- b +=
- 'ux9W7OBTQvgLxiq1qJ53NP5jZfMI8FE6fDrVnrzuw0itoUP9qa7qMbJPfIjVgpNdq9Jq9VGX1DR';
- b +=
- 'T+pIVv636Eys6xRTlTYs9crEy9WnvXq+pJK/6NxfD80mgdMgiUqpAZbdcIi81vNp19sGw0qjDSQ';
- b +=
- 'E7Lq/R8uo9LnN5nerUat55ayjSeluJm8XHU4O0Dfawfoe21BzeAohcIc8f56BX478RE8OCIEZ2m';
- b +=
- 'yV1MH5tJjh36DSIlN9NEZZExYxl6jXAMqbooESh6Qm6SZs4UMAlh440gnysjuPWMgCbRkDRWpdC';
- b +=
- 'xUa0BwFD5UhKhDmC4h+na5WO/r1cpFs8TnuTTVEfNMOEqbEfOOCZBKvcafaIp562X06S37iu+/Z';
- b +=
- 'X8yN7QHVHguVUXl/J+q1S/IuasDpVAOsiefUItOQAy06jHKoay3o4qD6WHPZ52J8BbX6Vao3WJU';
- b +=
- 'cT4OcYVVk+ht5z67Wn6uKhvhxmZGdV/XvNVVe7VWe52r9qGgv96btd5Xy8+JoFzxq2au+Kbmj/U';
- b +=
- 'hjGzy4q4jMAiT1d1Qw0fCZI0aJ1suUknR/IHjgkiukDNYHrnjiU4UAzFYXOXka1dLnNf5ys4vNL';
- b +=
- '+p8fq4V7WXPfiJKYfo2vf7jpj6R6ZX+qZpdXrJf6Y6j/6Rr/O+P3Z1vibvbcZFZ6aBmsqMmsoyi';
- b +=
- 'nAgvkHfXaxqrCkMX4aGL8dJRS6kNB8MEblClmmy4Jhxv/GbCdeO08ptm3oYb2e/qAbbLzqDLcy0';
- b +=
- 'y/VLDhcmZzchJWpDKge3BurFmMEmu3SmBnvDtAY7fYEG+72vHnMN9qBsscFeN73OsWl1jl3gG7z';
- b +=
- 'nuK9StljllDVVJoYDyRu61UYfJF9xxlIGaac+tVWkDCahWoTojY+m52mMmKexdRv9WB9B9BgtQj';
- b +=
- 'WP3bO5RciqRYiontvQ+rZIlsSZjMksnUXIatZGqxYhW87aGPgx15+1MQ/UjovQppLN92DoIX8BL';
- b +=
- 'Z5qLeCzcD12ZnfrDYj5xw8Yrg3Hg//QHlytHU4ReLSVFmmfdZxal51C7bEMeQvV5+ww9NKXXxsU';
- b +=
- '3rJweupyWHB8oijaomRqUReb5pbqn2uGmwetreYoP4figNgQZfPzGHzNEKj0drpUq23QgSJiNeR';
- b +=
- '5I3yoRvgwm/jCMecKfebz6rkh1O7JL3jPDV0tkUaQkJ2IeEnMbhWXdNvZ6ewa+QJ1oBqKQNDsmS';
- b +=
- '+oZiSi6noXDFtmMvkFDz80Cj/0wZ0dk8MQ6Q3BsFwbzJcmbuXpWYH/x3ZNAQ287vdjW1F8f+LNu';
- b +=
- 'lFPmXoVl5F4OFyOgNxVymAYa/4qTypok++4tZc/9evblmm4/oiRMmH2ik0obnQRVrNNiUe+82ER';
- b +=
- 'U1+WfFwfkJxbR6RRzJQmhqpveDa4C1ciLqC2m8agqgcYxzhsSoeR6TnQNMk52lStz7/7kSmGjZs';
- b +=
- 'yS6Jrr9jxJICns1MrJVPAOyZIhILwAsQD/4NjeVmRs7w45ofCjgi2x24E5wezcSMIonaT5mwtYW';
- b +=
- 'hrG8wOZctSDG0NGFrvUomAoQ0dhjYqYWgj78JwGFoPmFwbjGqDr1Fny6Uaub+iq0FIG5ntYzncp';
- b +=
- '2+l53sFXBTYgMlf0/OQjQW9cwVbtoLOCSYD9R7ZnOMAj1HB2Zerm6hEqLIcfMSeUIWtrs6U0kkV';
- b +=
- 'Fzwe+6aHM016Qx6QRWtwbb332FQJpvazm+/IeQrr15LOLQ9b9qHMJM4xLiHssCN77JGxstkXfuw';
- b +=
- '9RGm0GXPR+/vQ4U6e76cRkh6OD4VPa3XVrunsbjIuTnXkP9o4AsPuSP7ZlJSl+Gze/IpUdR427b';
- b +=
- '53Dpae6UP71bAEQPfeOA+/VgG4MEeHLoY/R1/nzi8376YDEolO3aOBT37efNTmtGc6j7YQ3MJFI';
- b +=
- 'fLxuFHZ/VfzqejJTxqkblEJXZr6PMM8pzvQvnLyky7wULBpWzdWP4Jx/DLqCYock06SfDx0TKhe';
- b +=
- '3HaCdxK+0lXv0sWzPtXDQq27rfdwueS7sV/eNjJUPWZniRzpEax4akmbvxUdR8OHZZW/03cjVyk';
- b +=
- 'ZmsLkV42jI0pz/0bhUIXfZX2RntzJgN6urokzbNlw3rWwCHl7OnyDuT19mg39tf0oF+0Sn4mUns';
- b +=
- 'M6tlONg4uSw6rffCaaiQGMD/fLtswfwqDgCXNjN/I+rRYD1ECH6NLFR5r6INEQ4YmJCKjysqque';
- b +=
- '14pDwYVd5OFShNHBhrlICldbfz5U7w6s55q0Z8QDlaY36+/igV3ZtWt2VmtRf2zjowoKDFj/GPo';
- b +=
- 'qU7+0ub+4V+xplEOMmXHYeBqSknOR7pCcmwUIyXmvBR1uaDWfJgB+2dbNWGa2tqqDSsxYE6ZS6Y';
- b +=
- 'deM8c8T404RBRKk1VwMkD1gLlTtSt4yd4tejbQYz0ArisrnNHZ17aSrEtP4wzdem/q+T4Sk6Fy8';
- b +=
- 'pcmpZqd0MFyIYmdnJMP4GSWId5XODmaVMlh3HyQuf9A1kR3ZlWG7jWLaS3NBpRwBmb90ajeZojt';
- b +=
- 'TIETD5G8Zx2iTbtbQCzajjnUIiyzGgWzqyxUTFgGoI5ZILmq2V8FQaXYTW4hHRFZ8PqQw41KDnU';
- b +=
- 'gGUwU1on49V63uxBP17z5Q6gK7PmRsXiRl2N8NBt4+I0jMZpGMZp+BCNZvNlnH/S6DUKIcAgofK';
- b +=
- 'UU0sCyQOdRWP19liFEMgmOAH/DYAJNje1iIzNzHcKSD9mVIIPnQQfaqoaT/NNiFCmrVsiENRm1k';
- b +=
- 'myMEaxbdTSpOaonBsvyB7q40q48DMdn9sz3VDmg+WEUhKx0S8UmVTTD7RccYpLCTVc2lPEogIMr';
- b +=
- '+MMlVrXvK9hBr3ItV6qKPA9CkuC0tDX6HJx6vmJHzVq1FPuF/o0tQyYVdVjKWW94fatKeDAb2hu';
- b +=
- 'KC4+4pMfmQKG74v99VNGK5gyroYp4+7/vaE1mtc7lUhlG/nTyyP36WGp9XSKV/5a+dNzmr3jG6G';
- b +=
- '/XpWu0V7ytggE62RLR3jy6XungpLhKztV3hdV52R5/0S+M1t1p97bX93J9/ZXd6K8P/Xe56pu4s';
- b +=
- 'P91Z377/3VnS3vn8l3ZCjDWOIMJX7x79obol0qK453Q6UnD2VelDnd8ZpLh/q3EJhe2d9pXbrj1';
- b +=
- 'KU7Vr4ORWaL5j7BddXNmA4LfzU7609nZpOKu9Ih02AziHLA/JYP0YAJiGkhli4MK/DL+3GoSh1j';
- b +=
- 'HF3tZ6xGQeFRYxd66KQ/hyl9iZtfNcsFY7qIvM9cIuM8oCvMA7pS23zFtJuyf7u7fvo577qR7BS';
- b +=
- 'jduI9RkTiP2S2c/pz7W2l0IvAnULhS35pvXkoyPZ817FcvHymxxib81PM+BZTc3+LV7n80uXoxK';
- b +=
- '4pgvvMbMF9UM4fsroKvKwPZ+IwdN8gGAGjFatk8oeW5Fi29AhueXweVxtE+33vVzvzTOnqf5cv8';
- b +=
- 'ir6i8wRK/3yjaT+DAtEtGNtyI4ec4S2yiLK9a6/aZ0YfPUcpt/ps+qjpnnt3KbeXHhWxyGLmy8F';
- b +=
- 'XgbKsBPeMx3hRkUHojRJAN6c33R8X0ZFjuaBnw1fuGvxTrOdpJ2Z2Qpp5bIw6FzrDGCAi6YgWPC';
- b +=
- 'cewnQQfD01RR5eu0nO6vl3GvTa99Ipkc22eoiK2Z3TSlv9uoN5p4N39VD8++SXZ9zOxrprkQe7d';
- b +=
- 'Es7DjMHXRPEY5WlxN9dy+9qRuPpJeWyn54hEk5pXTNTSOgwAyly4bNLNIwySj7nRogTqM3dYINp';
- b +=
- 'rNKns5fnKZyy3vkj3++H+4GI52VG+wGab6RzqrsT39Os3kjF6/W0AQ377XmjIij6ar14Wn53WDW';
- b +=
- 'h6ewv3J9eBK/oof/VU1z/LoXwXez5BxiHGp44wg0j+ytT4j0twd/IBiIZi3vGvzISGeRyMOBbL9';
- b +=
- 'iz8HUbussgOEEzJ4hWVylc+6DNPxLdKzch017rdlbw0WsqLNIivbWerA5FaffO3C6O0caSj5ZXp';
- b +=
- 'hACK8zwjBZxxSkwbVmf01zkLKeu4t6cL1tZndkMlSOIXH0DSNpcJtsTP2zAyHvZcZe4HU7nDzuz';
- b +=
- 'Bb1OlXppTtlkknG00Q27Y0j7ovnDYZMpaJuD8HItJKU/Pk3mkhfj2zY17dlyt2VDl1plsq8lYow';
- b +=
- '4k5Jbu6aEZmZpXIrRal83tSgb+nVU4E7XtPjycBxUVLcCZGeUJt2gr+D1ROiaSfoPeSQzQ8FPyZ';
- b +=
- 'Tzfix7GRwWzZ5MO5ljyQ/I8/9ueDGNnT66A6pb/JzxwNyi6zy7ACr5fKVG3bdLR3hHqkk3dMd3S';
- b +=
- 'mjKd2TrsLOqnR05/Z0lZzizl+5s4sD29M1rkSuX72TJb7O7XzK2nYUdldlr2S05VHc+UoT9EQtI';
- b +=
- '4Zv9Z6DtLt+wh2QOWGVjInV93RHN5gd3TVyq5uYfaqxpV2VH3tHdvorx8mFmBopgidn7yOBsm1N';
- b +=
- '7X7Z5jaUy4njX7ryRtDfZXXs3fetx8PNMu47MY9ogahQrWozq2TAV00c+VrkzpBKuIvjFVT/JGq';
- b +=
- 'X+YHQp6o760kRjKp6StYgh0F9i0wXrbiZvfWzMsyWZ3u/4ti1sgOyla3IHsoLnv6yFHSyx75S8G';
- b +=
- '99Tma5vziuKzbzqMsC/46Ku5m8IPbkds2C/xUG2nFZ9Y8hO/Oxrv235DF49tlwq0vKfIzsHdJ3q';
- b +=
- 'ptHgMAd78xTFzLUxzd3YE2vImAP1v/WbWTBS5u9tOXyCtl0HgjymRPAeoI8ZODAnzd34ChrZnu/';
- b +=
- 'TCaxe7/q30R0XvlKDIySD9mYSKMj8jHT0eQtCH53tSBVNL5+51JMk/JAq9JL93DwNWgWQ7vLw6H';
- b +=
- 'H8pFWbmjs7EoH2+MToEvNOzvSHdM1d3VWwphKlkRy+PMByIoSyPHRdJXcOUJRNdv/VdfAfScZPu';
- b +=
- 'DK7aUnpQWlmh0uzudjybxyrLMYc8ao3UtbYT2bkmlniTRry+VDrBQw7gv9n5YmnCEkS1p1k8w1Q';
- b +=
- '0intPomaW552e3pypulAVamq26Wz4DpB5H36cqXi7pSobG0NA2ts4dhJQ4wD8lUjoKEgRxZAGqr';
- b +=
- 'jxN38gDSnWT7/a5hyk7+npSV+MgfYo3a8V92bDj+3mNnop0bJn7jswcesBi/B7vmWGceJLhjSMn';
- b +=
- '1WvY0Ol5/mqSnFUDQiMQ9JiVIqz5PXQ8VRvqn88bZL5PX5SeD8o4lTVj5TlrpspVsf9xzVR0wDj';
- b +=
- '/TXmcfrKTVbqyMeZXsvljWR+kxctWDlW6YrbmxvQAGAjVymHEKluHWLntEJEIGYtzu6ASOj2RDg';
- b +=
- 'P7COwU9TbsHEaG6VQPZeoQLrySpTEQmh5dYtuk9uzHrYtqY6K56uYb18pB0RRbv3DHDSaWjctuQ';
- b +=
- '6SS4wnajdqDg9Sbz1mDBGu+7navn5eh1MehB5c8WR7cgc+Cpz+gcCCUnLjdGkoagsL9AS8A5tGp';
- b +=
- 'OzVHpsbkv0CTpqonu6v7mkGVgx8BBV3qBJiA6faAF5HK+PV8ODPyASI1KP1cnpcxpJhvd0l7qmS';
- b +=
- 'pMq0amiq3IAErPNnjaW1whdm7tDDHZBt+VZOAtD8KH6bI7n3EKCrwyW3vdpR6Zj1gFnHARbeg8B';
- b +=
- 'yk75m+WP0u3bCM3KwyaF6Eg3ryNbO8IiPIA/iGZUG2v22LmkkqxOpz0i8EDKLg4O5AXPKlnTOYF';
- b +=
- 'Jx6VgnXZgc/5ggkUrM/25gVv/Y4UjGRT386nYekELURPWX1lHxUExgbSwfX86/bUXwDTGt5gyzZ';
- b +=
- '54aa0AXqlyVaDwFU7iMw4d/SUP02B/k31RT0ISog2/m0Z0T5Y054WegbHDB0yQkYWjm7tt4znwJ';
- b +=
- 'PRhLAJ6oimaoEBu5kBkBGOdJia0kDznYd7zsNUHnhmErqiio7OxCCyTG8lrSujBvmZ2X81DOq8d';
- b +=
- 'm5TOqB9QHqdLCmyCnRXvtx/eVn0fDFlGHekNuuR1ixHsMnOn/ToVwH6x+WxkS6sX43LTMQ8MDM/';
- b +=
- 'jlzp6omYB45zwcqDyooc4ENZNynjO3mXP6wS+E4BFggEW8CZPO+YNP/iY93ohu7FWIDmpYspLIg';
- b +=
- 'goMJC3Oa5MRqtgtS8GHqEGQd9U/MzIUOCf7rzAjeL47RzxC+WTpRH2Qc4hpUTLymdKB9/2onSmS';
- b +=
- 'rZYXnqFMhX2+t05PeZsNfpAhQrQ/eFiICTilboXNAJivVjVJ6nsxS/++LORTpvdEbkPYbYEYc6D';
- b +=
- 'W+HyNZspqwh9xlie2kGUz2sGYI2trWTwACrza9QOSi1I/i3BfOPdPZFHBj9nT19oXOn5t2+pf08';
- b +=
- '2oSBNmM/lwcAtsLS8Uo2rRZJiKSBlT1f5rD5rt+6aaw0fy3UmL9dt6NJW5zChvMprMVIoe4yP4X';
- b +=
- 'xNIh/CzHkh/NZrJUuQ0FLZrHWwCw2n97ebqA5iDDLIsElJphA365L/zeN+umK/CZSZy/3Wmwmzk';
- b +=
- 'nml5bOL0NuAjlsspq8mumwcS/Cvy3QeqRxl6Lb3KFUIdDD0LZdP39Mb1vj21YGFxEM1S1t0Pk1N';
- b +=
- 'rYbkPl62Rj2xiEAtRqlxmeOeM0YpyRmtvQFrH4Biy+wsPgC0s/LX2C4+ALGfYFlg19g+cAXMOnw';
- b +=
- 'ZvmzDF/A6BdYjoKZvsDCvi9gZ/gCLmEI7DGXzPgFzOAXmEcgAmXH+Vm0rQPbYbqUK5vr3Qtm6t0';
- b +=
- 'dtncw0xcIZundRQO7XG+zdfFSAz9mZ2tgO9cGtmhgqw1s8wa2c2jg5+jiL5hbF5+Xd3FpYHkdpm';
- b +=
- '/1a2WABm7q/NPfwOnznz6KBjYugi1vYFomiQwZaOBJ86/cwAYNbLSBA21gdK+uGWxgpyP0SiPKN';
- b +=
- 'TLoHjjOBxo5cI1s2MjVlFRqGPJS5tPrSnO3Cukhfj7SQ/S/n/QQqlJ79qSTHmRCw4yXTUAqfOu/';
- b +=
- 'gjghdxvCtyTxI8PFy7JM315J8W3r4tvWz9DGa7QHP0Nj4DNMmpIU1yh/h0kz7UPEAx9CZn5fPPA';
- b +=
- 'hZjnSmuXIBcS4tn/Z6e0eP492b3t5G72/XTR8Gw3fbqrQBV09RWRGLm/HubydSzBgr5xJ7GaQnp';
- b +=
- '9OzCZFe3adYENyWETtqv0lvH4rlEumHQ5gjcHKQlonDru4tMA2eypBpU3P285MkiRDor6HV4WuQ';
- b +=
- 'RzASzeqHMUdw8EZA38K/ia8DUMoxqjEcqWOm3ZX9iJHIdHMXgT8CTjMkesRBTw7dmdnY6JPOm0h';
- b +=
- 'vRjzZEQYXDblBwoeGxAbkxLGBtiSirrtvg6MsXTypP+mfFX50kvSedeamvwwaHyJIjwq2RSimVr';
- b +=
- 'aJNnp/Kqwr18E5b3spGxly0o6Wz07UevJ3305eKKe1tfYvbX14ZSotovT+hXmRK2rmE64oeqjdo';
- b +=
- 'pcFQ/BT52oETz5WbJXdDRt13SjO5cFFBhnZX9Xv5WdpBfPyyi/F26FldnRJ7w2eqH6gbKtZw8DJ';
- b +=
- 'KJvKKedgCtjwTq8Rj1dtA4vVVPTWvKT8nu25sCQptx+WEpLWYOv/WRn5TTX0MpZXEMr+11DK3PX';
- b +=
- 'kBnprprZNbRy0DUUzegaimZxDRm6huZ719DqPtfQKriGVvW7hlZ519DqwjWEtc25hkQiv9b8vPy';
- b +=
- 'sXh++JQ3hGHqT7K1aH74BRs1rgv9LXRwz+YNM2R8kLxb8iNxQS+gckjvZkc58Onng66BvaKSzlF';
- b +=
- 'A2eIfCwOUDJlJ/fq87z0N+PYnFrmn2Tg39bXSDwu4JDipYOw22ElhAYfdctb27yls+V8Pyuarsj';
- b +=
- '0EgawBPTIBRGOGcHd3VGj8EZAGtztOcM6vgnFmV8uvO5JxZBedM3/EB58wqOGcGTuhzzqyCc2bg';
- b +=
- 'BOecWQXnDA9dtiH4sS6C+MaPdZsI0UJgyeq0eaS76p7uaLpqT3cNstGvTte8rg2ucf+OeL2IxsR';
- b +=
- 'X3NVdfY+0z+o9eOkEry+nwj1lBl0+AV0+VdjVRIItXD6rcxeOunZesrN7KX5fmq7Gz5r0JTu3p2';
- b +=
- 'tyL0531c4uD1yzvXOF9Pjc27NKvT2rp3t7Ous2MI+o3Lpw99DZc/k9ci+zo3MlLPP0K+3Mn4dF7';
- b +=
- 'p6jWvdoumZnd3SGG7xI2nPNzs6LWUlnlE/eWS33y71IRl7hstQeuYduqu76nd2r5Qbycxl2xwbf';
- b +=
- 'cC1Kf2h7etm091s7/fbdq7ZvMNu7a9PL9xxEhnj1PgXqfaqDaqbkfQq890lGULPsfbIjraZ6nwL';
- b +=
- 'nfeIZufdJjjeaJGP03qeA3ieepd4nnkLvUwDvU3OkVc/tixOPD9gX9z4+YF888PiAffHxLw/YFx';
- b +=
- '/OC6bk3Gxtdja/5J/+hJUe/YxfvILpHqxAPVh8YO/BsiOg+rgiXYfetDa98q7OqrSJYBQD5ui10';
- b +=
- 'vdfLN99e/qi7d0X7ei+GO08irNWa8rh/v/JrWzf3AG17dBGrugi1SWyjo/1QPVAJkwQKtwmAsyR';
- b +=
- 'VHrfZZhepKO9nuj25iYibmHLlDkZIuRKdKbOGtR3Y7vC+uhrkiF3OZ1PXXtN4O2fdEuJILcaJ6y';
- b +=
- 'WLnml9KVbIdqslDe5YsfO7uUi+nUuk5datSO99OZuIMNRinZI+apb2iFM06PYXS0dFU83erO0Da';
- b +=
- '7sXi4v3rlULhy9Ob0cflC57NZtMvutksaRF3jp9vSa7dKI0o1fkq7fISN2bEf6QzvSq3bIw4+l0';
- b +=
- 'pOv2p5evb2zekMgjb0qvWz79h2dKzbY9EXybNy5Em8rm92x9PKb5UZXoK7Ltr9+G2ZmXNBZScZq';
- b +=
- 'ecYEyuA4G5T3l0+2Or1ye0cGQDp2i5wu43S73Hcljq3EQ++QwTiarr2VYFjZuAVeXdYJESnPQN/';
- b +=
- 'YjD9v7tiyK3Hiy7lTNAU7/Hinma6B9rIqvVSee216aXoFdou3lL0d8E9Lj5KGlVcTfWCNOhXRVv';
- b +=
- 'J6a+RxZfcKfT2v/TUduQ7ea026Fk1x6c0duCsux0KzJr0UrblSXvfSdAzfVSTJbEj+P/zl43li6';
- b +=
- '6HswS/nSo5ceunrUwtA2qVsDukP2NqBZ9lx89Y2pE06OCN0khdvCHfcCuf968ltUxyK0zqmfs2K';
- b +=
- 'rSlV01WdlXqHy16fBrjDZbgb73CZ3uGyvjvYJmfUW3emq7ffys3hnX33seX7aEgJ2KMY5+7DT5g';
- b +=
- '1bKnilwKl1FACvYgphWoKF7zv68cVS6lbESCGJzAz/BwbJRy1qQaCnQx6ncWIZG/kxDvTBAUzXX';
- b +=
- 'hwRxqF6NDIXaaNPpepTBZlp2nj8mBZZ0naUN+pSamFmX7fqR1ZZw8wG63zndoRjQ2rlXynJl31c';
- b +=
- 'nu/cdeuKl/7kBJDrMqvPYTTDpu+q1e/3J6w7urV5avPhLx6dX41eSZO2vLV2dmw5LdlYMfTof7e';
- b +=
- 'G9NvOzqr39Ye67TUbxup39bQaStX3296fhO0Gd6Va7Kncbc0yl25LXXl4jFb6sftBsnr8hpel1f';
- b +=
- 'wuvz61ObeXTMqrcuQ/vNEDjpjPyHS+xsKHDsTdiNn2Irh0htm4KD33sEhR5IwUfegje7cygn/PA';
- b +=
- 'Ll9d6dGleCigIME2L5e91mT5H/gTMC4NgiknXxMCAAyWa5qLl5m5yMMxvpos2wGW3Z1qloquGaC';
- b +=
- '8gXfbsK21WVXrwC43H/ZwdW2cc+O7DKTjwysMpOnBxYZY8+miuA0S4iXLqBvh9CdsikWPVtrI8O';
- b +=
- 'z6w+sei1MDk2YQ2rNK/n6F+tORfR3HHhslMtt6kBQdLw0uz3xlIxKNng8qF1bJ4aIwNdWmmMdG5';
- b +=
- 'ZfR6yOjJmQD4y95qboP3Lh6uVLZKittRAl7bktaTscskPIp1wvaWHuRJiWHrQyrT0iMZBK0+Ir+';
- b +=
- '6sPE1fym8cDJiyAueinW42w4eb7UhrliPOMgNMtHzzJl696XwJSOLeaYmAJU9WthLUolfO+mCdv';
- b +=
- 'EZkae7WvK2HHn/rPhQ9HE4bVniMCyA4QHv+Q1Y9IQsxHACxuL5tl01vx2Z/O2JsuraU6pqltiyO';
- b +=
- 'zN6ezvo1Q3vOcqQ1y5HZ2pMxy99XK1rfjsvyhuR8NNCYTc7P0fXMHjjQZHagyTCRBNNcxc3ykdm';
- b +=
- 'bbEbLbTCrtTd4Lmvvv0CTscG4AkRYdxSwSjuvTi5R0XRRebI4w0Twe+ms5cAvnMAGec4mCb9Kfr';
- b +=
- 'pzsU4qnOwfqABxEPRN949VcQ96i4sTT1Wnn3iOtInwFisw+IDBDDgq5TKBV9NFuk6Qez27N4av2';
- b +=
- 'GSTFfiKTfZYFb5irT/B72SlcxF+H6vSFwx/R9RRFE3/ROccizaf8vpdLtMnOKmtPii6oMHxYDHN';
- b +=
- 'bBU5Bdnj6H3hyiUTrzSfvHT/mqXxZ+p6KS9bDrTR9ssWz8BaWYeTpZJ7XaK0vZkQjukrV6O0cul';
- b +=
- 'iymgNXWf6fFplp2FlBp8WFpgh1ykOwGcri3KnWrbtV9MR/FPv7Wb6TKe1sjoPo/5Wjjch5mjGVp';
- b +=
- 'Zqa+rYqpZds9q0ZdesNq10vP6mbRdNG5Wb1uF6FvQ1bawtGWnTanh+ugAF8XM2rR1s2hxx0+8ur';
- b +=
- 'DjETQDETaCIGzTtkmLer8MZW8csdxH+weGHNcBwjA60Z+pX5XJ7VjfRYH3h9rRMxgBvRd6ekbZn';
- b +=
- 'VLSnjPtZ29POoT2t9sxKCSq1wEOlLtye0QW66sUztqed3p6Ra0+ZweuIC0zwj/MH1tQZZgEv7ng';
- b +=
- 'Bh+G+vk3tc7ZppFSzFx7+Uvfc2tT1oAXThn97cPgv+H6Hv8rtwRymgCX5FAAjP9u1CfMLGBnnwX';
- b +=
- '8x5jw6Kr00gLjw3u5hemsALpy14e83sza8HWh42tUH1AqVbmOnVrRlC26yOtQKZLmqqzBabxHgp';
- b +=
- 'B+orh+ojg/0wgtpFiucZrGg112YfyOygcN5nmsWlXRBumKz/FmID7RASRuGoWosmEGzeGHfB6rr';
- b +=
- 'B5qzFlAraQG1QguoY2EPXevUCy3AfzCDiGZppwQuJlGD8s/z3PJ/tU/+r21CCslZB4VoAIjaTJf';
- b +=
- 'cIB9PU+/ITaycupBgtAwcMe3qMnrv+qSz6oyKQRXg8rkrBtJws0hlsxxpzXJkNqmM8QGGWjTFlM';
- b +=
- 'DpVcyUtGWgVekyptBzJmQUmDYyTu110KwxIljQ4B0Zg6qwOir9Kpq5sXlmNQv5lYdaC5qtEUyaZ';
- b +=
- 'YdjvSwx0nR18hEvP9b7znze0mRcCOBe5VR1UyVIqJvNbpWzRAPid+O5xO8+jcU+T43lX0P8jn8w';
- b +=
- '4ndDpZhGWWtpFA3XKKuAorvMhpP4/6cK0/jB6M5tP71hOmwXjedxEgY4iTOgqy3rC6gCRoh+N3/';
- b +=
- 'UvydLmAzRJkagS7clW4AygLkLbY01DrihTh+UASnSaM8g6YkDNZAgp7mFSZItMAo1whmkHeYRxJ';
- b +=
- 'A2Ha5ZDjVxCE8zpHLzGI6r0UGa0PacrCZD+PQjxaMPQddYnLZgxV2sZCSLlaVClsSGgyTgorOP5';
- b +=
- 'ECG5wNJCLNTCAfNRnM6B6QnS9eHNzUVNXYT/tychleaWzMN005+ljwgHeUEaZHnxeXi0zDCFUCr';
- b +=
- 'XGvSIohwPi9s2dKp9/adqseZCsDtGj3tXflpKZEFYfZ40CulZLpVfpaCaDFM56/Dw8IEnfwkqGe';
- b +=
- 'MZ7orNcC1LuK61jWO1o7h7qB8QqlIFcrK0Mu6GulbYnS7ZoYwYRJefcsqi4dxLB7T45OL29rSbW';
- b +=
- '1xW+tum5ppt722n+BVb0s2rG866jujnAXl+zqmmnUM09pg7+nKn93kmXjm/2XvPcCiSLq24e6eA';
- b +=
- 'QaG0OQMzYiKAQkqKGtgMGICxYQJyVHCEAQTGFAxYlp1TZhRUTGjogImzJgxY845r+mrU9U9M6Du';
- b +=
- 'Pvu8u/v+/3d9ey32VFfsCqdOnTrnPjS5bEYUfL1PZvYItZcU/1u6n8EwAGCgi/c7Gxn6jiQi4ef';
- b +=
- 'IJu9GYcd57HjaQMoraYD5MywZgoDKoT78RqGJLwcwWIMkVATa3jgRsTwjrtMAO0ichv2wsn7YpB';
- b +=
- '6jW0NxWFMXPeWz76KhyyZXMbQ89y526IdLz+ItktjeADpMRvtPmnKR+tfaIm3Oj7myDxm+DxmhD';
- b +=
- '1H3zRATfAH2Ao/Vwp6npdEYGBfbO7VTRz1gMOoB1q7FFtq0XNuPgHixCnxuZr2kRM0M+BCMx8Ib';
- b +=
- 'ecBcA+pTw68yaiNTHTyYuD/CttmshZxuXw0mq50aBpIK6YFgtwoIgBRBAKTkleVlPIrrxHIBtFU';
- b +=
- 'SI68q5x1MbGKqo1aCYb4NaQLoJ2OsTUZecovkFRwx6aqQxqCZMrKmoJdWlKCCZxJwFgrDeIH2NU';
- b +=
- 'XQKuCbVXdcgApIPCLzn4oV63hXNmgVAk4BUDU9BnOwJXvKiOW+HoEgJJ5AGOKuGncQo4YRRcnPo';
- b +=
- 'ZYQBA1oHUEbQQPIwj+G7C6a4kcBekkJ+kbJH/xptlIxwViqjtSgxBDTEDDE1MD5QL9Tg71Eky9j';
- b +=
- 'MQQMQ7DgCE4fB5JlIk3lwfosMHgYtspX83yJPQfgcoDUEaeIBEkO4MZEUDXxm6LLiXjsJ4nK4Qw';
- b +=
- 'WHAD2jwbGA+LEHYiYMhZxxdi7kjZG38R2f+jkEgOwjJTKoyR/qgEQyFiZlh5WUAXAJqmUd2tMyu';
- b +=
- 'YHUwefvzAmH7+nSThNvo8ACwrVKcH+bogKsQRXjI7RqDU6uH6t7+oHn5ooG7C4Mh3MqGgJMH9Qk';
- b +=
- 'iaGJgV+h3dkrvRP9QNozKICwbFtSUGJChrz83qlGzVovVSJjMbUYywI2qhwZwtAg2oOy2zA6hoX';
- b +=
- 'BUNHCuXwIMrzlIVqKAElAERXCQsrOBCrjmQKpEg1NWlALExTh1CrsQtiRpEAXRO0WAnvJBvEqrB';
- b +=
- 'LiYi6Ioa9Eyu3SDHxVs3jM9IqxwfsfkYgM67fb35QG6Bz/DhDU2EbK/oB7AV5WQP0Ar1U5dr5o1';
- b +=
- 'w7f5Rrp0jqoWwcD79PQOp5l3VoTEvGlBEwQPIL0DiGUoiPUHNNg8rUIwonlZtLUNXoH/YyjXHCa';
- b +=
- 'ZVrLgHA1B3vKeROFdG9OAIoS6lwjQA2S0YgurHTRLG0EUbXUkPUAbAlXwW/AWGUqAciGaVHS2Hq';
- b +=
- 'kRp+ul0tFf1gu3KrgUCPEfBoef5E9D2GmATJi9FvtkhAX/1ZjrxfVTm2/vqf5HiwDzvmwTk+7Ku';
- b +=
- 'Ww/kHM+fn06YJpUJX4aGSiQuyiVdLKZXHVoy4IoApS5tT6pNFiT+IwQjn3UT5Km6QfCU0hltRAh';
- b +=
- 'P+7HPefC1VdsDEb6X/QQfMnl+mzJEP4M1qOSjlpgZciL4YbWoiHnZHCb9znQBrSdEPqbShsg7KU';
- b +=
- 'XkwRBMT7X9yKTsTpspoBp/6YGVSNTF/BHgfKPf09wg/Hti/G5rUvMtPtLsJ0Jgq3GxdzEqokSLs';
- b +=
- 'yAkDk8lEaoBqYgBUqzm82MPcTvUBXq1EP1fjvoHLRgmrAa5JXX4wXbDk5yflNRJAlmUMbIAYyQ2';
- b +=
- 'qUAdzw/s4g4tvoDa/wPGQ+rxxVcJWkmnlUm1a/SnKJZTNyNfQBFU6Hz4tm2wj6DcTW93JnpPS3a';
- b +=
- 'YIO2rIFoDfaqDtSSfpMNpKbGhA5tEmLAtW54adPUtD8FWhjXd74MwKGcKZCOg+Iv6dEjMcMuaJ1';
- b +=
- 'JCSAGW6glH5T+ex7rE7AgcCba90DQPTWUT0jNvjb31A/JsAJtwSBrwkEIzXQoZsb+B7j9Nh1zO8';
- b +=
- 'HwUg3EwMrgQq0/SiihjMDkHzixkOLpuKsJeFUyhZ5U5ETr4StSkMF45PusRhlIDgHCXGbFUc76I';
- b +=
- 'xWswjPIN+jDMVQ0BpaQGIWaRe8lMaWEctIrQlcORQegX27SFBUx4AoQjOcSXvkoSNEdD5JQRk94';
- b +=
- 'CYAOFKMIyUCrNZjPo4hmcQMQKvJl8WQ/giVBCBFhOQdzWrZddEY4Z3ZOzzhBmFOSxldg1Vdh+aZ';
- b +=
- 'NfA2SU+jJRgX+LsREscLWsRK9P1YXoQ4EcLbFdTjD3L28TIF5KlousPpp9oluchcl6eh7uHB/K3';
- b +=
- 'wI7jBGakhOGB93V5B214qrEFNKkLccukGhMSXyUmFAxckfMMINozeOdiToinVb58gWXJsDpdaAo';
- b +=
- 'QwmiMJCiT4BSVYijbECT33gKUMtz0uNBGDsCLavGZxAAASvhMpa8LGrqgUgy63IiUivkW78BbeK';
- b +=
- 'UY7bIYtrmDHn5xVfzjrxVJ0XlTvXd+3iuMCieaFMjD9VYhDvWzmFyYfeAdqrwRq7dpJw/WXImx+';
- b +=
- 'NGPS9A8gPSUi6oPDSMlBPuN2BNXjqV0tPyzWOWqFheKxlkYYtRAL+o4NFTHg14GT+kvdB6jOjXt';
- b +=
- 'ZYgjTehKLFnbzhBXm9CP+MUGhsA7Ci/w3PKkVjGwMPG3/rhXYGMVxxDQOTlT7Ut+mB5mThb2L0Z';
- b +=
- '8w0rH/RktrGK+p4V59Pe0EN5Vo4VVdA1aWEIrncX/mBS6VqOEroQQNlPSwcVqdDCPrkYHN6jRQU';
- b +=
- 'BgcVWSwXxaSQYLaEwG8zGbuw+lWnHgx2SwmYoKNiNUsAVPBZtXp4JeP6CCyoJ/QgWJl7fqVPADp';
- b +=
- 'aSCvD8RngqW/ZQKVtF/QgVz6T+ignn0n1BBkv1nVBBn/yMqWEDzVHAK/deoYCH9l6gg2vS+p4Jo';
- b +=
- 'xX5PBSuYP6KCRcz/kAoWMYQKFjHVqGARU4MKFjM//to/poLVeqU6FUQF8lSwBCW4yhAqWMnwWku';
- b +=
- 'MepsEKljE8FRwJ/MnVPAc44krlxfhAb3K1KCCoCnMDzGmgsU0oYIzaUIFc2kVFdxA16CCq+gaVH';
- b +=
- 'Ax/UMq+CvNU8Fi5se9AppTzJ9TQWV6vH8yalQQs5mlFGEzSygVmwlQoTXYzN2atHamugdhMe86l';
- b +=
- 'L0FdPCF0tObLuDgIzZU4BQlWLgALKLSe7KYp5PksFyBUSrv0cLCcqYqaH6gTtNY002DvxtQOQM6';
- b +=
- 'hyeKmFAZsdLXtRhOR5DxDC2XYdcbKPcNNFgv4BAeSW7xROxNEUF1lwi1Y8wQdjjRXKug5Qw/y87';
- b +=
- 'R4JID7eo09pCiYmslWMamdHCI9g1NTgrBxbxcjpKPyTqgxtRqc1LC0WpW52ixWwBtwtFq/gccLf';
- b +=
- '09R3uFkHIMli74qVDFPqEBfZ2HAMJ46iqmlHgSo3l4bKxcSL6a4JXS/NYgFkRJPLOqdMqBBn+vW';
- b +=
- 'Elf8fQiZB67AEFjqcUTWC2e49VS43jp6hwvDYnViLWWkuMFuoa19PjCcEZJTZaXhni1/BI1nhVL';
- b +=
- 'FMsZYkfhBMgEGlhdn0fjFbEbEUEAk0byoQJILxGiimCBAWoRFHKcyIXlAvQr+cWLdKR49mNnIBr';
- b +=
- 'AfuJlghfaxj9ePBXMjxYPsBZk8cBaqbZ4spSL5wVVc/Ek8msn6SdLJ+WPV45CtXDggiVry88WDq';
- b +=
- '652sJJVK6bFLJs0vGqUTFA/KpxrbZoXH+4ZpqRJbNYbckIzA+/ZDaoLZk/Yn7o75mfH64YZeyPV';
- b +=
- 'wxhYH6yYlJ+tmAIX/MHCybrZwuGMEdaaswRXZ05+n7BCMxREf2zBaPOHX2/YFTsDV4wRXS1BQOS';
- b +=
- 'CpL/uwXDv/7Rgimm/9MFQ0iSjiCKwtwOBqyGrRF1OwEkxhsb5UVpkI1Xee1Vj0hgX1DV3bGwd/B';
- b +=
- 'OzI6DCfECew5pqPJDQhDNiZgYS/NEgixGxLsZ4YutoGsUe5gUuxz7wsV3g0414Jl/CqFfT+kiUb';
- b +=
- '16LIUUCW57iaP22sqU5CRCsS2gRBfizBgzdShVXQrDxGNOwiJG+MUqf0nIL2n96v5XiEuUIpHKW';
- b +=
- 'bnKucoPkx6k/yBpiVg9aTlJWiLmk5aIf1rqzh82oK7yy1UpiSdSpdM7/O11fpCu2ffJQDwvn0fu';
- b +=
- 'XB1o/At7Q5IvRL+wtyP8S06ppqYwr8glCAWmqKBjWeBDj4DB7SajrHFt42lpY3C8kYkxWnmoVMr';
- b +=
- 'nxPwt946jvy6jZJTPVvzz+PzGPfWIe4au0gaQhybudSmeJMpAnEik00r5IUwYlxppMdMhI7JsLJ';
- b +=
- 'NWyQ+xg4UZYuIlG1zPahPmy1A1hZbxLndkmkQkKROTV8SJsCYf0APig1LABEHJsYodw+cF3V0An';
- b +=
- 'oOxw65rZYAmIiFBcIQLHtNF2Cs0diFLisBuyBkhCN6O9fESwsE8jRiZHgrgCrLAUIoISGW62Ps0';
- b +=
- 'p4cOu2SmkB8Mp4t2ySJQFsKtgvZoQoQuWDaRFDqo9TtFHHG0eRCOPSVa0HIJaiqpVEK8bGuQYJa';
- b +=
- '2Wiw401iE262N77dQoaQIHbxBk8pREVLiBBwcWXP60BIt/I2kK/BmrsXp8R2lT/pUk6/OAIaAId';
- b +=
- 'daqB4D6GIR+QpUD4vxnEi12kIybSxDVjrG1sYyZC0hiKowJG6YHohgg0SHIW3iWVgqqyEjJmpEg';
- b +=
- 'ttLPNFrYcNr/tAGd0PtMHQMjb2jGEjZpyiNYw3SxWC5N2YvFtEC1doporV4LQByh8awbYFlESgE';
- b +=
- '2k/k+dfgCkbwS4rqv8o7mKvgnwdo4oWuGD/RYcmDKeFprQO4pDsAl7cgFxEB1yNqx9+CF9Mx7Gk';
- b +=
- 'swaDBe6QzxZ8cKaiBMBkHaHIBFoPdcP+Gdak5ogbg6CCSqqqHvQsnxS5xi+GYAHsI4r212BKczY';
- b +=
- 'Jks6mRrYLmXVaiDBK+BpYkNVEmrQANDhFG3iceBNXark3aLpGSczmuFOYK7MQiNg6jAeUK+IvQ+';
- b +=
- 'X2AcII/cIhCM7cKtk1tZQc7oY8HUQ3eM6H7lT2fhQmzFPewasMBwiEM8CSyQYnYEOKv/OcDXKil';
- b +=
- 'NsBFd0opgY/GA/yEId9dxT/PMWSAjzPKAa6AqCqGDDDgyP1ggI8zPx3gJwwZ4HPMfzDA5/Dr44x';
- b +=
- 'qgI8zZIBzNf5ggEm2KuY/GOAqpuYAq9r+3QCDoZZygJPxAPOdRwY4hJ8EwgDfJAMsdLAT+vhqA6';
- b +=
- 'zs+UKtagOM75gEpyQ0dkoCkDzyA6BNBOqJDn/mnQKzG5yIGJTzvB3vco7nBnl5wSg8bYhOApBE1';
- b +=
- 'B6syyW4hlYnPkTZiCFqCw1j5LbkHalFXvJQUDuyBbVBjBkTQzymUtg7NJbKgIIEboAYa0f0AZP0';
- b +=
- 'zOpODOViuS7R7SN37Zg1Jp4kQYKCYjGxI6761Nxh0UpHWbTgzFnJZ6IvW8zwHCKpB077iDMUkZt';
- b +=
- '4fKeEwscIc/KVIc4Jc2kiesDrhfClA2qwmij1Eig5VySUXA7ueNkVaiWjo/RxUvA3LOqGN15UHu';
- b +=
- 'yiuSJSOOFO7SiMoccWiIXLQeweGTsA0QGmhBnFYZQfVKxP6wkyUTYnGol+UoGExyFXn4QTgoQcx';
- b +=
- '6wfgV0TYe7VQ+qDnTnX9I/13fUrTOafXL9Kp4DHxWplqF0JC9pRgqdawUcxzYHiF/goJhllIvBR';
- b +=
- 'jEWDnBjgpuEk1xWAMT/Mp+MwPl3xWU1fcO6uhSHIa/golhBdNRFO/iMvxVrYJYKal2JRTS/FKs+';
- b +=
- 'zwjTn/XiKeGBJMaxqNS/FIIbGsmboDV6rR2or6K8sqrkO0RtVbL6oZmy+CF83ozeN2oOiGToudl';
- b +=
- 'DgkxJ/q2+CUX74MxV2HWeJNURgtfKqKOw2cTvwlSq1+dG8wbPGhvqDSM0/itT9o0i7P4rkKKk9m';
- b +=
- 'YhEtqlQc6AKbgz7S6W18XIFRUkwxpHfOcS7nUBk5CD5yV4VSW0FRU7A1cJ5sTcItzj2nkgqtftx';
- b +=
- '7E2KRP8gM4Y9TMGx9t/HgrQEppNa4YBKQ7Mt4ayEBoZtCQc6BTg4Q4WPAvkvXmVUtgwtQY4ZOQ4';
- b +=
- 'tRIi1o3jtDAz4iBUL5eNoXwiwaM5Yfd9zuN/4cwy4FcQ0r/h+GSXXYDtj2l8KATHbWWrBdy0TK9';
- b +=
- 'cg4Ej4ik0qrRBh3WEsnekgxkSKqq5eyvGexzE9ZgQdEA47tYqRV2wp4cWZiPJ1gVnvwbQgqTuSR';
- b +=
- 'xPyaIj3eCDusJoaEo1FsmEIACO8xhlZ6d++7adisQr712/fqCS8EbW3ltOx+gyt5HAp4oqJOP0E';
- b +=
- 'NTt+nzFR7jMM8QX/ZEUZVrij5Ecosr9RWIbEKXcYfsuR8AuIfS4iEJqO6pqyUFTuSqGo47hQTi0';
- b +=
- 'H/cMchT/PIcXTxRFMux6gnpR7Ykojz9uKfn9G/7CvaKzbjNkYpdI/6H6C0j+LU7M+sBXAPgOg/H';
- b +=
- 'iioLk3l1FTYZnLYA97tryQS+yNbwJWrK3mBtGi5gzjXUhJDcl8JFMe+4C0IkQcm8LI8VGZITo7Y';
- b +=
- 'lzKD3cRMzJLwVcQR8UqStBBG9pk9cMFiZcTqZdSowA2lEp/CXeiWJAeoWaakUhnrJ6nlZRGRCn4';
- b +=
- 'NXQErKNyMQDvWbPzyGtUz3S6mqaP1IS8bie89Y5l20ktcckmmHmi1CVWUlO+9USbiKWxtzRcCG4';
- b +=
- 'mWsB4tcEC5puHR4A9wWBsT6qDtAcmCm4Uccus9FmMZTz4ls9C+AUPrB0tuAVEkfNA7aw179eY9w';
- b +=
- 'ONq0dLgBdvYLsESmpOKfW4qglBrMl+kr+kjGIvklNhuZh9jVazq9RINQBE+0yKi4H8EpWiOb5+k';
- b +=
- 'lJgB048hJqp03FMwDGpOaBBa2SqOXpiiD488KMKmQRclIFxjEh+/NvwzigEirbSGHk6uMmQ+lpj';
- b +=
- 'AQmcM7F1NXoNwKYcwJUQupfFgFU4LRcrfBXwIxZtzBI/hR5NcIUlsYgJF8cAYyCAA3BibMQu/zw';
- b +=
- 'OC4rAt46W/IMQYIgfbw05k4RRbtKTwBgdi/bBpZEW4tRH4nrA2MIXe+kk+uZo2inkjIKXMMdgYH';
- b +=
- 'SRAguRIYhPFGiOK3iPpGy8LjaExgUZdNZjwGsGePysUZaYlEUrM4OvpBektcp2MYRvwkURB6JgY';
- b +=
- 'MyJf1qIUseAuIuu3nJQeqZVLefdp/LZRyWBkBf3F0apwm0hGgeaPylP1RPYgLZ6J2hI5W+qfU1n';
- b +=
- 'PVDqZ72w20i82EfI04lGP9qQk6zRWKcn4UKhBF9rdAqB6QcGZRJeV1Z4b4XnJSfhPTF/3zKG9Br';
- b +=
- 'Ndwo0BK8OPDd4l8qYuCsnt0y56NGC2SKWmv7gtZ/UmBAdTEzQE9MjU6XqIsa7NQCxrwGsH1pYP8';
- b +=
- 'a8gJwXjqOXA3BJ8I4nP6j0AVID1fJkP9FSgewQNlvMU8V8bbTq+FMNcfWMj14aeBELN0vy0Qxai';
- b +=
- 'vAbrSOOakhlMfJ9mZ30KCtEpiD8jRbCX3H4qzL8hZailUX7ysh1BKfZXkD41YxpiFi1fZldYCA1';
- b +=
- 'OKw7rwF3LiZyAM6RWDtoycsfCSCnEmts0wndbsKnxhFSB00QARLf1CizhdoCZnxB/wENsoLIEES';
- b +=
- 'IbmBbHCyI5ZWmGdwM744AFixywCBrDNa452iZiNj2iWDBYJ7KzxokmdjeGc0/7OhYC5ypU2BlgK';
- b +=
- 'Y3WhSx2DQYDuzk8zphIkLH8vdV4KmCIg6rGfUEjDKBhCRgaiQQ1UwgqpFAXD2BllwDvQANHc0Y7';
- b +=
- 'L1djG/5OFFXseAwA8yzodHCOIB1NCeKBbO5dnqCt3P8VXRDsjN3JPeL4IvcAYTI9tgnpDyI2Exq';
- b +=
- 'pnCaCnI1pkHQqdGhnTg4R5kYlInTRIkUOGsihgoHXecUBQ8UIjdKQZvCCyoJkouUyRUy4ryyPYG';
- b +=
- 'wZnCh2KDLF2YY8I3gjB39BERfSItOfyDOwHPZCdqC1WAbooXdIsZHwxPbOz9B3OlkHmrrjtrvq+';
- b +=
- 'j3VP73OfT7CG8frQGsqoa84jEwRQBfjTjILiBClpeDxn4z/BN8NUfhXwC3Nxj/cooBu0b45RgDN';
- b +=
- 'o0a2J844n+BEGpgTl3LGrcTWifyVLZislorhN8i0orcJ3/Wir7KVvgrW9ERA15/97Xq9diSn6gh';
- b +=
- 'YtIQManwxaM/q3CwskJSta6yagmuWgxTUUt+ALWcd/pN7LsEUixmX4l4KRXgL/BBDWCziFgH49x';
- b +=
- 'nJvNsG6uUSmC9bg/EhKnb0FHEho5ivaRSfXJgBukUO14kXcQQGSaRLAjEAsstMPPlp/cjcQOJk4';
- b +=
- 'Fbc0QF8aEecKoEB+OCQEEO7lDRckdtvod1c0ADD1hWEdhlABqAlZRT7pQSpYBA6sBLBuAhVgkIy';
- b +=
- 'LowUTcQApO+4tsl/LFr3u0S3qROEiPPvaM0EMJSLlI2UAOA4uC12ojPcyJrQMVj6T5RfRKDz2i2';
- b +=
- '5jWYevdNFAlcN9lIGPasCA8Mh1XS2Cwa4lVyHDGcuIG19rlz/XB2bkX29ZHApFI+pe8/Pjg+a/N';
- b +=
- 'puVClkAHvi4bVX6D98yutPmjqw+WLL6r/xuGCEB6wj/TfN2D528r4ARu3rUw1YJ+3lakNmCAIEk';
- b +=
- 'ZHbVT4M5YaR2FGrjCx8TS51gQLI3zY9zny+mXFklsPnj2lSG9fe155KGvp6opX2Cs4TpI79cn4R';
- b +=
- '7mTyt7xSY693Z+76NbmPVszVSNSg1ORHyipdiBkq490ZzIRYFJ8RNslWa+gT4ZtVflQabVQPq0e';
- b +=
- 'WqMK8XVTsVJdMhVYgJOUTtJkNDLpUfIscneL9fjQqHvHEHRSgs5Rj6HwBkOGDC4DqslzNT1FFpz';
- b +=
- 'matAC5DVWOAc8W2wE5Hd08h4D2neMynwGte7D5jKo01BMYekxMJqsmDefgZkzYQtiVQ5hi2QQe6';
- b +=
- 'BA4dYyckAH0B8n3DG6MizqoOUNY9hpRDEbvdWDty1UjAsivxCrR25t9WWY8sIJVCbmc4nRYYsoc';
- b +=
- 'lCsgYxID1iWtP06UQ8gzxbwlNMd9GjW0IEcHNk8ESF4gl4p8eiD64DZ1ITomWILqycM4edxu5vw';
- b +=
- 'lurwOa4cQ5oHWwAt/7AJfa8miwppoW6Y24zwokQygVsDveaIeQYJNATb9mJtTiz01SBDhJ2YWhO';
- b +=
- 'hDW9NSCxpgcvjvSYxWFiLHdLY4G+cguWslJwBKQdGbWnB90EzeGJ9SnkTnJRxYOTTSHIy4jglvp';
- b +=
- '5njUhvYkVZBvU2kE0hzwSSR0rGD5fthMtmlK+kiEFmGzgoo8DXihTPVzwt5eOUSxbeCaqcXIx8I';
- b +=
- 'pnSEAM/BYKDZys/JbG4wZEixWGyjDJYibx1KSkJNmUEK37E+8ufgoOABhxBhtAnQkUhuphhGLSQ';
- b +=
- 'GCJaQRFK1TKRyiMAMRykeMNBRFyT9AhphCLAkQQxyAfmSmWQL14NFvkMtshneFQNAN/gxD5sT/S';
- b +=
- 'PeCLxRIutxwCEI4smkIZKC3xcHrHAp2LZ3gT5qUZFnn9/PVIBZIJgsVTDB6gehMMYVQsEarUoqR';
- b +=
- 'ZFxBcdadKZYHxMYQ0xEfYLh2bPBQz+i/31gh8iBivOfy9E1iVC4h00DaJ4DHegZplLzoLYewP4x';
- b +=
- 'aSw8xVw0kIrBV7EJg7uTRjv6rdfeH8WsztpgdNhVJf9PGdAKzkDuhpnIFXD1xCjKjmxoHDCiWOI';
- b +=
- '4TMkl+MpRsunbCsB8TLa9aVEUjaHFqIqdgpRLXBfcbyPK+xjB5UfKxel4XEGS3yAWGIER1QU9mh';
- b +=
- 'DQPtIWW8OCmXh/j8vks7RYLSIVQenjujBFjH8IVbkTOEjKHpq60HRGrALE7t39hVRckR9AKgkFO';
- b +=
- 'LCRTz4hgTDM0AuHZmm3LUD9m/khh10yLV9scscvWoFfZefkTJKBXsZsf3l2Rboc9SLcGPhSkrU8';
- b +=
- 'dUjF0hw/8aupwnGinoFL5kfNFAoFNsACBUBBqI1dqHqGrve5xs91gGjCOs6aIq8sRxIA0MHouMh';
- b +=
- 'aYBMC3sdkag3AgzucCMkco3OnI4Pr9p03LKHQj1EcMoxccAgdCYoUmcUp4WrHeGgQ0xFAF8IENy';
- b +=
- 'UfYCtE0hz0VSWyMFoROKHzv2kZwDJkOAga4tUmJWapF2o4Vod0EIRcxJov0xDrQvhJq0RYABpyA';
- b +=
- '9S7dG/d6n2CoCU1eC0pOxWrFuvLIYdiz9QFR5CNlYxpx0DX0IwA8iaZUbBHGGJ4EDUQGTRXCTxI';
- b +=
- 'ZIfiDABgxERGIxIedAAwtpM2VdKJDJ47paXlPJzFweLD6GgnjJYfhIFWQhmiwg+RJUYK1vUnNlw';
- b +=
- 'wy+Kw2YfsehXPHsfZogNOONSIv+IJJ6MCSEFmjijCXYhy+eQabM7QKeAEcAeJPg8Dsc12A1KFvD';
- b +=
- 'X0ZoYmg1omgSjm4GEDKYOKKyiiQHXW+BZRoI6DOtvPKBiHLQwUgvNlsKBHKXA3hPluXQMux/Ee7';
- b +=
- 'oskBIcg8gJTuAAc7dQFIP9DaGatfF6lxDOGrUlBrcEswNirDKL7aCUbJ2oHmNCgBk4kgR/Kki5Z';
- b +=
- 'ABogX6wpKXsPKJ0IsMvLeAfGzab6HQ2RtT6INxTHwIfWFVYQ+b/hmEA7Z3qQ6EaBqHTvx+O/08N';
- b +=
- 'wzxNWpTJ8yvCVQhV3SUB1gmCG0ARzRBRAqO8++ON32+D8TuDjd/ld+E3xrWNkT9Bv9lRgK7lRRn';
- b +=
- 'LPwsxxohB2AsxStQeuYkcUHtA6EzImHzXQXQuoCgPilc02YzC9SisgEvL16oClNwEX/cRSBwcMp';
- b +=
- 'HnotKxRxmTGPk8XBM7miEchEk7PcweW7D9iUY1KD55URJyd4M3bBN5/l7c0mpq0pCGEXCjUEibX';
- b +=
- 'LBij+oEtQd/0wxaRqMtEfzDdyBMBPhkt2IIADyv5c6RswPI47Qxn+BM2cjFSbzCk/zNnTIKi+LU';
- b +=
- 'qm+nh/cjaKqcGLyRtOU3v08rwx9Eoz0XM12kSvx92KJuL76qngmGB/yQMMrmjxL6jpFvVXUcIcV';
- b +=
- 'QkAwx0CYqHRTcWwcgh2YNpXK+l/SAQ/KidEnXSfjjOalVpFbrUdwoMmIV+JUDhjRwpnRBSNwBfu';
- b +=
- 'lBR4IIgZc3UNDT0G98x5rIn9/BLCjYApJm8AYaJvJnpEtVMVIHWoV6QFYVjSUVchPMr2FGC0MLl';
- b +=
- 'IvJb8AzeYzFMmg7WY4nPDmby4tXlZGNSFe4CmC/iVBAXoGOqnJ31o3fsAAjCafDodzyMrXtC/Cf';
- b +=
- 'yPZFbpLlReTkgg4KzwDi0pCiKOkUMblVYIUDBT5OIC7aD6OO8XAXWfhijMYCW97upHUSSqTwovR';
- b +=
- 'xSDdNXgUhgkKkmaaM1pPjA516DoOaaZRFKDPhF0Zpcq0k+QtcrBx7aqmG5Oat1G7kLyHh8IDGUy';
- b +=
- '4hLLsm6BiB1BYgka1l2NikK+AVZibL7dOwu25NYuIqKBaJ4VrChpiIWHBilU4RNhWBfQCoJLuDx';
- b +=
- 'mTSgVFayVKchkopnZxKeHkeTfDEiAEtHKlhIhBBnpi/6oWTCDZpZAjwHJGpMASSDrOVan2nJ/Rd';
- b +=
- 'CekWBiadujYWPlXw+kFltKp0vkxsC0QrDwYEJEN1MsCzqPwOP4t0BG39ztIiEMVCL8vQh/iqvDk';
- b +=
- 'THQC5KEkmwj7rSAxHA+sKpr08nJMmsGaa/Bih4eCBTjFqjkQ+IkmmFYMHBFAw0OIUJeF7EqoL5t';
- b +=
- 'pFKahSC/BUIoKksLuCT0xOHAtvxRgKCtenAfBUaWQda3LiFHItiJODfByDZvvyeJm4dLSFYegrr';
- b +=
- 'GNH/SQ1sNTYaaqIQ60ksN4YfA47z8a2uZSa6yr+G0UkKyVtA7shgZWDkzFwwBjVADHCWO8Se35V';
- b +=
- 'yxwLNjsARAt8fyy+D5JupEG3hwZkW6AwpP/p7/pfzPc/QfPSEBoFuF+kNVjNHlUA3YhZCbTAO2G';
- b +=
- 'pLPDjo8eMk8ThjxIToYZYLlxHExR21AsMRonHM4ecm6tVwwgfTejPWnT0M1Xyy1vXInIkUQYfrE';
- b +=
- 'OxOirmGmINVbGnEHNtBEE/Sh3uTjfGh/YU9IGwWuu7Ul6t1Zbo6Dx4W0qkbPiGldcDYp+LeJL8Z';
- b +=
- '+VVXK9RXtH1Py6vmzqADTm166p8RTPVAb5guvBW36DM+wociNJwo83wYmTpM1odGvAH7h6VajNY';
- b +=
- 'terbNy2iW4UlXh2xWpUWYqrEGppaIA7hNaHk486Vki0Y7Y9TzmGEI7hTZHidKaDxCyEJQyCN8vg';
- b +=
- 'kGIW58Bx/7iEuxvZAUB+CYJ0nPwZBKQSx3O6CMohFbTchaAZBzGu8hyAeZWGn3KHNOI0S8QYL9U';
- b +=
- 'kPyi26ir3lFuQi3wJ73pZbyAsulfL3UfVxHIxXfazSJ8+9WEqwuOoTN+31QVIjSolxaAiytBLaw';
- b +=
- 'Qye82iQUNQTJQIWdD1RRwdzrN7kwMKjCFtj1xPl0g4W8IwCKPV6Im8HKTwsHCzhUUg76MJzIu1g';
- b +=
- 'Bc/BDtbwaOZggx1tOtjCI592sINnFu2gB8++DvbwcAVRNzpgOHDwyKMdDOGZ7uAAD38HGTycHGp';
- b +=
- 'h4R8+DdBcQ+x5D8L10GG8AXrXQO4EB4n6MKsa8OpEDUD00oAcezlDrj6qI5tzyOZk2VytbE4rW+';
- b +=
- 'bI6cJbi2zOKpuzzuZssjnbbFltHzonW2bEaWb7NMyR1eHMII1TNifK5nSyOfNsjs2W6XN28JbN5';
- b +=
- 'vSyOftslJbjsmUGOKcmFF3XJzN7LJpFKBGXzaEaxNmcNJuzzEbE0xEn0+LMsn30c2ROqB1EicyI';
- b +=
- 's8v2YXJkxpw+SsHVzpaZoDw+njmoOltOA94ZZMtMs31a5aCqUPnZMjNPNIgYLd4h26deDircgDM';
- b +=
- 'mUbU90dDBrT5qtU/dHJmEM0Zl4ChjTxG2qkcnLdxM/WyZnScaHgB0R3XDK1SRvicaDLxhmmT7NM';
- b +=
- 'vB1j+1sn0coSgt1Ak+1jkybVIg64nmEEpqijrSxwCagTh2EmXgKcJwAkaom3x0cgAWRGiGlSeaL';
- b +=
- '7gZOrhOCeocTzQ7AIyAb5l2tszBU5SOv9Aw28cIWmGKxslHE9WNyuSyUa/IpKQ8HfBLC8dVrWwf';
- b +=
- 'SY4MnAPwjTAEV7WgG4S+xDIHuzMQkRgJeK+FPGKhPntPUV+cFn8bGgCZtqfInwM386jrW+Zgoyj';
- b +=
- 'zbB8TaIsJGlEfG1QiKc3cU9QRe8o2yvZxzpEB9h5fj9STR/WXZfuIcsBajNMlMTaeoma4dD0yZd';
- b +=
- 'AE8hS54lJw69HMkdXyFIGhgAmaSD6m0IK6nBPJbQnCdeh462yfBtAiJ6FGW1CexFYwuJQ62TIOX';
- b +=
- '5Nx9bDvWEjD1UXTkKjgSWDTYxEZcESrvjZa8QZotRuipW6MFrYErWYNtGb10dLUdpBhYb28GFEd';
- b +=
- 'Ofo/63Ipj9xcn1hQaROp6R1a+PWVEX4dVr77xkhniXhjBKVpFRhignGgCAzsUKIWYJTF4RDaml3';
- b +=
- 'l+Z9RVRuxHR7cDuFoALKGuCK1ODhJtCBGsHxsuVosSHAgNpcWYivVYkv42BJl7AO12Bd87Atl7A';
- b +=
- 'e1WBBRtCCGRnzsxC+q2Ao+tkIZO08tNktEYtGTj81Xiy3kYwuVsUVqsVV8bJUytlwtNlfMf69Y+';
- b +=
- 'b18LIX7lrfZxRb/UgkZnrbSx5a0XnXTWJolhkn46ECzrVHAG1QOGfwe22Jymvg33FZgQwNIBIcH';
- b +=
- 'nDgPm3hp8SEwjwQFCm/e+EsHlAxwTBYD4h2G0yK5sIGmNgu8qIjNZwjCBFpAOpwUJ6hiiB2kiGQ';
- b +=
- 'WETNIEpcnAjtNCaeDQuChgxRZIlLl0OL0+Zyo81AaXVIKmn4SVGlrRMckOF4XhfKBAurCQw99RD';
- b +=
- '5ovejhFpGGwfeiB3xUPmInML8owspXeeIYvpewknOROIYHocFWWIy8UO0FtrXKV70AwJo8uD/Hv';
- b +=
- 'ul5yCKGdAzUo/1P1+Md+69Uk/UvfQ5fj9Y/XQ+syX+jHjRVoR6df3y60f/O+JSQfvvHl08V82/U';
- b +=
- 'Q0Md+v/42Ij+nTnA95nBP14P/S99D/XvzLUs8j3sP752mH/ne0rof4m2if4lmkP/S/32747P/6v';
- b +=
- 'n/40P1KPxT9fD/YvVYP8DJCVFCreIUYZx2awqjIuWKMNgTfa1FEzTsPUXp8T2gbskecWYMoqdy0';
- b +=
- 'inihkJaGjmkkuhdoINt1iln4kvcAXAKDFvykqw9rHhGIO1zCQx7BGRVKncyVo7EEU5rL2o0k/ji';
- b +=
- 'JYk+uXowTRjbRyISRyoFmKVTnLHhpUAZRrsdRFJzkBaW5U+JFGDJBaNXI1kdg7kiM8nk5BkYPut';
- b +=
- 'gVUAMYwTeIJvSHI4geNnrA4IpiKgP4xllhyv+InNZCFWSrSeUBVywLOgWHv+qpXoK2JXiZsxVLu';
- b +=
- 'ZB+OKtkHcjiya18MEbVAtrNEok7CluE2g9sprSjJgZYsBzJrBhZTYW6kOKYF/tAT1UaIQqdQXZU';
- b +=
- 'C5UQMuMPgWEH3DXF59UVs+W6m+mIs1jskQanvyLhLQkOErKcgESbHAAu6nnKVSSj47m8wJ6QYNW';
- b +=
- 'jsT66gBIBQRmWP9UiWEfEOYUlQM1pzhASG8qL4gHAe7YZy6J3l4k0czjuBHgDPOLmTWoIM36lkt';
- b +=
- 'nAIg5WQaaJBlYnnhLdSruthqAXtEBN0EDUMRpUcJA8vIbXhDDAb1GrGJYFBXCb9ExJvNPMGbDb7';
- b +=
- '/gjYQjTWsHYutKhoSyF8nvAKd0Dmd3ABKiF3uAD1KaXmAbwyLb+FbYdwYhqDywh0aL9onOBwqBz';
- b +=
- 'EMKFtQINwS41P6AD2GN9XDYnxihofRig0psu5VWvfZwtJW6eVnj/OHWV+9FaAGhdXxwEkO/wrUM';
- b +=
- 'UHIjycHp0V0Q52IV+gmSrBU0MNuiEWzIPWg5SdA6+liCQjbRcS6WVvGsDqE7oCaA/xjw55liPNO';
- b +=
- 'FqtAsHdF5BrSFf5pwn6EqQqFyC8pS/KOxU5XhUpFHBYJEpzALF6DHe76WSmnyZ6HwSVGtwyLL9Q';
- b +=
- 'x6Bjcp69AUw07t+Ji5FfhdxFUAerb0kMMLSbztabSifw4r4mO70ySxN7sMTEoQMiL+ffwlGeixu';
- b +=
- 'mJa6TVo+XlPAQZ+SU/txjbyssPKJHJDgiLjNiaf+eV6cU+AR4FbuyVXplml/BWBag1f6ES3PDqj';
- b +=
- 'UQzApWhh8pXGhiQT8IKJd7CNTTMOEMN4rKkHVlHEivUw/0FlQVd8EciBXXS6w8ZXzD9LaGkL0xd';
- b +=
- 'eiWHK5JdQqMU0ckujUKDFZEJLorwyOjkFEWGS7Ii1CU6Piw8vVGoIjglPLlRdIKzR4SbZ5i7e0h';
- b +=
- 'IsFtTV1e3CJew6Mjw5BRn10Zuro08cZbQBEV4UHBitEtoSlBasCI6OCQuvBGq5H9clSI4PiwoNC';
- b +=
- 'oY/Y/qa9zIDWeLTE1JRsVTVCzFUkEURa1Af3Up+I9F7yhqBPprWSPsiP7+5w0KiUsIjXUOSY2IC';
- b +=
- 'FeQHmiCM8ZFh6AWfUb1DUb19KUpyg49hfAyvn1CGNprUSPMqYU3oD+TGmErtfCiGvkhbF8jXFst';
- b +=
- 'XFyjPGcaTAtV4WY12tuUrl6+NgrXUQtLUbhRjbCRWtgUhRvWCJuphTVQ2L1GuHmNMKQfEh3GteL';
- b +=
- 'iwuPR7wJEPLTRMzQ4Li48jBvcIzw5NS7Fyys1fqgiONGp3mAuIZ4LjucGt1MoBnNpwXGp4RRNkf';
- b +=
- '/gyaA/EfqToD8x//c/nw/JUcGNyTxohjMkp6CkeG7qiliqH0X6uTGlCjeAemuEDdCfmW7Al9wJW';
- b +=
- 'wa8/ZY2P/KzeXrp0l9MDs/xM+1wv+L1iZgNL7zfXHE4Hn/yaeon6WL5UNooSXZf9/ysgl3Tvlhk';
- b +=
- 'WIXKppysrdXHOCjw2uzu3v71+hZ0Lwmk1reeYqMfs0zi/7lVsfTLN+gB7TRE2A5IqTePd/U9HNB';
- b +=
- 'nXsegdn16JAb0PTl0yJPey+ZaaQ2YdSfr9/2D3pn2VGS0VyQMCYiLDg1HXZqg4PtP6DuNv2k9JU';
- b +=
- 'ekxjm7N2rKk5IURXB0SrJLSvSQ8KBQRUZiCurMnr5d23Xxa9M5yKdLgJt742ZuQX392nt17Ny2v';
- b +=
- 'XNAR7m7s3tTj6DE1BDUUi42PIOLTuZSosK56LDw+JTolAwuMSE6PoXqImapSNTmQTxtEMJAP4zU';
- b +=
- 'wiE8rRDCo9CfG/pDdQcF+HZQtqGDe1Dfrm29UANw/QEBfXoF9fALkvfCSf6TpP5+/kHJ0ZHxwSm';
- b +=
- 'pivAft/o/LKlbry5Bf8tcdlefywJVx9OZqtRgqYHQD+jPGP1F3tOOyd4QuVvxOr6F11u/lZk99L';
- b +=
- 'tPidJYsO7SWHvLE1X9/2/aZ85qVt9nojSr7zPq4X9jnwnTqr7PCGFhnxHCwj6jHubUwsI+ox62U';
- b +=
- 'gsvqpFf2GfUw7XVwsU1yhP2GSHcrEZ7hX1GCAv7jBAW9hn1sJFaWNhn1MNmamFhn1EPN68RrrnP';
- b +=
- 'mGj/9X1GU22f0eL3mH9rn0nRrr7PCGFhn1EPwz7D6sxmlk1/9dbq160T6nx6uyXrbv1W22blL32';
- b +=
- '4oYXVovmz58V6hFqE7ohMuFjs32bmjNEamu9qLU4tWbNy/+ATxYsO5q3VTB9/y2LUpl8it8izj2';
- b +=
- '+3su6QbfpK/+n2stdPBydr159p2KmL7+APOsld+i30GGT/+4jAfqE6a+Oy790P8tWLf7jt+e5lt';
- b +=
- 'Z+/SF1zVuvu5axR076MpQYWht2Y+blk/dVgkwY6ddda5D2+80tMwfrxXstbHuk2wDfj6dEWK/z7';
- b +=
- 'mt9/ZX09dGlZg7+8j1HYKZ60UudHG5rk/8cbWltp9Q1NCAsbmhAWNjQh/NMNze0/39Dc/rYNze1';
- b +=
- '/bUOr0P1rG9pfIQg6avNKCoThb/iY1JCUuHA0sTz43YlsBYgI67FUIKpjD1oXQLhUce2Do6HFKQ';
- b +=
- 'lcYrAiOZxTm1LByVwwF5OMWh4Vns6hVkTHR/aKh/0UkofH45nKhQWnBFMSfRZ/jyuFtWMpVamQN';
- b +=
- 'Sw8NCFMvWhVdFq4Ijoig1POiB9mDI1OjApXpISnp6iiURRUX7P5P0pKYtBAqxcfmjAkJDo+XFUz';
- b +=
- 'SZDsxVEGLF4LammDk1P4PIkoSTJ6G5KRgnIAmaB01Qi7HvrT54mobzwaZ7RpqPUo2j0iU6IacV1';
- b +=
- 'TUYEh4VxzDy5Bwbk1d4evRRSgkZCHtEWegnLguocm8K849A+nCE9KjVaEh/3wE5OFsUhEf6D0L4';
- b +=
- 'Sn8mFWrb0QRgObGprC9UTEpw10aRtlF3JDo1OiuCZceFz4ELRA0TwyYVmqPk87BLpozJcFkomv/';
- b +=
- 'b9+Y1bsCdCoXKotqWzeuOPIRfUCVj9NpuT5SxGBdf3rhPnBsv8uX/4KlO+m9lfUKHyy6yiift8x';
- b +=
- 'ru9bv+Inz/2mzE/QOFgQuMnRIjkqITUuLL4uHo5h4YqEf5ElDTT6dznCc0bVOT71MKcWFjg+9bC';
- b +=
- 'VWnhRjfwCx6cerq0WFjg8ISxweEJY4PD+598fHhcXnZgSHeocmqpIC4ceaMyT9ajg5Ch3/Jb8jI';
- b +=
- 'gOjwtzCU9PBKZ+SHKkS/qQMKCU54xZaixqSzpFuEIhPIOf9H8Llf6DLWeYyV/bcNCeEqxQBGdwC';
- b +=
- 'RE8deEau/8NTQxXhIUHhSByghratJGr2iwKTUBbdXxqcEo02hhColM4VFh0KCopDDa4aJ6ACdPc';
- b +=
- 'mW8U2tbDI8MVqMPDQyFpRKoCbfwKTEeTUezPMgRzyYjYob0mnKJsTUnfTKLIJiaEx/OE10SNsJl';
- b +=
- 'i7jwxOBS4igS0y0TEJQyFdWbGYqLnokAkONTFMzTCwy08JCzcM8Td3bO5R6hHc8+mns1d3cLCGj';
- b +=
- 'fxCHONCPd0DQlr7gnfrghGvYf294RQ3Btp4eiJviYoAjGMQdEp4YqgeLTuw/E0orxRPcB0/cLPm';
- b +=
- '7+nviEJUHohKrsLKjNPCt8tL9nw31HIrML/Ll/JJqCsf4OMOC05OdlZkezcBB2mPciJJTwF916J';
- b +=
- 'BTmP+FLk7CaE2/NbVmpcnCI1PDguOTw+fGhKRmI4mT6I4UVpLFkiK6uxRZmrzQ6LGmHLGmGrGmF';
- b +=
- 'TnkIKYYcaYaButUBex9fnyFNAOKcGc22jkxPj0BKNHpJINlKydhThiO2IJ8smHM4aXGq8sD7iMq';
- b +=
- 'qVX/dvmUGEg4MOdrViqc5wFtQh7Ao+6qiWLuJOvbiGnHKxUjOsSJ/moSewqkJSfq1SxTXiU+Nj4';
- b +=
- 'xOGxgujwg0erF4aRV21IqvwKXpCn6FooAbhmLuJTxDyJQvpdK1ZPGZTrAjz8k+yyi2tCau8lWeV';
- b +=
- '/5bjnpt7EJzgEuNSkxFBbdbIjTAGEYnkmJGP6gyGp4ii/P+WOhE/iSpCK6vat9nYsFRvVH4bmsx';
- b +=
- 'p9XDTvyjPcFKbn/WEOYSe9WusM5/g5OjQrohrDo4Ml6dGKue/vyIhIcIvwj8B8dPJyegFSvsAtQ';
- b +=
- 'eO2E/RE9YsZUvG3xWdA5s09fBs1jw4JDQsPOIfHX/b6kelf5EhpPJt/12O0NGuOkeoHubUwgJHq';
- b +=
- 'B62UgsvqpFf4AjVw7XVwgJHKIQFjlAICxwhT1+E/ft/k0HEc6OxPUtlonYNQ38d4c+9jbNf73Y9';
- b +=
- 'Anz7tXNuG9DTmZehCfMf9i5epOQbn0JWiPPfLk76YxGGhPtrHOVfkL78M9Khv3Cf8c/ct/wDAj6';
- b +=
- 'llIGMyW8O5K4gixcVzENjtB/9PUN/liiuLfpLQH+NavAo/+xe5I4b10TGYnFgBk32opq096/sEe';
- b +=
- 'rtdxH2iB8IGlLThiaHRiHeCPb6WiwRpfBPff5pgJ6a//De37yWOu2XVx7+7zjkeUf+u3yVR1G+O';
- b +=
- 'RoCdwWMbXU+jKL61mYxxxZRm3BaEKb+Zu7wvy0L6I5QlEticAo6EsVDeZWojX4wkppkF1EPO6iF';
- b +=
- 'mRrxDB8fjDgEBWaZI7DAywudCeMiGkUnw22cIigkITU+DNXvhM4CQWjHqDelNuFuUzTIuVAob7q';
- b +=
- 'Y7KpccAoXB7I/LjQhLnWI6tD6gw4/Uof098U61Tlfnkmm3tQhnK8Qj7YpxN3ERxJJNmJ8Yeesy2';
- b +=
- 'Khm2NdMpPj0fHl7zqig3jW2a0Rov7u5JCOTxKEyrSoS7jK9zTpRyH8iSYnFSHMMNXjpQzh4oSwA';
- b +=
- 'QM7mfzdKTQ7p5q9aE3WtKM3eQaSp/d08py4nzxjPuBn1rhGcnhWGIXi57iLc/Ez/MQJeHJBeQxs';
- b +=
- 'TA/SOnrCc9lsqyHo6X13oesy9My1O1B8AT2b1Hkbq9uGyqryzNgvb0PlVWb3aZLWhirvFjmkdF0';
- b +=
- 'bquWMwXf63mzjPWVbuu1G07b+z29duGPVue3M8101T73Iavuu083DjPO2tlsXXcpok/6o7QzGqW';
- b +=
- 'H9yVy7piL3HW/W92zHjPt6J+lSTrvRRvYu9+uWtHO4eO/3Krc37R5NyWse2Kpee8dCycTnU4Pam';
- b +=
- '8drbNtWNKv9wiPtZbdXlbcXjah8tKDia/sxXQ8rgn0ad7jNZZz6aBTVwTq6T5si88UdNi01q3/2';
- b +=
- '5JkOtp0WvpkwRqvjygH7X9YLbdnxvqWV5+8DFR2D86oOpL9d1TGj3OLdhc1XO3YZeSrw0HND38U';
- b +=
- 'D2rzYEdve91Djnk9Wao7wHZC3dUvdcZt8k8uX5rndves73euoZNQg606/hY06qG/dvVPJl2tpZ4';
- b +=
- 'KzO7mOnGPSYdeuTq3ir8XFbX3R6eQRk4kTbjp2ln+2jHlo2a/zmpb+t9z8czsbd73Tr1XYgc59B';
- b +=
- 'i962XXkx85DisTxS6+6dGn7uuzOnYehXUwLX9sOujOvi/XCxJWptqe6zAiOmBCtEHV9+7H1Q5Ff';
- b +=
- 's66KD9NvHwiJ79rhU3P93V+WdbUcVn663p6LXZfM82qfUqDXLWzJnXXlk326tTx87cKuRkO76Ta';
- b +=
- 'fMyX694Juq9tcez/a5la3GbPPpS5bbua3baev8eQuXfwMTfSfXNg42s9svuHq49bb/fp/O1+xb9';
- b +=
- 'ljv/n7sm/taOfgn+lS90rtub38gz696P788yR/60Ues0yvl/iHtBV/+M30rf/wXhrb6f71uw/pt';
- b +=
- 'd/wZvrg7uX1m/S2nDu7+7CmpetuFB/pHlfa95jUjOpx+GWjvdOsm/RovmHXEIUsusfhwHraBrFL';
- b +=
- 'ethW7gx/uOxsD8duTvuWT5YErA9+tWHKhlYBuiP7PDV3Tg7wG7D+wcAPqwNCt1SGpL67FmCXeHi';
- b +=
- 'g9i6jnrW7NN82OapDz0ZLJizb4DOy58j9s2uv993cc8Cbj/EWV+/1TE4qmmQ3y6bXg/ZbzF5f6d';
- b +=
- '5rmcXgq897jO911C797Lr7u3u1Nm4QdizxZS/9yqYtvx6v3duo29jjLb379z7GnllSRzKj99fZh';
- b +=
- 'zq4djrYu6VXUWDxwt97RzgaF71d6ton66l5neSjYX2qHix6bvBlfp8pm8re1mtV0ef5wMbJW7uK';
- b +=
- '+8Y2pXIdgpv3PehDvYnemdB3d72sZrfOLu9bv0neocvllX2byjumG37SDyx1cn78aECbwJeKDyt';
- b +=
- 'rN0kPXD89zcBFviHwuOXa6D0PbgW2zjM58GSZeT+/csu3qyd37edu6/qx49Ax/UY5jvC0Nt3Rb7';
- b +=
- 'Fzf42Qy0/6jfnct81Iiaz/8l9cZi+c1Lv/FJ1fdrZxntJ/7r0DAZ0WlvZvyW1/MED0rn/X/NuyJ';
- b +=
- 'uMaDHD1PTknzz14wIgr8t0dM+cM6N/D6JHVjaMDMpI7n0k8Rg3s439ds+vXJgOH3JnTsaplzMAD';
- b +=
- 'GwY6F0TkDUy12tasT9a5gUbBtzSH5GkPWjeiq2NbsfegC1cGO/fSSBl03Ghn+lrNNYMy+9w369X';
- b +=
- 'xxqCNv/o3ajrVOKh/8Z2MMYkdgxSPB1osnzIqqO4Wr+d3zbcEvQzSjr1x7X7Q0x3H2vU5bzv4TY';
- b +=
- '8lk3uv7DF4U90JjQq6TUCrw8mrj2zPYGZu4Li0pq8G7/+cUPtcWZ3gN5+ONcpJHhCcPrL1nqblM';
- b +=
- '4IvDJjesI3XoWDdJlveny3/FDyBqhg2bqBbyBpq3Py7W8NDzlF3v9nJFoSM454HBbytCFn54JFn';
- b +=
- 'vrtG6Klld9v1yPQKLc3eGDtremKoe+SC9ulbVoR+9fbp27vqUuiSqHrvmzZkww6VvU5p49k2LH2';
- b +=
- 'Law+TdhlhvauKIwJ/3RjmoetR9X7P7bA209tUpq63CDdJ7tntbGW38CeH37DjOowNf/DRzTTcsi';
- b +=
- 'g8OH1Uv732z8JbSqd/uHBWFqF7cvP24xP7REwfHXTnW8zUiI+Fu5/dCCmLaLYo5tHcT+8ixrfVu';
- b +=
- 'DtyV8PIc51qbZz2Jjgyx/ZJv81Jv0Y+dlz90k7/eKTxUEmfsxPpqIuzjzaUPG4apef1xfNoeGxU';
- b +=
- 'x7ZfQxbbL43qd37Pp+zI81GbOq0fFlmqE72xW0FBVZF3dL+Qixct7qdEv/Q6oXeDWxt9oW1e1OS';
- b +=
- 'eVdG6vct9NkSbxEyPHXbWcpxvTLJmYEfubmaMZIWnc5PnW2J0pmY3ox8/iOnyYtX40tr2sa69nd';
- b +=
- '7MGxoQuzvW3S2z18TYtZqZX67H7I2tH5Yw6BjzOrZpS6nHqP1148boTts/cOvAuNOHm/22K3dm3';
- b +=
- 'KGPh7wfNjkc51n0IbcW8yWuVvICr94O7kMe+/kcWbcmYsi92zN3m/VcOCTx5C9Np209PUS3bFLZ';
- b +=
- 'JgfN+OkK58Z2a3+Jnx/5+UaPTknxmaM/zb2/cGX8jeDfRzqIr8Q3HFn8bPYtNiFtYWx9L+t2CbP';
- b +=
- 'Ham6ThAxLaGnkmNRuZGHCcbMhJ35deCchc0B5VvF+y8RTzUdW9LLyT2wzcWHbx9y4xJ5r95vWqb';
- b +=
- 'cz8eHsJgsSkp8nGl6jSmvn10rqbSJ3c5nZNyk2cMaXXdunJd2+OOx6E/f9SVenWpqVfX2fFPByy';
- b +=
- 'QLFV2fFuXdtlmrtC1HkvJmdcyR+rmKd2++Ph3c6oZAGjUie2o1JPpHWv8L1lkfy6J4K8Z7f4pIr';
- b +=
- 'Ug7LtlctTRb3yFh3u++F5PGr+vxq81yaYlL+7lpSqjzFYlhKr5NnUlMWzzv9aHSHdSmh38rcN+n';
- b +=
- 'eTGmxLznzmp9pqnSj/41zyzulRg6ZKQ1flZVaIhna7euprakvj5rc+iJ6lHrha5f1o3y4tCmt8v';
- b +=
- 'raBfRMc+lW/uxuZE7a7uBhMTdK96WZjpyyrMGl12n9FrpMTjvlNDRx7CfnnqKgoXXc9yw0CZk1t';
- b +=
- 'HDUk/3zvcqHDlh8v4m379ehH8tYh/Kn7ulFr3vW81oTmb7Sde2WibMWpUcO6pTYdMSZdPrdgOM+';
- b +=
- '1loZYxqnZBrfapHhlpfv0kVPkdGyfOYvS3JXZXQdNlTncJOrGYkFkyI+5xkOm9LHOesX7fbDEtY';
- b +=
- '3Gzxp8vBh4XG1Rnh4bhqW2aGhtTj77rBBge8d2t2zGn5lrlfTx6f8h59pmcPcE2UPbz+1wdgbbX';
- b +=
- 'cN79Ls0yZp7IvhQZrDFp/MdhzxboJFe5/VgSN+73kqNkeSO6JZ/f2H1ukcGHH4TXJRb72PIz68z';
- b +=
- 'I0o8HcZ+ctcq5LYmaEjdVo6FGoOnTeyy5R6A8pnnxxZ+H5+8y82olELU6mJLe54jhLNotZ2vjZk';
- b +=
- '1K3+3p381i4bdVlRYXO758VRudPFd6zr62XuujQmvruXT2a93FpH75anZTZOKWhhP7wgM6/8cfb';
- b +=
- 'r4zczeyqiya1wMuIu42PhVzAXh1jMcAUn3InMcyOX3P/zc4MieGhQWngoYjkPuJF7iVP03yU5+w';
- b +=
- 'mPqwgPhnsQzp1Ii5bz0iMhXE4TSYcQPo3CrdTCJ2iiBSWEL9JEaUEIezNEWkX/yX9wrpUX30NcM';
- b +=
- 'fotr7qPfixlhEJAlOvC34r/lf8oHs5Jos2/0JHq6ukb/DzDn8X/L/8XHR/hjP66BXcTRAHy6Y9Q';
- b +=
- 'T52uz/02v9p/lqYbOtwcZqL657qj5ug5bSbH3f+05uWZriHsr+e0o2Rx6cNWNmxj8/iWh9W6NvH';
- b +=
- 'jrV98DB73Iur2xG0fTGQefZv5vj681WPq02157w+xMbWmluj3WDWhT8eNxb+9umg10e9ixEp50Z';
- b +=
- 'Ibzae43pqWYaq1ysi+O+18b/PsC3UeSBsZrtDufmx01IYLO3btuXjpxgjrR16rlzV5+vJ60Jywj';
- b +=
- 'JuZX0x3l2c/ePeibqal4SPn0fPnGn7Qu+C9d6tueNnoNN+osto2s5KuN56Xm/iIXtBg6fgF48za';
- b +=
- 'lI6qV7XqtcMC0973F28UGXk2dTM4cTE7ukFxTuXczWdsPub2a33xhqdDzq/n2rd/q2/+e3LH4+3';
- b +=
- 'uBd3PW9fmzOmBCqOB4/WGtWgZsbJJwZntfkfG2m5afHF26Fy77gNr+czUXbrQvLRzxrUxN0ZdHu';
- b +=
- 'm3QF9n622jqIL+IafnhdX/9e4gc5Zrbhfw4tbo1VXbn7XtvtnIe4uzxZo6fid7dJ3ZN2b1tPz5Z';
- b +=
- 'X2M5StGFe4Y7l93beXIy28rXtk18Q8vCTqyqsdu42MbDniXWeSuejS/y7nH+kcMWrzy+O2kcZaO';
- b +=
- '4f71ARmb5JaD/fe+K7SPlKQwk686l0Z22LLq66B+lj3y6jVNKHRsMn5J2eOvnTuaXLF8lvsq0DZ';
- b +=
- '3cWZUTviF5mxQvcKttvs/dZnrvjr/fK13lpt3BQ7c1PTXlgX97XcNfXjAxCnk5si6g9bN7e3b5d';
- b +=
- 'PMCYtYvUVRRyqPrHv1Qn/Yhx0r51i1Mt/lNWxpcf9+ikbOs8a1NT3W7lOjcqujGzdMmzzJZ5HIs';
- b +=
- 'J32zE2r3l/d3OlO+tpFn5pZi5fKSx/PHPk2fqxzr00uh01FWyMjc1LDDvRd2Gdo3TpxhmeerKy8';
- b +=
- 'MnHIkDeHar+StqyyvlLrcXszrb2T9jezc1r+pYuZ7/ZeZwzjvsYvHNw5wM/toqH+pOfb/Yznbho';
- b +=
- 'c2S7bYsxkm5VL931QGBTUtdoZ47mevmBm123+4DJF7503B/dq6HiyrdEcs7ITIrs+b5ue3G085L';
- b +=
- 'aX7bp1tFRkUVC/QaVL2iS/EPPeOU0SmKri3b2MXx+I191mlJP/dFPF8cMzn9sVnes07Jmt1q4+0';
- b +=
- '7x1zl551XkWm/Dppblm+Y0k6nz+iLcJBpf7fq5rfEE34mHj3at/391lc71pg1fZGV4cN6He5x5z';
- b +=
- 'jiyf1lNqlW2hX1BxZteR/LVaYyvTEjYsMr5dYGU36OrlaytPl/TZXBhi7zepY+fOhR1HdZf/VjC';
- b +=
- 'txNry0tKz588HDjl2+cTN3isbm5kMH311qOHwPi1uXby/7lGZIVv/1ODAMYNeHfKos6pgrXi75e';
- b +=
- '6VWR2iLN7GHuz+uHevRTNMfh1HaT7NqF/r9GrZjWsjU9jeWk2W35x+7fRo3dNuv34OsGoX9+6BV';
- b +=
- 'fKd1U1arn7T9ouB6eLeHwJuOdkGDJzbY2DM3EtsSJ+pO0VXgh83euU/h9331upBuxWHT3XsVty3';
- b +=
- '/+Vrq8JnmHKxY+MunU0KXX/rprm9ndzwhOGS9U7jbZZ0FIteh4UusJZesdgbEFt4V3NR0+m2D03';
- b +=
- 'Nlpl2OGaQ8/pRbKcZijvcOkPP4qT0LleK2rZfaz1uCN3OJii09NAF08MijV6+or2/LTKzfHgitt';
- b +=
- '31Zh6eQ7Wiv24wNyqVm7VfFlrau29fhf7cTa9sTkauOz3ahr6RYfw2yWiak/nKJ73kJ82aZAZfz';
- b +=
- 'S3VrxxvFN+hd9ORjlw4c/h+1J0pK2xrN09/72qb9YiO28nZXtxuPu73hh9fF87f3aRWcFfzgg9G';
- b +=
- 'zd93cAroNiCoZ7Mo01cF/ewaNTy7M1U6MrPN4IC2/Sd1tOhb6+rh9+dd55+yXOMx4pchxnXOfFR';
- b +=
- 'Mydk6bfN0/ZcfG5jaF8kbTV+uVV/htEr65nDxNYvff9u70q/57tLxdhcGaM69Y/zuvau2ZdmghR';
- b +=
- 'ddX/x+wfGc/YegflomUXd9M6bWcbkxNs1y8L2bGizXPf6wTo99d08NMrHKHn1aN+vyS40E/fnjL';
- b +=
- 'nVm356LGmNCHfC7cOf2m7y3RlYNhj6l186PvmS4w+b9lvdXTIoPTqInmjxbnzKz8OCAjxvZhtrX';
- b +=
- 'o1Y9HeHb81FWwmynLVaO5+4EFPU56sX2+m1fGjfAdGyabZvBGb+EJK/d8G1Qlpnh4j3lpyPeNlh';
- b +=
- 'UxG5yP9a4j3Vm2BB5jwPFIwfrvZm2bMAN0+PbJ0Veif5y9F7L/ZXdRmYa3pg0VHHQwGXdRReNaX';
- b +=
- 'cafbPOOj+zvzj51cSCKTGtbPeFm0W09fGtcHp7tnfLXvM6fXtkuDxP5NNVPnFnnzm7X7Pu62we3';
- b +=
- 'mOiLp5oHpwx9HOZd//nZj17MFxGUvB9549Hok6YBhqN9180f9q2qJUj+qelmPbub3tmVaebrWZw';
- b +=
- '3b+YHnx3re0Ic337ZVbfvLuuPtrWc+amiiNGnY5Fvw87uUFqGN/X32+rgd0vLZ4d9K+c3GL1y4z';
- b +=
- 'k1rm6FkeOvPS8nKF9NPvN4TJ375bGV3we7ntXlr8mYZfu4h0R5Xa3F+w63uBUgEOdOYmjGvbIsx';
- b +=
- 'jjOycxR7HGquhanfAXKVuMF6VOtDIYl/p+iksryf0J2fbmg/KGKzxmBOnUmaf5ZImn5Y07lr/2/';
- b +=
- '+BteX5ce40XmQ1NujzqsG7jIeom66lxesr8WmyHa63bdVkRefK+4/mtHaafsdTcdHzRhYc9Ku13';
- b +=
- 'XNu/RJFv0qyuTud2z65kWDYcFW1ZNp4NrFxjuOx2UL3p7V0NpnskWQ0z3r16tM2WXStjX1dWDqp';
- b +=
- 'r6rJmzpPfbjuFdM+Zvr6q8xPWPPV51ftm+ose6HfZ+FuBsXVG/UCrWc6VhQGKC7Vv9V5j2qhXh4';
- b +=
- '4GezOmXi29vmN0u56GI3ZLL4/6dbrp7IVzp5yS7LKe63LB5JvhqqFphTcuKIY0MsuYcr3Nt9XdP';
- b +=
- '854vTn97Z69htPWfznztbVNmc2THf1koWE2lZPCfNwbF9LmL4JMt23bjhbn2AXTygLpgsB713IP';
- b +=
- 'NDBaLmoeZC5+d7KgbPlnq3NGtmMXOncpiB6k2LPA5mjHNj7mC29PupDT0+Ltl1tmEq3oBUaHNNb';
- b +=
- 'tMeg59ZlL7EvdypSDthqxsq+KtIt7p8hKE9vXP20uLu52zOmg0bcL3SKnxu7WM877ODI95Zfuxx';
- b +=
- 'xHVQ43Chph1zX468d6R/S0d7it/yzPDLXQGX1stsO5i3kH6zoebXJ8jPHQk+k9T+3cF5mgO6SNw';
- b +=
- '3pP+49JztdWzj5uH5g46VTXPh8tDr/ZM7L7tQuZw14vbd2q4Hdj6TOXIw8a7f22v2ih+5eM9/YX';
- b +=
- 'HF/ncfvcIjx+Nyv7cnimZbrtACur43WLBn1aRx+LSzUZfGfE8A3aAbMsjhRHLnsxkJ2fN/tgoc9';
- b +=
- 'juzcps1vH3HexunkvTVyXybk7oP4194n2r03uP26wKPtk3o7CZ4VOeZllbOWNG8EJnejArZ26pT';
- b +=
- 'Q+XmG1vsu9+7XPn6iqt6xV7vQLyaYvL3Qf331oUtdnW49dUqTXM3zQ5+GFB3sfDC/sWTB93NRUa';
- b +=
- '87Y4UaA+67PgddydGNWvDfN8rlv0capPHRDp/jEZw9nGkbEVNZtpqenaW7Yycq8jZ3NY4f1Txqu';
- b +=
- 'aBlrlBI/3GjhKLPe3frseWHzdeKVAX0/y29/NazVqXbI1tm/yoOCpw720Dhm8/Cc7YN6a9dFZt5';
- b +=
- 'v2fVDhcR8wjVzbrdD753uO8MufkweYrRyzpSIBtG1yh6Ver0qezLc1vb6BbucXWNO7m4S0p/p86';
- b +=
- 'u5hcWNzlohTVd+frf1Fl1w3SjwdVhG5cKJv8x+OcHTw9jN7ubbsYfbdxry+Wo/zUMzfOpaWDUQa';
- b +=
- 'S6J7+NqvnHx6dULehjnXj/d4tjI2la1LdxsVs18ZOd9d7Vri6+2HXdk9Ls9Ln+3BdV9fMkRt85n';
- b +=
- 'Dx7eMGZRwBHjE1uXn/B5aNhDe5X56fLsfPsVuTatGIcrKVpFN7y9FgdY+ut1OkZvNX2vMdgy8tM';
- b +=
- 'dH5PVOhLtBfWuf/DcMqzH57FN2YvXdPNn+LhOCyyqv2NW8+eWxp11OH1maqubH5998AneZ2LQQp';
- b +=
- 'LVakHL8PuH+/6+wGo+e6ehHhX2oTx+pe603I+506we1Vox/+HHs5N3LE/yDr7cynS3jf/NXbPXt';
- b +=
- 'Pg45s18K9NvbIPgLQsO7Eo9PO00t3/gbjfrHKt6ZjFzDpyR6t+P2hRSarp0+C7DiUMrriS0sp9Q';
- b +=
- 'd0yk4YKZA22892U1vBc6r1Xrikpr39Q7vo2PN97TfXv78G+6HczODfSPn35h+tHVgzS6H088Yxh';
- b +=
- 'wZMvtzn0s2176Et9t/f2xNmu83o3Rzuggujm39spJT06Z7fp0IOrc4LhTWRnjHsW/aG1U/6OW/o';
- b +=
- 'Qmw+7+9vYs29mqsa1sdnNpXG6j7rfqt7ksMR1gvm3N4fPFqyZfHt3r1M2zbKHRBINLskZJN3IX9';
- b +=
- 'rrLBIy+Zxuna+I3uV+Xy2bXbU/l//bYfNLyNSuXDV++IX3UppXcLZnxGo01y2KCzoysO3fbst88';
- b +=
- 'Ftv1PM2NmZh5Za59wftupjNHWQxdnXVSM2JERpdahyqvpcwzfiml7+gkOk9fH7u87q89+9n3u0D';
- b +=
- '5Lwt01N37fJt9Omtqadrut0ujTWwTv756v/njJdZkaMxwkwVtzEu+9j/k1Gi4HvuqzcynBzReHT';
- b +=
- '/aUEd/ZIONlmUL9fdWePbXSdizNOmobIrJydutjiV/7CiZMndr3fPWiWzhkrD0J/31LxfU7qnb6';
- b +=
- '2MXq5JM/8EvNrYavmfHmgtssI5p4wjvrNf7js2Z2/DZ9WSr82yPxBMRPSIKnvftUBi2M/eZ1ZXA';
- b +=
- 'FUX62bXqdIh7vf33VZNNfTdsn1VZMcYurla9oDnZLQxTCyfZv7Fa/KWgWf7XZ5LZ1u8Dz2+ut3H';
- b +=
- 'T3D2zxs+rrcWaNRw+9O2u2tMK5l5dbGwXt8rQ+GBfWQPtkcP2OX8tOpLR0iYtZn2353lfgo/3OT';
- b +=
- 'Z46ey5Zgef7ZEGWn29r22sfb/rNSMjr02f2/UfGLrq6jj9yo2fHtmUT3WN3djJJruwopXx6xCZ+';
- b +=
- 'bmLdYpfxd+uqHP5WGrZg9FG46esOPTIfMnWi/Xa5yxavdA2NtFf4/kNi/rtn4mXmo8vNM95fWlR';
- b +=
- '7S1VPWMnL+qasfi1UUqPdyEJj09MSG/nMsJpbg+7gfmDxuyTSc8eitl3ZLyRj8WdnZ2jjlu3MFg';
- b +=
- 'y8ZvXGf0o4yH1MryHNRxsMe/yvBlj7+jaOzrMblzee0t741vG+h62Fy22d21TLy99erOrW6+umN';
- b +=
- 'HphvGkjbH5EXUz+w12CF46Zu0x+2X7nu98nO1u2nVr160LdidYdps/JTjn9LS1LXNXvLsVEmiie';
- b +=
- '/OC1dLVlc+OXtrewG9MB7bdAsdBCxR1Rxm+m3Rjk0jXSuxra+H7Nvur3odfLPtHXzCpyOtkfG7g';
- b +=
- '4mMrPrqYjJiwju1KG/YIOBJ6w2vAvZ0fpQVWSZGXUwyW2li6FNp9+j2ht2lpj471L2UVrq9d0tn';
- b +=
- 'F5bWhYZPuemunNblvqn3CaPOox37WB/SSnrUaaL9uiI6Bk3vOJdNFK6ZODje3LO4j0eWczg0znO';
- b +=
- '01wqjFqzcNA/Wqjl/a+d66zZxfr3x+s/9FVcstiTcPB5mJDI3M5g706Gd17G2d0c3vGYof2Lxw/';
- b +=
- 'Nw7N/e6TNp0+nKbiie3p9i63ri0qvOYZQNbPzS7XGtsy02BmTcfLzvZbZN7T6MBzZu5bCs7FpVx';
- b +=
- 'euSdbuMCbG87D943sOmFgNmrw/wVojRzm8n3wjfVT1+T9mT7qmmnDhj93vZiwra1dQxeGk++OHK';
- b +=
- 'zll1IzI199WU9Wtdtk1AQ5qRp0W1i5vyJ3a6E2y98lePPNTPupHfcKaXTwYTwWY8MtjYusftlhf';
- b +=
- 'aEd0tjAscZyJLflc23+HW7VtyH+8/We1za+nZG0w3GvfvoVr1uPcrX8e0u2VjZSPt2BRe6vPsWd';
- b +=
- 'u5h7pwHUQ9cLU/npLf88G1sm2fJbZ8GcHVNUpbOmnvo+MJTL6eLXhp0tWd7MDtrr+gQnGmzReNB';
- b +=
- '5oZjlgZND+94eKbrcbMBp598e7nM5FLumSAHA2lLo8LLtRr3H8OW3vefH9V5XbD/lvqa2Q1irCJ';
- b +=
- '3epvsWibr5j2gV2xMsYNpwGzq2uwH3aQnfNsWPztyn+3+lCqfcNncqOOas4c6pelaX95D5cV1bH';
- b +=
- '8lbsLV2PMzlptuDDvRZY+mhu+kJbefX1vtZ7jJ69awch1Jfptvze65rNps/abRg0/NlzUPiP42y';
- b +=
- '+71OCezga+euHzaejh1wjeDzW9FuwwbPepwb4bDJVnrb5nbZWcH2LzqqZktHz1sW/i3bzMe5Bea';
- b +=
- 'vW3TzJOmQw7scG98ZfzTOkbPlrx+SUd5eAWOezxjhanUdrLlu7oLdg76VBVdnOJv2ML8wrBB42/';
- b +=
- '9Psrl/oTQgd4pvxr1nvHlQsX7uXeTLjULOTF+j+26y0fT9WZljCsd5vyg5Zmj5r1NE5yTfIIrfi';
- b +=
- 'ufNN4tX2Isk1ls7BYT1XXG5bUt/bxT7B5szXjVamLAissbJoa1pgZaTBgY7PQt7urDDX2H+B+fP';
- b +=
- '9J4xZwovfANg9fcmdrRatgAF/uxbZ+23LF3y66xSXkbggtfWXgsmuTW0P1dI4/Se3vvB741fhE8';
- b +=
- 'dIyx7Z47OQsuzm397pl9v24Nm64ZeXTs0o03brh/mGxpurL3e+7r0oX3X23uUvYxwWStrdHHLW7';
- b +=
- 'WnXY6TU9cMDuQvTZne+mTbYPavNW7m3XwqZNVp+uD6D6D7jY9sMI2Ujz5qcn5TRZ0wagdB6JtR/';
- b +=
- 'WokOxlZdv7LciYW3upgYvrji2rj1iNHmTqG1ywo+ulvq8/lNnHmy7o3FZrdK1DF9dXvZ3V9J6jY';
- b +=
- 'YOCs60WaLQM9G3Se7ysZbx1cc7VY6aLv1QN2W+oMeboS9PQpbcTDC2+bnGMlnsu+GWa4ekFZzK3';
- b +=
- 'BYaO10ptWvvgQTMb/dv6jWeYPDx9Jve9v+fidDOpTevpl9N2paTqHfJuaPG7Yfoht7u5ju+f7u6';
- b +=
- '4PLIqcL+Ns0b/Hd62DScfObvNvusGxtxRPCLoxMjeCecMGtxLnBxlpDnk0LyOR16MerrZsGU3ox';
- b +=
- 'TbJXsWV2kuLZnXp2z1lxX6ueb3jnbueibr/3T33gFRJPn/d/dkhjTkDIMiknMWkAFEUAQUEBWUN';
- b +=
- 'AMiMEMYFMRAUlGQoKAoopgVwQhmxKyYc8CAIihGUDES5ldd3eMit3f37N3e948Ht3b63VXVobpi';
- b +=
- '96s+hYzNqHx3KWDrQ/lNnhneWteQB0Xn6jyzGYbaOTdME1UeWCuMvhlStfY2W/XaNj29DK+vO3j';
- b +=
- 'ba8cpzZ6gMH+LU3WRS6NQsHXunPzJbdrcgPKXrpbc6YWHes/R5BtUD22reXt5+cFxSSarbsbLnF';
- b +=
- 'UI2VIjr6CsJ6c+trtTXqVap/X1B5nHnrktigmfA91bfdWydJsezKsitXkMN/SYudBF0Trbam7//';
- b +=
- 'Jl+dpqgG21lyTp8LaCkvNltXOP5I+MNJ3aqnZfcvm3OHWuG5a0LgiUtRxTjJd5pn59tWL1c5nbT';
- b +=
- 'rd1lrNZHtdzNIe6Ij8phkdaCJepqL4a/aWhFr1bLR6zZZ+motLtBM7/U91rShLSXdSOLfrLagsu';
- b +=
- '2NdS9UN9zLMlHar6RRuccj0VnQ15nfopaTndZfUxpyQ9byqyMJc1FDUwatzVKLvn0cRqreGtae/';
- b +=
- '6cewm8mxojbS/Fb9t66Nvr2yt2dWtxlHXObjyurX0+/IOs7OTl+67K8W6TIrnRm0XKB/Yt9fafp';
- b +=
- 'znxceWEAM3XVq0GRXdoD5uVZeb7JKe+YBfvZz+YTVUcJT/PTDZnEbVywZurUz+OCjTWunRiK7re';
- b +=
- 'fs/lD/fH9pg/DlbZWJFnM/7HFImm2oQzhcq75BFOV9kpRBJlIRwR3FBEOMXl2IYawlmPbZDcdBD';
- b +=
- 'ObriVr4BwTsCtWaoI5yq2Rc7K00Y4T+DmDXng/x5u5t1XQTj9cJN3VQvhFK4CmxR2eDU44Tq43T';
- b +=
- 'nbGwSphdubytRBmGPYNhXDOECgy1BgLIcywnkEBQZ0aCKcN5igQaxDDuH8hArCHSDgstWYgoiHB';
- b +=
- 'sJZCxUEPUDInZiiE7wHwjkCJY59gLDNmCw0wvEP8Ww3JAvHQJTEmo3jIOpiXVYCsZBf4Y/YQDxE';
- b +=
- 'PKnE7RUKMRE1Qudb4LiIOHzNPBwbIcJn3Xn0GuIjRPjq5kk4RqKDa8qJA8oQJ1HA9aK6CBwrUcX';
- b +=
- 'P9vJBOo6XaEPdWbzEGMdM8PBtqXEH2yBuAsNntdwgc3HsBIYvyY/K0cbxEzhpqd6od1gMjqHAaQ';
- b +=
- '2RX47satoCcRQt7OLCHIMuf3sJsRQs/MUDYw1PNERAPAWbRnG0es0B0xfpEFPRBBcnpLiV9C0fj';
- b +=
- '+MqCBJQSg2oz0zGsRUQfssXGndjizSOr2giWYun5j3dsuNiKMRY5BB2p2CE8rVbR1MgzqKEGLRd';
- b +=
- '3l2ZvSSOwFqQqYmjJ6D7ejaugXiLnNse7+JqzpNkJo65KLEeqR9grAiSkcZxF/U3F7sFYx71GDB';
- b +=
- 'w7IWl1/vusrK8lfWyqxB/UXzv2Llg3aqBpnduEINRt9GbeF1XW/Rt5Q6Iw7A4iSM8ajoGvhyWh1';
- b +=
- 'iM4oqLH24rblhgHYvjMWoH575htHjNQDg4JqOzv3DFGO93TtXeOC6j8NT82+Rp230uTsOxGdV7v';
- b +=
- 'fXvLOTC5u5Th/iMDk/r48oTyzLe7S6BGI1CE/e9A//96u0tPRCnUe1qNLjQ3Dl/ohyO1Wg3zM7Q';
- b +=
- 'XLDvw61xOF4jH3Vn9eYn02uWaOGYjUpm83yp4C9lr7k4bqP1vurayGC1frkN0RC7kZ855nRyTfi';
- b +=
- '8e4udIX6jcvqelUz5HI3CHZIQw9F0PN9q0GhUGuKD4zjyFw+ppCakpdVpEFjO0a1Pii/culURhe';
- b +=
- 'M5mmVL3hw5fiZ3w3Qc05HLMOR17qrn0huUIK6jfD91Qdu95y4+w3BsRyOGUTxBv+584pcKiO/IZ';
- b +=
- 'V369EwwxaHZCsd4lNjzzR8W8BdnimZAnEfdZndjrArVpi4cx3pYp9TqONNp2RX2ON6jZBWhuqJn';
- b +=
- '7MYF5+ZCzEddx9n/0fcreoJjCRD3YY2UHC5vj3wY9+YCxH4Uu6/uuueZtfNJewbEf9QORhjTjLu';
- b +=
- 'XMs1xDIjV7nDwgm2CyVUnHAdS1Lqw2dFjyZwsCRwLUms/LMVQjCt/Nh7Hg3SKPtMX1UZOTyjWhJ';
- b +=
- 'iQQkq3zzaVo8KxB4ZDXEi1OOFxcVXnRLXqWogNaT888zojyvK2bLskxIcUrttwVY/1X1B44gcxI';
- b +=
- 'hWy+/ynhv1HppRFQZxIy91HxtjJVXhonRaOFa14dLPh4oSJHWQcL1KZM8nrhdPGrU89ccxIa9ln';
- b +=
- 'yWtn80ZKvp0HcSP5xO4i9Cvv49UROHaknF/7KTu1KZFjTuBHd3fZW+5Y3Z7f/wpiSHKXVi1yWdG';
- b +=
- 'o9bZvI8SRlOf3vbzy1aRjxDwcS9K4Np3lpu68Z/VyV4gnybmnKd5gS1b2W+CYktKKFWqU11dRl0';
- b +=
- 'Y5iCtpVPYWb9rH1vVSxrEluZyf1pJPZ+68/6gf4ktKw38gRUpnVl6dhGNM6gcrT6a/nzrvZCCOM';
- b +=
- '7E2n+6+NzOpcm/nQog1Kfp+rpXK9T39uK0V4k1qsqrvXt0U/Gh+XwAxJ5aC9qvI85fnOL/+AHEn';
- b +=
- 'xYqOiJ+HTpQXbJ4FsSe1Ae0f33lmmXxfHH/SCT9QeUzUJ3XOH8egFOyrc2pGOwccHI7jUKqe3sP';
- b +=
- 'L/ce3b661gViUtrG0XaPcHv7LtychHqWQVpJrcm8a85k+jkmprhRuOVTwUaoiCceltB9fPD/pmz';
- b +=
- 'IjPAbHpuQVMtNHNmhe+rqQwKfur5mc3LZ5Xk84jlFp6bPvLU58efV7pSXEqeQtdhR0MiLQbyQcq';
- b +=
- '1JxXrF7mOThU/W5VRCv0uRp1H2hKfwISMExK/nRUaoHLobYd8jguJXy9blPW4+aLlp/qwBiV5qn';
- b +=
- 'pN5eLnNW2ByN41dyH693DByRfFDgjGNYyh88NizYIXNtd4EvxLE00pYN9zdsdptw3xxiWXLyie8';
- b +=
- '2pfaWsK9mQjxLaXL+9oIAp4aZJ6dBTEvdrsE7JMUzmXM4HeJarNw29fdF5VcnvpwMsS1FvcrIHZ';
- b +=
- '9+ur3ckADxLfVviMvO++s6u16cgRgXy4ZTuFL6bNvbx0KIcylmTxR8Z6U90lfEsS61jyvGVBoZ+';
- b +=
- 'lT44ngXq+6bsntaaugJHRzzUqxoWLdiUsCnuu2XIe6lJmrzsI9t568pXQCxL53WxGU5J/06ROoE';
- b +=
- '/hUiYbo5adPTpufTIAamWjf++2Wp8ffM1yZDHEzb1zxT9OpDx3QEx8IUdHqnijbOCk872Q3xMJV';
- b +=
- 'XGRYLx405tKL7HY6JWfguKPYr2B+qjONi8s6t062HmW34pIFjYyqSIbYna354dUXh+JhW7GTdw8';
- b +=
- 'ywwrvTcYxMHq01jJFO7Rr35TTEyZRRlfqmG/67qvZ/hliZZkTRjTltcgWb/HG8TO7HvrNKofdMC';
- b +=
- '6JxzEx5zlPbRx/H/0jsk4S4mQZzF2o45/qxs/Nx7EzuqpL756Azb2yn4/iZklulvIWRkJdbfxti';
- b +=
- 'aBqMjZIz1s7UuRWA42iscUuLvpx0307j4ViaUpXxJ6tkhYneJ65BPE3dPfR+k36t1Xs7HFNjyVt';
- b +=
- 'dFViELNyRZwlxNcXVC04W9JlsuNXRD7E1NW3/Kfe15m3evGc9jq+9jDKbMCK0sDAUx9gUN/RmVH';
- b +=
- '9I3iP4NAfibGpL5lZ4z/KrlOwKhlibTplveCJJjhPbYAvxNoWjOocYHsFyp4YRmNuOV+2XVtYEJ';
- b +=
- '79VgLibdjPr+ox1y+7qp+LYm0LvnZzZHu+XdRe/gvibqtOy4UFlO+repeIYnDbXblV92NJ3qZ3O';
- b +=
- 'EIeT7z9z7PmBXa9KhuFYnEp/vVFL9SpdW2Mcj9PS3jctX2/ABs3EMTl53vTkmjqXnFMP7SEup9x';
- b +=
- 'UL62kdrXN8sYiiM1pfisxqDM/aaqz6TbE5+RsG1IqRln82LYsH2J0yjlRxQvGzTsUUPcG4nSapV';
- b +=
- 'VqxbvrUibVykOsTu4r5ZmV+lTZ2BAcr1OyplU0RZjfdjPFMTuNZ+SmOev6c72dcdxO7sHZ3eXk/';
- b +=
- 'i3TxuPYnZLMbPVMT2c/y6d7IX6n3ry0+0pNx42ny3ZDDI81qtYkS0ln0SpTHMdTHHff/llLjH7f';
- b +=
- '4W6I5akXvRx2xRupqErF8TyWVbWxaBoykMciMD3X/K8nkrNctiniuJ6an1G9WdGzK9cfpkBsTyd';
- b +=
- 'prcWTKVLPdC/SIb6nIH1qnqJAdorRUQmI8akGfKx8OE7hQ70BgfPdmo1elLmimLzGHGJ9CovvoH';
- b +=
- 'PlRVOvLsTxPtUdPjmq9xfsPRmOY37aEvyJAi9//oNMHPdTKGgeIan6Yuk1dRz7U/kwqkv6aahJT';
- b +=
- 'iSO/2mlLWq4OOtI6Md5OAYof+tl29xz2/ebPj4HcUCVxdWVDw9O1HEMxLFArSBP1Ft+5QFy2TCI';
- b +=
- 'B8rHlaMt9+ZUUxxxTFD5zM/skivlF8fQcVxQ86jzxJYN06sKzgogNijXWdBxg96Qt7tBEuKDyi8';
- b +=
- '+aJ/zaRuhvrkIYoQaE4KtNfh1Id0jcJxQbqMRsqm5IjFBgGOFSj62Wcy+gfyx43G8UMNPt2Tx9A';
- b +=
- '0NUsXGOGa40dCm04b+4noKjhsqMW04w0jNj3JlcexQffHJmcEbp8ftX+oM8UPW9u7TNRINZJ3ay';
- b +=
- 'xBDVLxZm6rku+ms/uoFOI5I9p25XNDhlK6NY4kscvjppMvrfZRfukM8UfHs10++C2iPKzcEQkxR';
- b +=
- 'bXa9+TMtxu2cJZ0QV9RpvqFVK99xZl8Qji0q9HmOCAl5avN0ZzDEF1VHrfpg8l7pdLAijjFqd2g';
- b +=
- 'pOddPWNPwrg3ijAozeOrjdTeK2rY/glijysGBZ1VxS5selU6CeKOW5YZaUltDiGHlbYg5yg+cD8';
- b +=
- 'mdtrnuc3Y+xB1VGg+b6llKrUnaVAOxR63ZK9cdXL89fPFWJsQf5YMOe3AXl3575YdjkMpx24L6X';
- b +=
- '6V92bgpC+KQmmhn0MDeOMetPByLlCMNe+OidXaJzEIcj1TOqeEu12swvLV+EcQkNUrfzHhgJzfN';
- b +=
- 'I1cB4pJydltnF+WVWyhycWxSKddPcX/HUWe1+Tg+qSG/z7f4es85cxkco5Sb/EQnlZxy6NjNUTh';
- b +=
- 'OWXvnlX+e31aj80yIVaq/be/eJz9xe8uxGIhXsvS1E2eEjJh4cxaOWSru5THs6vhbFy3qhrilet';
- b +=
- 'HocxwT3pLUQBy7ZCUX202a4xoX0FkA8UtFP+uz+kpFudw2M4hhqg1zS0tam7ylf+1RiGPqKHn7L';
- b +=
- 'EYuLH5arQixTAX1tY+2n0w3UG6eCvFM1Y1Zt252r9ofOgrHNHW4JcNzJ6/3VxuB45oKC4Tvhr9b';
- b +=
- 'tDl89x6IbapWlb4yiY0t/LYmFOKb2qRjrHnVJw85ueEYp/yZ14qVF/fyfEoOQZxTxVqv5dRPzaZ';
- b +=
- 'QIY51alVPNjiimRJyZCaOd8p7J6S82uxX98odxzxVptH9n/tuqti4MhvinpoV3JtSSTyRZ58FxD';
- b +=
- '7lTzRSWVdcR08eheOfymamdMWFMteNl/lCDFTTZV5egmxcZOg9AY6D+lZuHRt4xvHT5QKIhSrrk';
- b +=
- 'IrVDGwufjjBh3ioRmDkD9k1bJdgexwTldtx5Ftg08xCo0ULIC6qJL/ji0FXjnmaPoGNSi5dk3F3';
- b +=
- 'n4vEgxaIj7L83oruj9NeLll0E2KkSsNeipY/4SUVfRwDcVL1u11N6TWjaT8OjodYKevS2y7l8ut';
- b +=
- 'jD22ZAfFSxcaXu8LmnlHrmIBjpmp2SW8zTNQt9nT/gLgpy8M3puIQu68lAcdOFYNaFy7oMDgml3';
- b +=
- '8e4qdqRvd1nmp/NlQ2wjFUnbkvb4/7bN8yQR3HURXUnuVrdZ8LeP5MAmKpqjqqb/USvm1Rm4rjq';
- b +=
- 'doKXfKrN6vT9x7aAzFVhQc19+f5Pmes21oJcVWVonLpdRvUJMnFJIitamXMzz9F7n4ZueY5xFfl';
- b +=
- '7697s49SG3FU9BBirCrSnryn1PvfdyzEcVat/HGimujFlc3+ONYqb6TVVN4XSzr+wgDircrCdrN';
- b +=
- 'jvSh5lyaOuWo2+/UHuTx//ubjBoi7ymVucq4pnLqW9+HC0ZhYCzdl9cuX73R1IaLXGXFu2c43NL';
- b +=
- 'pniNq/lEeMtnrHuXhjRJRcrd3oGanHHK67xk766bnnqFII5bptwBtargz6ykE51FDjYNRG3ZRJ7';
- b +=
- 'XI7I0pevH/wg8U9JlEjEzt98u10YZihv4OSi1Fh0K2TPcaM1aUHPkctVo9Ze1+Y+z1dgzfgFPCg';
- b +=
- 'fyULyZaetMUuJGqg0Yfr139Y0e15ScwEyvuf803D+jc6v1K7WKgesXfYneP8dVNdOxZZsH6a66a';
- b +=
- 'HGUskLCN3L5+x3Vnxe6bhKuvZkvRESoKl3c3xal9bDmSeDLzmnU+90Jh7br1Oy8yACVN6skzTot';
- b +=
- 'dNThl1RoGVuyWCb/k8fdI8j3d+zHpVCwsLSwsrC2sLGwtbCzsLewsHC0dLC0tLSytLa0sbS1tLO';
- b +=
- '0t7SwdLRysLK0srKytrKxsrWys7K3srBytHawtrS2sra2trG2tbaztre2sHa0cbCxtLGysbaxsb';
- b +=
- 'G1sbOxt7GwcbR1sLW0tbK1trWxtbW1s7W3tbB1tHOws7SzsrO2s7GztbOzs7ezsHO0d7C3tLeyt';
- b +=
- '7a3sbe1t7O3t7ewd7RwcLB0sHKwdrBxsHWwc7B3sHBwdHR3CJjuD0juDQjiCaI7bLzAK3iUvMlb';
- b +=
- 'ZBcBsF/41NDbtB81Ht/+ZZk+/C/8SmBpMZKIyMjndigr//icEUzOIXPttvagQLCcNmPRJzigdrN';
- b +=
- 'YTz7NQpRPI7FRqrAcmVIkjK+DWdEoR4BkIr/S3MNm4mVQAtB9n9Zm0AicSvaAOKz8v8v7SskBD5';
- b +=
- 'f2tZoTPyd0sJYi22fCDWYssHYi22fPBXZlk7DsrVTn+P9ZDEyGjsnqx+mx99NoqFTCHSELN2I9Z';
- b +=
- 'Y7tP+w+CdLzTa8D82a+AT/desGiCc7IugALRLW/wPZvfP5CUkgWNiF0bi4telTNRU/5d5PIn7f5';
- b +=
- 'vH33F/tygs1mJrIoM1e5AWWxMZrNUH6aoh8cXWRAbrEYO0uEyJtbhMibW4TEGrruxEwvYiZnc0N';
- b +=
- 'TKRJzZiFImbIoXW1P77lIvl8XkpcdGm8HBY0tkQD4+oCvVj8LnVYSS8tRhsXbgiBrcuPGpQuXb+';
- b +=
- 'e8p1PDcGL9eDn+PxGLwck4h5MwGTxrNT4+ZC66wgr6WA1hMRh9lBWPshynpASvz/SXFHpsT+tfI';
- b +=
- 'utjyFW5aNieP9Mm+FmeLAJugLQJGFnQbY/v0Ex9cYNL8/jp+UJkx1YrNn4nP3B8eGhjzEO5IwM0';
- b +=
- 'Y+Q33ZuDmLwfvZ0F4p1kmBjfavDoogOjoNpDGXzU3DuhLsVF406MXAQECCVI0Dh5iLd29gDHi9e';
- b +=
- '2fi7bX4MnB7pISpvP/+YaTF8YWmc+Ni50bGgmfyezOAdMzEbds1EfO8xPoo0a6LNTavSnZI3hbG';
- b +=
- 'sf7WuWFDTBRysYowPw7vZ7gSdg3EejQJvz7CGBWcEya2xIMZNfARIL/twwwYBP/qPo4RxHD4GcH';
- b +=
- '81LSkJEEK2EE83GBhjAOx6QGeWSDxDPBiMYmw1DohMun3Hf+9jQ2sMjPHzA7CApI/i4VgM6yKaJ';
- b +=
- 'hlL073XdDYpWEmOBKToOlabtxsUBRANsGNnP69Z5eIx08eRcfM83G674GTV5H/6dkHVWvYX04W/';
- b +=
- 'rsM/82C/8BvQdavcHArm9gvQYRbJv4ST/xK4P6YrVv4W0DoAuKL/FIiHpn4JRG/xGmymMQGET9L';
- b +=
- 'fD4iQJb4OhjE/v8+C8fzoqMj47FKz8z2Nzs0SEACbojmM3BYtcRhp2BWTkC/Og1UarGg+gBJD9o';
- b +=
- 'rUIuMH+PhwRkf7hU+yT/YzzPcA/w/CKu5+QJQiYjzqu6gY36A5jM5J1vAU+ok7XojEomaFn4QiY';
- b +=
- 'JqRaIa+lKXWpcdNlce7vF87vz8ltZD27e3St6/Pr9i24/wormeWbSdNdDO7xGRKHDfgGiXtt7Xv';
- b +=
- 'V+rb1nENskv+pw3fg73fu14j4PbNcavfbnQ8Y0cqv6/NFkUa4mnFvb3V63tVCfiDfAaFDcp+VmE';
- b +=
- 'DTRH1jARmz4r5Ergwixm/NzXxWPv6x19eWLB7X3mu9KbRqU2Fy14musyccw9iU7usgwNu48WRtO';
- b +=
- 'uLdj15PDnb3OUzjtd2qFcSeoXfjefdZqvmRQRc8jOLiJSQ2/XFg0qwnnw5NR/ZBXo8FMQrxTFTG';
- b +=
- 'sPtvaKm04FPQMBbkPRW4DbR/qfmUcCCRUh+M0+0t5n4Moq0P/pI7b6zx8xwvn+HFzgSZJFEv6sv';
- b +=
- 'QjDN4O14iA9doj/WMJMolg/QvGO7mAtN0i3D/Fv/w/z1l8NbxaMnXW2Jxvx9liLHH48tYA/7trr';
- b +=
- 'BYLzoTtPHrIg7zsUpN3bt88t8nm95EKJE9nkvxoe4VR0/Gd598FLEK+aFBb8A1Qab5f8FBW3dIg';
- b +=
- 'EvFtOt8esFN6Q7ZnNo0W/nPjwdtZrjou64VNpysB83xglxu6aPhD+i0e/aOz7T6JDVnFVrzf5OH';
- b +=
- 'XS5x6zyrX8vONd3Mmeau3lil00kshV/wCTwpLDGpMbtVevFF6sWvOwqmlS9KFmo0sN10qO9xwXN';
- b +=
- 'nzMTtpuoFPf4i6vfVWx9ry5wvBhWCW26kXFGumr5tZN/md9RerOjeOlplzSz9AvXRe/qufb7m0T';
- b +=
- 'dhuWhqiZl5nFsQ74jw0ODnYuocqNuVZ+pSL86c9nXWZTijZE3Ti2+6DX0vOBT1/K3Bw314vq1Jb';
- b +=
- 'b45Us833a4ZqamtOGPz/IvJhprdA0pvc6LWXupgth7s2e1ygfqnKvcW06wjZSymurGr5cKpZEOD';
- b +=
- 'teg4TqRt0nKZDBIL5jEen7U1kpBtr41e3Fo/X5r1Capf5E+4mSuzwvqIRU3CPFBr3JeF3Plt9f9';
- b +=
- 'R1klTfDtjAdklutLvL52xpc3Mo0+EdTy7YHOjel2TBNOHFbb7vc9H8snPEo7C+Hj5rxTPNC8tex';
- b +=
- 'ro40eXrIE9qm5P7PRlez5kXdSFj/hpxN+Wp/42Kt8phznDdsieDiLIW/Gh7hXHyLFVH0RrIvSOG';
- b +=
- 'O8M01s4Y/EY1eovqDv1/NK37WGJ8ljLz807rndhWStl+1M2ic1r+dZX2BeSZ5Kggvxdxds14H1H';
- b +=
- '+PVmdkaJWZ9+7T5HO63OmrbvdMpp5uc0MOjXLM7ohMr1LsdNgGnsinPRODG0o/iDZ4FM6zfyi12';
- b +=
- 'bZh0xYPirvn85K2YK/s2zEaZTPqBgLz10RT34+4kKx5ocat6EXe3OBgCbUzuzjFTKrKg32ChRfv';
- b +=
- 'LOI+mHpj0feMen7cLVKWlVC9SA3hdL6HN7J6lwLIWk46rqLNWpF9oZ8Y+9UcLofYX1J9VyiwG8l';
- b +=
- '1Xbq3POJi5mrypJ2Oo/dVfaX81bI4P/gBOH5+WqtIks8VfeZcmuVee6tz37fvBx9ZXVUXHtCZYu';
- b +=
- 'p95EvL68OWwqPPAhcq/wdltgvcSMSJOX2NeV8frGq7ETOqp92ioX/SKntR/jjV55TOn++GXw7Z+';
- b +=
- 'XZz3foXt2TP3D1nOYN6kfFXw4ME64YJRqsvBVmG2dTvMLvgVnDihA/T2OFFP3Kq7qqqa2Vumrtp';
- b +=
- 'cdHKW/v3nyEtzJKQdFeYLyXUDARP/sf9HTUt3t9E13W9TlQmLL65dtrEW7ok3U1J3h+NNp+MOyA';
- b +=
- '9bs9kkeHZK/tI9kW14MlT2yYHZ8ykI4/7ntgrLVNHV0nx3aI/Ru+kab7M3pHj2yONvi3OktUf46';
- b +=
- '8S9jnWfGNj0pYR9SOt2xwGTi6P7T7/6cbtZrOKaaErm4M1ubHC7raTX0cGldQY8GfMA/3dB5+wB';
- b +=
- 'GudNvunSBSFpvXmIt5vMovl7F5PHeasMflu2sWdpzY8l4uYbYf0uSZfmijXwnGpPk/+q+FBgn2G';
- b +=
- 'CXaONKpfJNo7/Wj/2ynDvyjcV1eesCOSvm3GuLPb/DanmRyrlDulOzX1PPNrb22jwsMXMudE2Ev';
- b +=
- 'BfTEWyDvuK0TxMu3mVkHDDNftOyUGqhWa85YqLKxL72U+l5tUXOoqU+VOfVlzFuSwCYHXRbG+Kq';
- b +=
- 'LVgVojJJe8Tf3UpCSxZFJyzqeWM6brLx1d5+ToHfLh5yPhCcX/IId9ATfyABU3kyIKbm074p/0c';
- b +=
- 'N7NxXs43+f+73s4rMzfrf/+Z/2Ok73gBu+S/pcdo6TIOPh+AOsenZyPr9ozjFiqSqyHEy++xFoP';
- b +=
- 'xc2IivUIFH/xJtb6Q/TIIdpgiDYcoo2GaOMh2mSIFr+4E2tdMr7owi//IdqeArudhwdA6pZT/so';
- b +=
- 'rcs6gMaf7H0Z5f1vnyWOIYd7EdZ8+l7xe0zw8bMWSy+8TjIsdg1JWKd6myommbnj40Jv+v3y6qe';
- b +=
- 'DmIgkzjocXshDMMOpB4vWcWB8ieq9ifZjorYr1kSG6hzBzM1h7DtJfhvhj2mOQ/jrEH9Pug/TPI';
- b +=
- 'f4/hxy/d4h/7xD/viH+fYR/8aR6znH+2KmTTvV57JfafC6l8Yqb40sb4/wkvUsjSlS0PQc9tzEI';
- b +=
- 'Jyv3NBjX6vzVQqupgOz5fFB1QmHbwMrVuj/Vdqst9Pq4yGA05YDok82bx8ODkJOiW1NCb/acYDP';
- b +=
- 'ZJxQkChofhTksWrq0JubhBef2DGen4Vd7Vj5frVQ3PGaCdpf94swc6VsfTPfL1eUtWXMuU4I+Pk';
- b +=
- 'bS22mK+9bzMzv0T8Yl921reOBn2bUp9FU3aeLJ0qDQDMRoftIafqtecMR9baU8OmfktyQDXT8fX';
- b +=
- 'YstjeYdlbtcfF+UZYR80Y9o7DLqHKiiLJ0UYJD+pIX3Vh19Y3lnpcyYCdvvjZ/zoWTRvibOMs2W';
- b +=
- 'udyeEQcCl6rLhmW1a+jq+bKK575Ru+1YqvzVOLCoTuaTxCF9u562lU8SG+9f2bjWxHtrY0+uavQ';
- b +=
- 'YK8VHJxd8u1LGNNvgPVnG29Rgr+FSu/rLTT2q/aZugc3d54a/9r82JU7kMTe6daupi7Sjiez9H8';
- b +=
- '8rwlpvrN6fsjWu4oFooHOE+QXRHPltO2iyPt09Gdn9Flk7yr4vYnEL9gVZtMjzpPOpvIVb2z4i7';
- b +=
- 'RGfhNXHDG7ofs2IOsSQ3Hs3/eiYlJdpXFWdtUcn59WPOvDya1N++uXFspuPLFJq+zAQ3PV43TZq';
- b +=
- '7dbWtU/WvJSgJ39pCjnTIb2fpR6/u16aufzqgQOxxya3+e+v8guZfGdZBqc/ILzUg5IWXfD02/h';
- b +=
- 'CiQuGD+cviNz7Mi010P2OPX9gvfdchZane7Tezps9uu5mV/v157ILYx5MHKeZo9U0vtWfmjl7OS';
- b +=
- '/A6FHK3QMhm36WNi0bu4trn3sv7vVbCZaRYhLHy/yExaMa1H/f9GQ3waJZu1XH/NjbP6c66ki1Q';
- b +=
- 'kuXrHDnNs9z91wLJ0845apQUJJ5ZnS9cslUw2YnyXXhcnUrE2p46MNTtK2j1o4cPkuFV8a8dH2F';
- b +=
- 'qDvYft84w1ErdycFaLYkyo1hv/NdYTHm/bWP2e/v5Voz+t5t8Nx2elFFt/Wc21eCjMe5n3JY0r+';
- b +=
- 'hRaX/5wGrkdt7q+Vnju+w87cTtQ2nxjifMpTldKfnyF3xedFLsTIvHrbkTsDEp2vzRtxubj2ttO';
- b +=
- '6e8U6P9kzOcc90E00pT3pP3kSSfCb18qzdvIVTdNhuE626PBV9WpLkX5X/6HWf5ZESQWu5sj9eV';
- b +=
- 'da/hCFUOvn1fbTzEQW2muLVYYtLe+ufXHJ15/qO0+/9NtJw+FvJ0y5O379O+GGR/znrvt6d97vf';
- b +=
- 'Hiu7a+p2hVY8ev9Eudk6dw6ohXjw9HZaHTE5n99p18NtPx/ybePOpNZs36mhyzdbx9Fi6u1TFgq';
- b +=
- 'kvl2cnS5kOMd1Z13/IbmoeZjeqYAjLcklRcP3ZGreizq+dPi8uy0P2uKPD9uoWLMkrlSlX1lhnY';
- b +=
- 'fohcb21uQ0Jz3emuyrX6IMv367oGlX9nltzXmrnpGnn6t+OH3M5pjluaMmLCl6U21ms+LsNSdXl';
- b +=
- 'B5Jif4eeWa0rWJfeWGouc8SowSa8SW5JXFNocUqyp3PerrvP94m/1frk9iU3LbPCycbx26fciRk';
- b +=
- '/QSt1NRGypti0rXW2wmSzM2WV1bqx+VsU82czyIb3fGkW0iP9nHfGh58ek36d6E3GPEPLItYXVw';
- b +=
- 'Q0T39oo8x1crhmeKWu/PLt+lHJwWP4Zx+WLec6fQ1zGiF+0OF+dr6/BfWC2yXMybnzdtEvd4dcP';
- b +=
- 'SVViOCPNUpNA+8cCOXathU8Fnym8Kxxj1N5f0hYXSVoBnbpm42SJS0+1p/LdcxMHHBj68bnu/5Z';
- b +=
- 'qwWMKbYC+T2gqr2qwclR09cJroQJTm1/9qllBe+4y2RHYfLrll1xYe7JJdX57UmlupW7PW99oa7';
- b +=
- 'PF+D56y7mPzkuIacJdNya85SxZYvJ8dtfH1reFDzurof29tdDcpP8mvopZpmJJ3Q6ytV8t9Pa+1';
- b +=
- 'HAx5uv783ZStPzWlsbrZpWFvj/CWXX73tO7136drZCbf3U3vX8zs1Vskf1XnaespQ4y1d7+rZby';
- b +=
- 'nlz1aWBmTMLlnhZ9cwcc/MBV5xi2RtvjiW7Zi/hTuhPSer9GdPxrS4l5uN7zKDwqX98gwVS633x';
- b +=
- '0/cPHH0jRh+oNvkBVNccmy279x8a/FP++D3H+vuyuxcmTpjltW6dYrqK+Sd954w9lIZN5L588va';
- b +=
- 'x+/f2nU2FgWv9drtr/7x+3pu1GNnY95zJPtyS+npqMYoVX2Tj0svHW6m+tce2SmrXIaa/MyYOc2';
- b +=
- 'FO6vquVf+k9AYxaavo/cESmsd64hauv/M8wvyKq7LJEuaZjScRVeov5vzeKBngvob1iO6zoSp6m';
- b +=
- 'en3+yVLg0cZ/1pbLnDluQpyhUbOCR23xg6ske5/suNbdpVrpOLJtGcZqu4zp7XdWy9UnfRGFTh2';
- b +=
- 'Cod9wGv3Ft6L9blZJpKK3ndc2iIl1jplKNVrqZvJNjiP3HqmwMxxeYS3yj2L6O//Hz4yTdBYXyK';
- b +=
- 'T9ON69enxlG8At3445cL3xTfJZmso78unVqZWMbzoXE+PD9266NlbLXG6M2xbau/08NldNUkDFV';
- b +=
- 'YqwMq5p/aZrTEaDJXXjnwygdSwBfR3Bd76A4zT3Skl6QF7biy7JGS6ZGzRxS0Gm4uSWRpGneMrb';
- b +=
- 'JNeBsxIZq1LLxLdUFoVX518s8nwxX6zj1Odk2JC5M+hIT0TPpYOrtdu6KA2XvENtjfeVak3MNH5';
- b +=
- 'ankcEELL+zFOd/wT1P0z28eaA1wnU2fPHzrY+tZrgPxmd+66mTXUZN6Eg++NnaPvb156qlNevZG';
- b +=
- 'UjfnnpguNyG/w4w3Lvpgj/qDw/sLBiicdQOTN20/jS7enDaq63vmp9H05tlCu4Kl4X7mhfFm3no';
- b +=
- '0htzAvWPPLi7ztJy98NTeqY1NLgV355Hlzn+I3WRWesESOXQ1XFPQpLWvf/HRF/7St7dsen2ieN';
- b +=
- 'Ju57V1O2dVvryyr7fMNPrYSg9K54WGD11f+eeDj6U8WXpar0KrQu3jrS37kq+oSfTWnPJnGWxzf';
- b +=
- '4i2+sjcSbGaI+GUINHTVRf+Vu742m6DkHzm1sdWvqlxSimbdXoP0HhvkqMOnS1KubYmeHvMnfcH';
- b +=
- 'fcO5d7KlQtsLQmU+ruFYZHTuK2/ntojarSsHXG0vn9fj1uj1rl/PEw5nzrRe3k0T+rqS0q2lt94';
- b +=
- 'Wvluxu37BapvaDTX1nDNLZpesX0p+Gfq2MWz7lYdN5JU/43faGvpObuhvS7Y+81nGrParzx2d1w';
- b +=
- 'ss5toeCWu825GlEK+2tdBpzvAbfiopG/tv1O2evV12xpEE0bx3UlvuDpNWW9S/aMWzkd8yl6pY7';
- b +=
- 'Aiuery7LJ3a+MAn7fuDEpdItTwVpg841YzXfevPjv60WxRL0Qh3mDdr/exTZM2Tb6RXHs9oePF+';
- b +=
- '+LQLkUFjpIaHrc9h868GGs3Rli3KEWXK+2zvmiXHPOU5somlyQqynOVEXf7xGOmrfvf6z++qAyc';
- b +=
- '+XuVThfTdZjTelSAhR5zvS41tD1+vemtGyMaEoMYFwRoMrYpp89t1L905OOLg/pAr7EXDKEc37v';
- b +=
- '28kHU6d2lqxb3sqoyzj54o2PrkOpptsJTQDdvbaFK+nryS+23TzjlHg2O5jPOtLyj9ZsL0+Wa55';
- b +=
- 'b0yM/Zc8Tv9Q+av1v//s0HqXxj2eA0a9Yz9J6Me7yGjHvhVrvDvXgLn3y+BVPMXv0NZLMdfBuiE';
- b +=
- '696+lNzgcdo0SbMrov6KJGu1v3++qdDYYbODlavJo/zia6M3jpZtF21aUbFnUyoysebLWpkanvk';
- b +=
- 'Z5TxtU1+vxW2WjYdKO8IOz/P71FCq+XykrWpffAvf3mCRFr3jTHCQ0rONwwaS49b0CkyFoQdcd6';
- b +=
- '49e27NU4WIsYXJHbqbzox0XZL/YNK09oaUS/EOyziRbjm0xyIMjUrI10JKLJYjSbJnDKa8V9GLn';
- b +=
- 'eOm8tjj9fDaKl0lhXUao4MDOg8yT5gnF9K9VGw0bXRaez5SbkpsezmbefdguW/C2I7lJ3OrVu7M';
- b +=
- 'fxtrWq7WsMg1Y23Ni0srOoor5K4U4i9NVoIHhY1qB2ufQbpsiD+mxw3S5UP8MT1+kF41xH/VEP/';
- b +=
- 'VQ/xXD/GvGOJfMcT/MDGaFesjxGhWrI8So1exPjZEHx+iGwn9bKPvw/ha7/ff67aTtXPDLZ8Yzo';
- b +=
- 'g0sg1cG6mivWKG30kbg7EpPNs78iMmTE8rjbDZxvyr3zN/pTcZQRwGpz8ZHw3/Su8h/mVD/MuH+';
- b +=
- 'JcP8V81xH/VEP/VQ/xXD/GvGOJfMcR/zRB/TA9+XmuH+GMaAyL+anr91XL9H6y2shkM+JejwXfB';
- b +=
- 'iRaKHotEO6eIRMGy8plTMgPiKg6ELz2dcXrrqP3x97bqPrq9fMSEz02aX/IRaQPDv5eCuFT6GwS';
- b +=
- 'xdwu4qg70X0EQYjoIW8UkMhr7oI+tTJIkSI2DsA/iu4IF146cAX4xbsWfy2Xz0xKjQEBBDDhcbJ';
- b +=
- 'wwdR7wUxx0LJxHJpg27LGvILjev5k3ObwCv1sSA95t9TZwt9lS/+puJw5aj3ESRuNhDRKWXgJBA';
- b +=
- 'kZDYUulBK3E6aDpK/GVUohFQNnYm+GkIX5DV1opXImTWmL/P1I1Aqldia/OIvYjUgm5CDQduwaM';
- b +=
- 'noLvndP4cUK88fTHYS24LV5lEl8qWYxZJUYm8cDzIKJA3mzIcpTCtKSEX4JYZ5lQvPQkkKIgZlI';
- b +=
- 'kPy76b8KhoJVsKwsbgoUi1gtFkKllOD33joGvRipOB/FvBLYMdcQf+kEZ3riKtYDPw7KcCUaeOa';
- b +=
- '/ETV6YWSBI8KBniq0jGIL8vm8KZPXx1I5kRwlAn2MOT5xJ/y7UfGYk+A90KayJblJsmhB7K46df';
- b +=
- '0I5vs7WS6JzEx3Jx7CYyOhoXiq2uHnQTMyUONtXADpV7EChICUyloc/cTGNB9IlMgbLRFwe/vzg';
- b +=
- 'QoXTBnWsQv+L0pUq5MJLFsLrME/ArgN7YKqr8BWLaMQLc/9A9hgx+pe+Cl/OO5hYY1PsUbgKX4k';
- b +=
- 'olifE0kWQ6MQWzoxLZQsxw+/CfyCCeCkpfIETKKZcuB+fOAGSBK9+ZhPJ8MfsCTbYjS/6G8iLng';
- b +=
- 'RP4CFIynDHPtE4sePAFYL9IM2EGeyYlMhE3hxBSjycYJCWwpskTBjL408irioEPFfBnFR2akYqq';
- b +=
- 'C3YMWn86F+LO2GBPSdx/DydiMkJ7ETQyY3DSpEwLhE7k0dAMLiXVPCEEuLieQkZ4uBx/F/P5/cb';
- b +=
- 'DeFFseFyYwI2J8AHS4c0fuRscHAMm/YAnWnsMWOBMF/IaArMQILhVzsZS4RU4lqwZIU3yXNiT04';
- b +=
- 'PATeYyp7kN5YNSllaAk+cwnGgOoDIJo/rJ+DyzGalEkdlewgSEwX8cYGDIvzJpYgjDboc/Hl6xS';
- b +=
- 'UkBGbwo4mrEYcbIz5eKrF6qhA8VIzZTcj4IxFM2Kk8HnumUJiU6mRuzhVEYyXE/FdWGc4HB5uVa';
- b +=
- 'spLNcWPZUrExAhlrNzA68DhFn2C3sY+zJgS67pheJkW1Jza/aAlsLYkPDFoCXuXvwVkzsvAfQSO';
- b +=
- 'upqF2APHBW4lcPXA3QSO04lFLWUMgG3zChYSBlxhBV5xEdkTy9B/VxlGZv2PC/GzNb8X4vhBI60';
- b +=
- 'ELFETBKkYKhzHny2IBzk9BctaqaDogQf365KjeNgdcFMESUk8LjaC+/dLO+St/fuXdti79velHc';
- b +=
- 'alwpJhgKHgUpUsWOErVuKNxd+9fJxBJZ6Oh6h4xhusdQfpXUP0KMrfNg0iMpVnZxOeEBc7U/iPt';
- b +=
- 'ObhSryRGUsUDA7xjRH7duYJv0nhC1ePJUbb2CgNG4lhoyEsTScAh3WlsGsOIDpKgztIwYMaV6xB';
- b +=
- 'xUbmWAOE9cqxhRqjgeMS5SwGawCAw7p+cUQejyfyWyK29BzWmGOdKeCSsXJFTN/BCnoaxqEAhy2';
- b +=
- 'Tno4tAEksdIqVYUuiwFsPmohnR0yiw0YJjsTCp1hl4OKC/EqTCcTi2WLtR0xOE+tRQ/ydh2gXqD';
- b +=
- 'nbj4GaIcAVcUVG40tROo1ydhEb6vq1YAa+EgZLTl5BUUlZRRVa3hqNqGtoamnrsHWHDdcboT/Sw';
- b +=
- 'NDI2MTUzBxb1RLh9B0Hx10rI83844xziQXbxTpziJ43RM8ntGDQVMXBqcuB9RRspP1To0E1S6S4';
- b +=
- 'uCbAUj4e5MA0oiZCiaeQSEDqg4+LPZnxIKz43U3qoK4W9sQ8QMETJMJJAr+dIwMeL1GQksGGhRu';
- b +=
- 'fTPCLsCAaFNAN3IAPFtI24AOOoTUcjAyyfNkGfDnuKKI2IKpk0HTExWTAWTSwU8ueKRCAPkCKIB';
- b +=
- 'HrV2B74rHKDK8nj4Nj2PzJOX6FA+f5DsJogjBLEPw8Yr2YhE/wGZw2c4ekR+YQPY94VguAYxH7F';
- b +=
- 'hJLsGYPaglysFwqEHphuHUALyUxDq5N7cnjg4rXQ8Dn82DzMYkXk5b6+45UntBbkCoM5oO7Ax1S';
- b +=
- '0KL78YRYL2jQnj/Cc6JguwzOROzjcTlcbooPH1RW2Abw4Ih7BsRxPEFvzz0FNBX8gLgkHicBS8W';
- b +=
- 'MMemgHksNEaQlcN2xyVpYPE/Y/IOn7ZP6x/avDRBiDBijZUwC0f35CRmgW8HDu2J/bPkKBEmBws';
- b +=
- 'hfp8Z8vEFPIUE8o8UHmx5DbHtGCiOxNV25/mnCENAB5E0DAz6iIfZKS0gAJwzk8eKxO/njDBPTB';
- b +=
- 'MLIMenRPNAT5WK7gwQCX6wdAwkpSEuJ5rmnpYKbA02iUBwR2+MJLhq7TY8UuGy4J282GJWmgrgT';
- b +=
- 'IvkZvqBFTCUuCovAB91QTkpsGjY92BckE3YKAT/WBwy+UlLSkkCSD5rN8dtED3An/jETYInxxxa';
- b +=
- 'mD+aDMsOLFaRgvbpfE4dA9woW7pi0BDyfYflKjqjhZIl6QY7IoxKEvyQ+wwCWL/GvFBEOCy9DTB';
- b +=
- '6UIsIyiLiShFMh/KSI8AwijhRxToVBYaWJXyqxXVjNQsqA2wJcA3BngbsNXAdwX4EjbQTDZOA0g';
- b +=
- 'NMHzgI4F+DGAhcEXARwycDlAlcK3HbgDgB3ArjzwF0HrgW4DuD6gGNsYiGKwOkDZwacM3DewIUA';
- b +=
- 'Nwu4NOCygFsOXAVwVcCJ67bcQWU7DzOQiJX7QfXFn/VSxD2gXwuGYy3wFnwJeYMteN3hRMLTI5I';
- b +=
- 'dI0hJBL0MWCWlRIKR+L+bSw7rIXE9kf+n1xKTKATXUb8Frx+5JHzi4z/0cEAwYmz+j2vbggKRII';
- b +=
- 'xku7qwLf4hHj8t0ZwblxEO333g780Vt7Jgr8eXyCdi7UdoEtEruYgB0nRwPcDDTZqMYLY+EVNLF';
- b +=
- 'Dn9VhIpswVJdUrwafFweH/ZXbWLQjmJph8oCKf6MmgiFVCdWUPtFiKcs5iXPupabiaxppXc76Ak';
- b +=
- 'a94uHP7uy/XbjMeUsy17rx5XW2i9jayv89qPhHAKr4DQJUx0nllF6JLbJ1I2PHywxFxJ/nzA0/g';
- b +=
- 'k/rjrsg/K7/KT9+vvjTlfp2enpDXttruzTJAo+mRq8BWVrh+8TwbHg79deJz1+D2/51rX4/BvgV';
- b +=
- 'TkT9MnJkFoxeXBXiRWZjPMwbgtVsD/07TmmiVikwRd2RbIlG0s2HtJI8rLnwaO46elwtDIr/Cz/';
- b +=
- '0V47FsHFlwcds4/DRuVFmMGKiwDQ+y5T+BMgUuVe/qM9QkKHHSuuUR8sT5FPGOx/kmUc7HGliiz';
- b +=
- '+2f3Am7cLHomLxoMPcJT06IMiNszxNZVTgW9CNC3Fx8n41+lyeDjRHK5BvhtDz7Mr+OkD7l+Jvq';
- b +=
- '7lhyipYboZBTv0f9Ke5ToFRM6l7hfseahv6fHeII3FGuZIceXJnTrGHUX8nX1l6d6rwxg5eHS+b';
- b +=
- 'UXVAaSdj3uvQO1/+PjJ/r2zRF97X0MtdS9eE5X6eQTcn3tUDv3LSyp07mx3KTvHdS5a4MtDcIm3';
- b +=
- 'vbq64G6oXlbXXFtclVkXx/Ulws+DJ8zbN2bzD6KCNOJgelupT5Xdq/qk4I65NrB6Rnyzjn7+hSh';
- b +=
- 'tp/cO8GujHX6cp8m1P4V3g6CN6tKXvbpQX3BKWfE5UXC+0i/CdQ9q5tWX72+uFqj3wbqjlojlQq';
- b +=
- 'mTZdtvzPURfttjXpjHfYH9HtCPWr0+Vutdy7mxff7Qn306m31kZ5Pzi3qD4J6VfOIY9c2xK+s7g';
- b +=
- '+DOm9r1Hy9hNpHR/u5UH9tCZeeErNr893+BKj1P555uvJ72+eufiHUh7NENTvqGhqYA/OgLhg3L';
- b +=
- '4EaHrVkxEAe1IEWp2wiRMebRw8UQh2sf7S0cJHfqmkDZVA3LjBM0pvzo1U4sA7q4sMdhzc0tm4r';
- b +=
- 'HtgCddl8Yf718J3fdw7UQn29ckfxyiTPI2cH6qGOV5Jt+t7NWNY6cBzqg5aWvOARe6/+GDgLde3';
- b +=
- 'CzBvn20avURRdgZo2ytjoLCus3Ux0B+rbK1Lj1ujp1fiIHkMtcwnJ/dSwpD9a1A71W3W5FVxGx/';
- b +=
- 'EFondQX8kPEEhcOV64RtQDtQlPrW2KyqGbB0R9IoSz7d5pzFbyumsiUN3WY+KSEWvrnc5OOAsI+';
- b +=
- '4uqPfc2vY6M4LaF8yTKvqc7js7Whu0ZghxQojdnXlt90gGWDTD6CHuTec1qQXEgYgL1zKzXu7Y4';
- b +=
- '3LqbCPvbYDw6bK2K/kj/DflwtIUgI3vP3rHcFP1+ExytIsiOuouFDrynexthm4Igj3i71IsYF3I';
- b +=
- 'fwNEogqzVSnb/oTX97Cf4agiUnlca20ziJqyQRrlQv1mepM79gLaMRBOgHjena+2azYmb3FEhbu';
- b +=
- 'o4fn59ZrrEpzB0HtRzVJ9kbGwPqp+D5kF9+lxl6IrFoYtXoIVQu0xfdfFcoO3FWrQMv9/q1T/D6';
- b +=
- 'o3KL6DroH4RXr2mcYPX0+foFqhHFDo+sjldubUPrYU6bEPF5pS1578qk+qhvnbidVBg0+NDlqTj';
- b +=
- 'uC1lzrBPKp/78n1JZ6Hemh52u/Ia+0oM6QrUrYG6mZ+nKVdkk+5A7WShs/pxQ3VbJekx1KsOvAg';
- b +=
- 'LvPlwx0FSO9TOntu3PJxX2XuD9A5qlueW7b6+s4+9JfVArb7O7WBX0a4CGrkPapO8kG2sLp0bbD';
- b +=
- 'IFfnw3tCx93bGFVTmKLAV1ldS6jb2VrFfBZEXcv2dU1EO2QW0SWRPqRde3z50x3jOrgKwHtemTW';
- b +=
- 'rJbu27TVrIJ1MUizxnm62KLTpJtoOYcLlxXpWJ9p4XsDPVOjRf1Kx6prf9C9oT64ZzWo/ymVW9l';
- b +=
- 'Kb5Q/39rZWNT4lLTYJfkZB3o7RGjLWw0KdY7idpfrGuG6F1D9O5/0+qwjcVNrDPbwJLt7My2szQ';
- b +=
- 'cFH/PkOMxidl4/+ojlTisNDGyFWu3IbpuyLFr/+m16mJNO2gLsVNmGAy+vsfov7m/QbcljvME/f';
- b +=
- '28T9E/qA0m8R6okwzy3EgEqV6MIm7uskjWqgoEef6FilxaO0ocz5qEp4VY25F+v7+EIfoFCe9Ri';
- b +=
- 'nUXCX+HJdZXCP0v8wrxNerdHhY0H3P8X/WGQi2mg55T1EiLkb/CN/7T8EmRKcLUP/pPoJoTxzlB';
- b +=
- 'xDGzMDM19ov0i+PHWPyb3ldiZDpuqkB8jIWE2QBDMzOkeS8L9qix10f4m6jIqGguL+bxFvyjmJO';
- b +=
- 'YzsG/Hg6lc9gRfgI+j6BzxHHe7cXfm4p/8Tcg2LhDyHYCD7Vo0KijGH4U5fLS2YI0IfYGJwp7T5';
- b +=
- 'HqBF+6gMvGvimA2xFCjQcEexAkYB8LjkSS9uGflEsGvR0qhe/sdF3AYAj04wb1kiMSeDFCNjsFe';
- b +=
- '+0ZQSQWk83G9jqxmfh+JzayZx/+4bUJ/GKj03v78A+1v0fEYhBRsbJJxPlO/DL243HEcbFA4vSx';
- b +=
- '2Y+necmgEeEKjLjAWnrsPNhfJtsE/I9pwpzPnm9gwDT50yEXyIwgA1qAbmjafsLcBzGi/v+N0bT';
- b +=
- '/8g9LcyxdPlFxkzsxkQmpPGFKGvbWUuxnK4F/zxBrMwm8V50SyY/FPpGDwkhkPXEmxX3AeJsNKQ';
- b +=
- 'JsF2F0p/MAnh9/gt8/jsHjc4kjmNTj+UPsj8fH/eCZUrFSAnM8iAQF4gviYG9Qourxt5j4+yTi1';
- b +=
- 'MR5QVHnCnj4BzuY7+G3oTg+8V7nt6BZ9fhb0XLwi73jvkiU03/33eIBCI+loRcVf1MzWBsM0o40';
- b +=
- 'vJ0U69gheiahQ83MzKZH8WLj+GxnF5hGBtiGIXvOTB5+zdirjIiICQ0s+EYoFPxiZSW8AU9DQQN';
- b +=
- '+3RB2IB4Q8c0yEjIoeGUCbmkUOw5+MI7jp2LNI9sAf01siD24CKSkAYcpKsEv9jHwVAP+/ae5AY';
- b +=
- 'cGxOfBjvBbLYVH/xX/ewP+nMTh/zQ9iTbD4CCe17AekcmfhU0DdaaAyzNPSonjC8UGsRAkCMQbQ';
- b +=
- 'ZiXshukmcT3CoSGomSUQqLS6SQGQ4LEpEqSZCgsVI4kT1WQU0SVSCokNWlNqhZDB9VDZ1HiSXvI';
- b +=
- '+0jHSddJN0l3pO5K3CPdJ7Wgz6jPSa8onaQP7G7Kd9JPci8qNXKUq59/8fr1GzILVq7atP/o4n0';
- b +=
- '0uoSdi+vkzzduUhRV7ewnhyys2b2n0faZ/JKlResp0jJy8oaWNk5jvHzG+flzeWEHD2lo0hlMSU';
- b +=
- 'UVO0enHTsfPJSwLyndQWeOco2JK14hJwhv+tA1LaqnTxQYtLbSzHykQXBV9cbNW7bvqDt6/CxNU';
- b +=
- 'kpJy2n0mInbtl+5Wk1XUx82wnX0q3ddonPnKezhI/QNrB2cvMf5BgQGT54yLWxGRDQvJj41ff7C';
- b +=
- 'ZVtq9uw9eWP3Hr7gxMoZwzKpZIopOYaMmptl5WiRLWU1KXoS2lRjqidFxiirhqZH0aMYMGwk/Ty';
- b +=
- 'y7SWUmQzVUWMcydEMCQtlqi5Zg4q6OVDGU80pTLoE3Y09kiIlYUd2oqrTKVL0AB97a2lruhmDma';
- b +=
- '0/abwxw0hZXV9TUUXCD5zAU1qNzqR5M0ZKpEm6uxrRRlGZtIk0lMoiU7MKorS9GcysbTOGjZFk0';
- b +=
- 'qQVnGhMOxOKStYRZ26glLcE02uMhjcjUNqHzsz66sXUIo/1sSfLMJg0Rzoz206NPoqsORmVtZLO';
- b +=
- 'rYxJk8w6u8w3WjrPgqVcXJMzduORHEe6ESWMps/0YhpQFXL2hvLGUxzpcm5Yllj9nZF3z0hi06t';
- b +=
- 'sa1lUiyZDYWQXLqXEU6XJEnTWioixEkLnrK/MVEaSktdcRSlFqRAJtawl2WPJi9xllfICdGi0rL';
- b +=
- 'vGVFddNMmUrE4hZbvpyDlR0ewbRjkvs74Z+lKYFFKunKevS9ZpZxpKCaZq2JCyZUwoXKnJzKzdD';
- b +=
- 'lrSJhQJOkmGlrU29wFFjixNnkMJp0lRUFkpigO4OQPGML/sICktcC12DBkQVIKedXkEM4+GoGQq';
- b +=
- 'lUYj0WkMuoQcU1NSTUpdmiUjJUthkeXlFSSUURWKKqpGVqdroJokHWU22ZhsKmmGWpAtSVbodtJ';
- b +=
- 'OUg1lF+MnqZfaTxogiyTq0jMKlm+yCJlSUFii+URGdrxvb5+Z+eiw6eFtecuLSlfs3Hf02LnzzZ';
- b +=
- 'eetneIEArM0PZOo1x8xk3PKwKe9UePnb907Xp7B/Iru4/C8vsMLi+vtLKq+dp1aTlDsMsnJDRsR';
- b +=
- 'jiXt7x0J4hyrrm1vaNbWm6MD5eXlbf/+Immu/e7P+YuKtiy7UTTuQvXWx55VzRePX/tuo+ff8jU';
- b +=
- 'GeFLi4r3HTzUdOr8hftyyiqhYV+/DYiyEpOftsro8AWaWuHzF+zes/DYcWUVbR2vsX7+WP5fsLD';
- b +=
- 'h3J27j7s/fklJLRamrdI3M9++51DThev3W9e6ra6wKNa5deeayM9/WiidIcsaaf6hiy+wdxntPq';
- b +=
- 'akNDA27WLzjZsPHr4aECHs8GE5rZQcT4YGhSaXXSuTtYuqI5GtQVZjoBRzig2FTkbpNLocM0BWn';
- b +=
- 'h5MJ1M0mRJkBplOJpHJZCkKlSxJQ2WUqH50DXoInURTkQqgeJBNQfUkR5OVcqJojQhnJ1Jmjci6';
- b +=
- 'SM3ZS1an5fSTp9KVJVQlsAw3i8akqdOm0o2pXkwTCsgbZEtJE4o6TZKcVQu8zC0nkLO2MJzJsmR';
- b +=
- 'nugPDmJojklNlmMuZknVldWWzCik5q9UklfLLqObUUSCnqUpknRgmlMq6py5FzRJRs1qlPlWR7S';
- b +=
- 'WywxSzDjOyLlOZqqPITJoDw4shRRNKapOnUaZKZOWqajKVJXwpWctou7ZIqVAsN1KyW/TpUlRq1';
- b +=
- 'jZW9hc6yjaiAd/llKwTZA2yrPQ/rcOJ33BupDASVOOqx1mwvcS+jWO/Yh1GfCn5h+PwsA8BWAMQ';
- b +=
- 'loZ9BYwA4dWJ79SSg3QMYcbyT8csUXGxeG8RjKNAeOxrYy2K98H/cfzAF+Bo25+M5CCkCUZyNn8';
- b +=
- 'y7BBgn5aI18lgzJZLYSOl1AhkukI1Iq/C1pFiR+h0mVQbG1mwTQTbnpmQdkSYavdGmCEDbLv1og';
- b +=
- 'i7fvS5HcrUtdeTfm6/SybS0Vx1o6OFZqT3Z+2Nvm42kQHdszZO9BfoTqo6vnEScj0ykHdzYyDSo';
- b +=
- 'huEPHsevLstMuRdu+7UG50bp7KRD1O70YXTkCSEjpiiKEoC/1BvSQslFsoD+ZBEQinDUW2NUEkn';
- b +=
- 'CQlUlYJKgCaTakx2Zhipomx7EIHCAPmNziRpoU5YdAoDBGGS1FESyRG0rRQSyN+oNomMSmKaCgK';
- b +=
- 'giiRl0PI6YecCoelkJkkbHQXiSoGYBuDw4KhkKsj5dJIkPCp2SeCkJExrkhxJf5xFC/VGKSg4OM';
- b +=
- 'pAJ6IkuhQjCiVJSNJ9SBoo9mcvg4IzUiVRPQk0hoLSwEWR1EgUMosiDTZpqCwK0p6sRdIG/9xIK';
- b +=
- 'J2BkiQlUFDq0DTSMHQ2mUKSQGnkRyARwNXSsSOSGDQmCbXQsaRYAE1FDSSkSGxwkyjZAYUXQnZi';
- b +=
- 'kEgVZFQapWMnJJPOuyHoGV2EvByNYCO0OBJCQZlsUgAJwfoeqBqJiq4mqctLo/oMNUkzsgWKJdl';
- b +=
- 'I1AOkPIkkBe7LHLUGRyWRqOC+jUgM9AOWbCjIjCwWNjRC29ByKkIGd0kxIFPQreD4CCmA7CVpSc';
- b +=
- 'lE7WQNwX0yyZbgmHTUhaxHRRmuqBTJRgI0Omg4GUtKkChoFUpmKMGURVFlVIZOpp5hYDejgqUqD';
- b +=
- 'XtQ2EN4C66NBn41SMEMbM8sFEZHeWTwUKmIBEr6Ap4JyBFoCTgfBWUzDWjwSdFIZDOQ4AgdJAg6';
- b +=
- 'SRlcCjjKXBoZOypIRW/sVCgCnq4NlYptoTRZBFRFCDqaMhHsR8xIKghIAwqVwSDRtSllZMSeYsV';
- b +=
- 'AZVBlKioLjioHj0jlotUgjgsFpAA9kY5EZHUjnKzsM4gkSkYyJZJSBNy0aF5KKomRAAYaaZGxPJ';
- b +=
- 'QyKS1ViEgBL+xTLo9rGpVBpkKCScvSzN7ezJJt8ItkYoPhn42phbWplb0hbU5kAghGw3hbM2spU';
- b +=
- 'PYTTaNArzqWx5fHLCY6WrENrCJtIm0cre2sDBETWZzDDI/hQQORqSRj2UT827ZpbIIgCoyzjBmY';
- b += 'mUhTXrrw/wGKgg/M';
-
- var input = pako.inflate(base64ToUint8Array(b));
- return __wbg_init(input);
-}
diff --git a/packages/bls-sdk/tsconfig.lib.json b/packages/bls-sdk/tsconfig.lib.json
deleted file mode 100644
index e85ef50f65..0000000000
--- a/packages/bls-sdk/tsconfig.lib.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "declaration": true,
- "types": []
- },
- "include": ["**/*.ts"],
- "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
-}
diff --git a/packages/bls-sdk/tsconfig.spec.json b/packages/bls-sdk/tsconfig.spec.json
deleted file mode 100644
index 546f12877f..0000000000
--- a/packages/bls-sdk/tsconfig.spec.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "module": "commonjs",
- "types": ["jest", "node"]
- },
- "include": ["jest.config.ts", "**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"]
-}
diff --git a/packages/constants/README.md b/packages/constants/README.md
index f03d5c56b0..d32b5254e6 100644
--- a/packages/constants/README.md
+++ b/packages/constants/README.md
@@ -1,18 +1,9 @@
# Quick Start
-This submodule exports various modules, constants, interfaces, enums, errors, utilities that are being used in Lit Protocol.
+This submodule exports various modules, constants, interfaces, errors, utilities that are being used in Lit Protocol.
### node.js / browser
```
yarn add @lit-protocol/constants
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/constants/package.json b/packages/constants/package.json
index 4730bb6c64..407e60e9a0 100644
--- a/packages/constants/package.json
+++ b/packages/constants/package.json
@@ -20,7 +20,7 @@
"tags": [
"universal"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts
index 269c2a49f3..677aba2cba 100644
--- a/packages/constants/src/index.ts
+++ b/packages/constants/src/index.ts
@@ -5,15 +5,11 @@ export * from './lib/version';
export * from './lib/constants/constants';
export * from './lib/constants/mappers';
export * from './lib/constants/endpoints';
-export * from './lib/constants/autogen_internal';
export * from './lib/constants/mappers';
// ----------- Interfaces -----------
export * from './lib/interfaces/i-errors';
-// ----------- ENUMS -----------
-export * from './lib/enums';
-
// ----------- Errors -----------
export * from './lib/errors';
@@ -21,7 +17,7 @@ export * from './lib/errors';
export * from './lib/utils/utils';
// ----------- ABIs -----------
-import * as ABI_LIT from './lib/abis/LIT.json';
import * as ABI_ERC20 from './lib/abis/ERC20.json';
+import * as ABI_LIT from './lib/abis/LIT.json';
export { ABI_LIT, ABI_ERC20 };
diff --git a/packages/constants/src/lib/constants/autogen_internal.ts b/packages/constants/src/lib/constants/autogen_internal.ts
deleted file mode 100644
index 79f4b18d95..0000000000
--- a/packages/constants/src/lib/constants/autogen_internal.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// This file is auto-generated by tools/scripts/gen-internal-dev.mjs
-export const INTERNAL_DEV = [
- 'https://167.114.17.205:443',
- 'https://167.114.17.203:443',
- 'https://158.69.34.227:443',
-];
-
-export const INTERNAL_MIN_NODE_COUNT = 3;
-
-export const INTERNAL_DEFAULT_CONFIG = {
- alertWhenUnauthorized: false,
- minNodeCount: 3,
- debug: true,
- bootstrapUrls: [
- 'https://167.114.17.205:443',
- 'https://167.114.17.203:443',
- 'https://158.69.34.227:443',
- ],
- litNetwork: 'internalDev',
- connectTimeout: 20000,
-};
diff --git a/packages/constants/src/lib/constants/constants.ts b/packages/constants/src/lib/constants/constants.ts
index 444e2b5850..8ae36f1ca1 100644
--- a/packages/constants/src/lib/constants/constants.ts
+++ b/packages/constants/src/lib/constants/constants.ts
@@ -1,3 +1,5 @@
+import depd from 'depd';
+
import {
LITChain,
LITCosmosChain,
@@ -5,8 +7,7 @@ import {
LITSVMChain,
} from '@lit-protocol/types';
-import { INTERNAL_DEV } from './autogen_internal';
-import { LitNetwork } from '../enums';
+const deprecated = depd('lit-js-sdk:constants:constants');
/**
* Lit Protocol Network Public Key
@@ -26,21 +27,6 @@ export const LIT_AUTH_SIG_CHAIN_KEYS: string[] = [
export const AUTH_SIGNATURE_BODY =
'I am creating an account to use Lit Protocol at {{timestamp}}';
-const oldChronicleChain = {
- contractAddress: null,
- chainId: 175177,
- name: 'Chronicle - Lit Protocol Testnet',
- symbol: 'tstLIT',
- decimals: 18,
- rpcUrls: [
- 'https://lit-protocol.calderachain.xyz/replica-http',
- 'https://chain-rpc.litprotocol.com/http',
- ],
- blockExplorerUrls: ['https://chain.litprotocol.com/'],
- type: null,
- vmType: 'EVM',
-};
-
const yellowstoneChain = {
contractAddress: null,
chainId: 175188,
@@ -517,20 +503,12 @@ export const LIT_CHAINS: LITChain = {
},
/**
- * Chainlist entry for the Chronicle Testnet.
- * https://chainlist.org/chain/175177
- */
- chronicleTestnet: oldChronicleChain,
-
- /**
- * Use this for `>= DatilTest` network.
+ * Use this for `>= Datil` network.
* Chainlist entry for the Chronicle Yellowstone Testnet.
* https://chainlist.org/chain/175188
*/
yellowstone: yellowstoneChain,
- lit: oldChronicleChain,
-
chiado: {
contractAddress: null,
chainId: 10200,
@@ -816,31 +794,10 @@ export const LIT_CHAINS: LITChain = {
},
};
-/**
- * @deprecated Will be removed in version 7.x. - This is using the OLD chornicle testnet. `LIT_CHAINS['chronicleTestnet']` instead, or use `LIT_CHAINS['yellowstone']` for the new Chronicle Yellowstone Testnet (Jul 2024). (Updated to use `yellowstone` chain instead 22 July 2024)
- */
-export const LIT_CHAIN_RPC_URL = LIT_CHAINS['chronicleTestnet'].rpcUrls[0];
-
/**
* Object containing information to submit to Metamask
*/
-export const metamaskChainInfo = {
- /**
- * Information about the "chronicle" chain.
- */
- chronicle: {
- chainId: LIT_CHAINS['chronicleTestnet'].chainId,
- chainName: LIT_CHAINS['chronicleTestnet'].name,
- nativeCurrency: {
- name: LIT_CHAINS['chronicleTestnet'].symbol,
- symbol: LIT_CHAINS['chronicleTestnet'].symbol,
- decimals: LIT_CHAINS['chronicleTestnet'].decimals,
- },
- rpcUrls: LIT_CHAINS['chronicleTestnet'].rpcUrls,
- blockExplorerUrls: LIT_CHAINS['chronicleTestnet'].blockExplorerUrls,
- iconUrls: ['future'],
- },
-
+export const METAMASK_CHAIN_INFO = {
/**
* Information about the "chronicleYellowstone" chain.
*/
@@ -857,6 +814,19 @@ export const metamaskChainInfo = {
iconUrls: ['future'],
},
};
+/**
+ * @deprecated Will be removed - Use METAMASK_CHAIN_INFO instead
+ * Alias for {@link METAMASK_CHAIN_INFO}. Added for backwards compatibility.
+ * See {@link METAMASK_CHAIN_INFO}
+ */
+export const metamaskChainInfo = new Proxy(METAMASK_CHAIN_INFO, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'metamaskChainInfo is deprecated and will be removed in a future version. Use METAMASK_CHAIN_INFO instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
/**
* Constants representing the available LIT RPC endpoints.
@@ -867,11 +837,6 @@ export const LIT_RPC = {
*/
LOCAL_ANVIL: 'http://127.0.0.1:8545',
- /**
- * Chronicle RPC endpoint - Used for Cayenne, Manzano, Habanero
- */
- CHRONICLE: 'https://chain-rpc.litprotocol.com/http',
-
/**
* Chronicle Yellowstone RPC endpoint - used for >= Datil-test
* More info: https://app.conduit.xyz/published/view/chronicle-yellowstone-testnet-9qgmzfcohk
@@ -885,16 +850,24 @@ export const LIT_EVM_CHAINS = LIT_CHAINS;
* Represents the Lit Network constants.
*/
export const LIT_NETWORK = {
- Cayenne: 'cayenne',
- Manzano: 'manzano',
- Habanero: 'habanero',
DatilDev: 'datil-dev',
DatilTest: 'datil-test',
Datil: 'datil',
Custom: 'custom',
- Localhost: 'localhost',
-};
-
+} as const;
+/**
+ * @deprecated Will be removed. - Use LIT_NETWORK instead
+ * Alias for LIT_NETWORK. Added for backwards compatibility.
+ * See {@link LIT_NETWORK}
+ */
+export const LitNetwork = new Proxy(LIT_NETWORK, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LitNetwork is deprecated and will be removed in a future version. Use LIT_NETWORK instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
/**
* The type representing the keys of the LIT_NETWORK object.
*/
@@ -902,6 +875,7 @@ export type LIT_NETWORK_TYPES = keyof typeof LIT_NETWORK;
/**
* The type representing the values of the LIT_NETWORK object.
+ * This should replicate LIT_NETWORKS_KEYS in types package
*/
export type LIT_NETWORK_VALUES = (typeof LIT_NETWORK)[keyof typeof LIT_NETWORK];
@@ -911,14 +885,10 @@ export type LIT_NETWORK_VALUES = (typeof LIT_NETWORK)[keyof typeof LIT_NETWORK];
* A mapping of network names to their corresponding RPC URLs.
*/
export const RPC_URL_BY_NETWORK: { [key in LIT_NETWORK_VALUES]: string } = {
- cayenne: LIT_RPC.CHRONICLE,
- manzano: LIT_RPC.CHRONICLE,
- habanero: LIT_RPC.CHRONICLE,
'datil-dev': LIT_RPC.CHRONICLE_YELLOWSTONE,
'datil-test': LIT_RPC.CHRONICLE_YELLOWSTONE,
datil: LIT_RPC.CHRONICLE_YELLOWSTONE,
custom: LIT_RPC.LOCAL_ANVIL,
- localhost: LIT_RPC.LOCAL_ANVIL,
};
/**
@@ -927,14 +897,10 @@ export const RPC_URL_BY_NETWORK: { [key in LIT_NETWORK_VALUES]: string } = {
export const RELAYER_URL_BY_NETWORK: {
[key in LIT_NETWORK_VALUES]: string;
} = {
- cayenne: 'https://relayer-server-staging-cayenne.getlit.dev',
- manzano: 'https://manzano-relayer.getlit.dev',
- habanero: 'https://habanero-relayer.getlit.dev',
'datil-dev': 'https://datil-dev-relayer.getlit.dev',
'datil-test': 'https://datil-test-relayer.getlit.dev',
datil: 'https://datil-relayer.getlit.dev',
custom: 'http://localhost:3000',
- localhost: 'http://localhost:3000',
};
/**
@@ -942,16 +908,12 @@ export const RELAYER_URL_BY_NETWORK: {
*/
export const METAMASK_CHAIN_INFO_BY_NETWORK: Record<
LIT_NETWORK_VALUES,
- typeof metamaskChainInfo.chronicle | typeof metamaskChainInfo.yellowstone
+ typeof METAMASK_CHAIN_INFO.yellowstone
> = {
- cayenne: metamaskChainInfo.chronicle,
- manzano: metamaskChainInfo.chronicle,
- habanero: metamaskChainInfo.chronicle,
- 'datil-dev': metamaskChainInfo.yellowstone,
- 'datil-test': metamaskChainInfo.yellowstone,
- datil: metamaskChainInfo.yellowstone,
- custom: metamaskChainInfo.yellowstone,
- localhost: metamaskChainInfo.yellowstone,
+ 'datil-dev': METAMASK_CHAIN_INFO.yellowstone,
+ 'datil-test': METAMASK_CHAIN_INFO.yellowstone,
+ datil: METAMASK_CHAIN_INFO.yellowstone,
+ custom: METAMASK_CHAIN_INFO.yellowstone,
};
export const HTTP = 'http://';
@@ -964,14 +926,10 @@ export const HTTP_BY_NETWORK: Record<
LIT_NETWORK_VALUES,
typeof HTTP | typeof HTTPS
> = {
- cayenne: HTTPS,
- manzano: HTTPS,
- habanero: HTTPS,
'datil-dev': HTTPS,
'datil-test': HTTPS,
- internalDev: HTTPS,
+ datil: HTTPS,
custom: HTTP, // default, can be changed by config
- localhost: HTTP, // default, can be changed by config
};
/**
@@ -981,14 +939,10 @@ export const CENTRALISATION_BY_NETWORK: Record<
LIT_NETWORK_VALUES,
'centralised' | 'decentralised' | 'unknown'
> = {
- cayenne: 'centralised',
- manzano: 'decentralised',
- habanero: 'decentralised',
'datil-dev': 'centralised',
'datil-test': 'decentralised',
datil: 'decentralised',
custom: 'unknown',
- localhost: 'unknown',
} as const;
/**
@@ -1129,41 +1083,16 @@ export const SYMM_KEY_ALGO_PARAMS = {
length: 256,
};
-/**
- * Default node URL for Cayenne network
- */
-export const CAYENNE_URL = 'https://cayenne.litgateway.com';
-
/**
* Default node URLs for each LIT network
- * Note: Dynamic networks such as Habanero have no default node URLS; they are always
+ * Note: Dynamic networks have no default node URLS; they are always
* loaded from the chain during initialization
*/
-export const LIT_NETWORKS: { [key in LitNetwork]: string[] } & {
- localhost: string[];
- internalDev: string[];
-} = {
- [LitNetwork.Cayenne]: [],
- [LitNetwork.Manzano]: [],
- [LitNetwork.DatilDev]: [],
- [LitNetwork.DatilTest]: [],
- [LitNetwork.Datil]: [],
- [LitNetwork.Habanero]: [],
- [LitNetwork.Custom]: [],
- // FIXME: Remove localhost and internalDev; replaced with 'custom' type networks
- localhost: [
- 'http://localhost:7470',
- 'http://localhost:7471',
- 'http://localhost:7472',
- 'http://localhost:7473',
- 'http://localhost:7474',
- 'http://localhost:7475',
- 'http://localhost:7476',
- 'http://localhost:7477',
- 'http://localhost:7478',
- 'http://localhost:7479',
- ],
- internalDev: INTERNAL_DEV,
+export const LIT_NETWORKS: { [key in LIT_NETWORK_VALUES]: string[] } = {
+ 'datil-dev': [],
+ 'datil-test': [],
+ datil: [],
+ custom: [],
};
// ========== Lit Sessions ==========
@@ -1184,35 +1113,341 @@ export const PKP_CLIENT_SUPPORTED_CHAINS = ['eth', 'cosmos'];
// ========== RLI Delegation ==========
export const SIWE_DELEGATION_URI = 'lit:capability:delegation';
+// ========== Lit Actions ==========
+export const LIT_ACTION_IPFS_HASH =
+ 'QmUjX8MW6StQ7NKNdaS6g4RMkvN5hcgtKmEi8Mca6oX4t3';
+
+// ========== Chains ==========
+export const VMTYPE = {
+ EVM: 'EVM',
+ SVM: 'SVM',
+ CVM: 'CVM',
+} as const;
+export type VMTYPE_TYPE = keyof typeof VMTYPE;
+export type VMTYPE_VALUES = (typeof VMTYPE)[keyof typeof VMTYPE];
+
+export const LIT_CURVE = {
+ BLS: 'BLS',
+ EcdsaK256: 'K256',
+ EcdsaCaitSith: 'ECDSA_CAIT_SITH', // Legacy alias of K256
+ EcdsaCAITSITHP256: 'EcdsaCaitSithP256',
+} as const;
+
+export type LIT_CURVE_TYPE = keyof typeof LIT_CURVE;
+// This should replicate SigShare.sigType in types package
+export type LIT_CURVE_VALUES = (typeof LIT_CURVE)[keyof typeof LIT_CURVE];
+
+// ========== Either Types ==========
+export const EITHER_TYPE = {
+ ERROR: 'ERROR',
+ SUCCESS: 'SUCCESS',
+} as const;
+export type EITHER_TYPE_TYPE = keyof typeof EITHER_TYPE;
+export type EITHER_TYPE_VALUES = (typeof EITHER_TYPE)[keyof typeof EITHER_TYPE];
+
+// ========== Supported PKP Auth Method Types ==========
+export const AUTH_METHOD_TYPE = {
+ EthWallet: 1,
+ LitAction: 2,
+ WebAuthn: 3,
+ Discord: 4,
+ Google: 5,
+ GoogleJwt: 6,
+ AppleJwt: 8,
+ StytchOtp: 9,
+ StytchEmailFactorOtp: 10,
+ StytchSmsFactorOtp: 11,
+ StytchWhatsAppFactorOtp: 12,
+ StytchTotpFactorOtp: 13,
+} as const;
+
+export type AUTH_METHOD_TYPE_TYPE = keyof typeof AUTH_METHOD_TYPE;
+export type AUTH_METHOD_TYPE_VALUES =
+ (typeof AUTH_METHOD_TYPE)[keyof typeof AUTH_METHOD_TYPE];
+/**
+ * @deprecated Will be removed - Use AUTH_METHOD_TYPE instead
+ * Alias for AUTH_METHOD_TYPE. Added for backwards compatibility.
+ * See {@link AUTH_METHOD_TYPE}
+ */
+export const AuthMethodType = new Proxy(AUTH_METHOD_TYPE, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'AuthMethodType is deprecated and will be removed in a future version. Use AUTH_METHOD_TYPE instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+// ========== Supported PKP Auth Method Scopes ==========
+export const AUTH_METHOD_SCOPE = {
+ NoPermissions: 0,
+ SignAnything: 1,
+ PersonalSign: 2,
+} as const;
+
+export type AUTH_METHOD_SCOPE_TYPE = keyof typeof AUTH_METHOD_SCOPE;
+export type AUTH_METHOD_SCOPE_VALUES =
+ (typeof AUTH_METHOD_SCOPE)[keyof typeof AUTH_METHOD_SCOPE];
+
/**
- * @deprecated Will be removed in version 7.x. - Use RELAYER_URL_BY_NETWORK.Cayenne instead
+ * @deprecated Will be removed - Use AUTH_METHOD_SCOPE instead
+ * Alias for AUTH_METHOD_SCOPE. Added for backwards compatibility.
+ * See {@link AUTH_METHOD_SCOPE}
*/
-export const RELAY_URL_CAYENNE =
- 'https://relayer-server-staging-cayenne.getlit.dev';
+export const AuthMethodScope = new Proxy(AUTH_METHOD_SCOPE, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'AuthMethodScope is deprecated and will be removed in a future version. Use AUTH_METHOD_SCOPE instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+// ========== Supported Provider Types ==========
+export const PROVIDER_TYPE = {
+ Discord: 'discord',
+ Google: 'google',
+ EthWallet: 'ethwallet',
+ WebAuthn: 'webauthn',
+ Apple: 'apple',
+ StytchOtp: 'stytchOtp',
+ StytchEmailFactorOtp: 'stytchEmailFactorOtp',
+ StytchSmsFactorOtp: 'stytchSmsFactorOtp',
+ StytchWhatsAppFactorOtp: 'stytchWhatsAppFactorOtp',
+ StytchTotpFactor: 'stytchTotpFactor',
+} as const;
+export type PROVIDER_TYPE_TYPE = keyof typeof PROVIDER_TYPE;
+export type PROVIDER_TYPE_VALUES =
+ (typeof PROVIDER_TYPE)[keyof typeof PROVIDER_TYPE];
/**
- * @deprecated Will be removed in version 7.x. - Use RELAYER_URL_BY_NETWORK.Habanero instead
+ * @deprecated Will be removed - Use PROVIDER_TYPE instead
+ * Alias for PROVIDER_TYPE. Added for backwards compatibility.
+ * See {@link PROVIDER_TYPE}
*/
-export const RELAY_URL_HABANERO = 'https://habanero-relayer.getlit.dev';
+export const ProviderType = new Proxy(PROVIDER_TYPE, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'ProviderType is deprecated and will be removed in a future version. Use PROVIDER_TYPE instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+// ========== Supported Staking States ==========
+export const STAKING_STATES = {
+ Active: 0,
+ NextValidatorSetLocked: 1,
+ ReadyForNextEpoch: 2,
+ Unlocked: 3,
+ Paused: 4,
+ Restore: 5,
+} as const;
+
+export type STAKING_STATES_TYPE = keyof typeof STAKING_STATES;
+export type STAKING_STATES_VALUES =
+ (typeof STAKING_STATES)[keyof typeof STAKING_STATES];
/**
- * @deprecated Will be removed in version 7.x. - Use RELAYER_URL_BY_NETWORK.Manzano instead
+ * @deprecated Will be removed - Use STAKING_STATES instead
+ * Alias for STAKING_STATES. Added for backwards compatibility.
+ * See {@link STAKING_STATES}
*/
-export const RELAY_URL_MANZANO = 'https://manzano-relayer.getlit.dev';
+export const StakingStates = new Proxy(STAKING_STATES, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'StakingStates is deprecated and will be removed in a future version. Use STAKING_STATES instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+// ========== Relay Auth Status ==========
+export const RELAY_AUTH_STATUS = {
+ InProgress: 'InProgress',
+ Succeeded: 'Succeeded',
+ Failed: 'Failed',
+} as const;
+export type RELAY_AUTH_STATUS_TYPE = keyof typeof RELAY_AUTH_STATUS;
+export type RELAY_AUTH_STATUS_VALUES =
+ (typeof RELAY_AUTH_STATUS)[keyof typeof RELAY_AUTH_STATUS];
/**
- * @deprecated Will be removed in version 7.x. - Use RELAYER_URL_BY_NETWORK.DatilDev instead
+ * @deprecated Will be removed - Use RELAY_AUTH_STATUS instead
+ * Alias for RELAY_AUTH_STATUS. Added for backwards compatibility.
+ * See {@link RELAY_AUTH_STATUS}
*/
-export const RELAY_URL_DATIL_DEV = 'https://datil-dev-relayer.getlit.dev';
+export const RelayAuthStatus = new Proxy(RELAY_AUTH_STATUS, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'RelayAuthStatus is deprecated and will be removed in a future version. Use RELAY_AUTH_STATUS instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
/**
- * @deprecated Will be removed in version 7.x. - Use RELAYER_URL_BY_NETWORK.DatilTest instead
+ * Prefixes used for identifying various LIT resources.
+ *
+ * @description These resource prefixes are also used as valid IRI schemes.
+ */
+export const LIT_RESOURCE_PREFIX = {
+ AccessControlCondition: 'lit-accesscontrolcondition',
+ PKP: 'lit-pkp',
+ RLI: 'lit-ratelimitincrease',
+ LitAction: 'lit-litaction',
+} as const;
+export type LIT_RESOURCE_PREFIX_TYPE = keyof typeof LIT_RESOURCE_PREFIX;
+// This should mimic LitResourcePrefix in types package
+export type LIT_RESOURCE_PREFIX_VALUES =
+ (typeof LIT_RESOURCE_PREFIX)[keyof typeof LIT_RESOURCE_PREFIX];
+/**
+ * @deprecated Will be removed - Use LIT_RESOURCE_PREFIX instead
+ * Alias for LIT_RESOURCE_PREFIX. Added for backwards compatibility.
+ * See {@link LIT_RESOURCE_PREFIX}
*/
-export const RELAY_URL_DATIL_TEST = 'https://datil-test-relayer.getlit.dev';
+export const LitResourcePrefix = new Proxy(LIT_RESOURCE_PREFIX, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LitResourcePrefix is deprecated and will be removed in a future version. Use LIT_RESOURCE_PREFIX instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
-// ========== Lit Actions ==========
-export const LIT_ACTION_IPFS_HASH =
- 'QmUjX8MW6StQ7NKNdaS6g4RMkvN5hcgtKmEi8Mca6oX4t3';
+/**
+ * User-facing abilities that can be granted to a session.
+ */
+export const LIT_ABILITY = {
+ /**
+ * This is the ability to process an encryption access control condition.
+ * The resource will specify the corresponding hashed key value of the
+ * access control condition.
+ */
+ AccessControlConditionDecryption: 'access-control-condition-decryption',
+
+ /**
+ * This is the ability to process a signing access control condition.
+ * The resource will specify the corresponding hashed key value of the
+ * access control condition.
+ */
+ AccessControlConditionSigning: 'access-control-condition-signing',
+
+ /**
+ * This is the ability to use a PKP for signing purposes. The resource will specify
+ * the corresponding PKP token ID.
+ */
+ PKPSigning: 'pkp-signing',
+
+ /**
+ * This is the ability to use a Rate Limit Increase (Capacity Credits NFT) token during
+ * authentication with the nodes. The resource will specify the corresponding
+ * Capacity Credits NFT token ID.
+ */
+ RateLimitIncreaseAuth: 'rate-limit-increase-auth',
+
+ /**
+ * This is the ability to execute a Lit Action. The resource will specify the
+ * corresponding Lit Action IPFS CID.
+ */
+ LitActionExecution: 'lit-action-execution',
+} as const;
+
+export type LIT_ABILITY_TYPE = keyof typeof LIT_ABILITY;
+// This should replicate LitAbility in types package
+export type LIT_ABILITY_VALUES = (typeof LIT_ABILITY)[keyof typeof LIT_ABILITY];
+/**
+ * @deprecated Will be removed - Use LIT_ABILITY instead
+ * Alias for LIT_ABILITY. Added for backwards compatibility.
+ * See {@link LIT_ABILITY}
+ */
+export const LitAbility = new Proxy(LIT_ABILITY, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LitAbility is deprecated and will be removed in a future version. Use LIT_ABILITY instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+/**
+ * LIT specific abilities mapped into the Recap specific terminology
+ * of an 'ability'.
+ */
+export const LIT_RECAP_ABILITY = {
+ Decryption: 'Decryption',
+ Signing: 'Signing',
+ Auth: 'Auth',
+ Execution: 'Execution',
+} as const;
+
+export type LIT_RECAP_ABILITY_TYPE = keyof typeof LIT_RECAP_ABILITY;
+export type LIT_RECAP_ABILITY_VALUES =
+ (typeof LIT_RECAP_ABILITY)[keyof typeof LIT_RECAP_ABILITY];
+/**
+ * @deprecated Will be removed - Use LIT_RECAP_ABILITY instead
+ * Alias for LIT_RECAP_ABILITY. Added for backwards compatibility.
+ * See {@link LIT_RECAP_ABILITY}
+ */
+export const LitRecapAbility = new Proxy(LIT_RECAP_ABILITY, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LitRecapAbility is deprecated and will be removed in a future version. Use LIT_RECAP_ABILITY instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+export const LIT_NAMESPACE = {
+ Auth: 'Auth',
+ Threshold: 'Threshold',
+} as const;
+
+export type LIT_NAMESPACE_TYPE = keyof typeof LIT_NAMESPACE;
+export type LIT_NAMESPACE_VALUES =
+ (typeof LIT_NAMESPACE)[keyof typeof LIT_NAMESPACE];
+/**
+ * @deprecated Will be removed - Use LIT_NAMESPACE instead
+ * Alias for LIT_NAMESPACE. Added for backwards compatibility.
+ * See {@link LIT_NAMESPACE}
+ */
+export const LitNamespace = new Proxy(LIT_NAMESPACE, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LitNamespace is deprecated and will be removed in a future version. Use LIT_NAMESPACE instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+/**
+ * SDK Logger levels
+ */
+export const LOG_LEVEL = {
+ INFO: 0,
+ DEBUG: 1,
+ WARN: 2,
+ ERROR: 3,
+ FATAL: 4,
+ TIMING_START: 5,
+ TIMING_END: 6,
+ OFF: -1,
+} as const;
+
+export type LOG_LEVEL_TYPE = keyof typeof LOG_LEVEL;
+export type LOG_LEVEL_VALUES = (typeof LOG_LEVEL)[keyof typeof LOG_LEVEL];
+/**
+ * @deprecated Will be removed - Use LOG_LEVEL instead
+ * Alias for LOG_LEVEL. Added for backwards compatibility.
+ * See {@link LOG_LEVEL}
+ */
+export const LogLevel = new Proxy(LOG_LEVEL, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LogLevel is deprecated and will be removed in a future version. Use LOG_LEVEL instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
export const FALLBACK_IPFS_GATEWAYS = [
'https://flk-ipfs.io/ipfs/',
diff --git a/packages/constants/src/lib/constants/endpoints.ts b/packages/constants/src/lib/constants/endpoints.ts
index 3672dce5df..5ce18498fe 100644
--- a/packages/constants/src/lib/constants/endpoints.ts
+++ b/packages/constants/src/lib/constants/endpoints.ts
@@ -1,7 +1,7 @@
-export enum LIT_ENDPOINT_VERSION {
- V0 = '/',
- V1 = '/v1',
-}
+export const LIT_ENDPOINT_VERSION = {
+ V0: '/',
+ V1: '/v1',
+};
export const LIT_ENDPOINT = {
HANDSHAKE: {
diff --git a/packages/constants/src/lib/constants/mappers.ts b/packages/constants/src/lib/constants/mappers.ts
index 5018f8373d..a55a729cc3 100644
--- a/packages/constants/src/lib/constants/mappers.ts
+++ b/packages/constants/src/lib/constants/mappers.ts
@@ -1,63 +1,33 @@
+import depd from 'depd';
+
+import { datilDev, datilTest, datil } from '@lit-protocol/contracts';
+
import { LIT_NETWORK_VALUES } from './constants';
-import {
- cayenne,
- manzano,
- habanero,
- datilDev,
- datilTest,
- datil,
-} from '@lit-protocol/contracts';
+
+const deprecated = depd('lit-js-sdk:constants:mappers');
/**
* Mapping of network context by network value.
*/
export const NETWORK_CONTEXT_BY_NETWORK: {
[key in LIT_NETWORK_VALUES]:
- | typeof cayenne
- | typeof manzano
- | typeof habanero
| typeof datilDev
| typeof datilTest
| typeof datil;
} = {
- cayenne: cayenne,
- manzano: manzano,
- habanero: habanero,
'datil-dev': datilDev,
'datil-test': datilTest,
datil: datil,
- // just use datil dev abis for custom and localhost
+ // just use datil dev abis for custom
custom: datilDev,
- localhost: datilDev,
} as const;
-/**
- * @deprecated Will be removed in version 7.x.
- */
-export const GENERAL_WORKER_URL_BY_NETWORK: {
- [key in LIT_NETWORK_VALUES]: string;
-} = {
- cayenne: 'https://apis.getlit.dev/cayenne/contracts',
- manzano: 'https://apis.getlit.dev/manzano/contracts',
- habanero: 'https://apis.getlit.dev/habanero/contracts',
- 'datil-dev': 'https://apis.getlit.dev/datil-dev/contracts',
- 'datil-test': 'https://apis.getlit.dev/datil-test/contracts',
-
- // just use cayenne abis for custom and localhost
- custom: 'https://apis.getlit.dev/cayenne/contracts',
- localhost: 'https://apis.getlit.dev/cayenne/contracts',
-};
-
export const GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK: {
[key in LIT_NETWORK_VALUES]: boolean;
} = {
- cayenne: false,
- manzano: false,
- habanero: true,
'datil-dev': false,
'datil-test': false,
datil: false,
custom: false,
- localhost: false,
};
diff --git a/packages/constants/src/lib/enums.ts b/packages/constants/src/lib/enums.ts
deleted file mode 100644
index f8db7b700f..0000000000
--- a/packages/constants/src/lib/enums.ts
+++ /dev/null
@@ -1,80 +0,0 @@
-/** ---------- Chains ---------- */
-export enum VMTYPE {
- EVM = 'EVM',
- SVM = 'SVM',
- CVM = 'CVM',
-}
-
-export enum LIT_CURVE {
- BLS = 'BLS',
- EcdsaK256 = 'K256',
- EcdsaCaitSith = 'ECDSA_CAIT_SITH', // Legacy alias of K256
- EcdsaCAITSITHP256 = 'EcdsaCaitSithP256',
-}
-
-/**
- * The only either possible error types
- */
-export const enum EITHER_TYPE {
- ERROR = 'ERROR',
- SUCCESS = 'SUCCESS',
-}
-
-/**
- * Supported PKP auth method types
- */
-export enum AuthMethodType {
- EthWallet = 1,
- LitAction = 2,
- WebAuthn = 3,
- Discord = 4,
- Google = 5,
- GoogleJwt = 6,
- AppleJwt = 8,
- StytchOtp = 9,
- StytchEmailFactorOtp = 10,
- StytchSmsFactorOtp = 11,
- StytchWhatsAppFactorOtp = 12,
- StytchTotpFactorOtp = 13,
-}
-
-export enum StakingStates {
- Active,
- NextValidatorSetLocked,
- ReadyForNextEpoch,
- Unlocked,
- Paused,
- Restore,
-}
-
-export enum AuthMethodScope {
- NoPermissions = 0,
- SignAnything = 1,
- PersonalSign = 2,
-}
-
-export enum LitNetwork {
- Cayenne = 'cayenne',
- Manzano = 'manzano',
- Habanero = 'habanero',
- Custom = 'custom',
- DatilDev = 'datil-dev',
- DatilTest = 'datil-test',
- Datil = 'datil',
-}
-
-/**
- * Supported provider types
- */
-export enum ProviderType {
- Discord = 'discord',
- Google = 'google',
- EthWallet = 'ethwallet',
- WebAuthn = 'webauthn',
- Apple = 'apple',
- StytchOtp = 'stytchOtp',
- StytchEmailFactorOtp = 'stytchEmailFactorOtp',
- StytchSmsFactorOtp = 'stytchSmsFactorOtp',
- StytchWhatsAppFactorOtp = 'stytchWhatsAppFactorOtp',
- StytchTotpFactor = 'stytchTotpFactor',
-}
diff --git a/packages/constants/src/lib/errors.spec.ts b/packages/constants/src/lib/errors.spec.ts
index 7198a94fdd..0a0ff43fdb 100644
--- a/packages/constants/src/lib/errors.spec.ts
+++ b/packages/constants/src/lib/errors.spec.ts
@@ -1,5 +1,7 @@
// @ts-nocheck
-import { LIT_ERROR } from './errors';
+import { VError } from '@openagenda/verror';
+
+import { LIT_ERROR, UnknownError, MultiError } from './errors';
describe('Lit Errors have correct format', () => {
it('returns correct format', () => {
@@ -9,12 +11,12 @@ describe('Lit Errors have correct format', () => {
const errorCode = entry[1].code;
let expectedErrorName = errorPropName.toLowerCase();
- let expectedErrorCode = errorPropName.toLowerCase();
+ const expectedErrorCode = errorPropName.toLowerCase();
expectedErrorName = expectedErrorName.split('_').map((section) => {
- let chars = [];
+ const chars = [];
- section = section.split('').forEach((c, i) => {
+ section.split('').forEach((c, i) => {
if (i == 0) {
chars.push(c.toUpperCase());
} else {
@@ -28,36 +30,71 @@ describe('Lit Errors have correct format', () => {
expectedErrorName = expectedErrorName.join('');
expect(errorName).toBe(expectedErrorName);
- // expect(errorCode).toBe(expectedErrorCode);
+ expect(errorCode).toBe(expectedErrorCode);
});
});
- it('returns correct format', () => {
- Object.entries(LIT_ERROR).forEach((entry) => {
- const errorPropName = entry[0];
- const errorName = entry[1].name;
- const errorCode = entry[1].code;
- let expectedErrorName = errorPropName.toLowerCase();
- let expectedErrorCode = errorPropName.toLowerCase();
+ it('Lit Custom Error has correct format', () => {
+ const error = new UnknownError(
+ {
+ info: {
+ foo: 'bar',
+ },
+ meta: {
+ one: 'two',
+ },
+ cause: new Error('root cause'),
+ },
+ 'unknown error'
+ );
- expectedErrorName = expectedErrorName.split('_').map((section) => {
- let chars = [];
+ expect(error.message).toBe('unknown error: root cause');
+ expect(error.cause).toBeInstanceOf(Error);
+ expect(error.cause.message).toBe('root cause');
- section = section.split('').forEach((c, i) => {
- if (i == 0) {
- chars.push(c.toUpperCase());
- } else {
- chars.push(c);
- }
- });
+ expect(VError.cause(error)).toBeInstanceOf(Error);
+ expect(VError.cause(error).message).toBe('root cause');
- return chars.join('', '');
- });
+ expect(VError.info(error)).toEqual({ foo: 'bar' });
- expectedErrorName = expectedErrorName.join('');
+ const unknownErrorMeta = {
+ one: 'two',
+ code: LIT_ERROR.UNKNOWN_ERROR.code,
+ kind: LIT_ERROR.UNKNOWN_ERROR.kind,
+ };
+ expect(VError.meta(error)).toEqual(unknownErrorMeta);
+ });
- // expect(errorName).toBe(expectedErrorName)
- expect(errorCode).toBe(expectedErrorCode);
- });
+ it('MultiError has correct format', () => {
+ const errors = [
+ new UnknownError(
+ {
+ info: {
+ foo: 'bar',
+ },
+ meta: {
+ one: 'two',
+ },
+ cause: new Error('root cause'),
+ },
+ 'unknown error'
+ ),
+ new UnknownError(
+ {
+ info: {
+ foo: 'bar',
+ },
+ meta: {
+ one: 'two',
+ },
+ cause: new Error('root cause'),
+ name: 'UnknownError',
+ },
+ 'unknown error'
+ ),
+ ];
+ const multiError = new MultiError(errors);
+
+ expect(multiError.errors).toEqual(errors);
});
});
diff --git a/packages/constants/src/lib/errors.ts b/packages/constants/src/lib/errors.ts
index 0236c87fe2..03ad6b810a 100644
--- a/packages/constants/src/lib/errors.ts
+++ b/packages/constants/src/lib/errors.ts
@@ -1,169 +1,220 @@
-export enum LitErrorKind {
- Unknown = 'Unknown',
- Unexpected = 'Unexpected',
- Generic = 'Generic',
- Config = 'Config',
- Validation = 'Validation',
- Conversion = 'Conversion',
- Parser = 'Parser',
- Serializer = 'Serializer',
- Timeout = 'Timeout',
+// @ts-expect-error No types available for this package
+import { VError, Options } from '@openagenda/verror';
+import depd from 'depd';
+
+const deprecated = depd('lit-js-sdk:constants:errors');
+
+export const LIT_ERROR_KIND = {
+ Unknown: 'Unknown',
+ Unexpected: 'Unexpected',
+ Generic: 'Generic',
+ Config: 'Config',
+ Validation: 'Validation',
+ Conversion: 'Conversion',
+ Parser: 'Parser',
+ Serializer: 'Serializer',
+ Timeout: 'Timeout',
+} as const;
+
+/**
+ * @deprecated Will be removed - Use LIT_ERROR_KIND instead
+ * Alias for LIT_ERROR_KIND. Added for backwards compatibility.
+ * See {@link LIT_ERROR_KIND}
+ */
+export const LitErrorKind = new Proxy(LIT_ERROR_KIND, {
+ get(target, prop, receiver) {
+ deprecated(
+ 'LitErrorKind is deprecated and will be removed in a future version. Use LIT_ERROR_KIND instead.'
+ );
+ return Reflect.get(target, prop, receiver);
+ },
+});
+
+interface ErrorConfig {
+ name: string;
+ code: string;
+ kind: (typeof LIT_ERROR_KIND)[keyof typeof LIT_ERROR_KIND];
}
-export const LIT_ERROR = {
+export const LIT_ERROR: Record = {
INVALID_PARAM_TYPE: {
name: 'InvalidParamType',
code: 'invalid_param_type',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
INVALID_ACCESS_CONTROL_CONDITIONS: {
name: 'InvalidAccessControlConditions',
code: 'invalid_access_control_conditions',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
WRONG_NETWORK_EXCEPTION: {
name: 'WrongNetworkException',
code: 'wrong_network_exception',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
MINTING_NOT_SUPPORTED: {
name: 'MintingNotSupported',
code: 'minting_not_supported',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
UNSUPPORTED_CHAIN_EXCEPTION: {
name: 'UnsupportedChainException',
code: 'unsupported_chain_exception',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
INVALID_UNIFIED_CONDITION_TYPE: {
name: 'InvalidUnifiedConditionType',
code: 'invalid_unified_condition_type',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
LIT_NODE_CLIENT_NOT_READY_ERROR: {
name: 'LitNodeClientNotReadyError',
code: 'lit_node_client_not_ready_error',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
- UNAUTHROZIED_EXCEPTION: {
- name: 'UnauthroziedException',
- code: 'unauthrozied_exception',
- kind: LitErrorKind.Validation,
+ UNAUTHORIZED_EXCEPTION: {
+ name: 'UnauthorizedException',
+ code: 'unauthorized_exception',
+ kind: LIT_ERROR_KIND.Validation,
},
INVALID_ARGUMENT_EXCEPTION: {
name: 'InvalidArgumentException',
code: 'invalid_argument_exception',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
INVALID_BOOLEAN_EXCEPTION: {
name: 'InvalidBooleanException',
code: 'invalid_boolean_exception',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
UNKNOWN_ERROR: {
name: 'UnknownError',
code: 'unknown_error',
- kind: LitErrorKind.Unknown,
+ kind: LIT_ERROR_KIND.Unknown,
},
NO_WALLET_EXCEPTION: {
name: 'NoWalletException',
code: 'no_wallet_exception',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
WRONG_PARAM_FORMAT: {
name: 'WrongParamFormat',
code: 'wrong_param_format',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION: {
name: 'LocalStorageItemNotFoundException',
code: 'local_storage_item_not_found_exception',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
LOCAL_STORAGE_ITEM_NOT_SET_EXCEPTION: {
name: 'LocalStorageItemNotSetException',
code: 'local_storage_item_not_set_exception',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
LOCAL_STORAGE_ITEM_NOT_REMOVED_EXCEPTION: {
name: 'LocalStorageItemNotRemovedException',
code: 'local_storage_item_not_removed_exception',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
REMOVED_FUNCTION_ERROR: {
name: 'RemovedFunctionError',
code: 'removed_function_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
+ },
+ UNSUPPORTED_METHOD_ERROR: {
+ name: 'UnsupportedMethodError',
+ code: 'unsupported_method_error',
+ kind: LIT_ERROR_KIND.Validation,
},
LIT_NODE_CLIENT_BAD_CONFIG_ERROR: {
name: 'LitNodeClientBadConfigError',
code: 'lit_node_client_bad_config_error',
- kind: LitErrorKind.Config,
+ kind: LIT_ERROR_KIND.Config,
},
PARAMS_MISSING_ERROR: {
name: 'ParamsMissingError',
code: 'params_missing_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
UNKNOWN_SIGNATURE_TYPE: {
name: 'UnknownSignatureType',
code: 'unknown_signature_type',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
UNKNOWN_SIGNATURE_ERROR: {
name: 'UnknownSignatureError',
code: 'unknown_signature_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
- SIGNATURE_VALIDATION_ERROR: {
+ INVALID_SIGNATURE_ERROR: {
name: 'InvalidSignatureError',
code: 'invalid_signature_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
PARAM_NULL_ERROR: {
name: 'ParamNullError',
code: 'param_null_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
UNKNOWN_DECRYPTION_ALGORITHM_TYPE_ERROR: {
name: 'UnknownDecryptionAlgorithmTypeError',
code: 'unknown_decryption_algorithm_type_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
WASM_INIT_ERROR: {
name: 'WasmInitError',
code: 'wasm_init_error',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
NODEJS_EXCEPTION: {
name: 'NodejsException',
code: 'nodejs_exception',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
+ },
+ NODE_ERROR: {
+ name: 'NodeError',
+ code: 'node_error',
+ kind: LitErrorKind.Unknown,
},
WALLET_SIGNATURE_NOT_FOUND_ERROR: {
name: 'WalletSignatureNotFoundError',
code: 'wallet_signature_not_found_error',
- kind: LitErrorKind.Validation,
+ kind: LIT_ERROR_KIND.Validation,
},
NO_VALID_SHARES: {
name: 'NoValidShares',
code: 'no_valid_shares',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
INVALID_NODE_ATTESTATION: {
name: 'InvalidNodeAttestation',
code: 'invalid_node_attestation',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
},
INVALID_ETH_BLOCKHASH: {
name: 'InvalidEthBlockhash',
code: 'invalid_eth_blockhash',
- kind: LitErrorKind.Unexpected,
+ kind: LIT_ERROR_KIND.Unexpected,
+ },
+ INVALID_SESSION_SIGS: {
+ name: 'InvalidSessionSigs',
+ code: 'invalid_session_sigs',
+ kind: LIT_ERROR_KIND.Validation,
},
INIT_ERROR: {
name: 'InitError',
code: 'init_error',
+ kind: LIT_ERROR_KIND.Unexpected,
+ },
+ NETWORK_ERROR: {
+ name: 'NetworkError',
+ code: 'network_error',
+ kind: LitErrorKind.Unexpected,
+ },
+ TRANSACTION_ERROR: {
+ name: 'TransactionError',
+ code: 'transaction_error',
kind: LitErrorKind.Unexpected,
},
};
@@ -171,3 +222,110 @@ export const LIT_ERROR = {
export const LIT_ERROR_CODE = {
NODE_NOT_AUTHORIZED: 'NodeNotAuthorized',
};
+
+export abstract class LitError extends VError {
+ protected constructor(
+ options: Error | Options,
+ message: string,
+ ...params: any[]
+ ) {
+ super(options, message, ...params);
+ }
+}
+
+type LitErrorConstructor = new (
+ options: Error | Options,
+ message: string,
+ ...params: any[]
+) => LitError;
+
+function createErrorClass({
+ name,
+ code,
+ kind,
+}: {
+ name: string;
+ code: string;
+ kind: string;
+}): LitErrorConstructor {
+ return class extends LitError {
+ // VError has optional options parameter, but we make it required so thrower remembers to pass all the useful info
+ constructor(options: Error | Options, message: string, ...params: any[]) {
+ if (options instanceof Error) {
+ options = {
+ cause: options,
+ };
+ }
+
+ // If the cause is not an Error, wrap it in one
+ if (!(options.cause instanceof Error)) {
+ options.cause = new Error(options.cause);
+ }
+
+ super(
+ {
+ name,
+ ...options,
+ meta: {
+ code,
+ kind,
+ ...options.meta,
+ },
+ },
+ message,
+ ...params
+ );
+ }
+ };
+}
+
+const errorClasses: Record = {};
+for (const key in LIT_ERROR) {
+ if (key in LIT_ERROR) {
+ const errorDef = LIT_ERROR[key];
+ errorClasses[errorDef.name] = createErrorClass(errorDef);
+ }
+}
+
+// Re-export to allow MultiErrors but keep the centralized VError import here
+const MultiError = VError.MultiError;
+export { MultiError };
+
+export const {
+ InitError,
+ InvalidAccessControlConditions,
+ InvalidArgumentException,
+ InvalidBooleanException,
+ InvalidEthBlockhash,
+ InvalidSessionSigs,
+ InvalidNodeAttestation,
+ InvalidParamType,
+ InvalidSignatureError,
+ InvalidUnifiedConditionType,
+ LitNodeClientBadConfigError,
+ LitNodeClientNotReadyError,
+ LocalStorageItemNotFoundException,
+ LocalStorageItemNotRemovedException,
+ LocalStorageItemNotSetException,
+ MintingNotSupported,
+ NetworkError,
+ NoValidShares,
+ NoWalletException,
+ NodeError,
+ NodejsException,
+ ParamNullError,
+ ParamsMissingError,
+ RemovedFunctionError,
+ TransactionError,
+ UnauthorizedException,
+ UnknownDecryptionAlgorithmTypeError,
+ UnknownError,
+ UnknownSignatureError,
+ UnknownSignatureType,
+ UnsupportedChainException,
+ UnsupportedMethodError,
+ WalletSignatureNotFoundError,
+ WasmInitError,
+ WrongNetworkException,
+ WrongParamFormat,
+} = errorClasses;
diff --git a/packages/constants/src/lib/interfaces/i-errors.ts b/packages/constants/src/lib/interfaces/i-errors.ts
index 6a12cf6fc2..11ccb44c10 100644
--- a/packages/constants/src/lib/interfaces/i-errors.ts
+++ b/packages/constants/src/lib/interfaces/i-errors.ts
@@ -1,22 +1,17 @@
-import { EITHER_TYPE } from '../enums';
-
-export interface ILitError {
- message?: string;
- name?: string;
- errorCode?: string;
- errorKind?: string;
- error?: ILitErrorTypeParams;
-}
-
-export interface ILitErrorTypeParams {
- name: string;
- code: string;
-}
+import { EITHER_TYPE } from '../constants/constants';
+import { LitError } from '../errors';
/**
* A standardized way to return either error or success
*/
-export interface IEither {
- type: EITHER_TYPE.SUCCESS | EITHER_TYPE.ERROR;
- result: T | ILitError;
+export type IEither = IEitherError | IEitherSuccess;
+
+export interface IEitherError {
+ type: typeof EITHER_TYPE.ERROR;
+ result: LitError;
+}
+
+export interface IEitherSuccess {
+ type: typeof EITHER_TYPE.SUCCESS;
+ result: T;
}
diff --git a/packages/constants/src/lib/utils/utils.spec.ts b/packages/constants/src/lib/utils/utils.spec.ts
index 8832ae342f..166b313f0d 100644
--- a/packages/constants/src/lib/utils/utils.spec.ts
+++ b/packages/constants/src/lib/utils/utils.spec.ts
@@ -1,12 +1,13 @@
-// @ts-nocheck
import { ELeft, ERight } from './utils';
+import { UnknownError } from '../errors';
describe('error handling utils ELeft/Right works', () => {
- const res = ELeft('ANSWER');
+ const unknownError = new UnknownError({}, 'ERROR');
+ const res = ELeft(unknownError);
const res2 = ERight('ANSWER');
it('returns result on ELeft()', () => {
- expect(res.result).toBe('ANSWER');
+ expect(res.result).toBe(unknownError);
});
it('returns type on ELeft()', () => {
diff --git a/packages/constants/src/lib/utils/utils.ts b/packages/constants/src/lib/utils/utils.ts
index 4fc38c22b5..48f98ab987 100644
--- a/packages/constants/src/lib/utils/utils.ts
+++ b/packages/constants/src/lib/utils/utils.ts
@@ -1,17 +1,18 @@
-import { EITHER_TYPE } from '../enums';
-import { IEither, ILitError } from '../interfaces/i-errors';
+import { EITHER_TYPE } from '../constants/constants';
+import { LitError } from '../errors';
+import { IEitherSuccess, IEitherError } from '../interfaces/i-errors';
/**
*
* This method should be used when there's an expected error
*
- * @param errorMsg is the error message
+ * @param error is the error encountered
* @returns { IEither }
*/
-export function ELeft(errorMsg: ILitError): IEither {
+export function ELeft(error: LitError): IEitherError {
return {
type: EITHER_TYPE.ERROR,
- result: errorMsg,
+ result: error,
};
}
@@ -22,7 +23,7 @@ export function ELeft(errorMsg: ILitError): IEither {
* @param result is the successful return value
* @returns
*/
-export function ERight(result: T): IEither {
+export function ERight(result: T): IEitherSuccess {
return {
type: EITHER_TYPE.SUCCESS,
result,
diff --git a/packages/constants/src/lib/version.ts b/packages/constants/src/lib/version.ts
index c3b964a9ff..07942c1da8 100644
--- a/packages/constants/src/lib/version.ts
+++ b/packages/constants/src/lib/version.ts
@@ -1 +1 @@
-export const version = '6.11.0';
+export const version = '7.0.0-alpha.9';
diff --git a/packages/contracts-sdk/README.md b/packages/contracts-sdk/README.md
index ade10b2923..214248db11 100644
--- a/packages/contracts-sdk/README.md
+++ b/packages/contracts-sdk/README.md
@@ -6,22 +6,8 @@ Demo: https://demo-contracts-sdk-react.vercel.app/
# Installation
-```js
-yarn add @lit-protocol/contracts-sdk
```
-
-# Vanilla JS (UMD)
-
-```html
-
-
+yarn add @lit-protocol/contracts-sdk
```
# Quick Start
diff --git a/packages/contracts-sdk/package.json b/packages/contracts-sdk/package.json
index 7879b2e8dc..545cf57e75 100644
--- a/packages/contracts-sdk/package.json
+++ b/packages/contracts-sdk/package.json
@@ -17,13 +17,7 @@
"access": "public",
"directory": "../../dist/packages/contracts-sdk"
},
- "dependencies": {
- "@cosmjs/amino": "0.30.1",
- "@cosmjs/crypto": "0.30.1",
- "@cosmjs/encoding": "0.30.1"
- },
"peerDependencies": {
- "bs58": "^5.0.0",
"date-and-time": "^2.4.1",
"multiformats": "^9.7.1"
},
@@ -31,7 +25,7 @@
"tags": [
"universal"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/contracts-sdk/src/index.ts b/packages/contracts-sdk/src/index.ts
index ded2807ed8..d6fba16071 100644
--- a/packages/contracts-sdk/src/index.ts
+++ b/packages/contracts-sdk/src/index.ts
@@ -1,3 +1,2 @@
export * from './lib/contracts-sdk';
-export * from './lib/addresses';
export * from './lib/utils';
diff --git a/packages/contracts-sdk/src/lib/addresses.ts b/packages/contracts-sdk/src/lib/addresses.ts
deleted file mode 100644
index 24e8cadf89..0000000000
--- a/packages/contracts-sdk/src/lib/addresses.ts
+++ /dev/null
@@ -1,170 +0,0 @@
-import { rawSecp256k1PubkeyToRawAddress } from '@cosmjs/amino';
-import { Secp256k1 } from '@cosmjs/crypto';
-import { toBech32 } from '@cosmjs/encoding';
-import * as bitcoinjs from 'bitcoinjs-lib';
-import { Contract, ethers } from 'ethers';
-import { computeAddress } from 'ethers/lib/utils';
-
-import { PKPNFTData } from '../abis/PKPNFT.sol/PKPNFTData';
-export interface TokenInfo {
- tokenId: string;
- publicKey: string;
- publicKeyBuffer: Buffer;
- ethAddress: string;
- btcAddress: string;
- cosmosAddress: string;
- isNewPKP: boolean;
-}
-
-export const derivedAddresses = async ({
- publicKey,
- pkpTokenId,
- pkpContractAddress,
- defaultRPCUrl,
- options = {
- cacheContractCall: false,
- },
-}: {
- publicKey?: string;
- pkpTokenId?: string;
- pkpContractAddress?: string;
- defaultRPCUrl?: string;
- options?: {
- cacheContractCall?: boolean;
- };
-}): Promise => {
- if (!defaultRPCUrl) {
- throw new Error('defaultRPCUrl must be provided');
- }
- let pubkeyBuffer: Buffer;
-
- // one of the two must be provided
- if (!publicKey && !pkpTokenId) {
- throw new Error('publicKey or pkpTokenId must be provided');
- }
-
- // if pkp contract address is not provided, use the default one 0xF5cB699652cED3781Dd75575EDBe075d6212DF98
- if (!pkpContractAddress) {
- pkpContractAddress = PKPNFTData.address;
- }
-
- // if pkpTokenId is provided, get the public key from it
-
- let isNewPKP = false;
-
- if (pkpTokenId) {
- // try to get the public key from 'lit-cached-pkps' local storage
- const CACHE_KEY = 'lit-cached-pkps';
- try {
- const cachedPkp = localStorage.getItem(CACHE_KEY);
- if (cachedPkp) {
- const cachedPkpJSON = JSON.parse(cachedPkp);
- if (cachedPkpJSON[pkpTokenId]) {
- publicKey = cachedPkpJSON[pkpTokenId];
- } else {
- const provider = new ethers.providers.StaticJsonRpcProvider({
- url: defaultRPCUrl,
- skipFetchSetup: true,
- });
-
- const contract = new Contract(
- pkpContractAddress,
- ['function getPubkey(uint256 tokenId) view returns (bytes memory)'],
- provider
- );
-
- publicKey = await contract['getPubkey'](pkpTokenId);
- isNewPKP = true;
- }
- }
- } catch (e) {
- console.error(e);
- }
-
- // trying to store key value pair in local storage
- if (options.cacheContractCall) {
- try {
- const cachedPkp = localStorage.getItem(CACHE_KEY);
- if (cachedPkp) {
- const cachedPkpJSON = JSON.parse(cachedPkp);
- cachedPkpJSON[pkpTokenId] = publicKey;
- localStorage.setItem(CACHE_KEY, JSON.stringify(cachedPkpJSON));
- } else {
- const cachedPkpJSON: Record = {};
- cachedPkpJSON[pkpTokenId] = publicKey;
- localStorage.setItem(CACHE_KEY, JSON.stringify(cachedPkpJSON));
- }
- } catch (e) {
- console.error(e);
- }
- }
- }
-
- if (publicKey === undefined) {
- console.warn('publicKey is undefined');
- }
-
- // if publicKey is provided, validate it
- if (!publicKey) {
- console.warn('publicKey or pubkeyBuffer is undefined');
- // throw new Error("publicKey or pubkeyBuffer is undefined");
- return;
- }
-
- if (publicKey.startsWith('0x')) {
- publicKey = publicKey.slice(2);
- }
- pubkeyBuffer = Buffer.from(publicKey, 'hex');
-
- // get the address from the public key
- const ethAddress = computeAddress(pubkeyBuffer);
-
- // get the btc address from the public key
- const btcAddress = bitcoinjs.payments.p2pkh({
- pubkey: pubkeyBuffer,
- }).address;
-
- if (!btcAddress || !ethAddress) {
- // push to error reporting service
- const errors = [];
-
- // if (!pkpTokenId) {
- // errors.push("pkpTokenId is undefined");
- // }
-
- if (!btcAddress) {
- errors.push('btcAddress is undefined');
- }
-
- if (!ethAddress) {
- errors.push('ethAddress is undefined');
- }
-
- throw new Error(errors.join(', '));
- }
-
- // https://docs.cosmos.network/main/spec/addresses/bech32
- // To covert between other binary representation of addresses and keys,
- // it is important to first apply the Amino encoding process before Bech32 encoding.
- // PubKeySecp256k1 tendermint/PubKeySecp256k1 0xEB5AE987 0x21
- // https://github.com/tendermint/tendermint/blob/d419fffe18531317c28c29a292ad7d253f6cafdf/docs/spec/blockchain/encoding.md#public-key-cryptography
- function getCosmosAddress(pubkeyBuffer: Buffer) {
- return toBech32(
- 'cosmos',
- rawSecp256k1PubkeyToRawAddress(Secp256k1.compressPubkey(pubkeyBuffer))
- );
- }
-
- // get cosmos address from the public key
- const cosmosAddress = getCosmosAddress(pubkeyBuffer);
-
- return {
- tokenId: pkpTokenId,
- publicKey: `0x${publicKey}`,
- publicKeyBuffer: pubkeyBuffer,
- ethAddress,
- btcAddress,
- cosmosAddress,
- isNewPKP,
- };
-};
diff --git a/packages/contracts-sdk/src/lib/auth-utils.ts b/packages/contracts-sdk/src/lib/auth-utils.ts
index c6d9193932..00893ddd83 100644
--- a/packages/contracts-sdk/src/lib/auth-utils.ts
+++ b/packages/contracts-sdk/src/lib/auth-utils.ts
@@ -1,3 +1,10 @@
+import {
+ InvalidArgumentException,
+ InvalidParamType,
+ NetworkError,
+ NoWalletException,
+ WrongParamFormat,
+} from '@lit-protocol/constants';
import { StytchToken } from '@lit-protocol/types';
import { ethers } from 'ethers';
import * as jose from 'jose';
@@ -30,7 +37,12 @@ export async function getAuthIdByAuthMethod(authMethod: any): Promise {
authMethodId = await getStytchFactorAuthMethodId(authMethod);
break;
default:
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethod,
+ },
+ },
`Unsupported auth method type: ${authMethod.authMethodType}`
);
}
@@ -44,21 +56,35 @@ export async function getAuthIdByAuthMethod(authMethod: any): Promise {
* @returns
*/
export function getEthAuthMethodId(authMethod: any): string {
- let address: string;
let accessToken: any;
// -- try if access token can be parsed as JSON object first
try {
accessToken = JSON.parse(authMethod.accessToken);
} catch (err) {
- throw new Error('Unable to parse access token as JSON object');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethod,
+ },
+ cause: err,
+ },
+ 'Unable to parse access token as JSON object'
+ );
}
- address = accessToken.address;
+ const address = accessToken.address;
// -- check if address is empty
if (!address) {
- throw new Error('No address found in access token');
+ throw new NoWalletException(
+ {
+ info: {
+ authMethod,
+ },
+ },
+ 'No address found in access token'
+ );
}
return ethers.utils.keccak256(ethers.utils.toUtf8Bytes(`${address}:lit`));
@@ -79,7 +105,14 @@ async function getDiscordAuthId(authMethod: any): Promise {
const user = await meResponse.json();
userId = user.id;
} else {
- throw new Error('Unable to verify Discord account');
+ throw new NetworkError(
+ {
+ info: {
+ authMethod,
+ },
+ },
+ 'Unable to verify Discord account'
+ );
}
// -- get auth method id
@@ -98,8 +131,14 @@ async function getWebauthnAuthId(authMethod: any): Promise {
try {
credentialId = JSON.parse(authMethod.accessToken).rawId;
} catch (err) {
- throw new Error(
- `Error when parsing auth method to generate auth method ID for WebAuthn: ${err}`
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethod,
+ },
+ cause: err,
+ },
+ `Error when parsing auth method to generate auth method ID for WebAuthn`
);
}
@@ -111,7 +150,7 @@ async function getWebauthnAuthId(authMethod: any): Promise {
async function getStytchAuthId(authMethod: any): Promise {
try {
- let tokenBody = _parseJWT(authMethod.accessToken);
+ const tokenBody = _parseJWT(authMethod.accessToken);
const userId = tokenBody['sub'] as string;
const orgId = (tokenBody['aud'] as string[])[0];
const authMethodId = ethers.utils.keccak256(
@@ -119,8 +158,14 @@ async function getStytchAuthId(authMethod: any): Promise {
);
return authMethodId;
} catch (err) {
- throw new Error(
- `Error while parsing auth method to generate auth method id for Stytch OTP: ${err}`
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethod,
+ },
+ cause: err,
+ },
+ `Error while parsing auth method to generate auth method id for Stytch OTP`
);
}
}
@@ -153,7 +198,14 @@ function getStytchFactorAuthMethodId(authMethod: any): Promise {
factor = 'totp';
break;
default:
- throw new Error('Unsupport stytch auth type');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethod,
+ },
+ },
+ `Unsupport stytch auth type`
+ );
}
const factorParser = _resolveAuthFactor(factor).parser;
try {
@@ -182,7 +234,14 @@ async function getGoogleJwtAuthId(authMethod: any): Promise {
function _parseJWT(jwt: string): StytchToken {
const parts = jwt.split('.');
if (parts.length !== 3) {
- throw new Error('Invalid token length');
+ throw new WrongParamFormat(
+ {
+ info: {
+ jwt,
+ },
+ },
+ 'Invalid token length'
+ );
}
const body = Buffer.from(parts[1], 'base64');
const parsedBody: StytchToken = JSON.parse(body.toString('ascii'));
@@ -196,16 +255,30 @@ export const emailOtpAuthFactorParser = (
): string => {
const session = parsedToken[provider];
const authFactors: any[] = session['authentication_factors'];
- let authFactor = authFactors.find((value, _index, _obj) => {
+ const authFactor = authFactors.find((value, _index, _obj) => {
if (value.email_factor) return value;
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -231,11 +304,25 @@ export const smsOtpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -261,11 +348,25 @@ export const whatsAppOtpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -291,11 +392,25 @@ export const totpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -337,7 +452,14 @@ function _resolveAuthFactor(factor: any): {
};
}
- throw new Error(`Error could not find auth with factor ${factor}`);
+ throw new InvalidArgumentException(
+ {
+ info: {
+ factor,
+ },
+ },
+ `Error could not find auth with factor ${factor}`
+ );
}
/**
@@ -351,6 +473,13 @@ export const stringToArrayify = (str: string): Uint8Array => {
const encoder = new TextEncoder();
return encoder.encode(str);
} catch (e) {
- throw new Error(`Error converting string to arrayify: ${e}`);
+ throw new InvalidParamType(
+ {
+ info: {
+ str,
+ },
+ },
+ `Error converting string to arrayify`
+ );
}
};
diff --git a/packages/contracts-sdk/src/lib/contracts-sdk.ts b/packages/contracts-sdk/src/lib/contracts-sdk.ts
index a0165d96d6..8561fbbd26 100644
--- a/packages/contracts-sdk/src/lib/contracts-sdk.ts
+++ b/packages/contracts-sdk/src/lib/contracts-sdk.ts
@@ -14,7 +14,6 @@ import {
MintWithAuthParams,
MintWithAuthResponse,
} from '@lit-protocol/types';
-import bs58 from 'bs58';
import { BigNumberish, BytesLike, ContractReceipt, ethers } from 'ethers';
import { decToHex, hexToDec, intToIP } from './hex2dec';
@@ -49,8 +48,8 @@ import * as stakingBalancesContract from '../abis/StakingBalances.sol/StakingBal
// ----- autogen:imports:end -----
import {
- AuthMethodScope,
- AuthMethodType,
+ AUTH_METHOD_TYPE_VALUES,
+ AUTH_METHOD_SCOPE_VALUES,
METAMASK_CHAIN_INFO_BY_NETWORK,
NETWORK_CONTEXT_BY_NETWORK,
LIT_NETWORK_VALUES,
@@ -60,11 +59,18 @@ import {
LIT_NETWORK,
HTTP,
HTTPS,
+ InitError,
+ NetworkError,
+ WrongNetworkException,
+ ParamsMissingError,
+ InvalidArgumentException,
+ TransactionError,
} from '@lit-protocol/constants';
import { LogManager, Logger } from '@lit-protocol/logger';
+import { TokenInfo } from '@lit-protocol/types';
import { computeAddress } from 'ethers/lib/utils';
import { IPubkeyRouter } from '../abis/PKPNFT.sol/PKPNFT';
-import { TokenInfo, derivedAddresses } from './addresses';
+import { derivedAddresses } from '@lit-protocol/misc';
import { getAuthIdByAuthMethod, stringToArrayify } from './auth-utils';
import {
CIDParser,
@@ -227,7 +233,7 @@ export class LitContracts {
this.randomPrivateKey = args?.randomPrivatekey ?? false;
this.options = args?.options;
this.debug = args?.debug ?? false;
- this.network = args?.network || 'cayenne';
+ this.network = args?.network || LIT_NETWORK.DatilDev;
// if rpc is not specified, use the default rpc
if (!this.rpc) {
this.rpc = RPC_URL_BY_NETWORK[this.network];
@@ -285,7 +291,14 @@ export class LitContracts {
const msg =
'No web3 provider found. Please install Brave, MetaMask or another web3 provider.';
alert(msg);
- throw new Error(msg);
+ throw new InitError(
+ {
+ info: {
+ web3Provider,
+ },
+ },
+ msg
+ );
}
function _decimalToHex(decimal: number): string {
@@ -650,7 +663,16 @@ export class LitContracts {
// Validate the required data
if (!address || !abi) {
- throw new Error('❌ Required contract data is missing');
+ throw new InitError(
+ {
+ info: {
+ address,
+ abi,
+ network,
+ },
+ },
+ '❌ Required contract data is missing'
+ );
}
return new ethers.Contract(address, abi, provider);
@@ -661,7 +683,13 @@ export class LitContracts {
const stakingContract = (context as LitContractContext).Staking;
if (!stakingContract.address) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ stakingContract,
+ context,
+ },
+ },
'❌ Could not get staking contract address from contract context'
);
}
@@ -677,7 +705,13 @@ export class LitContracts {
['Staking']
);
if (!contractContext.Staking.address) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ contractContext,
+ context,
+ },
+ },
'❌ Could not get Staking Contract from contract resolver instance'
);
}
@@ -894,7 +928,16 @@ export class LitContracts {
// Validate the required data
if (Object.keys(addresses).length < 5) {
- throw new Error('❌ Required contract data is missing');
+ throw new InitError(
+ {
+ info: {
+ network,
+ addresses,
+ context,
+ },
+ },
+ '❌ Required contract data is missing'
+ );
}
return addresses;
@@ -917,7 +960,14 @@ export class LitContracts {
const minNodeCount = await contract['currentValidatorCountForConsensus']();
if (!minNodeCount) {
- throw new Error('❌ Minimum validator count is not set');
+ throw new InitError(
+ {
+ info: {
+ minNodeCount,
+ },
+ },
+ '❌ Minimum validator count is not set'
+ );
}
return minNodeCount;
};
@@ -997,19 +1047,6 @@ export class LitContracts {
// Fallback to HTTP if no other conditions are met
HTTP;
- // Check for specific conditions in centralised networks
- if (centralisation === 'centralised') {
- // Validate if it's cayenne AND port range is 8470 - 8479, if not, throw error
- if (
- network === LIT_NETWORK.Cayenne &&
- !port.toString().startsWith('8')
- ) {
- throw new Error(
- `Invalid port: ${port} for the ${centralisation} ${network} network. Expected range: 8470 - 8479`
- );
- }
- }
-
const url = `${protocol}${ip}:${port}`;
LitContracts.logger.debug("Validator's URL:", url);
@@ -1107,19 +1144,6 @@ export class LitContracts {
// Fallback to HTTP if no other conditions are met
HTTP;
- // Check for specific conditions in centralised networks
- if (centralisation === 'centralised') {
- // Validate if it's cayenne AND port range is 8470 - 8479, if not, throw error
- if (
- litNetwork === LIT_NETWORK.Cayenne &&
- !(port >= 8470 && port <= 8479)
- ) {
- throw new Error(
- `Invalid port: ${port} for the ${centralisation} ${litNetwork} network. Expected range: 8470 - 8479`
- );
- }
- }
-
const url = `${protocol}${ip}:${port}`;
LitContracts.logger.debug("Validator's URL:", url);
@@ -1141,7 +1165,12 @@ export class LitContracts {
) {
// -- check if it's supported network
if (!NETWORK_CONTEXT_BY_NETWORK[network]) {
- throw new Error(
+ throw new WrongNetworkException(
+ {
+ info: {
+ network,
+ },
+ },
`[_resolveContractContext] Unsupported network: ${network}`
);
}
@@ -1149,7 +1178,14 @@ export class LitContracts {
const data = NETWORK_CONTEXT_BY_NETWORK[network];
if (!data) {
- throw new Error('[_resolveContractContext] No data found');
+ throw new WrongNetworkException(
+ {
+ info: {
+ network,
+ },
+ },
+ '[_resolveContractContext] No data found'
+ );
}
// Normalize the data to the LitContractContext type
@@ -1180,17 +1216,36 @@ export class LitContracts {
}: MintWithAuthParams): Promise> => {
// -- validate
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpNftContract: this.pkpNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
if (authMethod && !authMethod?.authMethodType) {
- throw new Error('authMethodType is required');
+ throw new ParamsMissingError(
+ {
+ info: {
+ authMethod,
+ },
+ },
+ 'authMethodType is required'
+ );
}
if (
@@ -1198,17 +1253,31 @@ export class LitContracts {
!authMethod?.accessToken &&
authMethod?.accessToken !== 'custom-auth'
) {
- throw new Error('accessToken is required');
+ throw new ParamsMissingError(
+ {
+ info: {
+ authMethod,
+ },
+ },
+ 'accessToken is required'
+ );
}
if (scopes.length <= 0) {
- throw new Error(`❌ Permission scopes are required!
+ throw new InvalidArgumentException(
+ {
+ info: {
+ scopes,
+ },
+ },
+ `❌ Permission scopes are required!
[0] No Permissions
[1] Sign Anything
[2] Only Sign Messages
Read more here:
https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scopes
- `);
+ `
+ );
}
// -- prepare
@@ -1251,11 +1320,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
const events = 'events' in receipt ? receipt.events : receipt.logs;
if (!events || events.length <= 0) {
- throw new Error('No events found in receipt');
+ throw new TransactionError(
+ {
+ info: {
+ events,
+ receipt,
+ },
+ },
+ 'No events found in receipt'
+ );
}
if (!events[0].topics || events[0].topics.length < 1) {
- throw new Error(
+ throw new TransactionError(
+ {
+ info: {
+ events,
+ receipt,
+ },
+ },
`No topics found in events, cannot derive pkp information. Transaction hash: ${receipt.transactionHash} If you are using your own contracts please use ethers directly`
);
}
@@ -1329,7 +1412,7 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*
* @param {Object} params - The parameters for adding the permitted authentication method.
* @param {string} params.pkpTokenId - The ID of the PKP token.
- * @param {AuthMethodType | number} params.authMethodType - The type of the authentication method.
+ * @param {AUTH_METHOD_TYPE_VALUES | number} params.authMethodType - The type of the authentication method.
* @param {string | Uint8Array} params.authMethodId - The ID of the authentication method.
* @param {AuthMethodScope[]} params.authMethodScopes - The scopes of the authentication method.
* @param {string} [params.webAuthnPubkey] - The public key for WebAuthn.
@@ -1344,9 +1427,9 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
webAuthnPubkey,
}: {
pkpTokenId: string;
- authMethodType: AuthMethodType | number;
+ authMethodType: AUTH_METHOD_TYPE_VALUES | number;
authMethodId: string | Uint8Array;
- authMethodScopes: AuthMethodScope[];
+ authMethodScopes: AUTH_METHOD_SCOPE_VALUES[];
webAuthnPubkey?: string;
}): Promise => {
const _authMethodId =
@@ -1374,8 +1457,20 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
const receipt = await res.wait();
return receipt;
- } catch (e: any) {
- throw new Error(e);
+ } catch (e) {
+ throw new TransactionError(
+ {
+ info: {
+ pkpTokenId,
+ authMethodType,
+ authMethodId,
+ authMethodScopes,
+ webAuthnPubkey,
+ },
+ cause: e,
+ },
+ 'Adding permitted action failed'
+ );
}
};
@@ -1395,7 +1490,7 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
}: {
ipfsId: string;
pkpTokenId: string;
- authMethodScopes: AuthMethodScope[];
+ authMethodScopes: AUTH_METHOD_SCOPE_VALUES[];
}) => {
const ipfsIdBytes = this.utils.getBytesFromMultihash(ipfsId);
const scopes = authMethodScopes ?? [];
@@ -1410,8 +1505,18 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
const receipt = await res.wait();
return receipt;
- } catch (e: any) {
- throw new Error(e);
+ } catch (e) {
+ throw new TransactionError(
+ {
+ info: {
+ pkpTokenId,
+ ipfsIdBytes,
+ scopes,
+ },
+ cause: e,
+ },
+ 'Adding permitted action failed'
+ );
}
};
@@ -1443,8 +1548,15 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
requestsPerKilosecond === undefined ||
requestsPerKilosecond <= 0)
) {
- throw new Error(
- 'At least one of requestsPerDay, requestsPerSecond, or requestsPerKilosecond is required and must be more than 0'
+ throw new InvalidArgumentException(
+ {
+ info: {
+ requestsPerDay,
+ requestsPerSecond,
+ requestsPerKilosecond,
+ },
+ },
+ `At least one of requestsPerDay, requestsPerSecond, or requestsPerKilosecond is required and must be more than 0`
);
}
@@ -1477,8 +1589,13 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
effectiveRequestsPerKilosecond === undefined ||
effectiveRequestsPerKilosecond <= 0
) {
- throw new Error(
- 'Effective requests per kilosecond is required and must be more than 0'
+ throw new InvalidArgumentException(
+ {
+ info: {
+ effectiveRequestsPerKilosecond,
+ },
+ },
+ `Effective requests per kilosecond is required and must be more than 0`
);
}
@@ -1530,8 +1647,19 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
capacityTokenId: tokenId,
capacityTokenIdStr: tokenId.toString(),
};
- } catch (e: any) {
- throw new Error(e);
+ } catch (e) {
+ throw new TransactionError(
+ {
+ info: {
+ requestsPerDay,
+ requestsPerSecond,
+ requestsPerKilosecond,
+ expiresAt,
+ },
+ cause: e,
+ },
+ 'Minting capacity credits NFT failed'
+ );
}
};
@@ -1579,7 +1707,7 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
* @returns {string}
*/
getBytesFromMultihash: (multihash: string) => {
- const decoded = bs58.decode(multihash);
+ const decoded = ethers.utils.base58.decode(multihash);
return `0x${Buffer.from(decoded).toString('hex')}`;
},
@@ -1597,7 +1725,9 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
const digestSize = parseInt(text.slice(2, 4), 16);
const digest = text.slice(4, 4 + digestSize * 2);
- const multihash = bs58.encode(Buffer.from(`1220${digest}`, 'hex'));
+ const multihash = ethers.utils.base58.encode(
+ Buffer.from(`1220${digest}`, 'hex')
+ );
return multihash;
},
@@ -1646,17 +1776,34 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
getTokensByAddress: async (ownerAddress: string): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpNftContract: this.pkpNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
// -- validate
if (!ethers.utils.isAddress(ownerAddress)) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ ownerAddress,
+ },
+ },
`Given string is not a valid address "${ownerAddress}"`
);
}
@@ -1696,12 +1843,24 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getTokens: async (latestNumberOfTokens: number): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpNftContract: this.pkpNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const tokens = [];
@@ -1745,9 +1904,7 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
const tokenId = tokenIds[i];
const pubKey = await this.pkpNftContract.read.getPubkey(tokenId);
const addrs = await derivedAddresses({
- pkpTokenId: tokenId,
publicKey: pubKey,
- defaultRPCUrl: this.rpc,
});
arr.push(addrs);
@@ -1759,13 +1916,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
write: {
mint: async (param?: GasLimitParam) => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpNftContract: this.pkpNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
let mintCost;
@@ -1773,7 +1942,15 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
try {
mintCost = await this.pkpNftContract.read.mintCost();
} catch (e) {
- throw new Error('Could not get mint cost');
+ throw new TransactionError(
+ {
+ info: {
+ mintCost,
+ },
+ cause: e,
+ },
+ 'Could not get mint cost'
+ );
}
if (this.isPKP) {
@@ -1861,7 +2038,17 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
return { tx, res: txRec, tokenId };
} catch (e: any) {
this.log(`[claimAndMint] error: ${e.message}`);
- throw new Error(e);
+ throw new TransactionError(
+ {
+ info: {
+ derivedKeyId,
+ signatures,
+ txOpts,
+ },
+ cause: e,
+ },
+ 'claimAndMint failed'
+ );
}
},
},
@@ -1883,13 +2070,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
address: string
): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const pkpIdHex = this.utils.decToHex(tokenId, null) as string;
@@ -1912,12 +2111,24 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getPermittedAddresses: async (tokenId: string): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
this.log('[getPermittedAddresses] input:', tokenId);
@@ -1963,13 +2174,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getPermittedActions: async (tokenId: BigNumberish): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
let actions: string[] = [];
@@ -2017,13 +2240,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
ipfsId: string
): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
this.log('[isPermittedAction] input:', pkpId);
@@ -2056,13 +2291,26 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
ipfsId: string
): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract || !this.pubkeyRouterContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ pubkeyRouterContract: this.pubkeyRouterContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
this.log('[addPermittedAction] input:', pkpId);
@@ -2106,13 +2354,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
ownerAddress: string
): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
this.log('[addPermittedAddress] input:', pkpId);
@@ -2144,13 +2404,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
ipfsId: string
): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.pkpPermissionsContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ pkpPermissionsContract: this.pkpPermissionsContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
this.log('[revokePermittedAction] input:', pkpId);
@@ -2201,13 +2473,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getCapacityByIndex: async (index: number): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const capacity = await this.rateLimitNftContract.read.capacity(index);
@@ -2240,13 +2524,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getTokenURIByIndex: async (index: number): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const base64 = await this.rateLimitNftContract.read.tokenURI(index);
@@ -2291,13 +2587,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getTokensByOwnerAddress: async (ownerAddress: string): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
// -- validate
@@ -2314,7 +2622,14 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
[...new Array(total)],
async (_: undefined, i: number) => {
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const token =
@@ -2382,13 +2697,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
*/
getTokens: async (): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const bigTotal: ethers.BigNumber =
@@ -2399,7 +2726,14 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
[...new Array(total)],
async (_: any, i: number) => {
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const token = await this.rateLimitNftContract.read.tokenByIndex(i);
@@ -2441,13 +2775,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
timestamp: number;
}) => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const tx = await this._callWithAdjustedOverrides(
@@ -2482,13 +2828,25 @@ https://developer.litprotocol.com/v3/sdk/wallets/auth-methods/#auth-method-scope
RLITokenAddress: string;
}): Promise => {
if (!this.connected) {
- throw new Error(
+ throw new InitError(
+ {
+ info: {
+ connected: this.connected,
+ },
+ },
'Contracts are not connected. Please call connect() first'
);
}
if (!this.rateLimitNftContract) {
- throw new Error('Contract is not available');
+ throw new InitError(
+ {
+ info: {
+ rateLimitNftContract: this.rateLimitNftContract,
+ },
+ },
+ 'Contract is not available'
+ );
}
const tx = await this._callWithAdjustedOverrides(
diff --git a/packages/contracts-sdk/src/lib/helpers/getBytes32FromMultihash.ts b/packages/contracts-sdk/src/lib/helpers/getBytes32FromMultihash.ts
index 847d3ccc35..40e3ddc199 100644
--- a/packages/contracts-sdk/src/lib/helpers/getBytes32FromMultihash.ts
+++ b/packages/contracts-sdk/src/lib/helpers/getBytes32FromMultihash.ts
@@ -1,3 +1,8 @@
+import {
+ InvalidArgumentException,
+ ParamsMissingError,
+} from '@lit-protocol/constants';
+
export interface IPFSHash {
digest: string;
hashFunction: number;
@@ -36,20 +41,41 @@ export const getBytes32FromMultihash = (
CID: CIDParser
): IPFSHash => {
if (!CID) {
- throw new Error(
+ throw new ParamsMissingError(
+ {
+ info: {
+ ipfsId,
+ CID,
+ },
+ },
'CID is required. Please import from "multiformats/cid" package, and pass the CID object to the function.'
);
}
if (!ipfsId) {
- throw new Error('ipfsId is required');
+ throw new ParamsMissingError(
+ {
+ info: {
+ ipfsId,
+ },
+ },
+ 'ipfsId is required'
+ );
}
let cid;
try {
cid = CID.parse(ipfsId);
} catch (e) {
- throw new Error('Error parsing CID');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ ipfsId,
+ CID,
+ },
+ },
+ 'Error parsing CID'
+ );
}
const hashFunction = cid.multihash.code;
diff --git a/packages/contracts-sdk/src/lib/utils.ts b/packages/contracts-sdk/src/lib/utils.ts
index 2a15182661..214f45589c 100644
--- a/packages/contracts-sdk/src/lib/utils.ts
+++ b/packages/contracts-sdk/src/lib/utils.ts
@@ -1,3 +1,5 @@
+import { InvalidArgumentException } from '@lit-protocol/constants';
+
// Converts the number of requests per day to requests per second.
export function convertRequestsPerDayToPerSecond(
requestsPerDay: number
@@ -41,7 +43,15 @@ export function requestsToKilosecond({
case 'second':
return Math.round(requests * 1000);
default:
- throw new Error('Invalid period');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ period,
+ requests,
+ },
+ },
+ 'Invalid period'
+ );
}
}
@@ -60,7 +70,15 @@ export function requestsToDay({
case 'kilosecond':
return Math.round(requests * 86);
default:
- throw new Error('Invalid period');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ period,
+ requests,
+ },
+ },
+ 'Invalid period'
+ );
}
}
@@ -79,6 +97,14 @@ export function requestsToSecond({
case 'kilosecond':
return Math.round(requests * 1000);
default:
- throw new Error('Invalid period');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ period,
+ requests,
+ },
+ },
+ 'Invalid period'
+ );
}
}
diff --git a/packages/contracts-sdk/tsconfig.json b/packages/contracts-sdk/tsconfig.json
index ab0659018e..f5b85657a8 100644
--- a/packages/contracts-sdk/tsconfig.json
+++ b/packages/contracts-sdk/tsconfig.json
@@ -7,8 +7,7 @@
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
- "noFallthroughCasesInSwitch": true,
- "esModuleInterop": true
+ "noFallthroughCasesInSwitch": true
},
"files": [],
"include": [],
diff --git a/packages/core/package.json b/packages/core/package.json
index d8471d1286..c922d3a447 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"name": "@lit-protocol/core",
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"type": "commonjs",
"license": "MIT",
"homepage": "https://github.com/Lit-Protocol/js-sdk",
diff --git a/packages/core/src/lib/lit-core.ts b/packages/core/src/lib/lit-core.ts
index 51b267c1a6..d32c7b1abf 100644
--- a/packages/core/src/lib/lit-core.ts
+++ b/packages/core/src/lib/lit-core.ts
@@ -19,24 +19,29 @@ import {
HTTP,
HTTPS,
LIT_CURVE,
+ LIT_CURVE_VALUES,
LIT_ENDPOINT,
LIT_ERROR,
LIT_ERROR_CODE,
LIT_NETWORK,
LIT_NETWORKS,
- LitNetwork,
RPC_URL_BY_NETWORK,
- StakingStates,
+ STAKING_STATES,
+ STAKING_STATES_VALUES,
version,
+ InitError,
+ InvalidParamType,
+ NodeError,
+ UnknownError,
+ InvalidArgumentException,
+ LitNodeClientBadConfigError,
+ InvalidEthBlockhash,
+ LitNodeClientNotReadyError,
+ InvalidNodeAttestation,
+ LogLevel,
} from '@lit-protocol/constants';
import { LitContracts } from '@lit-protocol/contracts-sdk';
-import {
- checkSevSnpAttestation,
- computeHDPubKey,
- loadModules,
- unloadModules,
-} from '@lit-protocol/crypto';
-import { LogLevel } from '@lit-protocol/logger';
+import { checkSevSnpAttestation, computeHDPubKey } from '@lit-protocol/crypto';
import {
bootstrapLogManager,
isBrowser,
@@ -47,7 +52,7 @@ import {
logWithRequestId,
mostCommonString,
sendRequest,
- throwError,
+ setMiscLitConfig,
} from '@lit-protocol/misc';
import {
AuthSig,
@@ -116,10 +121,8 @@ const BLOCKHASH_SYNC_INTERVAL = 30_000;
// Intentionally not including datil-dev here per discussion with Howard
const NETWORKS_REQUIRING_SEV: string[] = [
- LitNetwork.Habanero,
- LitNetwork.Manzano,
- LitNetwork.DatilTest,
- LitNetwork.Datil,
+ LIT_NETWORK.DatilTest,
+ LIT_NETWORK.Datil,
];
/**
@@ -138,7 +141,7 @@ export class LitCore {
debug: true,
connectTimeout: 20000,
checkNodeAttestation: false,
- litNetwork: 'cayenne', // Default to cayenne network. will be replaced by custom config.
+ litNetwork: LIT_NETWORK.Custom,
minNodeCount: 2, // Default value, should be replaced
bootstrapUrls: [], // Default value, should be replaced
nodeProtocol: null,
@@ -166,22 +169,18 @@ export class LitCore {
// ========== Constructor ==========
constructor(config: LitNodeClientConfig | CustomNetwork) {
if (!(config.litNetwork in LIT_NETWORKS)) {
- const supportedNetwork = Object.values(LIT_NETWORK).join(', ');
-
- return throwError({
- message: `Unsupported network has been provided please use a "litNetwork" option which is supported (${supportedNetwork})`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.code,
- });
+ const validNetworks = Object.keys(LIT_NETWORKS).join(', ');
+ throw new InvalidParamType(
+ {},
+ 'Unsupported network has been provided please use a "litNetwork" option which is supported (%s)',
+ validNetworks
+ );
}
// Initialize default config based on litNetwork
switch (config?.litNetwork) {
// Official networks; default value for `checkNodeAttestation` according to network provided.
- case LitNetwork.Cayenne:
- case LitNetwork.DatilDev:
- case LitNetwork.Manzano:
- case LitNetwork.Habanero:
+ case LIT_NETWORK.DatilDev:
this.config = {
...this.config,
checkNodeAttestation: NETWORKS_REQUIRING_SEV.includes(
@@ -191,7 +190,7 @@ export class LitCore {
};
break;
default:
- // `custom` or `localhost`; no opinion about checkNodeAttestation
+ // `custom`; no opinion about checkNodeAttestation
this.config = {
...this.config,
...config,
@@ -202,7 +201,7 @@ export class LitCore {
this.setCustomBootstrapUrls();
// -- set global variables
- globalThis.litConfig = this.config;
+ setMiscLitConfig(this.config);
bootstrapLogManager(
'core',
this.config.debug ? LogLevel.DEBUG : LogLevel.OFF
@@ -263,34 +262,20 @@ export class LitCore {
// Validate minNodeCount
if (!minNodeCount) {
- throw new Error('minNodeCount is required');
+ throw new InvalidArgumentException(
+ {},
+ `minNodeCount is %s, which is invalid. Please check your network connection and try again.`,
+ minNodeCount
+ );
}
// Validate bootstrapUrls
if (!Array.isArray(bootstrapUrls) || bootstrapUrls.length <= 0) {
- throwError({
- message: `Failed to get bootstrapUrls for network ${this.config.litNetwork}`,
- errorKind: LIT_ERROR.INIT_ERROR.kind,
- errorCode: LIT_ERROR.INIT_ERROR.name,
- });
- }
-
- // Validate stakingContract
- if (!stakingContract) {
- throwError({
- message: 'stakingContract is required',
- errorKind: LIT_ERROR.INIT_ERROR.kind,
- errorCode: LIT_ERROR.INIT_ERROR.name,
- });
- }
-
- // Validate epoch
- if (!epochInfo.number) {
- throwError({
- message: 'epoch is required',
- errorKind: LIT_ERROR.INIT_ERROR.kind,
- errorCode: LIT_ERROR.INIT_ERROR.name,
- });
+ throw new InitError(
+ {},
+ `Failed to get bootstrapUrls for network %s`,
+ this.config.litNetwork
+ );
}
log('[_getValidatorData] epochInfo: ', epochInfo);
@@ -307,12 +292,14 @@ export class LitCore {
}
// ========== Scoped Class Helpers ==========
- private async _handleStakingContractStateChange(state: StakingStates) {
+ private async _handleStakingContractStateChange(
+ state: STAKING_STATES_VALUES
+ ) {
log(`New state detected: "${state}"`);
const validatorData = await this._getValidatorData();
- if (state === StakingStates.Active) {
+ if (state === STAKING_STATES.Active) {
// We always want to track the most recent epoch number on _all_ networks
this._epochState = await this._fetchCurrentEpochState(
@@ -389,7 +376,7 @@ export class LitCore {
);
// Stash a function instance, because its identity must be consistent for '.off()' usage to work later
- this._stakingContractListener = (state: StakingStates) => {
+ this._stakingContractListener = (state: STAKING_STATES_VALUES) => {
// Intentionally not return or await; Listeners are _not async_
this._handleStakingContractStateChange(state);
};
@@ -403,11 +390,10 @@ export class LitCore {
*/
async disconnect() {
this.ready = false;
- unloadModules();
this._stopListeningForNewEpoch();
// this._stopNetworkPolling();
- if (globalThis.litConfig) delete globalThis.litConfig;
+ setMiscLitConfig(undefined);
}
// _stopNetworkPolling() {
@@ -432,20 +418,17 @@ export class LitCore {
*/
setCustomBootstrapUrls = (): void => {
// -- validate
- if (this.config.litNetwork === 'custom') return;
+ if (this.config.litNetwork === LIT_NETWORK.Custom) return;
// -- execute
const hasNetwork: boolean = this.config.litNetwork in LIT_NETWORKS;
if (!hasNetwork) {
// network not found, report error
- throwError({
- message:
- 'the litNetwork specified in the LitNodeClient config not found in LIT_NETWORKS',
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_BAD_CONFIG_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_BAD_CONFIG_ERROR.name,
- });
- return;
+ throw new LitNodeClientBadConfigError(
+ {},
+ 'the litNetwork specified in the LitNodeClient config not found in LIT_NETWORKS'
+ );
}
this.config.bootstrapUrls = LIT_NETWORKS[this.config.litNetwork];
@@ -458,8 +441,10 @@ export class LitCore {
getLatestBlockhash = async (): Promise => {
await this._syncBlockhash();
if (!this.latestBlockhash) {
- throw new Error(
- `latestBlockhash is not available. Received: "${this.latestBlockhash}"`
+ throw new InvalidEthBlockhash(
+ {},
+ `latestBlockhash is not available. Received: "%s"`,
+ this.latestBlockhash
);
}
@@ -474,11 +459,6 @@ export class LitCore {
*
*/
async connect(): Promise {
- // If we have never connected on this client instance first load WASM modules.
- if (!this.ready) {
- await loadModules();
- }
-
// Ensure that multiple closely timed calls to `connect()` don't result in concurrent connect() operations being run
if (this._connectingPromise) {
return this._connectingPromise;
@@ -511,8 +491,15 @@ export class LitCore {
!this.config.contractContext.Staking &&
!this.config.contractContext.resolverAddress
) {
- throw new Error(
- 'The provided contractContext was missing the "Staking" contract`'
+ throw new InitError(
+ {
+ info: {
+ contractContext: this.config.contractContext,
+ litNetwork: this.config.litNetwork,
+ rpcUrl: this.config.rpcUrl,
+ },
+ },
+ 'The provided contractContext was missing the "Staking" contract'
);
}
@@ -525,7 +512,7 @@ export class LitCore {
},
{}
);
- if (this.config.litNetwork === LitNetwork.Custom) {
+ if (this.config.litNetwork === LIT_NETWORK.Custom) {
log('using custom contracts: ', logAddresses);
}
}
@@ -551,9 +538,6 @@ export class LitCore {
// this._scheduleNetworkSync();
this._listenForNewEpoch();
- // FIXME: don't create global singleton; multiple instances of `core` should not all write to global
- // @ts-expect-error typeof globalThis is not defined. We're going to get rid of the global soon.
- globalThis.litNodeClient = this;
this.ready = true;
log(`🔥 lit is ready. "litNodeClient" variable is ready to use globally.`);
@@ -630,11 +614,11 @@ export class LitCore {
const attestation = handshakeResult.attestation;
if (!attestation) {
- throwError({
- message: `Missing attestation in handshake response from ${url}`,
- errorKind: LIT_ERROR.INVALID_NODE_ATTESTATION.kind,
- errorCode: LIT_ERROR.INVALID_NODE_ATTESTATION.name,
- });
+ throw new InvalidNodeAttestation(
+ {},
+ `Missing attestation in handshake response from %s`,
+ url
+ );
}
// actually verify the attestation by checking the signature against AMD certs
@@ -646,13 +630,16 @@ export class LitCore {
log(`Lit Node Attestation verified for ${url}`);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (e: any) {
- throwError({
- message: `Lit Node Attestation failed verification for ${url} - ${e.message}`,
- errorKind: LIT_ERROR.INVALID_NODE_ATTESTATION.kind,
- errorCode: LIT_ERROR.INVALID_NODE_ATTESTATION.name,
- });
+ throw new InvalidNodeAttestation(
+ {
+ cause: e,
+ },
+ `Lit Node Attestation failed verification for %s - %s`,
+ url,
+ e.message
+ );
}
- } else if (this.config.litNetwork === 'custom') {
+ } else if (this.config.litNetwork === LIT_NETWORK.Custom) {
log(
`Node attestation SEV verification is disabled. You must explicitly set "checkNodeAttestation" to true when using 'custom' network`
);
@@ -674,7 +661,7 @@ export class LitCore {
coreNodeConfig: CoreNodeConfig;
}> {
// -- handshake with each node
- const requestId: string = this.getRequestId();
+ const requestId: string = this._getNewRequestId();
// track connectedNodes for the new handshake operation
const connectedNodes = new Set();
@@ -691,12 +678,7 @@ export class LitCore {
} nodes. Please check your network connection and try again. Note that you can control this timeout with the connectTimeout config option which takes milliseconds.`;
try {
- // TODO: Kludge, replace with standard error construction
- throwError({
- message: msg,
- errorKind: LIT_ERROR.INIT_ERROR.kind,
- errorCode: LIT_ERROR.INIT_ERROR.name,
- });
+ throw new InitError({}, msg);
} catch (e) {
logErrorWithRequestId(requestId, e);
reject(e);
@@ -743,11 +725,15 @@ export class LitCore {
'Error getting latest blockhash from the nodes.'
);
- throwError({
- message: 'Error getting latest blockhash from the nodes.',
- errorKind: LIT_ERROR.INVALID_ETH_BLOCKHASH.kind,
- errorCode: LIT_ERROR.INVALID_ETH_BLOCKHASH.name,
- });
+ throw new InvalidEthBlockhash(
+ {
+ info: {
+ requestId,
+ },
+ },
+ `latestBlockhash is not available. Received: "%s"`,
+ latestBlockhash
+ );
}
// pick the most common public keys for the subnet and network from the bunch, in case some evil node returned a bad key
@@ -756,22 +742,22 @@ export class LitCore {
Object.values(serverKeys).map(
(keysFromSingleNode) => keysFromSingleNode.subnetPubKey
)
- ),
+ )!,
networkPubKey: mostCommonString(
Object.values(serverKeys).map(
(keysFromSingleNode) => keysFromSingleNode.networkPubKey
)
- ),
+ )!,
networkPubKeySet: mostCommonString(
Object.values(serverKeys).map(
(keysFromSingleNode) => keysFromSingleNode.networkPubKeySet
)
- ),
+ )!,
hdRootPubkeys: mostCommonString(
Object.values(serverKeys).map(
(keysFromSingleNode) => keysFromSingleNode.hdRootPubkeys
)
- ),
+ )!,
latestBlockhash,
lastBlockHashRetrieved: Date.now(),
};
@@ -894,12 +880,12 @@ export class LitCore {
/**
*
- * Get a random request ID
+ * Get a new random request ID
*
* @returns { string }
*
*/
- getRequestId() {
+ protected _getNewRequestId(): string {
return Math.random().toString(16).slice(2);
}
@@ -954,12 +940,27 @@ export class LitCore {
private async _fetchCurrentEpochState(
epochInfo?: EpochInfo
): Promise> {
+ if (!this._stakingContract) {
+ throw new InitError(
+ {},
+ 'Unable to fetch current epoch number; no staking contract configured. Did you forget to `connect()`?'
+ );
+ }
+
if (!epochInfo) {
log(
'epochinfo not found. Not a problem, fetching current epoch state from staking contract'
);
- const validatorData = await this._getValidatorData();
- epochInfo = validatorData.epochInfo;
+ try {
+ const validatorData = await this._getValidatorData();
+ epochInfo = validatorData.epochInfo;
+ } catch (error) {
+ throw new UnknownError(
+ {},
+ '[_fetchCurrentEpochNumber] Error getting current epoch number: %s',
+ error
+ );
+ }
}
// when we transition to the new epoch, we don't store the start time. but we
@@ -982,7 +983,7 @@ export class LitCore {
Math.floor(Date.now() / 1000) <
this._epochCache.startTime +
Math.floor(EPOCH_PROPAGATION_DELAY / 1000) &&
- this._epochCache.currentNumber >= 3
+ this._epochCache.currentNumber >= 3 // FIXME: Why this check?
) {
return this._epochCache.currentNumber - 1;
}
@@ -1097,21 +1098,21 @@ export class LitCore {
url: string;
}): AuthSig => {
if (!sessionSigs) {
- return throwError({
- message: `You must pass in sessionSigs`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {},
+ 'You must pass in sessionSigs. Received: %s',
+ sessionSigs
+ );
}
const sigToPassToNode = sessionSigs[url];
if (!sessionSigs[url]) {
- throwError({
- message: `You passed sessionSigs but we could not find session sig for node ${url}`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {},
+ 'You passed sessionSigs but we could not find session sig for node %s',
+ url
+ );
}
return sigToPassToNode;
@@ -1252,10 +1253,11 @@ export class LitCore {
};
}
+ // TODO Likely a good use case for MultiError
// -- case: if we're here, then we did not succeed. time to handle and report errors.
const mostCommonError = JSON.parse(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
- mostCommonString(errors.map((r: any) => JSON.stringify(r)))
+ mostCommonString(errors.map((r: any) => JSON.stringify(r)))!
);
logErrorWithRequestId(
@@ -1270,15 +1272,15 @@ export class LitCore {
};
/**
- *
* Throw node error
*
* @param { RejectedNodePromises } res
+ * @param { string } requestId
*
- * @returns { void }
+ * @returns { never }
*
*/
- _throwNodeError = (res: RejectedNodePromises, requestId: string): void => {
+ _throwNodeError = (res: RejectedNodePromises, requestId: string): never => {
if (res.error) {
if (
((res.error.errorCode &&
@@ -1289,22 +1291,28 @@ export class LitCore {
log('You are not authorized to access this content');
}
- throwError({
- ...res.error,
- message:
- res.error.message ||
- 'There was an error getting the signing shares from the nodes',
- errorCode: res.error.errorCode || LIT_ERROR.UNKNOWN_ERROR.code,
- requestId,
- } as NodeClientErrorV0 | NodeClientErrorV1);
+ throw new NodeError(
+ {
+ info: {
+ requestId,
+ errorCode: res.error.errorCode,
+ message: res.error.message,
+ },
+ cause: res.error,
+ },
+ 'There was an error getting the signing shares from the nodes. Response from the nodes: %s',
+ JSON.stringify(res)
+ );
} else {
- throwError({
- message: `There was an error getting the signing shares from the nodes. Response from the nodes: ${JSON.stringify(
- res
- )}`,
- error: LIT_ERROR.UNKNOWN_ERROR,
- requestId,
- });
+ throw new UnknownError(
+ {
+ info: {
+ requestId,
+ },
+ },
+ `There was an error getting the signing shares from the nodes. Response from the nodes: %s`,
+ JSON.stringify(res)
+ );
}
};
@@ -1387,22 +1395,25 @@ export class LitCore {
* Calculates an HD public key from a given keyId
* The curve type or signature type is assumed to be k256 unless provided
* @param keyId
- * @param {LIT_CURVE} sigType
+ * @param {LIT_CURVE_VALUES} sigType
* @returns {string} public key
*/
- computeHDPubKey = (
+ computeHDPubKey = async (
keyId: string,
- sigType: LIT_CURVE = LIT_CURVE.EcdsaCaitSith
- ): string => {
+ sigType: LIT_CURVE_VALUES = LIT_CURVE.EcdsaCaitSith
+ ): Promise => {
if (!this.hdRootPubkeys) {
logError('root public keys not found, have you connected to the nodes?');
- throwError({
- message: `root public keys not found, have you connected to the nodes?`,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.code,
- });
+ throw new LitNodeClientNotReadyError(
+ {},
+ 'root public keys not found, have you connected to the nodes?'
+ );
}
- return computeHDPubKey(this.hdRootPubkeys as string[], keyId, sigType);
+ return await computeHDPubKey(
+ this.hdRootPubkeys as string[],
+ keyId,
+ sigType
+ );
};
/**
diff --git a/packages/crypto/README.md b/packages/crypto/README.md
index ca2c3bc468..f7cb8d8f30 100644
--- a/packages/crypto/README.md
+++ b/packages/crypto/README.md
@@ -7,12 +7,3 @@ The crypto.ts file in the Lit SDK handles cryptographic operations, including th
```
yarn add @lit-protocol/crypto
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/crypto/package.json b/packages/crypto/package.json
index 0ffed46782..a39968b3b5 100644
--- a/packages/crypto/package.json
+++ b/packages/crypto/package.json
@@ -21,7 +21,7 @@
"tags": [
"universal"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/crypto/project.json b/packages/crypto/project.json
index 4f97b8b107..d9b420ffda 100644
--- a/packages/crypto/project.json
+++ b/packages/crypto/project.json
@@ -3,6 +3,7 @@
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/crypto/src",
"projectType": "library",
+ "implicitDependencies": ["wasm"],
"targets": {
"build": {
"executor": "@nx/js:tsc",
diff --git a/packages/crypto/src/lib/crypto.spec.ts b/packages/crypto/src/lib/crypto.spec.ts
index 3b93f9d122..9938cbd9eb 100644
--- a/packages/crypto/src/lib/crypto.spec.ts
+++ b/packages/crypto/src/lib/crypto.spec.ts
@@ -1,4 +1,8 @@
-import { initWasmEcdsaSdk } from '@lit-protocol/ecdsa-sdk';
+import * as ethers from 'ethers';
+import { joinSignature } from 'ethers/lib/utils';
+
+import { SigShare } from '@lit-protocol/types';
+
import {
decryptWithSignatureShares,
encrypt,
@@ -6,12 +10,7 @@ import {
combineSignatureShares,
verifySignature,
combineEcdsaShares,
- loadModules,
} from './crypto';
-import * as ethers from 'ethers';
-import { joinSignature } from 'ethers/lib/utils';
-
-import * as blsSdk from '@lit-protocol/bls-sdk';
const publicKey =
'8e29447d7b0666fe41c357dbbdbdac0ac8ac973f88439a07f85fa31fa6fa3cea87c2eaa8b367e1c97764800fb5636892';
@@ -25,14 +24,9 @@ const identityParam = new Uint8Array([
]);
describe('crypto', () => {
- beforeAll(async () => {
- await loadModules();
- await blsSdk.initWasmBlsSdk();
- });
-
it('should encrypt', async () => {
// execute
- const ciphertext = encrypt(publicKey, secretMessage, identityParam);
+ const ciphertext = await encrypt(publicKey, secretMessage, identityParam);
// assert
expect(ciphertext.length).toBeGreaterThan(0);
@@ -49,7 +43,7 @@ describe('crypto', () => {
];
// execute
- const plaintext = decryptWithSignatureShares(
+ const plaintext = await decryptWithSignatureShares(
ciphertext,
signatureShares.map((s) => ({
ProofOfPossession: s,
@@ -70,7 +64,7 @@ describe('crypto', () => {
];
// execute
- const plaintext = verifyAndDecryptWithSignatureShares(
+ const plaintext = await verifyAndDecryptWithSignatureShares(
publicKey,
identityParam,
ciphertext,
@@ -93,7 +87,7 @@ describe('crypto', () => {
}));
// execute
- const combinedSignature = combineSignatureShares(signatureShares);
+ const combinedSignature = await combineSignatureShares(signatureShares);
// assert
expect(combinedSignature.length).toEqual(192);
@@ -152,19 +146,15 @@ describe('crypto', () => {
]);
// execute
- verifySignature(publicKey, message, signature);
+ await verifySignature(publicKey, message, signature);
});
});
describe('combine ECDSA Shares', () => {
- beforeAll(async () => {
- await initWasmEcdsaSdk();
- });
-
it('Should recombine ECDSA signature shares', async () => {
- const sigShares = [
+ const sigShares: SigShare[] = [
{
- sigType: 'ECDSA_CAIT_SITH',
+ sigType: 'ECDSA_CAIT_SITH' as const,
signatureShare:
'BC8108AD9CAE8358942BB4B27632B87FFA705CCB675F85A59847CC1B84845A38',
shareIndex: 0,
@@ -176,7 +166,7 @@ describe('combine ECDSA Shares', () => {
sigName: 'sig',
},
{
- sigType: 'K256',
+ sigType: 'K256' as const,
signatureShare:
'BA77EB500884A60583DEA49578D4BB64BB55EF497F37C88DF935D739CE8E0A9F',
shareIndex: 0,
@@ -188,7 +178,7 @@ describe('combine ECDSA Shares', () => {
sigName: 'sig',
},
{
- sigType: 'ECDSA_CAIT_SITH',
+ sigType: 'ECDSA_CAIT_SITH' as const,
signatureShare:
'EF850AE61B6D658976B2560B880BF03ABC1A070BACDEAE2311781F65A524F245',
shareIndex: 0,
@@ -201,7 +191,7 @@ describe('combine ECDSA Shares', () => {
},
];
- let sig = combineEcdsaShares(sigShares);
+ const sig = await combineEcdsaShares(sigShares);
expect(sig.r).toBeDefined();
expect(sig.s).toBeDefined();
expect(sig.recid).toBeDefined();
@@ -212,7 +202,7 @@ describe('combine ECDSA Shares', () => {
v: sig.recid,
});
- let msg: any = ethers.utils.arrayify('0x' + sigShares[0].dataSigned);
+ const msg = ethers.utils.arrayify('0x' + sigShares[0].dataSigned);
const recoveredPk = ethers.utils.recoverPublicKey(msg, sigRes);
// normalize the public keys to addresses and compare
diff --git a/packages/crypto/src/lib/crypto.ts b/packages/crypto/src/lib/crypto.ts
index 95a4984506..8861a50893 100644
--- a/packages/crypto/src/lib/crypto.ts
+++ b/packages/crypto/src/lib/crypto.ts
@@ -1,181 +1,124 @@
-// @ts-nocheck
-
-import * as blsSdk from '@lit-protocol/bls-sdk';
-
-import { LIT_ERROR, SessionKeyPair, SigShare } from '@lit-protocol/constants';
-
-import * as ecdsaSdk from '@lit-protocol/ecdsa-sdk';
-
-import * as sevSnpUtilsSdk from '@lit-protocol/sev-snp-utils-sdk';
-
-import { isBrowser, log, logError, throwError } from '@lit-protocol/misc';
+import { splitSignature } from 'ethers/lib/utils';
+import {
+ InvalidParamType,
+ LIT_CURVE,
+ LIT_CURVE_VALUES,
+ NetworkError,
+ NoValidShares,
+ UnknownError,
+} from '@lit-protocol/constants';
+import { checkType, log } from '@lit-protocol/misc';
+import { nacl } from '@lit-protocol/nacl';
+import {
+ CombinedECDSASignature,
+ NodeAttestation,
+ SessionKeyPair,
+ SigningAccessControlConditionJWTPayload,
+ SigShare,
+} from '@lit-protocol/types';
import {
uint8arrayFromString,
- uint8ArrayToBase64,
uint8arrayToString,
} from '@lit-protocol/uint8arrays';
-
-import { nacl } from '@lit-protocol/nacl';
-import { LIT_CURVE } from '@lit-protocol/constants';
-import { CombinedECDSASignature } from '@lit-protocol/types';
-
+import {
+ EcdsaVariant,
+ blsCombine,
+ blsDecrypt,
+ blsEncrypt,
+ blsVerify,
+ ecdsaCombine,
+ ecdsaDeriveKey,
+ ecdsaVerify,
+ sevSnpGetVcekUrl,
+ sevSnpVerify,
+} from '@lit-protocol/wasm';
+
+/** ---------- Exports ---------- */
const LIT_CORS_PROXY = `https://cors.litgateway.com`;
export interface BlsSignatureShare {
ProofOfPossession: string;
}
-/**
- Loads all wasm modules into the global scope
-
- - ECDSA utilities - wasmECDSA
- - BLS utilities - wasmExports
- - SEV-SNP utilities - wasmSevSnpUtilities
-
- @returns {Promise}
-*/
-export const loadModules = (): Promise => {
- // if 'wasmExports' is not available, we need to initialize the BLS SDK
- if (!globalThis.wasmExports) {
- blsSdk.initWasmBlsSdk().then((exports) => {
- globalThis.wasmExports = exports;
-
- if (!globalThis.jestTesting) {
- log(
- `✅ [BLS SDK] wasmExports loaded. ${
- Object.keys(exports).length
- } functions available. Run 'wasmExports' in the console to see them.`
- );
- }
- });
- }
-
- if (!globalThis.wasmECDSA) {
- let init = ecdsaSdk.initWasmEcdsaSdk;
- let env;
-
- if (isBrowser()) {
- env = 'Browser';
- } else {
- env = 'NodeJS';
- }
-
- init().then((sdk: any) => {
- globalThis.wasmECDSA = sdk;
-
- if (!globalThis.jestTesting) {
- log(
- `✅ [ECDSA SDK ${env}] wasmECDSA loaded. ${
- Object.keys(wasmECDSA).length
- } functions available. Run 'wasmECDSA' in the console to see them.`
- );
- }
- });
- }
-
- if (!globalThis.wasmSevSnpUtils) {
- sevSnpUtilsSdk.initWasmSevSnpUtilsSdk().then((exports) => {
- globalThis.wasmSevSnpUtils = exports;
-
- if (!globalThis.jestTesting) {
- log(
- `✅ [SEV SNP Utils SDK] wasmSevSnpUtils loaded. ${
- Object.keys(exports).length
- } functions available. Run 'wasmSevSnpUtils' in the console to see them.`
- );
- }
- });
- }
-};
-
-/*
- Removes wasm modules from global scope
- if found to be defined. Can be called multiple times safely.
-*/
-export const unloadModules = () => {
- log('running cleanup for global modules');
- if (globalThis.wasmExports) delete globalThis.wasmExports;
-
- if (globalThis.wasmECDSA) delete globalThis.wasmECDSA;
-
- if (globalThis.wasmSevSnpUtilsSdk) delete globalThis.initWasmSevSnpUtilsSdk;
-};
-
/**
* Encrypt data with a BLS public key.
+ * We are using G1 for encryption and G2 for signatures
*
- * @param publicKey hex-encoded string of the BLS public key to encrypt with
- * @param data Uint8Array of the data to encrypt
+ * @param publicKeyHex hex-encoded string of the BLS public key to encrypt with
+ * @param message Uint8Array of the data to encrypt
* @param identity Uint8Array of the identity parameter used during encryption
* @returns base64 encoded string of the ciphertext
*/
-export const encrypt = (
- publicKey: string,
- data: Uint8Array,
+export const encrypt = async (
+ publicKeyHex: string,
+ message: Uint8Array,
identity: Uint8Array
-): string => {
- return blsSdk.encrypt(
- publicKey,
- uint8arrayToString(data, 'base64'),
- uint8arrayToString(identity, 'base64')
- );
+): Promise => {
+ const publicKey = Buffer.from(publicKeyHex, 'hex');
+
+ /**
+ * Our system uses BLS12-381 on the G1 curve for encryption.
+ * However, on the SDK side (this function), we expect the public key
+ * to use the G2 curve for signature purposes, hence the switch on public key length.
+ *
+ * The G2 curve, `Bls12381G2`, is typically associated with signature generation/verification,
+ * while G1 is associated with encryption. Here, the length of the public key determines how
+ * we handle the encryption and the format of the returned encrypted message.
+ */
+ if (publicKeyHex.replace('0x', '').length !== 96) {
+ throw new InvalidParamType(
+ {
+ info: {
+ publicKeyHex,
+ },
+ },
+ `Invalid public key length. Expecting 96 characters, got ${
+ publicKeyHex.replace('0x', '').length
+ } instead.`
+ );
+ }
+ return Buffer.from(
+ await blsEncrypt('Bls12381G2', publicKey, message, identity)
+ ).toString('base64');
};
/**
* Decrypt ciphertext using BLS signature shares.
*
- * @param ciphertext base64-encoded string of the ciphertext to decrypt
+ * @param ciphertextBase64 base64-encoded string of the ciphertext to decrypt
* @param shares hex-encoded array of the BLS signature shares
* @returns Uint8Array of the decrypted data
*/
-export const decryptWithSignatureShares = (
- ciphertext: string,
+export const decryptWithSignatureShares = async (
+ ciphertextBase64: string,
shares: BlsSignatureShare[]
-): Uint8Array => {
- // Format the signature shares
- const sigShares = shares.map((s) => JSON.stringify(s));
-
- // Decrypt
- const privateData = blsSdk.decrypt_with_signature_shares(
- ciphertext,
- sigShares
- );
+): Promise => {
+ const signature = await doCombineSignatureShares(shares);
- // Format
- return uint8arrayFromString(privateData, 'base64');
+ return doDecrypt(ciphertextBase64, signature);
};
/**
* Verify and decrypt ciphertext using BLS signature shares.
*
- * @param publicKey hex-encoded string of the BLS public key to verify with
+ * @param publicKeyHex hex-encoded string of the BLS public key to verify with
* @param identity Uint8Array of the identity parameter used during encryption
- * @param ciphertext base64-encoded string of the ciphertext to decrypt
+ * @param ciphertextBase64 base64-encoded string of the ciphertext to decrypt
* @param shares hex-encoded array of the BLS signature shares
* @returns base64-encoded string of the decrypted data
*/
-export const verifyAndDecryptWithSignatureShares = (
- publicKey: string,
+export const verifyAndDecryptWithSignatureShares = async (
+ publicKeyHex: string,
identity: Uint8Array,
- ciphertext: string,
+ ciphertextBase64: string,
shares: BlsSignatureShare[]
-): Uint8Array => {
- // Format the signature shares
- const sigShares = shares.map((s) => JSON.stringify(s));
-
- const base64Identity = uint8ArrayToBase64(identity);
-
- // Decrypt
- const privateData = blsSdk.verify_and_decrypt_with_signature_shares(
- publicKey,
- base64Identity,
- ciphertext,
- sigShares
- );
+): Promise => {
+ const publicKey = Buffer.from(publicKeyHex, 'hex');
+ const signature = await doCombineSignatureShares(shares);
+ await blsVerify('Bls12381G2', publicKey, identity, signature);
- // Format
- return uint8arrayFromString(privateData, 'base64');
+ return doDecrypt(ciphertextBase64, signature);
};
/**
@@ -184,157 +127,127 @@ export const verifyAndDecryptWithSignatureShares = (
* @param shares hex-encoded array of the BLS signature shares
* @returns hex-encoded string of the combined signature
*/
-export const combineSignatureShares = (shares: BlsSignatureShare[]): string => {
- // Format the signature shares
- const sigShares = shares.map((s) => JSON.stringify(s));
+export const combineSignatureShares = async (
+ shares: BlsSignatureShare[]
+): Promise => {
+ const signature = await doCombineSignatureShares(shares);
- return blsSdk.combine_signature_shares(sigShares);
+ return Buffer.from(signature).toString('hex');
};
/**
* Verify the BLS network signature.
*
- * @param publicKey hex-encoded string of the BLS public key to verify with.
+ * @param publicKeyHex hex-encoded string of the BLS public key to verify with.
* @param message Uint8Array of the message to verify.
* @param signature Uint8Array of the signature to verify.
*/
-export const verifySignature = (
- publicKey: string,
+export const verifySignature = async (
+ publicKeyHex: string,
message: Uint8Array,
signature: Uint8Array
-): void => {
- blsSdk.verify_signature(
- publicKey,
- uint8arrayToString(message, 'base64'),
- uint8arrayToString(signature, 'base64')
- );
+): Promise => {
+ const publicKey = Buffer.from(publicKeyHex, 'hex');
+
+ await blsVerify('Bls12381G2', publicKey, message, signature);
+};
+
+// export interface EcdsaSignatureShare {
+// sigType: SIGTYPE;
+// signatureShare: string;
+// shareIndex: number; // ignored
+// publicKey: string;
+// dataSigned: string;
+// bigR: string;
+// sigName: string; // ignored
+// }
+
+const ecdsaSigntureTypeMap: Partial> = {
+ [LIT_CURVE.EcdsaCaitSith]: 'K256',
+ [LIT_CURVE.EcdsaK256]: 'K256',
+ [LIT_CURVE.EcdsaCAITSITHP256]: 'P256',
};
/**
*
* Combine ECDSA Shares
*
- * @param { SigShares | Array } sigShares
+ * @param { Array } sigShares
*
* @returns { any }
*
*/
-export const combineEcdsaShares = (
- sigShares: Array
-): CombinedECDSASignature => {
- const type = sigShares[0].sigType;
-
- if (!type) {
- throw new Error(
- "Sig type is not defined! Here's your sigShares:",
- sigShares
+export const combineEcdsaShares = async (
+ sigShares: SigShare[]
+): Promise => {
+ const validShares = sigShares.filter((share) => share.signatureShare);
+
+ const anyValidShare = validShares[0];
+
+ if (!anyValidShare) {
+ throw new NoValidShares(
+ {
+ info: {
+ shares: sigShares,
+ },
+ },
+ 'No valid shares to combine'
);
}
- // the public key can come from any node - it obviously will be identical from each node
- // const publicKey = sigShares[0].publicKey;
- // const dataSigned = '0x' + sigShares[0].dataSigned;
- // filter out empty shares
- const validShares = sigShares.reduce((acc, val) => {
- if (val.signatureShare !== '') {
- const newVal = _remapKeyShareForEcdsa(val);
+ const variant =
+ ecdsaSigntureTypeMap[anyValidShare.sigType as LIT_CURVE_VALUES];
+ const presignature = Buffer.from(anyValidShare.bigR!, 'hex');
+ const signatureShares = validShares.map((share) =>
+ Buffer.from(share.signatureShare, 'hex')
+ );
- if (!newVal.sig_name) {
- newVal.sig_name = 'sig-created-by-lit-sdk';
- }
+ const [r, s, v] = await ecdsaCombine(variant!, presignature, signatureShares);
- acc.push(JSON.stringify(newVal));
- }
- return acc;
- }, []);
-
- log('Valid Shares:', validShares);
-
- // if there are no valid shares, throw an error
- if (validShares.length === 0) {
- return throwError({
- message: 'No valid shares to combine',
- errorKind: LIT_ERROR.NO_VALID_SHARES.kind,
- errorCode: LIT_ERROR.NO_VALID_SHARES.name,
- });
- }
+ const publicKey = Buffer.from(anyValidShare.publicKey, 'hex');
+ const messageHash = Buffer.from(anyValidShare.dataSigned!, 'hex');
- let sig: CombinedECDSASignature | undefined;
+ await ecdsaVerify(variant!, messageHash, publicKey, [r, s, v]);
- try {
- let res: string = '';
- switch (type) {
- case LIT_CURVE.EcdsaCaitSith:
- case LIT_CURVE.EcdsaK256:
- res = ecdsaSdk.combine_signature(validShares, 2);
-
- try {
- sig = JSON.parse(res) as CombinedECDSASignature;
- } catch (e) {
- logError('Error while combining signatures shares', validShares);
- throwError({
- message: (e as Error).message,
- name: LIT_ERROR.SIGNATURE_VALIDATION_ERROR.name,
- kind: LIT_ERROR.SIGNATURE_VALIDATION_ERROR.kind,
- });
- }
-
- /*
- r and s values of the signature should be maximum of 64 bytes
- r and s values can have polarity as the first two bits, here we remove
- */
- if (sig && sig.r && sig.r.length > 64) {
- while (sig.r.length > 64) {
- sig.r = sig.r.slice(1);
- }
- }
- if (sig && sig.s && sig.s.length > 64) {
- while (sig.s.length > 64) {
- sig.s = sig.s.slice(1);
- }
- }
- break;
- case LIT_CURVE.ECDSCAITSITHP256:
- res = ecdsaSdk.combine_signature(validShares, 3);
- log('response from combine_signature', res);
- sig = JSON.parse(res);
- break;
- // if its another sig type, it shouldnt be resolving to this method
- default:
- throw new Error(
- 'Unsupported signature type present in signature shares. Please report this issue'
- );
- }
- } catch (e) {
- log('Failed to combine signatures:', e);
- }
+ const signature = splitSignature(Buffer.concat([r, s, Buffer.from([v])]));
- log('signature', sig);
-
- return sig;
+ return {
+ r: signature.r.slice('0x'.length),
+ s: signature.s.slice('0x'.length),
+ recid: signature.recoveryParam,
+ };
};
-export const computeHDPubKey = (
+export const computeHDPubKey = async (
pubkeys: string[],
keyId: string,
- sigType: LIT_CURVE
-): string => {
- // TODO: hardcoded for now, need to be replaced on each DKG as the last dkg id will be the active root key set.
- try {
- switch (sigType) {
- case LIT_CURVE.EcdsaCaitSith:
- case LIT_CURVE.EcdsaK256:
- // a bit of pre processing to remove characters which will cause our wasm module to reject the values.
- pubkeys = pubkeys.map((value: string) => {
- return value.replace('0x', '');
- });
- keyId = keyId.replace('0x', '');
- return ecdsaSdk.compute_public_key(keyId, pubkeys, 2);
- default:
- throw new Error('Non supported signature type');
- }
- } catch (e) {
- log('Failed to derive public key', e);
+ sigType: LIT_CURVE_VALUES
+): Promise => {
+ const variant = ecdsaSigntureTypeMap[sigType];
+
+ switch (sigType) {
+ case LIT_CURVE.EcdsaCaitSith:
+ case LIT_CURVE.EcdsaK256:
+ // a bit of pre processing to remove characters which will cause our wasm module to reject the values.
+ pubkeys = pubkeys.map((value: string) => {
+ return value.replace('0x', '');
+ });
+ keyId = keyId.replace('0x', '');
+ const preComputedPubkey = await ecdsaDeriveKey(
+ variant!,
+ Buffer.from(keyId, 'hex'),
+ pubkeys.map((hex: string) => Buffer.from(hex, 'hex'))
+ );
+ return Buffer.from(preComputedPubkey).toString('hex');
+ default:
+ throw new InvalidParamType(
+ {
+ info: {
+ sigType,
+ },
+ },
+ `Non supported signature type`
+ );
}
};
@@ -355,32 +268,21 @@ export const generateSessionKeyPair = (): SessionKeyPair => {
return sessionKeyPair;
};
-const _remapKeyShareForEcdsa = (share: SigShare): any[] => {
- const keys = Object.keys(share);
- let newShare = {};
- for (const key of keys) {
- const new_key = key.replace(
- /[A-Z]/g,
- (letter) => `_${letter.toLowerCase()}`
- );
- newShare = Object.defineProperty(
- newShare,
- new_key,
- Object.getOwnPropertyDescriptor(share, key)
- );
- }
-
- return newShare;
-};
-
-function base64ToBufferAsync(base64) {
- var dataUrl = 'data:application/octet-binary;base64,' + base64;
+function doDecrypt(
+ ciphertextBase64: string,
+ signature: Uint8Array
+): Promise {
+ console.log('signature from encrypt op: ', signature);
+ const ciphertext = Buffer.from(ciphertextBase64, 'base64');
+ return blsDecrypt('Bls12381G2', ciphertext, signature);
+}
- return fetch(dataUrl)
- .then((res) => res.arrayBuffer())
- .then((buffer) => {
- return new Uint8Array(buffer);
- });
+function doCombineSignatureShares(
+ shares: BlsSignatureShare[]
+): Promise {
+ const sigShares = shares.map((s) => Buffer.from(s.ProofOfPossession, 'hex'));
+ const signature = blsCombine('Bls12381G2', sigShares);
+ return signature;
}
/**
@@ -402,10 +304,17 @@ async function getAmdCert(url: string): Promise {
`[getAmdCert] Fetching AMD cert using proxy URL ${proxyUrl} to manage CORS restrictions and to avoid being rate limited by AMD.`
);
- async function fetchAsUint8Array(targetUrl) {
+ async function fetchAsUint8Array(targetUrl: string) {
const res = await fetch(targetUrl);
if (!res.ok) {
- throw new Error(`[getAmdCert] HTTP error! status: ${response.status}`);
+ throw new NetworkError(
+ {
+ info: {
+ targetUrl,
+ },
+ },
+ `[getAmdCert] HTTP error! status: ${res.status}`
+ );
}
const arrayBuffer = await res.arrayBuffer();
return new Uint8Array(arrayBuffer);
@@ -433,43 +342,45 @@ async function getAmdCert(url: string): Promise {
* Check the attestation against AMD certs
*
* @param { NodeAttestation } attestation The actual attestation object, which includes the signature and report
- * @param { string } challenge The challenge we sent
+ * @param { string } challengeHex The challenge we sent
* @param { string } url The URL we talked to
*
* @returns { Promise } A promise that throws if the attestation is invalid
*/
export const checkSevSnpAttestation = async (
attestation: NodeAttestation,
- challenge: string,
+ challengeHex: string,
url: string
) => {
- /* attestation object looks like this:
- "attestation": {
- "type": "AMD_SEV_SNP",
- "noonce": "RPFFYVWtSV37r9/VExEvma5xAjmPazJ4+AG51lT3cD0=",
- "data": {
- "INSTANCE_ID": "YzJjNmI3NjE=",
- "RELEASE_ID": "ZmM1YzkyNTBjY2MxNTllNGEwM2QzOGZiNGRmMDdhNTM1OGE0NGEyN2NjNDkxYjBk",
- "UNIX_TIME": "gqNFZQAAAAA="
+ const noonce = Buffer.from(attestation.noonce, 'base64');
+ const challenge = Buffer.from(challengeHex, 'hex');
+ const data = Object.fromEntries(
+ Object.entries(attestation.data).map(([k, v]) => [
+ k,
+ Buffer.from(v, 'base64'),
+ ])
+ );
+ const signatures = attestation.signatures.map((s) =>
+ Buffer.from(s, 'base64')
+ );
+ const report = Buffer.from(attestation.report, 'base64');
+
+ if (!noonce.equals(challenge)) {
+ throw new NetworkError(
+ {
+ info: {
+ attestation,
+ challengeHex,
+ noonce,
+ challenge,
+ },
},
- "signatures": [
- "MEQCIH4A2AhIi6GgedbNnmXVQFn+qx1tBppcsrEhmv4fK2vTAiAWhfHnJHPepkSoKzoxMc9Sc3wNtKyzEt1IJXdfqd0RgQEEouNBbEJ/Y5ZQNxtsJ1EfM+xOKzCnc1dSxSMXdCVTun8KDChld60axa7i6kCkUjDG7XrIRzaqjO3pHwbKOYSatQ=="
- ],
- "report": "AgAAAAAAAAAAAAMAAAAAAAEAAAAFEAABCwyQBQajBzX8XJJQzMFZ5KA9OPtN8HpTAAAAAAEAAAADAAAAAAAKqQEAAAAAAAAAAQAAAAAAAAD="
- }
- */
-
- const { noonce, data, signatures, report, type } = attestation;
- // base64 decode the noonce and compare it to the challenge
- const decodedNoonce = Buffer.from(noonce, 'base64').toString('hex');
- if (decodedNoonce !== challenge) {
- throw new Error(
- `Attestation noonce ${decodedNoonce} does not match challenge ${challenge}`
+ `Attestation noonce ${noonce} does not match challenge ${challenge}`
);
}
const parsedUrl = new URL(url);
- let ipWeTalkedTo = parsedUrl.hostname;
+ const ipWeTalkedTo = parsedUrl.hostname;
let portWeTalkedTo = parsedUrl.port;
if (portWeTalkedTo === '') {
// if we're on HTTP or HTTPS, the port will be empty
@@ -478,31 +389,49 @@ export const checkSevSnpAttestation = async (
} else if (url.startsWith('http://')) {
portWeTalkedTo = '80';
} else {
- throw new Error(`Unknown port in URL ${url}`);
+ throw new NetworkError(
+ {
+ info: {
+ url,
+ },
+ },
+ `Unknown port in URL ${url}`
+ );
}
}
- let ipAndAddrFromReport = Buffer.from(
- data['EXTERNAL_ADDR'],
- 'base64'
- ).toString('utf8');
- let ipFromReport = ipAndAddrFromReport.split(':')[0];
- let portFromReport = ipAndAddrFromReport.split(':')[1];
+ const ipAndAddrFromReport = data['EXTERNAL_ADDR'].toString('utf8');
+ const ipFromReport = ipAndAddrFromReport.split(':')[0];
+ const portFromReport = ipAndAddrFromReport.split(':')[1];
if (ipWeTalkedTo !== ipFromReport) {
- throw new Error(
+ throw new NetworkError(
+ {
+ info: {
+ attestation,
+ ipWeTalkedTo,
+ ipFromReport,
+ },
+ },
`Attestation external address ${ipFromReport} does not match IP we talked to ${ipWeTalkedTo}`
);
}
if (portWeTalkedTo !== portFromReport) {
- throw new Error(
+ throw new NetworkError(
+ {
+ info: {
+ attestation,
+ portWeTalkedTo,
+ portFromReport,
+ },
+ },
`Attestation external port ${portFromReport} does not match port we talked to ${portWeTalkedTo}`
);
}
// get the VCEK certificate
let vcekCert;
- const vcekUrl = sevSnpUtilsSdk.get_vcek_url(report);
+ const vcekUrl = await sevSnpGetVcekUrl(report);
// use local storage if we have one available
if (globalThis.localStorage) {
log('Using local storage for certificate caching');
@@ -514,27 +443,31 @@ export const checkSevSnpAttestation = async (
localStorage.setItem(vcekUrl, uint8arrayToString(vcekCert, 'base64'));
}
} else {
- // if nodejs, store in memory
- if (!globalThis.amdCertStore) {
- globalThis.amdCertStore = {};
- }
- vcekCert = globalThis.amdCertStore[vcekUrl];
- if (!vcekCert) {
- vcekCert = await getAmdCert(vcekUrl);
- globalThis.amdCertStore[vcekUrl] = vcekCert;
- }
+ const cache = ((
+ globalThis as unknown as { amdCertStore: Record }
+ ).amdCertStore ??= {});
+ cache[vcekUrl] ??= await getAmdCert(vcekUrl);
+ vcekCert = cache[vcekUrl];
}
if (!vcekCert || vcekCert.length === 0 || vcekCert.length < 256) {
- throw new Error('Unable to retrieve VCEK certificate from AMD');
+ throw new UnknownError(
+ {
+ info: {
+ attestation,
+ report,
+ vcekUrl,
+ },
+ },
+ 'Unable to retrieve VCEK certificate from AMD'
+ );
}
// pass base64 encoded report to wasm wrapper
- return sevSnpUtilsSdk.verify_attestation_report_and_check_challenge(
- report,
- data,
- signatures,
- challenge,
- vcekCert
- );
+ return sevSnpVerify(report, data, signatures, challenge, vcekCert);
};
+
+declare global {
+ // eslint-disable-next-line no-var, @typescript-eslint/no-explicit-any
+ var LitNodeClient: any;
+}
diff --git a/packages/ecdsa-sdk/.babelrc b/packages/ecdsa-sdk/.babelrc
deleted file mode 100644
index 158083d278..0000000000
--- a/packages/ecdsa-sdk/.babelrc
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "presets": [
- [
- "@nx/web/babel",
- {
- "useBuiltIns": "usage"
- }
- ]
- ]
-}
diff --git a/packages/ecdsa-sdk/.eslintrc.json b/packages/ecdsa-sdk/.eslintrc.json
deleted file mode 100644
index 9d9c0db55b..0000000000
--- a/packages/ecdsa-sdk/.eslintrc.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "extends": ["../../.eslintrc.json"],
- "ignorePatterns": ["!**/*"],
- "overrides": [
- {
- "files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
- "rules": {}
- },
- {
- "files": ["*.ts", "*.tsx"],
- "rules": {}
- },
- {
- "files": ["*.js", "*.jsx"],
- "rules": {}
- }
- ]
-}
diff --git a/packages/ecdsa-sdk/README.md b/packages/ecdsa-sdk/README.md
deleted file mode 100644
index 6ff713804d..0000000000
--- a/packages/ecdsa-sdk/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# ECDSA-SDK
-
-Read more about it here:
-
-https://github.com/LIT-Protocol/lit-ecdsa-wasm-combine
-
-# Quick Start
-
-### node.js / browser
-
-```
-yarn add @lit-protocol/ecdsa-sdk
-```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/ecdsa-sdk/jest.config.ts b/packages/ecdsa-sdk/jest.config.ts
deleted file mode 100644
index 2f5d41225a..0000000000
--- a/packages/ecdsa-sdk/jest.config.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-/* eslint-disable */
-export default {
- displayName: 'ecdsa-sdk',
- preset: '../../jest.preset.js',
- globals: {
- 'ts-jest': {
- tsconfig: '/tsconfig.spec.json',
- },
- },
- transform: {
- '^.+\\.[t]s$': 'ts-jest',
- },
- moduleFileExtensions: ['ts', 'js', 'html'],
- coverageDirectory: '../../coverage/packages/ecdsa-sdk',
- setupFilesAfterEnv: ['../../jest.setup.js'],
-};
diff --git a/packages/ecdsa-sdk/package.json b/packages/ecdsa-sdk/package.json
deleted file mode 100644
index 8710e428c5..0000000000
--- a/packages/ecdsa-sdk/package.json
+++ /dev/null
@@ -1,30 +0,0 @@
-{
- "name": "@lit-protocol/ecdsa-sdk",
- "license": "MIT",
- "homepage": "https://github.com/Lit-Protocol/js-sdk",
- "repository": {
- "type": "git",
- "url": "https://github.com/LIT-Protocol/js-sdk"
- },
- "keywords": [
- "library"
- ],
- "bugs": {
- "url": "https://github.com/LIT-Protocol/js-sdk/issues"
- },
- "type": "commonjs",
- "publishConfig": {
- "access": "public",
- "directory": "../../dist/packages/ecdsa-sdk"
- },
- "gitHead": "0d7334c2c55f448e91fe32f29edc5db8f5e09e4b",
- "peerDependencies": {
- "pako": "^2.1.0"
- },
- "tags": [
- "universal"
- ],
- "version": "6.11.0",
- "main": "./dist/src/index.js",
- "typings": "./dist/src/index.d.ts"
-}
diff --git a/packages/ecdsa-sdk/project.json b/packages/ecdsa-sdk/project.json
deleted file mode 100644
index 2bdd97b866..0000000000
--- a/packages/ecdsa-sdk/project.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "ecdsa-sdk",
- "$schema": "../../node_modules/nx/schemas/project-schema.json",
- "sourceRoot": "packages/ecdsa-sdk/src",
- "projectType": "library",
- "targets": {
- "build": {
- "executor": "@nx/js:tsc",
- "outputs": ["{options.outputPath}"],
- "options": {
- "outputPath": "dist/packages/ecdsa-sdk",
- "main": "packages/ecdsa-sdk/src/index.ts",
- "tsConfig": "packages/ecdsa-sdk/tsconfig.lib.json",
- "assets": ["packages/ecdsa-sdk/*.md"],
- "updateBuildableProjectDepsInPackageJson": true
- }
- },
- "test": {
- "executor": "@nx/jest:jest",
- "outputs": ["{workspaceRoot}/coverage/packages/ecdsa-sdk"],
- "options": {
- "jestConfig": "packages/ecdsa-sdk/jest.config.ts",
- "passWithNoTests": true
- }
- }
- },
- "tags": []
-}
diff --git a/packages/ecdsa-sdk/src/index.ts b/packages/ecdsa-sdk/src/index.ts
deleted file mode 100644
index fc80174933..0000000000
--- a/packages/ecdsa-sdk/src/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './lib/ecdsa-sdk';
diff --git a/packages/ecdsa-sdk/src/lib/ecdsa-sdk.spec.ts b/packages/ecdsa-sdk/src/lib/ecdsa-sdk.spec.ts
deleted file mode 100644
index 577496142c..0000000000
--- a/packages/ecdsa-sdk/src/lib/ecdsa-sdk.spec.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-// @ts-nocheck
-import { TextEncoder, TextDecoder } from 'util';
-global.TextEncoder = TextEncoder;
-// @ts-ignore
-global.TextDecoder = TextDecoder;
-
-import * as ecdsaSdk from './ecdsa-sdk';
-
-describe('ecdsaSdk', () => {
- it('ecdsaSdk keys should be more than 0', () => {
- // test if the object keys is more than 0
- expect(Object.keys(ecdsaSdk).length).toBeGreaterThan(1);
- });
-});
diff --git a/packages/ecdsa-sdk/src/lib/ecdsa-sdk.ts b/packages/ecdsa-sdk/src/lib/ecdsa-sdk.ts
deleted file mode 100644
index c0e4165d3e..0000000000
--- a/packages/ecdsa-sdk/src/lib/ecdsa-sdk.ts
+++ /dev/null
@@ -1,4543 +0,0 @@
-// @ts-nocheck
-import * as pako from 'pako';
-
-// Contants
-
-const skLen = 32; // bytes
-const pkLen = 48; // bytes
-const sigLen = 96; // bytes
-const maxMsgLen = 1049600; // bytes
-const maxCtLen = 1049600; // bytes
-const decryptionShareLen = 48; // bytes
-
-// the number of bytes in a row derived from a BivarPoly
-// which varies depending on the threshold.
-const row_sizes_by_threshold = [
- 40, // threshold 0
- 72, // threshold 1
- 104, // threshold 2
- 136, // threshold 3
- 168, // threshold 4
- 200, // threshold 5
- 232, // threshold 6
- 264, // threshold 7
- 296, // threshold 8
- 328, // threshold 9
- 360, // threshold 10
-];
-
-// the number of bytes in a commitment derived from a BivarPoly
-// which varies depending on the threshold.
-const commitment_sizes_by_threshold = [
- 56, // threshold 0
- 104, // threshold 1
- 152, // threshold 2
- 200, // threshold 3
- 248, // threshold 4
- 296, // threshold 5
- 344, // threshold 6
- 392, // threshold 7
- 440, // threshold 8
- 488, // threshold 9
- 536, // threshold 10
-];
-
-// the number of bytes in the master secret key (Poly)
-// which varies depending on the threshold.
-const poly_sizes_by_threshold = [
- 40, // threshold 0
- 72, // threshold 1
- 104, // threshold 2
- 136, // threshold 3
- 168, // threshold 4
- 200, // threshold 5
- 232, // threshold 6
- 264, // threshold 7
- 296, // threshold 8
- 328, // threshold 9
- 360, // threshold 10
-];
-
-// Encoding conversions
-
-// modified from https://stackoverflow.com/a/11058858
-function asciiToUint8Array(a) {
- let b = new Uint8Array(a.length);
- for (let i = 0; i < a.length; i++) {
- b[i] = a.charCodeAt(i);
- }
- return b;
-}
-// https://stackoverflow.com/a/19102224
-// TODO resolve RangeError possibility here, see SO comments
-function uint8ArrayToAscii(a) {
- return String.fromCharCode.apply(null, a);
-}
-// https://stackoverflow.com/a/50868276
-function hexToUint8Array(h) {
- if (h.length == 0) {
- return new Uint8Array();
- }
- return new Uint8Array(h.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
-}
-function uint8ArrayToHex(a) {
- return a.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
-}
-function uint8ArrayToByteStr(a) {
- return '[' + a.join(', ') + ']';
-}
-
-//https://gist.github.com/enepomnyaschih/72c423f727d395eeaa09697058238727
-/*
-MIT License
-Copyright (c) 2020 Egor Nepomnyaschih
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/*
-// This constant can also be computed with the following algorithm:
-const base64abc = [],
- A = "A".charCodeAt(0),
- a = "a".charCodeAt(0),
- n = "0".charCodeAt(0);
-for (let i = 0; i < 26; ++i) {
- base64abc.push(String.fromCharCode(A + i));
-}
-for (let i = 0; i < 26; ++i) {
- base64abc.push(String.fromCharCode(a + i));
-}
-for (let i = 0; i < 10; ++i) {
- base64abc.push(String.fromCharCode(n + i));
-}
-base64abc.push("+");
-base64abc.push("/");
-*/
-const base64abc = [
- 'A',
- 'B',
- 'C',
- 'D',
- 'E',
- 'F',
- 'G',
- 'H',
- 'I',
- 'J',
- 'K',
- 'L',
- 'M',
- 'N',
- 'O',
- 'P',
- 'Q',
- 'R',
- 'S',
- 'T',
- 'U',
- 'V',
- 'W',
- 'X',
- 'Y',
- 'Z',
- 'a',
- 'b',
- 'c',
- 'd',
- 'e',
- 'f',
- 'g',
- 'h',
- 'i',
- 'j',
- 'k',
- 'l',
- 'm',
- 'n',
- 'o',
- 'p',
- 'q',
- 'r',
- 's',
- 't',
- 'u',
- 'v',
- 'w',
- 'x',
- 'y',
- 'z',
- '0',
- '1',
- '2',
- '3',
- '4',
- '5',
- '6',
- '7',
- '8',
- '9',
- '+',
- '/',
-];
-
-/*
-// This constant can also be computed with the following algorithm:
-const l = 256, base64codes = new Uint8Array(l);
-for (let i = 0; i < l; ++i) {
- base64codes[i] = 255; // invalid character
-}
-base64abc.forEach((char, index) => {
- base64codes[char.charCodeAt(0)] = index;
-});
-base64codes["=".charCodeAt(0)] = 0; // ignored anyway, so we just need to prevent an error
-*/
-const base64codes = [
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255,
- 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255,
- 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
- 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32,
- 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
-];
-
-function getBase64Code(charCode) {
- if (charCode >= base64codes.length) {
- throw new Error('Unable to parse base64 string.');
- }
- const code = base64codes[charCode];
- if (code === 255) {
- throw new Error('Unable to parse base64 string.');
- }
- return code;
-}
-
-export function uint8ArrayToBase64(bytes) {
- let result = '',
- i,
- l = bytes.length;
- for (i = 2; i < l; i += 3) {
- result += base64abc[bytes[i - 2] >> 2];
- result += base64abc[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];
- result += base64abc[((bytes[i - 1] & 0x0f) << 2) | (bytes[i] >> 6)];
- result += base64abc[bytes[i] & 0x3f];
- }
- if (i === l + 1) {
- // 1 octet yet to write
- result += base64abc[bytes[i - 2] >> 2];
- result += base64abc[(bytes[i - 2] & 0x03) << 4];
- result += '==';
- }
- if (i === l) {
- // 2 octets yet to write
- result += base64abc[bytes[i - 2] >> 2];
- result += base64abc[((bytes[i - 2] & 0x03) << 4) | (bytes[i - 1] >> 4)];
- result += base64abc[(bytes[i - 1] & 0x0f) << 2];
- result += '=';
- }
- return result;
-}
-
-export function base64ToUint8Array(str) {
- if (str.length % 4 !== 0) {
- throw new Error('Unable to parse base64 string.');
- }
- const index = str.indexOf('=');
- if (index !== -1 && index < str.length - 2) {
- throw new Error('Unable to parse base64 string.');
- }
- let missingOctets = str.endsWith('==') ? 2 : str.endsWith('=') ? 1 : 0,
- n = str.length,
- result = new Uint8Array(3 * (n / 4)),
- buffer;
- for (let i = 0, j = 0; i < n; i += 4, j += 3) {
- buffer =
- (getBase64Code(str.charCodeAt(i)) << 18) |
- (getBase64Code(str.charCodeAt(i + 1)) << 12) |
- (getBase64Code(str.charCodeAt(i + 2)) << 6) |
- getBase64Code(str.charCodeAt(i + 3));
- result[j] = buffer >> 16;
- result[j + 1] = (buffer >> 8) & 0xff;
- result[j + 2] = buffer & 0xff;
- }
- return result.subarray(0, result.length - missingOctets);
-}
-
-// export function base64encode(str, encoder = new TextEncoder()) {
-// return bytesToBase64(encoder.encode(str));
-// }
-
-// export function base64decode(str, decoder = new TextDecoder()) {
-// return decoder.decode(base64ToBytes(str));
-// }
-
-// https://stackoverflow.com/a/12713326
-// function uint8ArrayToBase64(a) {
-// return btoa(String.fromCharCode.apply(null, a));
-// }
-// function base64ToUint8Array(b) {
-// return new Uint8Array(atob(b).split("").map(function(c) {
-// return c.charCodeAt(0);
-// }));
-// }
-let wasm;
-
-const heap = new Array(128).fill(undefined);
-
-heap.push(undefined, null, true, false);
-
-function getObject(idx) {
- return heap[idx];
-}
-
-let WASM_VECTOR_LEN = 0;
-
-let cachedUint8Memory0 = null;
-
-function getUint8Memory0() {
- if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
- cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
- }
- return cachedUint8Memory0;
-}
-
-const cachedTextEncoder = new TextEncoder('utf-8');
-
-const encodeString =
- typeof cachedTextEncoder.encodeInto === 'function'
- ? function (arg, view) {
- return cachedTextEncoder.encodeInto(arg, view);
- }
- : function (arg, view) {
- const buf = cachedTextEncoder.encode(arg);
- view.set(buf);
- return {
- read: arg.length,
- written: buf.length,
- };
- };
-
-function passStringToWasm0(arg, malloc, realloc) {
- if (realloc === undefined) {
- const buf = cachedTextEncoder.encode(arg);
- const ptr = malloc(buf.length);
- getUint8Memory0()
- .subarray(ptr, ptr + buf.length)
- .set(buf);
- WASM_VECTOR_LEN = buf.length;
- return ptr;
- }
-
- let len = arg.length;
- let ptr = malloc(len);
-
- const mem = getUint8Memory0();
-
- let offset = 0;
-
- for (; offset < len; offset++) {
- const code = arg.charCodeAt(offset);
- if (code > 0x7f) break;
- mem[ptr + offset] = code;
- }
-
- if (offset !== len) {
- if (offset !== 0) {
- arg = arg.slice(offset);
- }
- ptr = realloc(ptr, len, (len = offset + arg.length * 3));
- const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
- const ret = encodeString(arg, view);
-
- offset += ret.written;
- }
-
- WASM_VECTOR_LEN = offset;
- return ptr;
-}
-
-function isLikeNone(x) {
- return x === undefined || x === null;
-}
-
-let cachedInt32Memory0 = null;
-
-function getInt32Memory0() {
- if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
- cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
- }
- return cachedInt32Memory0;
-}
-
-let heap_next = heap.length;
-
-function dropObject(idx) {
- if (idx < 132) return;
- heap[idx] = heap_next;
- heap_next = idx;
-}
-
-function takeObject(idx) {
- const ret = getObject(idx);
- dropObject(idx);
- return ret;
-}
-
-const cachedTextDecoder = new TextDecoder('utf-8', {
- ignoreBOM: true,
- fatal: true,
-});
-
-cachedTextDecoder.decode();
-
-function getStringFromWasm0(ptr, len) {
- return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
-}
-
-function addHeapObject(obj) {
- if (heap_next === heap.length) heap.push(heap.length + 1);
- const idx = heap_next;
- heap_next = heap[idx];
-
- heap[idx] = obj;
- return idx;
-}
-/**
- * @private
- *Entry point for recombining signatures.
- * @param {Array} in_shares
- * @param {number} key_type
- * @returns {string}
- */
-export function combine_signature(in_shares, key_type) {
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- wasm.combine_signature(retptr, addHeapObject(in_shares), key_type);
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- return getStringFromWasm0(r0, r1);
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- wasm.__wbindgen_free(r0, r1);
- }
-}
-
-/**
- * @private
- *Entry point for compute hd derived public keys
- * @param {string} id
- * @param {Array} public_keys
- * @param {number} key_type
- * @returns {string}
- */
-export function compute_public_key(id, public_keys, key_type) {
- try {
- const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
- const ptr0 = passStringToWasm0(
- id,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len0 = WASM_VECTOR_LEN;
- wasm.compute_public_key(
- retptr,
- ptr0,
- len0,
- addHeapObject(public_keys),
- key_type
- );
- var r0 = getInt32Memory0()[retptr / 4 + 0];
- var r1 = getInt32Memory0()[retptr / 4 + 1];
- return getStringFromWasm0(r0, r1);
- } finally {
- wasm.__wbindgen_add_to_stack_pointer(16);
- wasm.__wbindgen_free(r0, r1);
- }
-}
-
-async function load(module, imports) {
- if (typeof Response === 'function' && module instanceof Response) {
- if (typeof WebAssembly.instantiateStreaming === 'function') {
- try {
- return await WebAssembly.instantiateStreaming(module, imports);
- } catch (e) {
- if (module.headers.get('Content-Type') != 'application/wasm') {
- console.warn(
- '`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n',
- e
- );
- } else {
- throw e;
- }
- }
- }
-
- const bytes = await module.arrayBuffer();
- return await WebAssembly.instantiate(bytes, imports);
- } else {
- const instance = await WebAssembly.instantiate(module, imports);
-
- if (instance instanceof WebAssembly.Instance) {
- return { instance, module };
- } else {
- return instance;
- }
- }
-}
-
-function getImports() {
- const imports = {};
- imports.wbg = {};
- imports.wbg.__wbindgen_string_get = function (arg0, arg1) {
- const obj = getObject(arg1);
- const ret = typeof obj === 'string' ? obj : undefined;
- var ptr0 = isLikeNone(ret)
- ? 0
- : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
- var len0 = WASM_VECTOR_LEN;
- getInt32Memory0()[arg0 / 4 + 1] = len0;
- getInt32Memory0()[arg0 / 4 + 0] = ptr0;
- };
- imports.wbg.__wbindgen_object_drop_ref = function (arg0) {
- takeObject(arg0);
- };
- imports.wbg.__wbg_get_27fe3dac1c4d0224 = function (arg0, arg1) {
- const ret = getObject(arg0)[arg1 >>> 0];
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_length_e498fbc24f9c1d4f = function (arg0) {
- const ret = getObject(arg0).length;
- return ret;
- };
- imports.wbg.__wbg_new_abda76e883ba8a5f = function () {
- const ret = new Error();
- return addHeapObject(ret);
- };
- imports.wbg.__wbg_stack_658279fe44541cf6 = function (arg0, arg1) {
- const ret = getObject(arg1).stack;
- const ptr0 = passStringToWasm0(
- ret,
- wasm.__wbindgen_malloc,
- wasm.__wbindgen_realloc
- );
- const len0 = WASM_VECTOR_LEN;
- getInt32Memory0()[arg0 / 4 + 1] = len0;
- getInt32Memory0()[arg0 / 4 + 0] = ptr0;
- };
- imports.wbg.__wbg_error_f851667af71bcfc6 = function (arg0, arg1) {
- try {
- console.error(getStringFromWasm0(arg0, arg1));
- } finally {
- wasm.__wbindgen_free(arg0, arg1);
- }
- };
- imports.wbg.__wbindgen_throw = function (arg0, arg1) {
- throw new Error(getStringFromWasm0(arg0, arg1));
- };
-
- return imports;
-}
-
-function initMemory(imports, maybe_memory) {}
-
-function finalizeInit(instance, module) {
- wasm = instance.exports;
- init.__wbindgen_wasm_module = module;
- cachedInt32Memory0 = null;
- cachedUint8Memory0 = null;
-
- return wasm;
-}
-
-function initSync(module) {
- const imports = getImports();
-
- initMemory(imports);
-
- if (!(module instanceof WebAssembly.Module)) {
- module = new WebAssembly.Module(module);
- }
-
- const instance = new WebAssembly.Instance(module, imports);
-
- return finalizeInit(instance, module);
-}
-
-async function init(input) {
- const imports = getImports();
-
- initMemory(imports);
-
- const { instance, module } = await load(await input, imports);
-
- return finalizeInit(instance, module);
-}
-
-export { initSync };
-export default init;
-
-export async function initWasmEcdsaSdk() {
- var b = '';
-
- b +=
- 'eNrsfX2UFld9/7zPPO+zsMDCvjAzIQkkkEACuzFazexpErfoT//Ir8fT03OixkR9NmpAGmNddje';
- b +=
- 'GpGuLLVZUolRXpQVtaGnFSjXqomhXxYqKFStWfi1arKhY04o2Jr/v5/u9d2aeZ58lpHpqT45w9p';
- b +=
- 'k7d+79vt/vfb/XeNGrX2EahmFOvn5y0oheaBgvNMyJF5oTBv1RwJqgEP1Q0J5AGL/04kzwGz/o1';
- b +=
- 'Z2Qd3lShDehYlSAovwJHadDFFmZyP/Ra2Oi9R9FlSQ0Pj4u6MYFy7hgG1dYt6rnmFClosc5l8dP';
- b +=
- 'zr5V2BlDWCUdE+bG8bDuhRQC+zUvfumiW299zYtf/sqXvPT2V9766i2bX/7Kl9760tu3GA6+LSt';
- b +=
- '8e9WLm7fftuXWl2x+1V23br79DsPKEnCGW68ZuuP2a1/yotvW3bb+JWuvuWa94SJBvyS48/ZXvn';
- b +=
- 'TLy269ff3Trrvjxbdds/6Op9227iXr7zDsApBX3v6aW1/04pe8aGjw9uuuu/bFL7ruRRvuMEwk6';
- b +=
- 'JMEr97yottGbx3ccN01Q0+74/b16zesX3fbHYNCqUpy++bNr9p86x3XbVg3ODj0ojuG1r34tjtu';
- b +=
- 'U0nCAjNbXrb5Va+h6I9PkRg+GnhBObCrVc8LHKfsuYHtOZ5TLgdW2XHLZcfzfNd3S7Zf9jx3wPd';
- b +=
- 'qjjNQdVyf3nw3cALfcxzHp78yvTiU3Pa66Y0eAb04C+qOS/Aarl1xXMLl1F3Pd1yv23OXl4PAdd';
- b +=
- '1lFmVzLUrkIjNBpX8mkeABlwugjhO4NhLY9AmvzkKi1GUEHoEvl7vLXuB6BMAN9L8KpfRAZxB4l';
- b +=
- 'NpxumyLEjmOHboL/TJIDQKrQew6tku/FGM7TKztMA2UlZkjTL4FpJS3bHsAFdiEynNKhB4PfLQD';
- b +=
- 'j0Voet1LHdf1yiRD+mdZlmM5dtkJLN91fD8olwh0mURBiV0PmTw7sC1ir0SICDUR4JWJTXwh9Iw';
- b +=
- 'ZVDiAZHEMfS5bRDTH07+q5YIHEQ104bpCTJlePJ8USHJBvO9DXBRPeu0jUVHCqkIAvoiSwCcOPc';
- b +=
- 'OruJbnWRqBZ7O4HDKVIDAQK5ZRQiZXlOI6HBAFcaYA6uHPrrzChJCKKAVoCxoljumbRZRBVJKZV';
- b +=
- 'EEclQN6BmQSImXi2bF96FtLxK25Hgdsx7ZLziIS9+LKkopTKhF8+Uc4iHWmyifjQTSJrYxsNhkx';
- b +=
- 'mCQYQQkYYPiUBrnE0soWkWpTNBFpg2qLaNXcksRJafTd9yFz8EdFxyNV0gf8s+k7kQXpKwBkR77';
- b +=
- 'LH11OQREWgHk5Ry74FOzy0+GfzZR46oX+OWyvvu9nUaAQ5LFJs3UimU28267JXLH8LXJknp39M1';
- b +=
- 'zTtCslH58v8p/ze5PkRMy7zM/Tf/c+fjG6vDdwYMJMJydnjIr/1nvp1fdecfsrXrX5tZbRddurX';
- b +=
- 'kHO6PZbX/3yl77yRVt+Z/PtxvfsBRR51+9suf3Wu37nxXe+/LZbR29/rfERu6vgt17xojvvfNVt';
- b +=
- 'xu+5CwqRm2+X2A+6ywuxL3rJS27d8irlNO961ctfueX2zcaPvUYhyR2bb7/deLNX2nUf05yalaP';
- b +=
- 'mnwRf9t8ZHPf/wf+Kf8L/qv9h71+tWfOM9a7gkPeo95g/6z1onnfeHWzz3u79rfVBezr4nPMl+7';
- b +=
- 'jzGedD5nuC91snrfcG9waTweP+64PPeB809wR/GvxZ8A/mh7zVf+v9u3dfcNR7vb83eKO5L/is8';
- b +=
- '77gz4Pfd8667/ceCnb5+4O/8Y85fxG8w//L4C3+g/4h/0DwJ/6f+tP+XwV7/Hf57/X/OniP/yH/';
- b +=
- 'A8Gf+Ysf8d/vv8/f7x/w/8r/c/9H3sEg/Qv/S84+/yH/L/0PBt+wv+zs9f8meJd1wHuT86Hgg/5';
- b +=
- 'B/1DwAf+v/Q8H/2Wec//N/aJ7wv2c/SX3uPtl96vuP7hfcT/pftT/V+/t5keCv/buD8547zAfDj';
- b +=
- '4afND7jjfjf9f9T++I+y5nt3nI/bj3Me+VH7A/Huy2jvhnnG/Zn/K/43zHvuffnE/6M8Hrvb+19';
- b +=
- '1ibf+L8m/3H5k+dH7sf8T7qPWbPeO90/9b8sPWwdzg4a5/zvut8Ivih927vU95bvZ9YR4Ij3ieD';
- b +=
- 'L/g3f8B81Pl7/z+8vzDPOp/37zf/zCz/5B3bUUd979fMSycuMdJpczSxVxiRnRrpjBF+yY/tyIy';
- b +=
- 's1NvSjJ3IWGn1xS4ePbGHR3fs4xHGAR7VuIRHEJfxcOIKHkZctW6wbyAozk01M7KHyXLJZoes50';
- b +=
- 'QEetC6gXDNGIPWr+OVQs2kNmg9myOb4efdxEpDwh+O9KbWlrieGrFl30CZ6pF1c43oXGk9I7bwu';
- b +=
- 'C5u4LE+NvFYG9fxWB2HeKyMu/BYES/AI4oX4tEXd+PREy/CoztejEcYL8GjGvfgEcRL8XDiZXgY';
- b +=
- 'cS/RWB60JglFVBq0tuHpDVpTeLqD1nY8/UFrN57BoLULz8qgtRPP6qC1A8/edNc39+10mknfIIt';
- b +=
- 'gWfqmN3zjDX4z6We2o6XpF35831+8rpkMiEx60j/90Fc/P95MlouszhlN+p008buDfyGo/cz1XX';
- b +=
- 'GEx5Y4xuOeOMFjLL5EyNquyJpSZG1TZDE7lyiyE0V2rMiOFNkDQu1yIbJPaOu/GJL6hKR+IWlAS';
- b +=
- 'FouKLcrlFMK5TaFkklarkgaUCT1K5L6FElL0q9v+/pn7WayQmhbnP7wvUe+4DaTS4XIReme+x97';
- b +=
- '02ubyWVCbXf6lY/+8MTvNpPLfy5JLldkDyiy+xXZfRcpycuE2suFyBVC26W/VEkuTHd95Z0zWzN';
- b +=
- 'JLkjv/Zs37jQzSXalH/uDT7/byiQZpp/8r7/a5/5KknMkWU8f+fBP3uJnkjTTx/7lpw/ck0myke';
- b +=
- '5947l/ym3SSh/55x9sH3sKSrJ30BqDexu07oFXG7S2wJkNWneh5CpyFytyFylyuxW5CxW5CxS5X';
- b +=
- 'YrcUEt5UNceLFMlSiH3FJPbmehpJvqF4txfIs79ZeLc72Tn/vOqvzc9/OXv7RnP1L8sfeCPfvKz';
- b +=
- '8Uz9S9NPf+SBx4xM/T3p0U/+9bT1FFT/ElH/YlH/IlF/t6h/oSJ3gSK3S5EbKnLrilxTkdtQ5Fp';
- b +=
- 'aykq4SqZKlBev/m5R/yJR/2JR/5JfSI30gxN7fmAVaqT3v+FLX3YKNdLJL3/iW26hRvrHN337Q/';
- b +=
- '5TUP0LRf0LRP1dov5Q1F9X5JqK3IYi11Lk9ipylylylypye7SUlXCVTJUoL179oai/S9S/QNS/8';
- b +=
- 'BdSjX7pPT85/NpCNfq97X93+HcL1ejsF7ZPvq5Qjf7d49/66eueguqvi/pNUX9D1G+J+nsVucsU';
- b +=
- 'uUsVuT2K3CWK3MWK3EWK3G4tZSVcJVMlyotXvyXqb4j6TVF//RdS9//obZMfGivU/X/3nnfu31q';
- b +=
- 'o+7/46fcNFqr+f/3Snnebv6r6nypV//1vOflRq1D1H/rE2XNWoep/9Ot/9R2nUPW/+e2nHnR/Vf';
- b +=
- 'U/Var+499+3z6vUPV/5C37PuAXqv6/+OM/+MN7ClX//V+bffNrf1X1P1Wq/nd/8fG3/G6h6v/c0';
- b +=
- 'e/MFKv+c2/9iz8eK1T9733vX31k7FdV/1Ol6n/w2Oe2by1U/Xu2nz5YrPrv/+6h6YlC3X9u5v33';
- b +=
- '/aruf8rU/W99/Zs/bxbq/qkT3/ihWaj7j37/3R+2CnX/B3/yiT+1f1X3P1Xq/g88eG62OBD92eP';
- b +=
- '//J/Fbv8Xdv7oZLHb/6Nv/u1h71d1/1Ol7v/+/R/b4xfq/h98+i2f8gt1/85z7/6zewp1/9S23d';
- b +=
- '++51d1/1Ol7v/p4/91P7Xke3Td/92vHX4PNf2W6rr/x3/37R+/rpks03X/v//wUx+gpl/vxcjaE';
- b +=
- 'lk3RNamyLp+Eep/Im+6TKjtFSJ7hLalgzy16jZjNzIjrxl7USMqNeNSZEXlZlx+AnLHIr8Z+0xq';
- b +=
- 'FDTjgGmPKs24wsxE1WZcjWqxWbUqoKSJqeXmSsNIGmnPFhLU5GP2pjTYspmCwd38RqGeuzdvHrQ';
- b +=
- 'MkpvTjK2qUalUIgPTrX308AatHnr4g1Y3PYJBK6RHadCq0qM8aAX0qAxaDj2qgGGn02ZzhVF5y9';
- b +=
- 'VW/4Qzjgnv8mjirDCsGy7+f2Suso0kfn7NQChIkufXTITC5JLn16woji4ZS1ZE8S01sqUouaXmE';
- b +=
- 'NqukRpJdLWxDIK92uwhTTpR/EwiyUnNlDLxtHh4S+KRQshkndSguGhqb4QIh96DZmqku8zwS/4y';
- b +=
- 'ypo809pjqrxJMe8Ri/MmWd59SLbHbLYBuOSZ1qylAFxSBHDGZgCXZACOItms1QYgPWfjdbd+JTM';
- b +=
- '7a8tzO7G4/5PRiuGJsdduHf7E2w+fccaHJ9/9+emD1higJt7h2BdBHk6C1Hg2CdKJzPCSZUKpDs';
- b +=
- '5aEqyaFXo7C3xRMHqYYiqc208nfgNZKdofTR9/3N6UmOG1OZBrcyDX5kAij5NSFEVEzkqSdkIGs';
- b +=
- '7tMnx8NmvQ7bYbHiKcSPp6xkzKFyht7k0q6cmPNI7yVmpEacaVaqkSV1NyE9Q0I3MzRNfqrVwN8';
- b +=
- 'Gt8UNxAjgKFxUBN7SMELIsyVlpGEkUePZhJENQLWTLpgpybZelKLakiwgCh2mpymFgVROBJ1RcH';
- b +=
- 'IZsqBlLVowQjF1kY2EyKPdERF1kwZXYNcE7U560QYEVRJj3zusJH2pafoET5uG5V0JyL604NZxJ';
- b +=
- 'nPcoptWcQ0IgbTE5/VESc+QxFD6Y4sYhci1qSzn1ERxPfK9OSP6e099EaSqd7IOoJoiZwtCbWKP';
- b +=
- 'WaZHko9wpwZ1RRP5HnAkwmeKiwWwKikl2+smQpUhUA1YWyIN8nBQJkVUeNKssCkHlXIkVVIb2a6';
- b +=
- '6nkooFg/YsJwIPsba2Y6QXFjwMsgm0KSKVbCb8HNkRcFBMIj/OSzKukE2ZrZG3tgzItcslwKlFj';
- b +=
- 'xpapbiUrpRJPMS2yR6CLztjfFMBoztZ8HQcTmsBHHVacSBemjlNDfRG5SxYpRbLCM4fJ4FI8l7B';
- b +=
- '+0KehoKkHZl2DeL9V5viBIbQkzDWEhAfgPiDeH5OdDjn61UlDhu6FQs02hEMa8lBJQhcIjUSRej';
- b +=
- 'dx1FO9NTGiwpDRIAdJexNorAWsJ2iuJ41tJLiwJWWck1S76M6PwxhqaTU8kW5R7JV+7Vb75l1+e';
- b +=
- 'jO0K7KMo2fDnlSzlgWyJ95AqVRMQVRmBBwxzKYeQMjwgXqmKKN9IFVX5iQUKfyUCtdoEmn355Qm';
- b +=
- 'UCmQuwnf/3CJ00GA4Y4PTMsSoqj16ycRYhhi7IMYuJEWAmlkH4Mh2uE1VSanqg6NSqr+oj+GIUx';
- b +=
- 'q0jvsUf9Cbk5SiUouSdudJz0PKJ/w5SSkqtSnpIq4Dpf6q43k+SBaTy1tM/qqKqspQJIyh3SYox';
- b +=
- 'tCSExBjaJQxKuoC0/OAF/fgedyPl1KZW0ZCXBb3RtUOXrMiHhvOUvnPJ/KWBLDvybSwoMjU3Mje';
- b +=
- 'FfVHalLlVkVd24/KE7GpeRNxWNWVbJ2TOFzJEnux117BphOvvpg6lpP9t6tZNqd+rvDmVnaLRGy';
- b +=
- 'M4cJ1nQXDqsIdpgF1tqpxHXXZUvyReBtSnzU6aKb0pDWjZf1corkeN8iH0HtDi7xRFHlDRN6AyK';
- b +=
- 'ttIj/o/Y+KvHqRIu++aJE7EHmDa6C+1Nkc91VIrz34I7H1Q+LUw+og8fLPJfFG3C8S79cS7+cGp';
- b +=
- 'ZJ4v0i8v5ORU8n+ZRp5dR6JL7xoiXuQeL+SOFUmJPH+aAn+2IGRxN2O3idrs+lWGrfZnozU++Oq';
- b +=
- 'SP3JuxbC+b/RtUjH5mIlH2TuhSRvsuR7I/umWpk6+b1NilvbvN4gAai22ACFBnQ72o96kWXZhZv';
- b +=
- 'T1PqYTzWNNtU0FDFz+19V1f9aTqHllLMPlVqVFdnHLe4+tHj6oLpId7zwTdTXB/X1/zK7X/1tyo';
- b +=
- 't+UR2hPrROSgpUX94R0sp0MAZE8lwS9eFPq670i+8CNbgLpHpCJNcQskWxCqn4XGRPKPzf1RMKq';
- b +=
- 'VFJ/PyfWk34+z+sNBmR4LaWqTqYkJOnZVtVsqWk1LCqqTYbBesFaZOxmLCPOh4BSz6GCgIWtDKF';
- b +=
- 'm0nfXkd5k3lZz6tRU8CKlhHgqBeZIVGATyewucJLGYGlEVAjtwbm1hhG+jQqFcgL24I+SL6INrm';
- b +=
- 's18hSo96NtToJwmqmayMPwzpVIEvXUQKSRS9Mz6L09LUXX2EAyyLWZT1dCyjSgyQPQcWMM9Pn9P';
- b +=
- 'ysap2nZ6mdni6T5joPFTSK/Z+5n/sv/Ll64c8t3VYqG/N2aSObqDwz2/lbX1sXjThCy5p4fbqJw';
- b +=
- 'cVlMrhoDfJI3nS5ucJoCN9Tn/mFdOyo8Qc3V9Vd52reG6lC3HXVCSFnPoBO3cCT6SVb//t6yejU';
- b +=
- 'VX9xnbqBOIT4Bor94oFchAMQYQgRhugXU77l7MiWYwBh+VOgfzzw84oyG7xZDhHaqqZanotwOUS';
- b +=
- '4HCJczoPH1APNe6HPZRAtJZUyFItiufg2udLqnbAxLD/jjSbuxQ3Ly3B8lA3Hx9lwfILh+ChKxq';
- b +=
- 'IIg/ERxuQdPfzuRtEzrWrk8gh4VBwBf4g+ktONshHwkN67C4PfbnrQLAx+u6h+D5jyPGbx4Hf0Z';
- b +=
- 'Aa/XdJsNtLtpgfMeUa6kS4f7FaD2py+OKjtRu5KIgOD2g9TTZbudpsKqGpY2XGZJ57KIzUWMEal';
- b +=
- '0C4uyRgS50jv4UmbuIxY3nDHRmAWioQnRQL9lULLIvKYUCBVziQC0CB9TMqGx8MH8oErLgdtL5L';
- b +=
- '1A1FAJrktIVXs/O5Je1KZJbQmMeNbkcjskKiQJI4I5D2wZC8dFxNW7bGK9FlUeyfKYClIBAfG+J';
- b +=
- 'pmUk5LzyW7ISE+7KF2H2EbbhsFVaaHsaH00KcPG9J0AoIsH7W4IDb2JyYGfIvC4yqYux1l3XTw9';
- b +=
- 'hPxQc1slR48S/re81S59bbUfZk4VXrWWOZwRKpxLlUCPZkkItE4SqKoKM38o/rEzqSzFMF0QY5x';
- b +=
- 'BoVgsAyZf4jbRPAhk1wWtXzIHdT1/EmdRVLH/EkdEmggTs+flOmvivmTOhrwaFCWhUEUWbJ/br9';
- b +=
- 'X8/Z7JWu/l9va7+Wo3NZ+L1PbqtLafi9L+71MLexyW/sdbVhqv1fbpk8mP982fXLuaNv0yamjbd';
- b +=
- 'Mnx462TZ/MHO3cSqm3tTYaN2aFqdreZRCnoXsM5bk9hnKFRXIjt8+4+hNI9bzHUFctCBctiIfRM';
- b +=
- 'i3h76ImTdilZD0GscGLmDThYT091+AiqibzZightSeqcdkCxKm0jvDnH1pqt2gsiZ5ZMAgdzXVn';
- b +=
- 'lNW383ypzvMFQXY0cwf4609u6qRIX2xqwIXaN1K1b01GpFnptbzyrUGONSiwhnoLA62qxjiMjsr';
- b +=
- 'hxHt2shDyjpzRw1gMEHmjkT3Sm5R5dqWCDGW0XVxMvzxiE4LjVlt1wVE8kN2t65ZBaxeF0vP2nK';
- b +=
- 'QUxQPZi/KknSsheaEeUKgQUHCBAkDBLlUN8TC1BDHovVh8CvWwGHhcwvMRO16C5y437lHuh4ew2';
- b +=
- 'WiXxb0XaDrUYOaGHtOAYOMA7lo+U3YqSjfVTF3Y2DmwplAIb4RbrEVL8cfjEwTL4Q75E46YA95F';
- b +=
- 'DJr3c4mhXh86YH0yWlWVIQ8e2mgb7hjgYRAkkeKgHGdhwKpeHLCqssN0ModZjapI02gZsKqSCOo';
- b +=
- 'j1LrLfWY1asDHVMnHVNt85gD3JJNay4BVZrQt/mtxy3hVda7/qlaYQh6vcjGk8RCGw/ujPh4LiX';
- b +=
- 'rwR4IbkGGpARa7iNwikXddpMhRaMvo1Dn06L2ptpAHwaiPS2+j3AleOM8wYi0ekGHEAa2YAShmu';
- b +=
- 'VLMgChmAIrpm6uY8/b/qGL62hSzfH7FLLpoxfhQzAA3mPsxaN5P/Y1oCf50cfA6FocF/53iUBT9';
- b +=
- 'AI/9zSkTyy+uTBy3fqll4gKi775o0ZeyMoFpiSZE30eVdx9X3uzVAnFnbaIPf17RU+kT0de06Gt';
- b +=
- 'a9HV2qCz6mrb6eqvoD5gtonfmir7RLvqBOaJ3RqJGi+gH5rf61iHYXPT1uc0pdKMuVvyVrMrFJA';
- b +=
- '3EjxEyDKIbMojerwbRWRXFVk79ybVyak+6lUNim6eVM8+X6jxf5mnlgHeMmE0f1a2c2vwjZnCt6';
- b +=
- 'YGj8w7SDVx4DK/vwp9rT+Lz/0DrK1oWlWFpZPIVtKlqLW3BWutITFtDpMQNkcJiIvsiFhNJeRJD';
- b +=
- 'sdoM5YA5x1Lczpbizmsp7ryW4l6MpVjFBS8ddeA+CR2UdB8G5bTDAiJuwR6zqFVQwt9/qw9z0a7';
- b +=
- 'wcXNT3TJMrxJVbqy5vJKGwNmYJcbgOw+sk5twVdvCluWzVV7MZKkx+7I0LU1emqM45n5cPlofyN';
- b +=
- 'C9jNFT+lEKRmXMjAYyEI8hBW6kuEJZmaxnnQzjyMB9upZgl9kpc1AN4JdVPr3qK1rI7R8bDdhqZ';
- b +=
- 'DI6fCijV1a6wNi5iRXBn8sG87Ay+Gih7JPGKvlgebkwWO6mM54MliPTDp3py71WMrEEI4A7LF6Y';
- b +=
- 'GznpMQOjYwewHgeLjy0JYqpwpXVn4vJ8jIlJtA3k0y/D4/nJ5ePJyr2JhZe7klURvV6B0TdoyRq';
- b +=
- 'JVkrYx1TXBuuWZGW0ajy5ci9qIXMkupK/8qzYBuue5ErkXk0frWhldNl4soaCJXx6QXIV8l29F9';
- b +=
- '3E0kh0tUAlgQHHGnmrwiBGotXyhrEQf4RqJKroFIKxZDUQXM0IroxWjidrGcFVwLWOqaRUv52sA';
- b +=
- 'a5r6D0kCNE1Aq+LenaEeZ28LRDMa+VtIdWS1RHqz9dGsNC6MpIRc7VisNZCyKSZXA1K1jElq0HJ';
- b +=
- 'NYqSK8eTa5mSNSBqPTNJOV6YrAVRG+i9GwMrGwTxIurvEInr5W2xkHitvC0REhX5PUTdwhEqrlU';
- b +=
- 'isREtYEK7RiAnJnSdIlSo7CIOFa3bzGQdaL2Wab0atK5nWldHVwlBoJXIHmRa14LsIdYGZX5Jcg';
- b +=
- '3Ivo5lRBK6TohZSpZPTAzJ2zJhYlDeeoUJxWCfMKEY7McqES3nrmgJ/S6IFjMri6BqYeVaxUrGx';
- b +=
- 'yISjeJmykyuBTcbmJt14GaQubka3AwpblYLyeCGGHsac3MNGLueDYvgvCxZD8aeznKujURP11KG';
- b +=
- 'gKPr5W1A2HyavC0XNpUIImFTiSAWNpUIEuKtHy2vOjPYR7+Lol76XRwtY2aX5sxu6MzsUvDr7U8';
- b +=
- '2gNlBZvZaMDvEzK4Ds9cxs1dHa4RDMLtaOASzVwpztWg9+H7GXnhMd39yObheRW8ummqrtAI9yO';
- b +=
- 'AZ8uaJDJ6u1ckyuF6rk2XwNK1OloGSyCUiAyWRFSSDJJdBzDKIWAbL6XcptUQhiZ5cEoOdJdGjh';
- b +=
- 'LEB7K9SkrgKPksksUbk4xP7V4t8KsS+soAqsa8soBZdDklcxnolbi/TWmVun6adDnOb6Zi5zXTM';
- b +=
- '3GY6LhXc46XE7Yqc20uY237mFtrvYe0vJZGDZ7KBxBOeV3UotdraN4DLyxTDa4R3MLxWePeJS2L';
- b +=
- '4KmZ4PRgeZIYvB8NXsi1XtYPWBXZQO1rm6yqtfeZrpdY387VK67sRXYoC63GBTeboUhzm8twPXa';
- b +=
- 'Y48tpd0QbwoNlZq9m5Jlqn2VkPdq5kdi4HO1eJf8zoXCxUX6mrjiLV/S1ULyeC+0bYqOEre5n2Z';
- b +=
- 'Ux7NSt/1VZ6awWSQezanNhrNLHrc2Iv18R2FWha0EKT30ITKZ/EpPx3nW2jgYqGqCEHmFRaqalq';
- b +=
- 'gkDKNZqU9dG1mpTLNSn1AsZGC0a07ZaOsOKbhNxnXFRvEGEtuCqMDojWa0SXA9HlXB4I3uXaL1S';
- b +=
- 'Bq6IgNUaAogWSibwWHItJKZvhBx2s0V1lB0PWLCbkqel/xJQ5+BlTVgY/jOeiQesQnj2D1kE8B3';
- b +=
- 'iO0MHGpYfwXCJbc7CvDTt5sM8Ny98xEb3blMXIu/AMeN+WE13xTGuHyQ1IahHx9COfz7lMrf+YM';
- b +=
- 'W6qqU/UAMUCQd2dHcxa19g7RV/CpgJBAGRN8THOETbDAzYw0J+rVlRhFLJEfz5mXegPsy8Wzx5O';
- b +=
- 'OtQFSSMKLd+UWKO8xvgY7wdz76aeCrXPV2LT1t1xaZ6xVzv9pr0x8dFjRvseWQREU/r7pNLylqi';
- b +=
- '0mTpDPODg38hdoyJlvnR72jLGPsoRYfYVno8TnkonPEFTppAIj7+ZoDGeShuedhycCRtOKsBRYQ';
- b +=
- 'zvIgzVThiqjKEKDJXNBMvmachMwhWe7WpDwHl4rAEIqoqJx62NSa0TipBR1ICiulkvbawVmGiHz';
- b +=
- 'xlkEJXg10QVBN3rBL1bdY8Iem0zwSIGPMUAiPfagXN6Xq0E4J7WAIF3O4HvYfAuwHubCRoT7yri';
- b +=
- '22FzYsJLfT2C7YrkCXK9E+Q+6coBsruZYBHhdSIcRFvtgDltHKDDRYB5+TV1UlZLaV1JD2/QWiF';
- b +=
- 'lPZLlin2y3aiHHrz3kLevhARvn9kcNoZsXg2UB3dlQTx2mKrQRlJmd+gyG85XZKnfQ9xLUgqssh';
- b +=
- 'VcxIc6PmyND3R8kMXDb+0wh+y7SHDosVJRjW0eT5h0RnCabhqmx748o3pzujxLUY5tRalAP4Vkx';
- b +=
- '71IYVPf7Mi8m3q+4Zu8cBs6aTss7Lb8DPXZJkx06sLRxGxd1REZ6X+YhDt8S5BYaRBOebGddkuA';
- b +=
- 'BCIBVzyPeiWCRtnfu4TPaTZH0/OPv66ZvmZTuhW+mr6M9EbGc6mXbJAMBYKVGiutqW3DN9YcghU';
- b +=
- 'QXiudtAhvujwmpWOYxd/IC9zIbtPg7pcmxig4IRDmltH0mU2yjpQ+j/L4C2wnPTv5CZn2t9la8e';
- b +=
- 'fAsKwoCCe9LUw0R/LyCTt8axB+2gfdIzwhZ4EHD8M4fuxFdkyGxHAkbMfYlEXC71auEFkwPdd/d';
- b +=
- '+ps0oXevrkXH3pj9KdNQhnZN9Z4i2waCvNKYq9rRsbGXiUK6wYIY9u24YTMPLXvTry7EyO1MVOs';
- b +=
- 'NDLxarBONTV93pLY6bbXK1YN5TKJyPTReyky4SFPesWWWz4MOaiijJHuxyPrNZsGgQdDAIAUfoN';
- b +=
- 'UEj5K/GKvHKtk+7bh59bstprBgCBYXYlxY61Mec56L2sVuUhT68MOf+IiKYaWjOwThpdRdkcSpx';
- b +=
- 'fHVcNaesmMDU7Ng0uAkxBx4U99CD18AwZiRGYj2ABEn2Mesgi/z6DCez1FNVVcphp1SZGJKkFvS';
- b +=
- '/gWoPG2bALBiQfhOXOFh4IkwnMgPHqF8BzIUISn1EMS9IoSBA1CKzgj4ODRLZBkk+5tDOncs0kQ';
- b +=
- 'wAZXWju3DccsYq32gCj2SfFbEn+TWrIScO2HZUdUEzLKyI15fgdUwfZEwa48fJBqgyoqLk3SK17';
- b +=
- 'sHK+n8VpFvH6K4SLgZWPD0HsQ24KXMCi85AC49gBe3q6ORq0nDxDD1jUI6ClvAyfOtVV5Ld88/l';
- b +=
- 'bhjxjKs6lEwboiZzOXNIfICaAzZWybYEL2XGuLyRcaqDpszqwtjPRoPQ8UjlLIG9mUuL2wIaweZ';
- b +=
- 'nPLrczhkqW1ZIgHYF2OPg8DZE7BCskayArVMKO2REOr32YT5G/svThiO++n93LpO0Whu2yeELrH';
- b +=
- 'QncgdE+ETv1lJXQn5v0YrOysNDsthTpXthZpzZwzkK2ZpJTP00zvEKY31qRSY7kSO+TwjVFyNmC';
- b +=
- 'xqVy+dli82Xxy0qFg+CcOaqiVloMGCjc5yhW8VzFVD/i7iX56DxK3mVDVuRvKR/w0igQXe/J9g3';
- b +=
- 'jNadyFqsBIz5K8YngN6OsH3k1U5nGAPfSGmWGk3CdeCL7EGKk5WLVkhLNothrhZ/wowCn0hgIZv';
- b +=
- 'sutOaoAcz7K5An2fbBsHKxgK6TZEgOckY+ZIzNHjZHzFiQ3ccOFcRQAcMUi2XlRMnGAkFXJIKG1';
- b +=
- 'A+ulL+SJRMZJaTR9eTNmuYgifY6P/FGSXyStAFbCSG/io2CV0QWEcXItXZFqpKpr6Zqupesp8wu';
- b +=
- 'IDYHYGE1CuKvGICinz+RQ0FGsRrVmMwqbowm1ocg80GtMTTJFBwiqGm63hqsQhEhH8KIQo21Rdb';
- b +=
- 'TZpCwk7snJSZO6UQQIhH6fCvQq6+y9w3FXVOZTC1ZZj9w7PMTLvbrokfJJEefvVQ7k3L3KW5zlA';
- b +=
- 'HW8KDUUkzpgGqaxM8DQtUdCw2RkhMYS+hiktRIeo0qacB4/9cMPuVyL6hJqoISSzRoF/1gsofBD';
- b +=
- 'BpdQI3eLhqpGIyNzi0ZFiiaG0vP6Fg8DJbSkrltw5FgMaBK3MJDEmXaoxVANLPIx9ObKmw+okTH';
- b +=
- 'K4zfigjxd4fmRy0ZBDrg5yh0/beo3abPfiTDq9U96NelwGXCOjmLfIG8mrXpDdYbQLJOK0L+JW0';
- b +=
- 'Jcp7hSp7RWfw5JJasBqbHSjC14YDbFqg/52MqylJ+hJHABCNloum3WrJPXKCE9fG7icYpUs6Jcb';
- b +=
- 'yKwIFWVUde5kj+o6EqNHSGByfyzHWnvnVU7QttOgUc+uw0YE++xW0A7r6gqRZXmyG2GP7KqTiUD';
- b +=
- 'KHRvz5jdLswCh+JUXJBKzEnR/k1VWhCSN8RsPomF3thorcxoLTJaDc9GYy2zXaPddi22XYttl6/';
- b +=
- '/sLTtWsp2DfSpDLFdS9uuIQ+u5xUiC4Q/vnzQeogFOH8hZVIGranXI4wGFmn09Xn8Ng5v5/hdhT';
- b +=
- 'TbObyTw9OFNDs5vJvD+wppdnN4D4cPFNLs4fBDHD5USPMQhw9yeKaQ5iCHH+bwbCHNw4X4Ixw+w';
- b +=
- 'uFjhfBRDh/l8IlC+DiHj3P4VCF8ksMnOXymED7N4dMcPlcIn+XwWQ6fL4Qf4fAjHJ68Lw8/KnLm';
- b +=
- '8BTHb7uP5X9fHr+Nw9s5flchzXYO7+TwdCHNTg7v5vC+QprdHN7D4QOFNHs4/BCHDxXSPMThgxy';
- b +=
- 'eKaQ5yOGHOTxbSPMwh49w+FghzREOH+XwiUKaoxw+zuFThTTHOXySw2cKaU5y+DSHzxXSnObwWQ';
- b +=
- '6fL6Q5K3Lm8OS2PM0jhfhH7xtGJWnrLrKqJH1dSQZ5LSzunlx7UoZ/M3QtbKMWDuDeqRYuN7VDR';
- b +=
- 'L2R18LtCFyNAH1RD7UweW40GefWwhXprmctv+ei3fZzuN4KLy1YQWgr25ZbFRlKOGUTNMRhYMQM';
- b +=
- '/956cscLrDF6eL0FBZaizk1dHq9FW/mQ2Qy/4sgpVfR5GbWPvm6gaein/0VPXkWbftOmBurrZ4z';
- b +=
- 'wOXFQ7eZV6H1Y9c5uFsySKJzqQsyQm4QLwy3+9UYPb+Z4XFZlm+EHPF6wRKGDnlT7qIwJJ1YZXW';
- b +=
- '/ssTDETUXFEqrod5oa4C9D0kMmaluEHjYTHjkgnzIDZ0I0/dAiosKK5J5Efe6lM2ZzFdW51P7ZZ';
- b +=
- 'ncE52XgAqzsagfXADjyyDuK4IasnZ2BuS3ArHZgdQVsuhXYnlZgdwowjCbfVEMvALDsdli1imCK';
- b +=
- 'Sx0pcVoocTrlBiUHWik52JktuwWY2w6sqoDNtAI70hmY1QLMawdWUcCOtQI73gZMzJkBGhlArAP';
- b +=
- 'x2wGSOXdhUiOm596YKt30FJ/qBUi2GteG7RIuHT/TGn9Ox+9ojT+m4w+0xEfeKtLwkH3KkvAMhW';
- b +=
- 'dUeAeFz6nwAQofUzaO0UpqxHYBmIZ6bA7UY5TjgFVdoFUfVCRZeJ57h+QT5pbmoL0s6pLo6ZIY5';
- b +=
- 'iUx1CWxm0viblUSd1kYsKekhiqVqJjUc0Y9j6nnKfU8p56TNvqZoJJ+d5HqbrmQdzpma/f0RZsc';
- b +=
- 'UOmmWofNcJFfD0xckuj5AXoHDPaHbhLcWFtE5V/MYRpD49RomEF18FFbeQZlQsiwyxX7ubFWV0b';
- b +=
- '1oCcBEb9opSj+Q+aQPW2R2xMMBxjDcWCoCIbGfBhqolfBcODCGEjBCxWGGcbwTWBoCIb6fBiqYr';
- b +=
- '+CYebCGGZgQvogiO8X6K+1Qn9rBj2sVhRJx5iknyCTL5mq85FUliIiJB27MEnHrExxpxjD5H05h';
- b +=
- 'sp8GEpSmAXDqQtjOGWRegTDOcbwe8BQFgzl+TAEUvwFw7kLYzhnkXoEw6QNDG+6Lze+0nwYfAxq';
- b +=
- '2QrDpH1BDJO2cvvTFjZR3oypPq4dzLimTf3hDNsODUxMugCMrHjI3mFrM8ZMEoNQtgwQ9N7AImZ';
- b +=
- 'e1cm78Kc1uANzwB0gcNO2dskzVlLhDr3yi5lBFrPMUBaqfKo1kzF/fy7mqlvhT8r82z6JLVKRJ7';
- b +=
- '8UYAe49tqZrRWxHSNsM7a2r6Sh+FVGxiKzKpnLzYypCOIUgThma08FI0pqwqXoKrOPJCxmO0fZD';
- b +=
- 'pliE1Q/WdoogFO56fM8LKnMEfGVqHYjn6uhXDuTtsvsKMv0vNGRZMzIzacuyH6XmbN1T67FfUzq';
- b +=
- 'LhvoqdfPRFKD1ka9sNKasuMGntvsGCRNmR0Fnp4RksJ2DUyZuUxexmVuJdXrJHuyr8aNAA0dKnl';
- b +=
- 'AP8rNaNVXxKQoARagxsoo+bV+I29k3CHZ7byC5El8E1POBYOmv3KxpKoieJ736tVEu1S8ZFiKy/';
- b +=
- '95dfAH20/+6VT2qSoGmX86ln2qSKHIP81kn8pSAPNPB7JPvqrENnP8tMSnPMuv6nOsj+2hqvvNF';
- b +=
- 'tfNR9m57GtxHOkJ8Titkac5cqo18hxHijVliqvx6g5ujz1sSlvgkFLiPnMIK0A4vIvCx1R4isIn';
- b +=
- 'VfieIesMGiOPMuwzrbBxoyjaF7iSE88GdazxLFGHGU/cHCotJftlQ9YjMjmA1RBwGtL/0WUvPcZ';
- b +=
- 'LOrBniQSEeg3bX3eQzL4trSUuZ9OOfCWD68oaz+xOMFuhDKbq//eDHZpf7T0jdswzymhza84NWd';
- b +=
- 'twJbfJjkr/S7Og9HNWB6W3+QNReltJFaW3eefK/EqnkpspnTxHpnQq3ZnSybsUtd7mfrTW0SGbR';
- b +=
- '9vkh1jdamaY9Wnm+pQzrGpGZxMw52q7IlZjiK/q0Unl4GRHjlHGuDOJOAh/7Mdmq84A8JSNCf1/';
- b +=
- '6rOq0gs/F+heeN+Fe+FoyfbpJm2/7nFPOmwkk05Lj3ugY4/7B8TbuXu5x+0rnxl1tKufo8eNnhq';
- b +=
- 'kgA4cqFI2yj22SUf32LY53GMz0pn7Ch0sn1sHEOUp6bFNOqo3kywYsk63QvztXC6AXLcN04Kvbw';
- b +=
- 'fJNd6+oCka3u0QT+gF2oaKDhGN24RLLdGs4O3Y86yj0XLa5lC9Fsylo5UGqyMNs0JDjn1WsOd4j';
- b +=
- 'xHSOehmW9HdKahIvxZ3aNiy7U4IIWWuyfLMzbm0Oh1pnfKQZRuElR4XE38COG5HOCcJTkcI2h6M';
- b +=
- 'zB4q3IOfC2QBd7ir0YK9MLT0jK90I0pS63IkPmxmOm2J72lmJpDFz2o4s61wZjWc2VY4sxrObAs';
- b +=
- 'crr6CIfuML+FZCs/6RdONUX+ctZoi1VwWuzjqZBaF3rXozFduAs0PV9UF7cXcnq8rbj5xV/ygL0';
- b +=
- 'X0gM+Hu3HX+pAvz6kgo51Hg8gEeD93Xa1e5O3u3AuflRah3wz/71w/NRtoR/WZAJOjHfre1PP2V';
- b +=
- 'c+bO96ARB1v8q+NrId4yG/tePvSfxMzQgbp+0w60n875Ku+zyFRbqnY6ZmksnTIl25VubW3Lc6w';
- b +=
- 'APZtGVgcpKFXNOadZ18q37kZan5ucgHMxGo1zwAmVYwLEBdkcVHAoTM+95WqHXrWPttJAfVbNWp';
- b +=
- 'PmY90a1iEdeSdRZFyJa/fmvdBV5tcDoPLfklVbASqHvlxWC1nSyLzvq646wuBc5ULKICrEbguEp';
- b +=
- '8oeCpo7dz6YvCdFAzvPxUoBU8FnRU8FahidAhz8tSrDZSHzHu0CsUu7ePFVor9i0M+9WmCgqWWp';
- b +=
- 'VlPpULZzHstXZ3BnQWqYskUeyhQdUoWc0BXJ3MrE2lmZBWU+JnM7WQ1lPillvigmfmxojua9QGW';
- b +=
- 'ujU15TG04WZUc3djDtUn5lB9bD6qZ4O8hvG5i6RrN239ud/UDJxpZWBWM3BmDgNnfGBQTbNCdx7';
- b +=
- 'VgTr8Rtl0HlnLLTOPZAPjkdy8p6wqplN252oE8Z2qEcR3qkaygYK2amTG7lyNzNgXrEak3SPVCF';
- b +=
- 'pQ1G0LYpb07kBK1a5A9aODmPuJ24O43lLBHJtbwaj2rIx0HA20DKgI6CEBVe9gYWexZKoiJ73IQ';
- b +=
- 'Hlk6UXC10qHIujUi4Q7nuZSLJIGozKWkEWGeeSBLLInj5xx8vHzLHI2iyxkh41ji6MWr/6AnsBO';
- b +=
- 'LDuqU4/AkR7Ddke6JVOOVILbHGlxTjqqK2IPWbtUeIbChxAOB62TjvQrT2Dh4CmmgmSeSRubFg7';
- b +=
- 'A3R101bhc/on6JdtkGTfLtMTlsq+ZVbTUu2H9lFiaUUmGCrd53EXR3j58rydftRef7VDLzHaoZW';
- b +=
- 'bnrWVmUcuUdY+Vi7LVubnR3kVwOuv9L82C3vNyXdB77gQKes89RkHvs34Hvc+2Zj/mtHpM1jn1F';
- b +=
- 'HYoHbOuq/PrmhxNpmvymqLrstLxyUzHWZPtQKbb42265ZFTpTwzVx73L0s1o7O+zbmqrYiJqP5l';
- b +=
- 'n04qHUtHupmqf+nP0788F6B/ef/C4i5gewXWpMku4L+01BVElgQJEy5yShw8tpuJG9nYBXwpHs9';
- b +=
- 'PLsOGn8TCy10Jb95dVdgFnG0BMpHgluRybMa7QvYFj0RXZLuAbewCvgK5r1QbiS6VDcEBPr0gWY';
- b +=
- 'N8V/HmpCDb2IWzxqxs36/aCXWl3qqGMyX0/ltGMJZcCQRXMYIr9IbgIFoDXGuZShu7gHlb7jreF';
- b +=
- 'uVl+35DGEa277dLMF+tt2/Vsd2spjaJlfNtWVe1bMvShEyaCe88Xqv2I6sNwaDkCtkQ7EWrQdS1';
- b +=
- 'zKSNXcDZ/tuFBF9vi+3GmF6273eRkHiN3vXGJK7Te4L5FGXZ01XH/l8iNMx3s61t2a4c8u47pnW';
- b +=
- 'bmfDO3muY1qv0huCAyF4jBIHWK2RjbTm6GmTLhmAbu4DX6b2nCwr7fnuiCpgY1BvcmIkN+ZbSIG';
- b +=
- 'OwV5i4Vm8qrEdLtJxD3v/bhf2/xEp3vpHwmnxrpPDRzVsjmZspM7lGb6+2orV6Q3BAjKntoODmS';
- b +=
- 'iEZ3FyhNwSvA2OyIdjGLmDeVHs9yznf97ukZd9vv7B5nd4TzGwO6Z2GzOag3i/KbG7Q+0VD7ELU';
- b +=
- 'm52xC7GbdyEuwv5DtfdVMbu+M7M9fPLC/oT38MqW52v0huCA+F4jHHrEt9rwCmav1BuC14Fv2RB';
- b +=
- '8Lfh+Ou/7dfYnl4Fr7B50IjfbPbg0cgv7ft2Wfb/LRAZP0+pkGVyn1ckyGNL7YoPCTuhLSAZxLo';
- b +=
- 'OIZbCcZTDA+2L7WRJLckls6CyJJUoY66PLhXJIYo1sUgxk5/MGlgTvAx9kSazTFlAh9q/QG4Ivg';
- b +=
- 'yQuZb0St5e27PS+Lt8fWy7omLnNdMzcZjoOCu5xBXF7Sc5twtzmu7+XsPZ7SOR6D6orPK/sUGq1';
- b +=
- 'ta8Hl5cqhlcL74Hsdb6cGea94GuY4WvB8AZm+DIwfAXbckU7aF1gN2hHy3ytyfenBhkny4SvbE9';
- b +=
- 'wHbuba0x5yPt/W3UpDnMg90OXKo7cdlfEG5U1O1drdnhTs7DDe7uvYHYuAztrxD9mdC4Sqq/QVU';
- b +=
- 'eR6r4WqgeI4N4RNmr4ymVM+1KmvZKVv0orvdUCyabsSNbErtPEXpsTe5kmNizQ1NVCk9dCUw9OA';
- b +=
- 'dP+u8a2UUdFow5AKLdSU9EEmbL1+NJ8Q7KQcpkmpVbAWG/BGBCynhFWfBObGLJzI7xWXGVGZ8oe';
- b +=
- 'Y0F0md55XAW8y7RfqABXWUGqjwBFCyS1C9jFLuBAdgHbka13Adtopx3BU+aJ+GLKh9XtlYfU7ZY';
- b +=
- 'H1S2NB0zZWvGQuu1yn7oTd4+65XJa3dbItzeW1O2Nvrq9cVW2C9iefxewrXcB2/PuArbR0raLu4';
- b +=
- 'B53T8BDENk4317xxZYiyeW8XHMJjfDuBtg8UbBHl5Wv+v4DWiTS85V1g79Kovup/QrhSc5PPzxn';
- b +=
- '/3ZY1a8FI1AO508Tv1a3kh4rzU8I18QH/F5L7awiYbdLQn592XDP/rE39zrjCe9fDAzRT8/oWqk';
- b +=
- 'b/jIx79xvzue9LOqIr7d+QWJtz8ZGE+WS1yfzhrprM9J/P1JrLMmOuuy8eQSCcc6ywqd5dlJsD+';
- b +=
- '5VGe5TGfpI2OV8KU6y0qd5deT0n5qcqosV+gsMbUkJbxKZ1mts9yQlPcna3SWq3QWcu/SoEOa1W';
- b +=
- 'TVFLeKWmmcbY2Gsi5LspIKGZ4rEhxQSd72muxTRIVJWkx1PqeixuV1LRe4OpfgdXtVfCLNmVp0N';
- b +=
- 'RcYpKxGq/fm8VfpeIqR0i9nHSBlJVq5N4+/QsdTy7VCFD/46SPvd8QTIonyhEjT4LxE6FpOy2cK';
- b +=
- 'XL43/7Jibx5/mY4nZ1UhaSqoq1SS7CiKCtqTEe70KcOXNUZyEIRofQ78kgLwqIA00fHkzhqkaYX';
- b +=
- 'oUpUk8xMNdklgsYT+QGWkhaPrcuDLC8B7C0j7M46oVUpWqBDFmqM4l1MUwE0JLwT8GaCNrf+3k5';
- b +=
- 'CMW6hbGA1o61jFtc4ybVtruOLp0xj65Kwe9H7CHG+vmE3vXqpzB9oi47aSN6DfB9gql+nky+Rz/';
- b +=
- '15q7eTlKtYlQCxYlSB+VPgkIJFImWW0kMXaHS3kmrmbWV5MtQuR32o2Ph88oYUZF4Q8UBDyskK8';
- b +=
- 'qxVbQd2ptFFWuB1uUbDWl3CEJ52cJkppxqBiJYgWwh1p05DITNxiihHZBHmmzPy1f1KJenUmJaT';
- b +=
- '+Nv/F/iwXdFTwW8qH1aIGKFMJLtGaKToz5bVEdFSgM2zKp9UFoPJqFhe+bqotlcvAMTdKx/g6wM';
- b +=
- '7CYidyGZtUnVPCQVhRX+HrCu10KP4SVQMjpsYxSSHl8kLKSMfDPRWMis21PhItUxag4XTlYJbux';
- b +=
- 'XYuKvqJ1Zt7t/69udfrLXi9NYX4BoxC3GMJESlLCBvAC4BWFTJcWgBU0Z6ujqYCZWZltGWOC5kX';
- b +=
- 'qmiK8Ef2R9b+McrEfKpMkAVF4hA5Zm7/GDVml45H3RRY+kxpMWgtRoso5VI+nG/pM6VRoc0hqhY';
- b +=
- '/7ZNPIs9ocfETN02WkSUV4rjZgjcyYI44mEXUJOJQFlEHgc/kFpC6m3vabIYHMWBzSJ+EYOPsPR';
- b +=
- '3MTk2w8Zg25ZSR/IwEBiAtGsAzmxuw6VGeWyMrXf47DzEJBuPfG1utbZ1JPjVBoOTj1hIf6viwN';
- b +=
- 'T7Q8dm4ODf4prH60OTW0qnsJmy2wfBNODpg+d30lA30FNisTkKwsXybWlQfDq1ABrbWPsG103Kr';
- b +=
- 'RTW71aKW3WpRx60W1ag+RqZQxb0WVAEXLpmuDz+u/i3/zRrf+Hm12ZOYOIEPZ/vVtiYNMIODB1/';
- b +=
- 'IjV199YXbm3jpXThVp45D/esRRcjHyckZQ32/R76Hbd8nJ02VYEwSBHMSaAzjksCZk0Bw0CdLfQ';
- b +=
- 'qHJ/5v4o8m7uhhymc8u+ZFzvAEDhDrmiLeG/cN2dgRWv/Nmg82FYdy0AWJhj9X8TlIpycigpIeM';
- b +=
- '+5MD+x1m+nfh69IzPSLhtyK5Wyhlx2fP2xA04kIsHEfn5vVNfys+5KuB5IqaThZMJ4sxLMbEpoi';
- b +=
- 'T7dgfAwdRZ2hOp7wh8Vj8ZJooYrFkNA4ClGkAY8xywGuA4l7hk3eh22mu4D/atNojqbP2rQ/qT+';
- b +=
- 'QLB2eGIsXwqNHmoLGeNJVgJsjZgREynhS7YBlGX1qjMeNCEDiXt4GEHcR0rcrpDgfk9KEkb9fYa';
- b +=
- 'IKoh+duXFSA70OtDOKmiiJxqJwDpvL5xKQxGPD5hiOsMIFKOmOvzdGZP3ftl8bqcm1AJOf+OrVO';
- b +=
- 'I4jSDEIz3dyjGBHfcBfJAIb691qvZJ6KS9S2P/PjkpDgPhVUiiQp4EltVKbR+lVytMGhXWytMyb';
- b +=
- '40sbkwAR1eySh4e/1nbJw0Nfa7vkYffX2i552P61tkseHj3Rdkf22Sxi6tMMdN+n9VG1DsbBe9T';
- b +=
- 'ZTPToaYaHnQvEw3bTY1/VN2s5KSZvpt/oKSZJwHgTNs1K+tAJJuCkJiBaEvXARpdHC+/DsmE5WT';
- b +=
- 'QuUQTZ2ljUOxYtG0uSrdQeIbV1IVUjPxZf7Vsn8K+UI5ZwAkdkytnHJtpKfkpt9wpOEcW4AYn7z';
- b +=
- 'lHqkEVk02QlY0n4m+SuCOnNNUsdfzpsxjUCWcMWbxgmTiK1GBoZXZmMGpYDoC6AqiNTQ/oS18iY';
- b +=
- 'KQGZNlGZVF+Ajdn0spUcxNLfinHs3/JoyVYquFFtLMZ5k0tvISe5EH5wYUTJebSqmU7gEFRAotZ';
- b +=
- 'NdWxrvIieC7fGJCCCFS8Y5jsDeXXr0jFiYuEtxOwC8sEEvTr2W7yKGpt6wSvWtDCZi+CjuzQZC3';
- b +=
- '+L3BSh3xpTtU9Cx4cadjHLccrbT2QHrNLb7vxNeHXT8kgM4OVXxi4v46uk50j/6dL01Fe1Vruic';
- b +=
- 'CshdFnS9d+ihOA9aZAScRtC1CCHQlyHJCRKWwcPXI+EUfdYtHiMbIJoXhD1bSW3NrA1irZG8VbS';
- b +=
- 'xkBE5Twei/rH4sawEWG4vjo2BqlQq418Rg0vy1k8tSikeliLpzFGEV0QD2eJQ5ISH+pEzWtIqSL';
- b +=
- 'XTNbHSBxkeWO40xhyR4YQ0SHIHCMSyMtvJfdFEv2tmkkSQ4DYE6jqEApqsDBnOD2Ks5PVLLulhm';
- b +=
- 'OZw61o5m79LT6wguzGuoWT9A5vHXsBH5fA01CYYlYh3pJdklNroQFMG1K6alzTyHqiGpDxlT81G';
- b +=
- 'EU16gEyigeynhxZ93hU+01OFQ6/YJzYLKK0s5BVRMmzYXJSLpzAWrQd9jcsN190aa3AmToGzp6y';
- b +=
- 'hp0hq8pHYMQ2n5QRO7BqbLEnSGexv9vhu7ksQD7NTzKy6p1NbLw8R+8YzgmaJFEr7VOnExTLujR';
- b +=
- 'I9PHmOAiawZpy+hEfNnzaboZ7AWm3Ra1wXFQ1+aYZI/yR3POhZhwtXqDb08TRKUiyQ5JQ7btWT+';
- b +=
- '9KkhCj+Ga6sjU2wEgdtQizWGoQWT28j8zCamEBOq3wnjQKeDEfaq20qrj2EIHudJt1ZzN8wBbSh';
- b +=
- 'e48+RmHyfTQ4lMEIApeuCWCGomujogsWdB/xmF5aqQKvJBHecK1wB/FTEYfKYwePXBD+Ei/K5rp';
- b +=
- 'WU3GcZ6yzaja5zEJVrqexJNJZh+flkKB1SSeTDLWKmvFkL0PTdJtflNghf/qZ/RQZBqFExR6KFB';
- b +=
- 'Uhp/GXv4TMgvPkHCAH0fg7DEdARs66cs+/hO+RmWdymELRMoX/ia4O23XQMYRjyVgZyOOnERUG/';
- b +=
- '65KblTI/xKrhOgjrKs+Dz9x5T5x3bYn/GF2AMUmx7Hp/9nZ/hbwJpFsPS9DezpAtgTGdhHAHbXm';
- b +=
- '1vBQnDkb60Ww0EEThRqEef3bdRhuTTmyWZ2znbORpeINWBK4U1PEilSftNH/gjBs7amH0R+2OEL';
- b +=
- 'PqlMOIk/ZJ11REfaHu3I527K9x02uQRHhYkNYossykTCNhnezOeg8ZV0X+e03VhDgdJDhQ/FBqc';
- b +=
- 'WY0LfBHg5Mp5qJjXZb0nxgs/sVhb/Mw9x52wx9rO26pcJ6ZEyTjFzdkGnbWXnYtpqcYSVPmo3s1';
- b +=
- 'KgIyMlHJDCns253jjhSGnc5w2JiHpwqOKwKVAsnN5npYfeNMNtKyttDIqsmFic8GeJvkR0Qo+YO';
- b +=
- 'tpf91u6eIPM89qUq83wMS9Tbk/hC6V1w1NWZrAE40/y4g6N/7kud1XxjJDZblfFZUaXLfPjErfN';
- b +=
- 'H7Kl9K0hfq83zoG8SepMhA/aUjFEIgQSU08kNIMhPuRDTBxo3mrJ6fpM1s9wgpaYhCk24uB0e4M';
- b +=
- 'dlpw7Y8pCDr4gRYo4KddGTqwHCT9oF1Se1wlaOMpkoYnTdlGMh/6Q7HfWyaRCxNzryLEqqygpFG';
- b +=
- 'ekuoRkkoAJ8YKRRqXdENJtO6jsXqkyzOBlFvXCjzkXoJ4hqCf89ATFpkuVrFGq0kd0uvQYUZUOK';
- b +=
- 'Vc/hW+n/yiHQfh6cjSk8QMIn9uhUvxl3XKkusZdlll1vUKq6755q+uHHamuDzmC46CTVdcJ7HDG';
- b +=
- 'aauXed+W1MqJy/nlbhWplw86SgdH2TD7mumJ3yMK/50q3ZXWMyjXET7jLPwehL+yKQnTM0hzqiX';
- b +=
- 'b+Twb/ACfSxj+gP3DUfFY07I6kH18oX6a1qUZgLubLfHiGu22igu7u6dbkO+aypCvIOSrc5LPGh';
- b +=
- 'r0vilN84zNlX2fruxXpCcMquyn8G0XN09WNolv3TTgGIKTR+GKibYoIYUhKxiSCNuVVgDJcVsKz';
- b +=
- 'THl5kgotsg/QltEgdnhNiUSBnOkUM+LiE7ZzazeRWR7vXvCFQM/7oqkTpARn3SFCfKk4T6XHaiQ';
- b +=
- 'hhr/fXAtj7iK3vBhvE57ADys1cDutPgW6Dcei0O5DckiSLrp1BtIxO/zVJ3AlQWYHZ7m4Zsha7s';
- b +=
- 'q5Ns89jgAFpHJTmavg9aUp+jDph7yWF4z/IHN/UlLrAFkvoHNKsBqNHoeMRN+nzUTe0SiqsDOh4';
- b +=
- '/wvCvXOTNIxiXExIl7JpeJni043PQxe1MabNmMmupufsOXuzdvZtIwk8uEUDf65APE4F+7qnqa1';
- b +=
- 'C2raa8wDCjxYTOTXUt8TzOTcLFhOO0N2ZNephqwrXWRRZKawsMuWHmEfx/l32kW9z4v/KQVqxzh';
- b +=
- 'TxUkoQ6GEuTl6oCpqBOraonvaWaGVSxwx90h+wCAH2NCyEjFNqFcst7HzU2pcTPJDAHzpldfb+y';
- b +=
- '0FL1MCcqGHX7fygoTRUgdd9DRKmVD3O1KBXdQV3A7XMXDSau9gjuJndmuVHA7reuNfW57BXfczm';
- b +=
- 'q4oxwEXjhMruOyklao40DXT3Qld0wV2KN2oZo7bneq5wgW5cMxox77o/CNtjz/CUTpi0xU04saH';
- b +=
- 'Ttd8eE7dGF0Io/bXufYkA+YN9Zy9wa9nGBPIM2wFdIMi6QZxtvqTnK2FaoZRnUHOzTl904oL6I6';
- b +=
- 'qiuoqtjShOY02a5ubwnXWIGQnn1A1VvAvuv3ULanWqq2g6Z4mva0+5D2RCEtwTxI6Y/aeTpQxTB';
- b +=
- 'nW2F2THNIp3lj1SpThUlCcPjAS0J+nWhiLfrI1xt1etxrPd2sSs+Y1CR+ykif0VTrSKlnxJ3mBn';
- b +=
- 'Y286nBXEU6crusyceYB7KpusSXzZqxHFZEqckFVeS0bYweYqqFut7P48PQSnyjD1l/UqK3Ct6SC';
- b +=
- 'rkirI+NKjcxaFfuY2dwUTUuU9c+5QOVAKcSuTclJRwLishSb1RtysHi6N1Pn9GDPdWIHAdnKI8K';
- b +=
- '+Ujh8X0zI3KzFMgOCmT7bWQHT0T2xlay/Vaygzay/SdHdjDKIm4jOyqrm5MK0xu8mJmvWUoqvUk';
- b +=
- 'N48Fu5EcUrkS4JSCCfHF+78aapUYYwUJUC7/oy5iLE9VGk2AjHzxvb1LnpDu4MwuXY2G317ARN9';
- b +=
- 'AuddKxTSw4jrFvGDYZFg7oba4zjAeGMQhs5UEzC+IZNbbRvxj3EFRwbVaFb5MjAoKo3IvT7eVia';
- b +=
- 'UDE3XaFbLyRn28NrWK4q8r5SiLuCaK7RjqeiNUm/0ApFHS6XCGWEggW9//gGisHV7dW+W66EmKw';
- b +=
- 'kWji1RGaF6NJGTH5WGyr4suseNz2TSyUMZ3GKi8phAGpnUflcBUUZXBHhRY5xM+TyFIU3JSUYQk';
- b +=
- 'lzKmyJZRwXrpIo41+v0h/vTP9QUa/r+gvXZj+jRegn9f+14VU/79BP0565/PM/I29oxA/ds3VDJ';
- b +=
- 'iL3jYIQ6rA0NhxSIoUBU0lqkoCsjRgrxYsrfqkLQ2XITpy9TQsRsyrOr954aa4pCSMoPC1OU8cm';
- b +=
- '7hS7t9aIb4zklHHPnrjU+z5iMVuetRwir0RNYbsAOdnilN9RlMqwoJ7RflLJ8/oq754uz7e3mvz';
- b +=
- 'KaWOvPE30nZ64Ex+RZiTzmRvF/i2s2KZEwO8B8DWewBm0NjHhmpnGNOiOEx02Aj/0VLbA+hTkHj';
- b +=
- '0KYs9JbFh4hdjz0lsTxIUYzGRq+AGOVzU3q0gKaIF2g5q8rQA2pEDCnNAM+2AzrUDmm4HNJ0D6i';
- b +=
- 'lw2g5o0moDdKAdEOa4V9k3AMbwvdRWv0t/iMh7DEcPoJitsp9ProZlLG3dMRn+nDTHkvIYJN6ad';
- b +=
- 'W1TpC6JMc1zy/4xLK1fZb9wDJBWUZNyDHsk1HQ6UpUjj1IpyDsAGfincH0Cx5M9EDljcwhFwb9l';
- b +=
- 'P9a3r7JDTMCwahVQqjWAuo6PdykSThHshqhPpQqYQNQ4jIkJnFEE7uhM4DR9DkGjAxrdjEaXaZw';
- b +=
- 'jkWMaStwl6lVvC8RI1NtChmzF3SxcK17EalAfF4s61dsSMQr11sMiteKleK6Nl7EO1Lde0bp66+';
- b +=
- 'Nh67ifF2IiNJBJcDk+4c5FKQaKa/KdkGDMWrFYlLBz9bXB8iUxN5h/lu85Jd+ZC8r3mJJvtowiC';
- b +=
- 'nP5olcpkbWoiqxUIfK32hyzcJVZVPn8OCxNqQFOEmIxWLQwqkcxACg26tDRgnaya6C8q53Mxhhf';
- b +=
- 'RR1Fy4WCSIgH2S4Elmm/Grn8KRqyZ0FCPzbW3bIfp9MgVTVaGvWQjEEArp9EXIlsJFpCVIEtRQ7';
- b +=
- 'T4Ua9mo6yosODxCLBGPBpeDYWeRMCjxFTnj4lDrhezuNEAwq9gkZghuwTyOogE/wwxfL5e7yuZo';
- b +=
- 'raUGKyOEFL4s7jG0/Y8zyKPTwxZJ+xeH3LjIUifsZqhq+FBfPJH/up9ThBPvmYwWNaT+bMTTkbm';
- b +=
- 'qry+hJDH1pXKleqtXoj7Fq8YGH3Ih7Qu6447L2WHtv/BQO1q9H7+2eE1vPAwepm+DYvtquLO+bZ';
- b +=
- 'c8E8izrmefiCebrRh8GVGoPWczgUcF+LB/6+Kr1WfobcEV0ho9/o5xhNvrqAAKXnCUNqySyVFf4';
- b +=
- '/qwXBQkFgKrAnWmApADtPEwBTAJjtABZ05OrQ6Qtx1dWK9GudkJ64ENLwIgBMfStnew6ARkeq93';
- b +=
- '3rQlTXW5F+qRPSo9+6ANW1jkjPXhBptWOebd++UJ5KxzwPXTBPOTc0MPePnZib+fYFmCt1RHryg';
- b +=
- 'kiDjnl2/uuF8vidmbtgHq9jntkL5nFzbVPJQ11pSnHryUJfN9DAZXgh5vXOzBhyX4gqfxCkfb3x';
- b +=
- 'bIwxDlq/HlnD0ZD1DHpghRIF18u00GrOsbrJE0RZKRY5Cy3OL8AL7PwOKc+exwvYrdo/2Un7J//';
- b +=
- '5Atq3LqJAHv3OBQCYLSxqZVE/yy6UlPkVxienkJc30yWyWuAJaJk8M59zkPmLPFOLDM/MzwFyUb';
- b +=
- 'sUHYbKhytWZcLhTkQXL7hE55p6GZFM72Njyu533iB3ZkW87MBH3M5CHBbZI267jqPwNoQjdQkxG';
- b +=
- 'tF2+A6bX1Mz3fPOGSP8Izcp8cHUaqSVL6rGoTZqRJbfcQ6VGrnFO/doEMIVLUmZ4MYlhMOkQhKi';
- b +=
- 'v4296XgzruKuDPzR60QT66Z4XZKL8UIn7cYqdayvcbc0wzfYyN/HLO8Km+HXsVW7JJ3zdLIht48';
- b +=
- 'R+aWmJNCTliUcfxeXZPUsX7PljvTGkP0UYeTBnwagiYQQZ0sQ2cp8ZeDjZhzkk1Ryxznf0ObJlX';
- b +=
- 'NB+izq3af2CEf+WhOLHrkfje61iUEtpuLOJg/MVaPSTVj+CfZK6XFI+A/duB65jNFVl4Bjk2Jqb';
- b +=
- '5FG69TetLEpwRkyFWGyzuAiN/wCloea+NvYK0Oj6QRfqL0lnXi1ut/rWRvlHnYQg0JZg6jr6QQV';
- b +=
- '3NJoUuKUflTaH4c59V2Rtz9ecEEWXM3CzncxCxm91JdXX/bIF+rV11O+OryNR44XHrum9kb+Jly';
- b +=
- 'cfF8UPrB3M99XLmsfGxtrYr98lKFmG1vdPcW2yYcRhemRd+X3ve3iu+Sg23/zJdBuFxNNuZu+jp';
- b +=
- 'O0dc6OrFoZ4Yqx05nWwElSg75wd413MVqKasocNVXYI4akSakZft7hMSMCyMO4uEGQSgcLQKyeR';
- b +=
- 'xYKfASpg0s7gnRrM3XUhfVkir2Ew8KSu67n8UnfbhrepKFImUjqmSgU8C84he/qOs1MbtlX0FBv';
- b +=
- 'pQHrBFmrUyxTUkeFtBGm2zJ9GAIqh9vdDE+77GbCb+K5o0smHgCKcj7yTpWTF+K5cjFbKZ/q8dk';
- b +=
- 'FqZeA/Y96cdQxblFmA7wF782+uDg3pa7lEeXW6nIRITjJXFtdLiFEXJjHBTouc3F1zGbuCsX7sX';
- b +=
- 'tzYdQuGyOC5LcOai7eW7H61Ho3g68NjLBMjO+4SdQ1TdQ7+b3DRloKu1uXzq+01vJlU9c15UIck';
- b +=
- '4oodTxirB47LXd6eUj1QirDZvpMPdoYBzbOwrDzQWp9JR5ukYMlRB75TDQFSTLN1ZTr4xPPqVXk';
- b +=
- 'NUHp4JHKGXLYE7/BJlQij63iqukNzyYY5XT5Jp4d4K9b9dea/trAVwvlaYzp8jel3hbyE8/atFk';
- b +=
- 'GIXk+ruaiLVXGp6p8Um8V/SbJLIqdnDyCQxTTCb4yk95x32I6TtKgcIjw1nSM0zlUBPh6TaeJ29';
- b +=
- 'FimQglQb0MZ1aopQJJvUneisolJsj5/tRR8oKQZtIVUZg8YFQfjdErr+BvYy8WzI/Gi3jaioW/m';
- b +=
- 'IKzElxCwWNGpqdcO+lxCfZg18N1cX+27rhO/xfjb6Q36kknbkqWcj0YRAsJ3+JoaS912etU4usb';
- b +=
- 'e5tY9sqZnKSXaMO9eRh57o+6iMV1hjE1bN6HjRULol4sAA5wOhzLaOJmWSFK1Vm0jCS1iGy1wZM';
- b +=
- 'tLs7zLmHCsAxgfl6QUY4JcLmJY8Jgbn08pE5wy3iUqQdfo+ib4Ot6oyWjxPBSUtCSeDHauEFUeR';
- b +=
- '5vZCg3ARfLpsuAW8WjBJIAokQAIjeHUh+lz4AOWBSzkEjOYioE2YJMKiQVCqOUdZOF7Hl9PuKKa';
- b +=
- 'wf0G0TE6NPjhRSV9Ej25qQlajbxGXpYnYkx5fTsG+jr/bYueav5oM2V1koY7/ObPGdcHkFjDis3';
- b +=
- 'OcejkgOpIvysSH+IYhyE/+jeyBZLbS5fTYKgAYXh6XT777eg6VNoetrRYAoCTZYRnOsPv8SHraa';
- b +=
- '7kf2DlvgQyscW2x2+kw8BWltjd7Ce7S5o8mWbbvpQW5aAb51rz4JpOsxSUI3iK5eBt+dy41ecBJ';
- b +=
- 'VsvivRwQ1XfkU7PTQ8TpNo07Xpzvv0Gm4xlarMqZRQ+mSUT1+axQvuIoPd9VrexbO2GT5GRKwx3';
- b +=
- 'jA5vEyvJzL5HmTrhrQ7dcI9XoIzA0mXfA5PWSZLy7zxpNSL9nWZL41BuIq6EpOrJsYHyemWG9hf';
- b +=
- '0B1+1ucrzzy+23MP6H2PZ1RmS2bvOOYUNlhOQhrdQF7ZGccrLvqi12rijY/hPcCxOkgVyHs1KeG';
- b +=
- 'dnJ+8UysX71FSHY/4y4qkJl+6kzre+5KGvPckId57ki5570sW4L07WSjvEfkbEwAXyfuKZHEEIk';
- b +=
- 'oRgfYjQK1EgFWPACGMkG9BhNTdnHBx5Ixj4JCS25y8xMkrnLzOyUNOvoCTd3PyxREYs5HJ5Uw+Z';
- b +=
- 'ypxpgpnqnOmkDMt4EzdnGlxRDJIlgwvmxpLevh3Kf8uw8Dc8vuS3uHyA8hNoCsMOmTQCxh0N4Ne';
- b +=
- 'zKCXtWTrG97xU4NpCkCT8ARpL1UJljLc3ixZGclAUI9K0MMJejgBxkPHFX0EgfMoOnv5t38vbtF';
- b +=
- 'dvgk2xBdTIssiRuqwIAIWBAjoY7ghGKozQwuYoW5maDEz1JmV/jZMIWNaBEwLGZPo2WFMAYs8x7';
- b +=
- 'cA+ELG1834FjO+i8PUzZgWAlMXY1rEmDzG5DCmgDWT4+sGvgWMbzHjuzhMPYypC5gajGkhY1rEm';
- b +=
- 'DzG5DCmgAWX41sMfN2M7+Iw9TGmBjBVGVMXY1rImBYxJo8xOYwpYMHl+IBE7/5aDLSJrRA6LQjd';
- b +=
- 'DGEEJ0h5oyWSkIyOUiRqAPo+lcvlXA7nMjfJnKUzvHiKEtcfAJIv+uPaRHU6QOdFI8PeA9q+xyh';
- b +=
- 'XRiHyLZsiY5dPz5RbFLO8TuVNZcucqPJ6TUut15Q9mPawMfzYhx77z3868PjbTJnrsXhGjeLffe';
- b +=
- 'I75/e///D2Txr6QyQfgPRVOm5tHtfQcZjK5I2dTifwmM10OsI/pb60IDhXiMwwYD6TN4y6nTBgk';
- b +=
- 'tLtiGFafWnBcKAQmfMgGHow59qBB5mn7MSD+tLKQyEy58FiDBHmbzvwIBOfnXhQX1p5KEQqDIZa';
- b +=
- '/acn0mR8UQfDPMhPHArD848lnrXByTY8mRbIvE0Fr2sRzfORFTI5hJLqGF+0nU+32UgoM5UybWU';
- b +=
- 'VZjMZ6AuRF0CZunyWlQl4PlAEMntk5fO1UWl4/D4h8YYxNa1UYyA8CcdPW01CMRJMz1ZE4UXCMO';
- b +=
- 'tZEspKYihF5Ji0tQW7LUamJ/Ey7JOmRl/P0JYUGZZMzZbEPopoMVdYE7Q1sS31tQ7AnGSGANsKc';
- b +=
- 'E0BtmTGsibGUsxSZ1qsMZ6Toyy8VIyvrMO0WpnnxrRu8mniiog9UIJyeVcPT1RbhSnRkpZAga9p';
- b +=
- 'S8SZTfVGih1NbIkXVfCd5KDAFQpqzEU+XUyUuUJBWc3yQVUWk5LPBqN6Ew1V9MRfqO6IJ2Swap5';
- b +=
- 'JFNjZzLDCqeYUCfaQLbVNkOXBIICFqb8VRuWbZbOKyb5pRy3AwDBr+PuuOqKHflh49HAllp0afn';
- b +=
- 'EQEz99+XDKxlZzJ/wDvOB8ZCty5QUrquU7f5Dkk7L9KuBzhrKj7SU+5GMH8ai0xAd8/B0eNR0f2';
- b +=
- 'RyadIoYmHjBLRv4MwrC7ZpU3BmbkepG/rykBmrBRE++4L2sosJ8UXs1W1aR1Iu03dBCW6ThCmZz';
- b +=
- 'HtrMIm2Wpm26kxjVsb+5/NT5wJWWCOpbtEvslI3rITOGcj46kt8uFyGI6ReyZoT+JwESdB18x4x';
- b +=
- 'R5GbGbGZwWyTCn8J/8kUbZmFxc1lFZKNe1XzJQgHrjKnRmh04mbQy7dB3QTvdGvcHBVIMRcrFi8';
- b +=
- '/qgHQmFwCOzmBTK2UQKxnEC9i6wM0gnrLmMSj+pMV3ymoT3ymrTXxym0oRLW5OYryTnQyBXwX8R';
- b +=
- 'TPQ2aLsnAFcHFRgQNRBxTlzH1kJwtUxv+9GRgu8OVlJx8WsgkpnVXruwJayjUmzJbc68UTnnjE6';
- b +=
- 'MePAwf64ZJpwsDOlrMWZmuGnTGlH0lvYUE1FaVry6yn1CktrqHaeahny+7R6B1UN1UpT7Tr5Xmq';
- b +=
- 'q+tUSVKdkIwtHtyY6lSeatPJEUTENal1P0kwX0pxqAYR6qy6JZgqJcJlTgSRK1KdIKiSaaUkE87';
- b +=
- 'tOkVRqFqOLNJUydKeC+dDRl9RWNBUSabGqN0rkKO4KiU61JJrOE03OC4m+pK6iyZ9X4H4GaWbeR';
- b +=
- 'DN5oml/Xpr8DN3kvInoi9bdKa9ZtI0iTV5OkzevnLxMmNPevDR5OU2FRJMt6LCJRtPkzoeOvqRl';
- b +=
- 'RZM7Hzr6kslp3kT0JS0pmgqJJlvtyc1158xHOH3RhM848+rOyWly5pM4fcnk5MxX7HJsp+x5VWf';
- b +=
- 'nYpo3EaoaTZI9H3PYrKfQTWaJzCI9aEkggdHmAnDr0vf88M+96w1uWZbg+A6U9ebIU95o4q7AAO';
- b +=
- '8ZFxXF71PbFKspsGsWUXltxNGhjg5bogMdndVMLqrdMy4auG56nYJHBpjluk4B29Uax5B2eC1gp';
- b +=
- 'qh1fZ2iEC3g96iDUDAQf8bFzoX0ZybavG56L+U0jCEM0qsmfYKh5EfdHMnXbVyjZKtEs+pKBZ0L';
- b +=
- 'ML/rXm98FvPu7tXGd9ynm7Mcxn4rLHmmbsQ5EyO3Q8aX5cNZgW58zlZEClhs73cx5SKx2N7PU7I';
- b +=
- 'ssvAPg/C0T03yf/GwV46plc/h2/0MDFjY96czRvivprA75aV80ItLwgt/hKvAXeoRD2GzFC/Gwd';
- b +=
- 'xwxpRWYOJlzM/aLTrMbrOSLwU1JkG7ImdbuAsfUtxk0mMo57nlTfItRuACAR1B0AxAu4en0lZZZ';
- b +=
- '924lK10J5lajsyx7dLiIBH9u49jvLaKBM6aiZOd76UvFnMxJ6vFERTEYfJs2vXGrM2bU3gD3c01';
- b +=
- 'I5M3oQn/NGeM9DIJjZ6xcgGSphKnWAzOWHISRbEMnJEbWZ1iAZAW6Bkrg06JxCAws+umU7bG8C0';
- b +=
- '/0xWXgrko3Q4o3XlRgoV9do4SOBglFHfSK+oxo0PkQbnCS+m509X5vuNnCSky/LrsBnJXWrM25L';
- b +=
- 'jKOmrzPLJAPE5WdFRNsEObMw5FzjgF09JfVQa4at7qFj5mClwu0VgApXKq4zfyk2GIVpenJm0kJ';
- b +=
- 'wOyxGRm9dZ0+UB0WeoQFyffS4Fj5bRhAOIZHAwoeWepoCki9/wZlbmP4TwHF/Uvecy3lUx3Qs2F';
- b +=
- 's78EmCo9sBNOz3un91qYzp20eBWLsdqYtNKPT/xGDbPbsYeIx00V8ZiKeExH/MyUnSNeNq8NJ+N';
- b +=
- 'h5JtasYNWmLqxlx47c9iQ3TYuNpdk37AV5/in+Bvu24hMnlByeI5IwPShIz1o9RTm6amBuzHxeL';
- b +=
- '6Ml2uQFvRuL0ttan8ebwW09DQajg2OGTlvYjFjW8Dwhi+qXbZif6kdWRt7eeADTpkhYjriJgblY';
- b +=
- 'XbPJvcyKjIi2ElJc4ztQjgJio8njtQVdby5xiomGVdJgjzJeFuSrXOTbG1LMtaShCJe14z5BCm7';
- b +=
- 'iUVs9o01R5+7A+HQ4+aayWcUUQoB9Bs1PibI5JGZTNhYAO71YkWkHILzMJueiwn1LLwWq/tc9ji';
- b +=
- 'D1gs4FFLo+RxaSaFnI1Ez3f1vh7FY0cV0PTXwvmVxNOHiw0Zwstqxf9PbflzM3mcY2jGv7YD4hR';
- b +=
- 'liIaGakRDkJJz+DpHgKBKcdhKI99GYT1oyb8yvaRMdQ9yJiaUYBnYRm+mzNsUwzeWbeKL31o182';
- b +=
- '4m3JTI2UxkWm05lyiE15TZKA58pr8XLKgwuZHeJUXppdctmKfs6lY1U9GHBlnRy8pyxaXNiqdUX';
- b +=
- '2mYZMLeu+Gw6CfMaDDvFWJqsweBaw2YNgsEm1lq6fB6Blmi7pD9WkPSGDpJ+WSbpF2YqFpmvyGQ';
- b +=
- 'e5TLfBZm7SuZum8zTo187jE28Ds9Yf7isdgTYvMAycsDmDamZPvw27KXHCsPrUEugAf+ffmqEH7';
- b +=
- 'fkWLvn4ES7VfZ1Q9avUwTPeHCiH/DSJqrPzM2yE69w5pzDVCBx+COuUWWlj8M3vWLOm+fpw//kd';
- b +=
- 'Y8nTKwmcPjCV06Rbt9FJP0NjltDRWzdXMOyxe0Y8FtpnTbxe9ZMd+/CFuXwY/S+xtiOYsgH7+Ht';
- b +=
- 'jTZ+/9AO/x1xuy11poyT9g9aL8Eu40FrJ2PchVWxO3BCgXO12fN045zJx/edM1kBCJ7CatZdlmL';
- b +=
- '10V36/B4HVKwftH5bMeVAveH5jCFHciiGzj+IMy+cjEncDPtJJZjTvOmdkcr3dOrtwr6CsNI6xz';
- b +=
- 'yfN8O/YmZ3WLzGcjtXtof1qjPBRpHhp7CxhNJN2Yl1vfEF9rA3Y82KzEoxJ+f1TnYHh6xbeDxbV';
- b +=
- 'qYe4Vt7/pEZfA6cOD1/nUDwej8Gka10Y9fNFgLqw8c9JYb7PV7D4qgxdsVWti4C9kRsD9mQPJan';
- b +=
- 'iEAedmRBG+FbiZ/V6TEI4j1uqw4HSGN2QYmzb8+VuMqOhoqK286SgFAKSjz19kyJOYEn5hB4QhM';
- b +=
- 'YFAnkRb/4qaYnHrwI6o49WKTOeGLqzjyYUwe4stI4N9m3aXjpzE4Es4zbH2xhSwCn9uY0VgYyxZ';
- b +=
- 'Hvs5qqje3wYJGTvrsQc56N8ME8hqg23mRxV0aDZUOFTcBAwiUtZmWE/+GoYzC5A78TQ3pYG42f7';
- b +=
- 'vARVQTEVMjSwlOucif3k6uX6GO2LJfsyP/ud8zH/5535PwLQTt5DAo3Qn53Jx9nINa76y308tDb';
- b +=
- '9JEH7OReyMtlvoAjjuirSrjzrap1942S6U1ERvgzP0aNYoSf9hMz/KkfSyPICP/OR1XDTUp+/55';
- b +=
- 'qLTX5wFYKhv/lJ9T0WWnt3DbMB0astLAbPqW2gpXy/t/t24a5iWCFH3IbqCcxaonFjEb4BlNuGj';
- b +=
- 'So4uUjg/Qio4QXj7pYCFTFXjKsW7IqKSPatm04HScg9t2voYqS3rDP+uzkJ3j2fZSrK3TsjPBBn';
- b +=
- 'N8ieXaDhtFBPBsVad+Fh/noRE0ZXzamm4XIsmvbMO8fULxhqboF8WjmC4xYYISbAFbGiKUYsWQT';
- b +=
- 'gmIEbWXeFt6REW5Khfd6US5QJ5NhA5vJYRaUi7/vIJ6ofUlfd4iEqb6Sln5GMcsMmXbqTNuzTEo';
- b +=
- 'thK7B9HCMBHaCFBPJ92wbfm7NDN8SJFgdN+XFZtotASsNJWBTHgmm1hYscFTTdP+fvbeBsuuozg';
- b +=
- 'VPnf/7130kt03breBzb5zQfrFi5Q2xHJtlfHriH0XxsjPP7728rFlrmLWyJuS2F+OWFcGayFYby';
- b +=
- 'UaAgQ4xoOSZIIiDBdiggCF+IEgLDGiBIEpiHgYMUYITNLHBSnCwAIFnf9+uqnPu7ZawebBmMsFa';
- b +=
- '7nuqTv2dOnWqdu369reHw/nqxNO/O6xeugDJE19csGmGb4Sde8Xq5Uau3FgpuO2TwgKT5QbzQyn';
- b +=
- 'sGo6OYL56+ml524uL2xdkuyg/QzSHxUuJj9/60QASExGVAdfmzRx2TwCCTg5MYHgD8FpIQvwJ5e';
- b +=
- '4hODzV8YTJ0Gwr/lC9ysnIBqov0IKBr0f/vSUBLzYKMijIZdT0JICK5os9OTyJEDGog04LkxEZ1';
- b +=
- 'wM00gFqn7jvOqqPnQWafTITaQ59UwIfIl/pwA0HCN/S4/OQ3laOCHRz6DrVdnPiujnlQ3wHPo3R';
- b +=
- 'xaF0rzYKlNoXYQBww1O8GRuqcP4qfX9L2kwdHpJ4B1Py6zbu65Zi77Cf372SXPYw0tx70TB5828';
- b +=
- '250xijL1soTopvTnUCcd+FYOoAq4w2rZ1oNoNcDHRYqDi4NrCr6UM+2oqRLBgGSjsK9QfaXre6f';
- b +=
- 'xFHuY70ltWIzbvgdi816Qq5wuKwNSthOXKTt5rsJMbsJMjqrwd+PaZQW+UndyAnRz3i7H7jp3cg';
- b +=
- 'J0cCfIVCVwNt2iCeEUCy07eAzu5vbXjP5KbfDVW8fDUrOKTkl3y3jb3wt23SyHl7kEBUm+w5iMw';
- b +=
- 'URYEXvU8C7mSim8vPfG3lHBKQvHtAJKP8YkPUjKKT+6+h3D3Ec7v3pwpJ28frAUzcLFzMHEd4at';
- b +=
- 'Ve3MPFtrh1urOLx4kDrvMJAoDLHP03ZnSdyeMa9J3Z6el786Vvjs7NX13ptXU9N3ZqvTdmdJ3Z5';
- b +=
- '6+O/X03fd/yTFtL8pVdV51t4sYZ85+CluZfnX8iy4DqLSzU1NpWzXQpLqUJW32QbAWHBwY3dXLj';
- b +=
- 'LgAnHYZzx+k1b2Zl1lrBhYBQ/ogN43tTAYK7VTJs8OSk8AN8/1Mia9T2esoQbLcxYG8wSLY5INO';
- b +=
- 'HR902uSDXv5i/axMC+i4GigpzTbNQ9bsvo5qLn0aZdyOtOIJEGpP0IJKW9BTom0Zmjv7APWj3AH';
- b +=
- 'UmFRvgfkGzyv315a94v+YVELrI1886O1Y6jTZfTLcwJud8GItk9NNxGhy0A2B4WeuvVgn7XwwM2';
- b +=
- 'uANiZOOFSQb3SLgoNjxQAn8vUQPJwq+ji7ZfucuV3xwjkhjNKIW3DWDXCwApZbtwASQ3ByW5PL1';
- b +=
- 'vcWWtUDGxkxU4vp2y5pMOgw6aBLtGIP4EJZUlBywpQZU7aYaLt8wkg1afGRBTCQWdkB0llr3F5O';
- b +=
- 'ogTZZ98ixeTMG9m8Ltcai4/soNq1UjQs/W6x04Dcn1BUrU3Vs7E91LXWJnS3COjtSAO05a59Bf+';
- b +=
- 'uHQPydm5R3DA6psV+WMOaUjQ2RGNxJyZKdHLkOV2L146VC6gSylDMccYyk7LT7IkUoOUQZa7aB+';
- b +=
- 'MlThHa1QZgu8U3p4VJ2Zlvb1ymtyAuLMNn3NJp19IE/R2xtJydGY+2N9TCf3CJAN3mKCxhYTELC';
- b +=
- '117I442be9kA1+bAok7CG3Z0UjZ8Qi+NkJru3PfVwRsCHxtOIqvjZkrGsHXRsDXhsTXhsTX9ua+';
- b +=
- 'p/jaaARfGwJfO9FE73p8LapSdxAeXxs28LX7cpPtsGrqp1vUaFbJNhU8VEDcawaRLj87YL2C5ae';
- b +=
- 'U3dJ2WMHI1DSsw1ibzt/UjyKyn4Y0tBhk1SymsBS6d+62U02aaAlgBsPJjXIqmaqEBaD1PwzMmg';
- b +=
- '9S+4D/N89I+vBKF5+DZ8yHZDtRxT4k29Aq8aEpCaU+BPcNmQ+tw8bfh2Bw1/Kh8yTU9qFZCXV86';
- b +=
- 'AIJdX1og4R6PvR8CU340MUSmvShF2DX7EPQoK3xIejd1vrQ1RI6w4ege5nyoeskdKYPXS+hs3zo';
- b +=
- '1yX0HB+C3mrah14kobN9CCqyc3zoxRKa8aEbJLTOh26ETs2HtkL/4UMvk9C5PrQduh0fWoQ2oe+';
- b +=
- 'DuxAc+OBuBH/aB+9A8DwfXELwZ3zwTgR/1gf3IPg8H7wLwVlY1c3Kv0eeqg2kmqGsGapuP0GvH4';
- b +=
- 'zg+swxLwObdnlQSw8iSu4JnUAGdquc6MB9Hj6ZpJ/TLDTcyt0tjHHM/MBsA4Mlj680GdS/kkRZu';
- b +=
- '2htlFO9feqm2o234XH1tT2rJTcsBx/dy+SLhPGbCMj4zKAbgYfxMtoKBUyA1XbbFqq48LXF3g/G';
- b +=
- 'Jn5tpN3eCrQoEksmnUxy95zVjmZb3pOHmTXaj3nY5Wy+cho4K71xpseO/a50Mg8lYXSHnwmeHkB';
- b +=
- 'hmzVPMHMeYPZ8IB+qq6CknAAsF4ZNydZhzWJnyZXlmlugrMxx+hLjuCabl4mrbF0jYwEmtciGc5';
- b +=
- 'vTNWh2ZYNmmw2aHWvQrKQth3T4wYPL2WHxzoiW5fAzAuMwGYXVQ293psK2hkHmHn6QW/ZZWxHBC';
- b +=
- 'bmiZ5t3cjL+aYcMOu6OnmJHOEDaH9n6X53x17VI4/Nh8RdR8ZegcsSzDroK78N5/4CP1iHoT8HX';
- b +=
- 'PMmfHUxqfzNpqh3QKm2CSa2Uxgk4e5B5nkS0xYcSB7nAzeILGa1b9SGaId/cX1EoxZFokF0SHDH';
- b +=
- 'cUVjkgny++0OeugKCbk9dgZFunrpadl2W2Djhduy6Gl+Mxk+7+OkR+Mj+iOy6euvJP4XPU3cGDZ';
- b +=
- 'OEWHMXr8q0Rf4p5GbxCzZR6MiimzefMrbhrHjJjIBl9oe2oUtmtKGhA7mYcbjMkpGG4qhnyVXRb';
- b +=
- 'JoN8pYk0KYxZBstLZpppiv+azjS3A8ldX4p9M1k+AiqR9++HIwdkVfn2CNyewwvA/XR5im8rN+w';
- b +=
- 'gJdyCKN8Z24ino3/vMMS5coOYHssJzGFjCUfc8JxITc67ITjTS5G44joa4yAveEo6KHaF44hI/h';
- b +=
- 'Wm4Mg5NUJ4xESe9RbhCQ9q/bhK8ED7LsT2p9nDYtHjU0jX3Q454o/i9+xaYbl641sGD/7z0Jh7G';
- b +=
- 'otEoV9zpS2DNNwttfMcXIsx1tR/YFYv/Rq/19IOx8IeVZ4gK46fi8tfj+61NybMu5kM+7d6Q+qb';
- b +=
- 'H869I28N3VV3vSDsh1nUm3puxvZ9Pc4h1zmp6m64CN4lvt/xiU5a+gfTUvBLZdGXknfvpEnLxj6';
- b +=
- 'tiLJX6xM8oH1Q98un+TEeu0wO+aqsh9Gusb+XaAAIMlWnQvmFFaCy1RSZXbhAcltFbtMVLfs0AV';
- b +=
- 'Bnk61s/oY1ISG1UeDK3uxNoDcuiHIA4pjtim2ZZ9xKQwFapvCAFHKk+j+sM8DENQwlpFMAJqZN4';
- b +=
- 'prmglqbxfSyLCra752gv/mjv+8Hr9QvI8UaZGOFIv3xjeCTj/9A+gbZGJ0v0/8A5/hrbnJMVccj';
- b +=
- 'TzkuvhypoBrWrREGqxNWWKN2EvbiwiYbo+mjIibd/divUd89sg9fL3GmmpNN3wdWNcIzlimiYdz';
- b +=
- '7hFgWuRsR1pNyvbLrYuERWcoEDrEuUWEW5wmDsvuSHxwUS0ljDXd8nNUaiMa/CDeuKtR66Kx1e5';
- b +=
- 'tVIF6X504pLk6dNlrbLUKKfVxTGfR3ZHDor6qbp8WseyexKYJbF8uu76su3BZuzAps5GoHL063m';
- b +=
- 'HLUY12d+4cbMtD34vWisBwcajxiVwXPCgx5ZIw+kYCW4EWfdSMVKDw+WX34M2+WQzrVxKOyA4aU';
- b +=
- 'Yy8o3DFKwldveEqD8agFl8/Sv0Uqz7A8moF6YjXW0dHX679GMJh89vw77huR+S/kHDF1+OafzS0';
- b +=
- '5hrNwdWoS7OWI2PGFqSWFozU4MVDz6gVADeS+MDskCLqRlVpnB8uRxvhLgd4aREnvpkp1G5v2jR';
- b +=
- '7O1smrtkhaS8G6itlkDDyCGeKI9bo7QiN3hB/AnhmZioeMhQ+hhpbhcU7QpcAZbIMTaTmTeOJmi';
- b +=
- 'kOjac4kujko5UkalvHwD5WcCSxGdiq48yud064MpEENm++CNi8nbKIPWFdBL5pX4RpFhGerojlR';
- b +=
- 'hGHXBHHQkcpnBUP1x0EAtI3Zc0ibCQzLUW29GJX7O8u0eMXe+eByHcyKmeeo3UcBFnfZD6aq3x3';
- b +=
- '7PI0CpZIbcu+RlsQ6fuAtxpZNPn+2CdvVrd/teL2u+IWR4t7WK2akrHukWi9r2UAsT3LFbdRgPY';
- b +=
- 'De775NmBZc3az3a7TfFW2ax9Sh8e+Ks0A6wJXVbNYV1XzfbmqTjSa5Equ306jp/EmRgs/4SptFC';
- b +=
- 'R95VM1qwNq6JTVHQlG6ttLfO0b8zBSpcNepRv3MFRCMDE7R1sH0gG3Y7OpSpaw6SukMpcE9OIYY';
- b +=
- 'eNaPAwd5cUiJp4f7f2Ty9XacgODe1yQluaIWbIxkHEBa5Co3X9ChkEmOv7HIkauKZYMZcGYGtIl';
- b +=
- 'M7Q3A/v4u6SHXw/TsrvtBQy8qSmV7QTYiELOI0sAVj2I6/C+QTZ36e1lOte6XcSMbC66fZfELH4';
- b +=
- '/2jk3e/suiVhcPJntnJu+nZeLJyZ3zuW379olGcztNkKuJ3drOsSfu5vZy3zu4t27du0iVbJ1+j';
- b +=
- '2Q0bWILmIrHgylFY+EtO8FzJpkoMNq79vgujG2jOWz4TT+rCtel+J3CjpheBzSfpAp7yrLzhVWF';
- b +=
- 'y9UF1/JjqHRBd4BFspq/9voz0fCcEyTFB8mur8OWePHL6fWsPHiZublkcya8sMxsgeXBCfwhT4U';
- b +=
- 'Dr3vI1Que9PD2s13h+r6CFzRs9LfwB9o9EXhkdCbYx4CvwHlzuL76vBcUp8MRcKR38UIfhMi69f';
- b +=
- 'lZEjrZpvVFMcSpMmp+cNVV1/wbPgkDp+tgvAHO0A6BARZaJ85rp68u3aAxDFVle5pquW9rj/USt';
- b +=
- 'QmmAamCwbogTcXtXcK3snqO7m7k/NO7gw/g10hzFqOhuroRS0xAnyrrWGZwy5GPoBhmenV2bJ68';
- b +=
- '6qMLgyWzKVBXyJ/GkW/niMd32FCBE3tLNg+UFmjROOCCl8oNkn6ZNMEVSi5OmrAKfPCBzLZL1gA';
- b +=
- 'yyBSyEq8RacFcj2pAtdhqOiPAR4wSvJfgk9OysdeZ0A7mxi8fIruioFOblVEg8fU0ZYtstC16LP';
- b +=
- 'E4pXbEnnuAsqSi/9ts1Jobi3bW8ANWoVDurNR6rfYwZTbTEyYcluSA6aMxNFYYkUr5w20cstxxV';
- b +=
- 'G9289JbDdf5th46j355GSO6+hzBO4pcsVY59WLlM7zRpLlaXNsZXgYtKRZMUC4vnJbteLAuP3FT';
- b +=
- '0mDhoAa5dBBqvDGyqxhE2D6MZoqQ3kGmz/MDTMKCo8UOUQWX3lH03hH8q2sybATBQrIOvsQ6X6T';
- b +=
- 'vszi3/VjiybTmsmIC8cfqU0Zq3sZ7MFbenP7At3eMAYoZSmnJZsFC9Ifkly0EQibAY/lV7V5C44';
- b +=
- '/WnpIpdpuMFvmLDVvpMx1xOjIQmrVjirxmPyoI564pl0vJ+IwMCH8vLChtD3IKrMN1WLylausoy';
- b +=
- 'Mxdl2F4wZMuSk7UR+OxxE4dQMXaS531yQB8QdGu3TVvoaXU7odwr1cY7UXLUAs43SOtmENta0Yq';
- b +=
- '4F141VLizfx95Q1dhYz07LHjXJHJJXtC2CNnB9E+p6BVgcLaKDeg+hsSdEZKOrKQcbWGWunEsBv';
- b +=
- 'jfMrpBBCvhPIRbk3IPmVIalNG4GwGWi8aQMKUhkhfM2ZChPzgL/hW2ux4FYjsaV+5flMaE9U8DW';
- b +=
- 'Hl6u365wujup28NTTWALQCwKj5SAy9JGhjUSvhtugkAGyMuSMleqxKrgS+GcTTkLRSzx6Uqfvcn';
- b +=
- 'nSLAzaypNL958ys8i602dEmVIxZSwiM4fJXLaN/L9bqltfvitf4Kx76nvxqe+d6kZrKP+BBZbq0';
- b +=
- 'TLQryjCx4DHy3SKlRXw6VtPZguYbfE7rG5djG+oim2YyEN2qH+WQUtXUa3L1HX19bSNfdwC0nDV';
- b +=
- 'hipSJ7SJcsz2TNQaS9TRhfnpW9fhyVdplU5IBn1N3F60oOzK6CcdlKF7CwazUeRiIo5ezEbGj0T';
- b +=
- 'THKOmOUZNc4zS7UpjNlIUJmYjahxL00hpkUY55gYd1GHndVk4oTa+JQVqnQKcq+GkGlDDwsNDcF';
- b +=
- 'xn8pFbec74JzLWmkwP5uRJau9LVk/aGnSwAnV1He3oh9LlOtqjRya7jk5IpKyjk+DK1nV0EivTx';
- b +=
- 'JZ+D9TaSsFbTpBC1a2jE3D4NFQXX7qcTkguLKc9nxiEnFzOJhvraM+vo/AYBkdTEQ4yeninxUUK';
- b +=
- 'Xl4fxCIQU2hdH0ziz8S8dbDIdVsWvqjegUgXb1KLuCudEZg3iosxNtqarq3p2o10bW/QF7tFApl';
- b +=
- 'RxXyZuqnY+WOhV5e4YbNAYo54sGZjVEjeNfewjYv0p7do+hP2NUzYaPs854CLZ30wc20P0A2467';
- b +=
- 'okOEd+26A4pXTf1T2JTqXoVq0Mq4z1VlKoLVumkz+lDpYcVuBiam8GITnqANGTvJhQIgoZmAXkB';
- b +=
- 'O5vMFtOsF5E2V1FSPJafOflJLhUbfGk24yBKTSApMirchZaIa69hVbPWmiRZr89xG8brKktkrPq';
- b +=
- 'IXEkLZVHre59qoa0YYGSmEctbaaXLkILfEcCtfKjlBPXLxgvLgJGLpxXuzC+PNN4c/iU8Bj9WEV';
- b +=
- 'cGGFNukpNdZer9L5c2UY2PAvXLeqwZe1Khy306Qie/0sCqIpfa5yrA1juFdYh8r6Dyu1fQLPw1d';
- b +=
- 'AqVcHSH1jXIzxnRgGvW62Aw6croBgtYOlZF0CXncHPRfkvsYDfW62Ax09XgPohkdkfeoBQdh+rF';
- b +=
- 'LD7HacpoKePEMYbWcDEKvn3Ir85RX76JDmv6U4Dns33SRb1bP7APQcJMmrm6aya58Bp87RXzXPk';
- b +=
- 'tHlaq+Y5dto8+ap5Tpw2T7Zqnl3vPF2edNU8S6fNk6ya5+7T5olX7+vT5olWzfPQafOEq+Z5/LR';
- b +=
- '5ICqoHYQ1+il2SnSHZIgygwSdA5lJd4zMBWHV0kUoKn5b5FADYQTWDeaU1g26jDcNVDK6IJDt45';
- b +=
- 'iBimzoZOmaKaNrejJP6xpks/2ubO03z9g61FoKCjkDc6AE1lLpuIWB2kklcCqJzbczJ0r1msY5I';
- b +=
- 'hAWB9OeyKkoJpP2wMZlU6+lm6ccAPWQLkjVTIrVUQBGdK57LWnkJrvdkqU939RLrAWKUSE1nYft';
- b +=
- 'ux7sAbU25N3iLjyKSECmeBP1NzmU7zzWKnHkUN0oUj4MR+7M+7ol/U5WEiJh6NtXgsQp1qYrSZn';
- b +=
- 'NDweRtV9B7L5dcwPaBmJdvAhBjd/L+Iim9hIvQfm4iXNSOV36w0rlqd0pAOrYggH/uOVU1rCcos';
- b +=
- '8MfV26vYrxXhJe7E5w5OR+Not018JHK0+LONPLAdy3tlHuLSRuNwvjBS2XoDTmsVu1RIcwapJMK';
- b +=
- 'SrM6gpTGHJlxUdRNgB1NMHCY9AEq5d1led+fpCsbHfqikm1jfjZLHX1EnrHVdsvbepmqiQoY6sV';
- b +=
- 'frRpRoEqRclRs7JEVBqraVBFTvAl17Q9bBpUyEV3QOVSTDueT2TVy6rtHNYzQ/f6WI/sa6SiMsJ';
- b +=
- 'Sho2BpDhH/p7MOh/C16uyt6HbG2xip7yf5O6wH43ZVmOrJqV9NgS9eRfkA7joKVBXEdYGLig+F1';
- b +=
- 'NQGv/mRH4dEGyJHfX6KwkR/BIUOtwq/kNwpXOlUH0j0ERPBuqA5ruELsQNFndY57fHq5T1PijeB';
- b +=
- '+s8KFyrqLg3RCelWMftjZ3NGwnWZ3vjdtyI7Y0Y667eKG7nB0jvXpQYF+RVfzTmXXpEjvt45wzj';
- b +=
- '7xvMIO611NSQiDPSxUfF62N0QE6wYI7LVj/pWOURBMuO36/EE2FgGJlS4uSObaTj0xUymL4GkUV';
- b +=
- 'j9eogYxY9CwAI+s5Ur8LjzVZLty47yw99G1+2Pfu9QN/HBTLv4WuLICoajL3RLu5ZtxFS7FU9+p';
- b +=
- 'JS/KN2iHKf4PaX5LaxfWj84wf146vz7dg6mSGEssrGmh/Z5oeu+Xtd8yGDNxoSnHZoRiuHJh+/G';
- b +=
- 'sC8v/GaOaqeVTl2WFeXXEW7xffhjYV8JlOl48nlfeen6NaIPmXGY0N61ih0jFB4N1Z473wqU0Bb';
- b +=
- '6RzfTqHZbxn5YrH3meqdQozHzTNlALx+x3Aiz4wxuWm1ue2Iqz+SuCSRuJQatYF+hBeq1vcR5aq';
- b +=
- 'Iqq6lPEdzH46tsFsNindDd6iSqyR2QQqiF7oQRczchSg8dl2IYmHbhSjw9VyIolzLhVI2Aw/+gI';
- b +=
- 'yxC023Z+rHu9BgfC+eiDCaFvdHqoyWyweiq9TME+qrqfGHaOOJF/f/+Y6bqqdfd2DHNdyNWsQ+N';
- b +=
- 'nwpe2ixUP/pMXTWi2bLJcGZDKXbqmWEpuRT5JM0k5zFUHdbdZRJXAZfgnx0fF77Mj8R6Qvkz5ns';
- b +=
- 'd6OTv3yoxdsj1yGBHjkkPAPKx3Mb/7Krf+GsamAnzQJKMuIUF2qtRIQ3S9A+nXLO1S80Z4kYtwi';
- b +=
- 'kESzY0LOqG1084qLaPEk6ZINb0O8wd42d4p49G90kwQM7htXi0oEdm+zxleuD57BT1m6rjrsuSp';
- b +=
- 'pd5Huw7rPY99n4m2Ts5HhsNvqkzxm/n7oO9d25IonIBTh5VOmd542UySOweE3JBADJuVraCwaU6';
- b +=
- 'o67HZQ/dP36gZTGzG4jHnTuzBya/egPiWYfR443cewNzHjw4waxH4tWotiPRU0Y+7FoDMd+LPJA';
- b +=
- 'dr1d3Hd6GLvWQRw7eeOikXqIVS+a4HatEf6CVwDYA1afVEeUgixyNGdAjrro4i+j4r+n0A179Lr';
- b +=
- 'S1Dr0ensUvX4sAnw9IFkO+qLrA3Un8Fi/AWgvPZucMsGST6w4YEVcMsD9XQ1gL0dCbCziNsnPA8';
- b +=
- 'Y9yOHQXpBL7YgFkct9ZVl72CXUm8W/t6FQqeaOOMT4nlHE+BGHGN8zihg/4hDje1YgxvcY+ip2B';
- b +=
- 'G3a1b4dvuct89u/9yFtIdr2xpGEyvZWt/xA4oPop7coZ4SCwqWfnxyhZjstmtxDxo8SMv7t1MSE';
- b +=
- 'jBduid0/iQ56DdSES4UiKPzZ/iMTukw8NKEYikIP94/44EXhwxPOJzoK4l/lDT4yMSxujQgG8Yd';
- b +=
- 'dkXLjyM91dkM9G15/rddaXhT+KoEkngZHbm9QExqcySUKBJCtnQcBhB4EAGvihE0LYZ6D6qu4Ov';
- b +=
- 'ye5rF+YU/ilwp7Eq8n9IU9ul8q7NG9j5520dM+Gqf2S8XGqFCeCGKQF7tYBtgNMmQO3FdbOhBWa';
- b +=
- 'YHBxME0bzLiKFF0PuY4PCRB+xo11Q/FVVRU7++uXkAfR1I8nYjU12a0zSFfqqXeWItwdLKwDe7W';
- b +=
- 'KOVDtItGalliZ6AuX42+Wr0hBRYzmsC+bpuMJE2N7MXPNnMyJC9F4xg63nPj5Gd9eRLny4NFlVF';
- b +=
- 'kka+aqvH0Jlh259uUi7J4g/Imuce1r8zbmqCDOAI63LxwxLDApNq7Y9WHNMUMOdDGu+F44ZDcmh';
- b +=
- 'bvuzIi+QQ3yDN0XCuSZr/U1b8mU8KwozPu02taa0QWl9y0zYgsNLlpmxFZdHLTNiOyKNZFgvzWN';
- b +=
- 'iwrHLBSOcHlVvGo5XvXsb23ORNqfOHii9H4fFg7tG9Ql++VmfCoUUpwLVPmuLqtDhZzZCwytwjI';
- b +=
- 'FXT0ocJu2DtqefG6mLMN2kAriz9NLgn+KGLcYtiIe0tkn762GdFwbTOiYVkw44aRxdG1tR8BdtM';
- b +=
- 'fRa6z9o1bjqzIt9ygQ39LM59eHA897DIfLfqJsJlkb2fon/stK9J4m4uoevs5NU87kizFK5J88p';
- b +=
- 'wG4b1LcuycEbMMveXatj74xDkwImAym+szsU/Dxq0PvrZKmqrEgXBEEkIDsw2dEfUb09ySvLimm';
- b +=
- 'W0Vm4mR1vAZDU5UjbNuOF3D+LynSGkNMvTx6yefwUp4PA2THeEtPEvOFgahc3lpDbKr86/l1ipy';
- b +=
- 'bBF7jaqow63VHnCD/CIczdGoA7besjMY8OBN8QKcTwGbmCOURFkWZZaWhNlCP3axPE+GzzhSM2w';
- b +=
- 'f5JdRjx0DUp26aLKb2Dv5Ke90T3EHl/2cMwjtQ7ZLE92pojM+fZv6TgUC4JQtksy2KDVw9dCb/B';
- b +=
- '72nZT2PPBKBrRfHwIjiktDTs8ApI57jWIQx61vTZUveArLVbpfFlr6B38GXZ2t2tXZSFfPgZjll';
- b +=
- 'jLbPsjGetvdYedlYx2+2s3uqW/iEoQmz7bbV2md5Lel1T1fZs1eD0/b68qOVCyoCHn0EziXK37x';
- b +=
- 'HI0ubfQxRMc+ejmw8ScQn/n4RWPj7/ykxE/U8aGNP4z4GcSXulI23vbnMvniUjq2zZUz03wYIAM';
- b +=
- 'FGv/v1PRRud1y/EjZzkHbMRHluyTe3A6CB8sN0Zp7/u57qqcnFwbpzKAzZ3b2u1XkqDMrU0nnSR';
- b +=
- 'qb/cTTwc5B77pBNlP2GnG/NsPjbYltXwd3qhNxhDPfTgUFKPWAn3kp4DPd6/rJnOlPSPNc7pKEJ';
- b +=
- 'KUP578G5pzOXDhnwJozUX36pdXhl8plmboSgODKLzXHcPAhG6Wj8jsni97DCHdkR4FfWcn+MR/R';
- b +=
- 'adH4XPWH2MaAVQf7gWrpy9LXvyd/5CmD/yCVawzoiFFrONPP4Mu2MnL/hbvvQURI4NxEJI8IrCW';
- b +=
- 'Uf3sAonr9l3FQdicuw0vNUo58oAHMLQDFcRzHzUxvGMvkMuCwIFTMFKMjAkDpRyJSU/ngUnMXs9';
- b +=
- 'mS9jziS9ISQM9Xba2SMj8oTx1cPVMmN8jFn38vUPfWS+SQPJKrAap0SrytOpMO68sIdGTgt1tcD';
- b +=
- 'KWnkqJfJgct2jGeDZdyFrA8WoDMagWdDPOOZajMxxksl/KN0XJObeLPm0P5QHIpiDUngeMyeSwf';
- b +=
- 'zEGyY/PHxW+R2xK9ATKx8b6xM5z2tnG98eWx3og6z7r7qj/AUPiZavnLB71u+XR1oIbD2Ozqw+Y';
- b +=
- 'XhYdyJQ58EL/ZRXg623HF/8yijudQ9CSd16ZhVxZSWBAYJ9niWsSRGofJWT0hqpUj+nw91uLeDg';
- b +=
- 'C9K6jVN2rpGW4lCCr3sNKcydrE6HXKdh8HTim8yuO4tN9W+FOuzl+7xNANen1Tdglp697Xn5RVo';
- b +=
- 'ChDudeRaA+kglGTQs2LMpLJd3vZxso3ecv2QYHZt8C0q2ey/ahmlWKVXUzpXZSfyL3inoFRJooO';
- b +=
- 'DsgipaOI7azMHXnWj3Qv0+SiMCMhuNPtgMm7hVPKfqvsWXB2Mr5kaP+FBCXqtmPCkV/0e9JtHTw';
- b +=
- 'kuk/Zg4H02qpo2o50Qi4tbpc934E5kUroWfVBjUccJPKQqWICXQfiPK8r0YYltZUQo+68/DSdZz';
- b +=
- '1B51odGGqI3pV3op6NpQPpqrcLXnIrSrjua6P7JrCioYO6zQ5K6Bp8vFfbI6GRzqsUSRcRaprqt';
- b +=
- 't3w7eLR2zp2wJrI1rQodAwM8LusL3doeXyQRuRJtIVsHgjje4g6L88UblR4c5qVB1sTs0lu/zNR';
- b +=
- 'nof5Kv+l+JNxkEBLHlHJWy3Gl5p2KcLORoOTzUeOmUtNsPqtR3krXe3WI7yVrHbrAd6KV7t1NMA';
- b +=
- 'tSsGLizF30isTPchERGZ4qWA8zWeZxnRGMBYqWpji/ySyvbjfsHxnZUQbGqqmq3RYYd9HmxrMhV';
- b +=
- 'D3fE+Ck1S6Ty5Uj39L5HMaREwwKt42GttjbD4W22Vsdyy2w9hiLLbN2Kmx2BapL3+rCreBF99UH';
- b +=
- 'U4u0l5wn8qMdmGw76nq0oAf7hCeq9/5VKVWH9H5Rk07dJuYYuW50ASXMqp9iULppFqVg/8tdwBO';
- b +=
- 'D6t2tQcf9F6dQpshKMBkc/fy1JNuQVL6OZ7VYBVaN8ChwMDMEDORWMsQpQri/X5are/rKb9MU/H';
- b +=
- 'CKFoxUnMJIIH+Xd+S7+oWxW5uZEfSsiktQNkAuKs3ty/0Oy6GExCglIOuhyF3mwDlbhOg3B0F0X';
- b +=
- 'd0im4rQLmlPiPaw36XpXYbKTmxd9WXQ0sZwEqu925ZDih+EBE1NejiZ3rQpk1JVPxRLK+PRMhYG';
- b +=
- 'dSgQXPFcAW7+dlnTXWvp8YVmGI2kBRvfVDy4MaoOWF56iKl2vlKmZC5fmN2xjzRrTagoqZNBssb';
- b +=
- 'aQLnE/pjCsqOeu/ga0Oh/bxhMjIwNBoJZLDlfF0cJTlMRQwtUHCVe6JJZzTS1edqqdFIe6yJwMl';
- b +=
- '2V2miyBL1EwLCjBZ3G6Yiavcn4s1VNHnIN03WFJejZbI2m6Dz5iQ0O1q3WN8p5HyAxhKm4YNV3T';
- b +=
- 'Ij8lbZyNxoI/GJnw+zL+sOdsP2wXgSCt/wrdrwJQz3sHCzCm6s88MCnlyjufL27fTHPJKZPqPL3';
- b +=
- 'c4jbEYXviJVS7Zp+MqNy5TloIiERaxoYoL8keYf8wqsjmJTuqqF4100jXzOmS9U25XNme2D/Lr7';
- b +=
- 'wAXbkW+Lbcp8m7wL2VbtQlbLK+BmNlYnyFJewnYiUayNRJNQihQ898JXDIhKq50rR67AyBdYosB';
- b +=
- 'EG5igA5nbZy3HsiaaNWEu+uXVl+r8GNt6IyhyksvC62x/XRZej5friHazss2G28IuC3/dp/tfca';
- b +=
- 'aO5rhXJG+ESV7kk/wmi+Ljyo58u0sYXRa+mHeQ5gbyGsCS/93Wa7dM0R9NwmRHRL/jxg3P83j+F';
- b +=
- 'JLIHhdY/H+TRxbHuMIMImu7S9/YOQx4W8/CgDdvGPDmDQPe3BvwtpwB74u5voHywJnvouWPwsvA';
- b +=
- 'dqroKZ3KRPDQq5eD4p/0xcLCYxp/aLoLcw/ZKIW0I+MnLGPHme5G3nTXqA9sYITxWz36arU2Dau';
- b +=
- 'TdML1IWuI50KWzOTLjrnk4mbmJ0cya8oPxdYmVF5I9WTQtNwNlYEw1C7n2d6L0eDfFEHfRoKT0D';
- b +=
- 'GrSB0g5GxY7Urau8yAz7rXXEsMRsqzu7sMPxybNcWBXUg8B2bCEDtipJWLO+GKxtP6TW+VkLfaT';
- b +=
- 'b3Vbmqtdl9cKkMJnjaudr+2Pt3D4KlK9yDVk6/Ujgj0SOU8d4RHeaKwUUUdlduo3EfJ9xict5Gy';
- b +=
- 'yrLRc59UZa6Uxq6o9Z8Tp9FaNP+mNVovU4XWjarPerGqs16k2qz/63SKrOyZKbLyFYosEttBlRV';
- b +=
- 'GARW+5dD7qZgcVmuKNU7jU1JFo352GvfV2tj6mGf+MW1PuTG6zvqluQ5/rodPm1+naqf0mp1YNT';
- b +=
- 'vQjUVWNzbr9WnnqZqntLoX4EFqZVquemqb4Q0jGWxiIG68sqgML1cqf/gC0kN+aoIuUEXQrNcDn';
- b +=
- 'dfI7ZU+s17n42531LeM0/hkJDSFwud61f9cV9pus+qeRaPqng8k1ndvND9ILapHPcfBgFxF4gRQ';
- b +=
- 'qc12qkuqoy/cTI5w8MOBDGe2TNcH+0NlmYWl4LlDUOJGRGPLBkKTykX10zyySYFB6pIYvNgd611';
- b +=
- 'MgIiwaeVrv1O5KsDXaekiyP24Feg4zijbtlxq9ofNXGHB6Uf6c99rlkX01GBXOciLfRFnu+6weE';
- b +=
- 'N0STCa0ybFEzG/paNIed6qDfwl+QXLE1u8zGgcn5aaE36I3zFeKZKvUuuyWbVaFFHXGzXr1QTSm';
- b +=
- 'efZ24+Hrn6dB0kT/KiPLOrIR3xkXkee1MjICiAauStykUUdeYePnPaR8FO512wMHwp5He2NNoKt';
- b +=
- 'wQ4JpTgE9cMlwW9DsMVKZcibCw0FO70mL7jz1OQF6rfMjkJPaJDiKFTkjY9DHM6IRzOeAg0eCiB';
- b +=
- 'T/uWn7vjqex7+50duasi1iN/14a888MXPfeSbB3aMyKzBnA9v0PBiU64lh9r5Ub560UeCU5V9NB';
- b +=
- 'gr/HiwSulYUKX0YvXSSZCyaul7zVjp+7Wg6dULWj5lQUc0X7kyV0ApGyfkgZObwRllJWVI9yI9w';
- b +=
- 'mwtGBWEY90uqATMDNep6F2L8yqe2mIWIbBvjAqW46Viu11o2b0K9ywv2u7YqWwilevBaM7iWNmS';
- b +=
- '0dos7xvBcI3a9mtt0/p4YC4+P7pxO/4uG/4cwY/f/9idwnZ9oTYutRsDNnG7vqdVW6TvZbQZwNK';
- b +=
- 'RfUyG8d5UUSTPxphx3KzxOSvNGteeMXXmWdxAfuHryzjxg1FU9yxEHG1EnImIryGirRFTiPgnRH';
- b +=
- 'Q14gxEfO/rNDtgxFpE3PoNUvnstAaQpnr9N+oUBSLe+I26UO5v9zYiJhDxTkTkGtFDxHu/QauHn';
- b +=
- 'dYi0FTvR0RPIwhW/ygiJjWiTR8YjRQtRHwFERMawQ3944hoaQQQ9dW/fKN+/BQRJxuFkm7l1U/U';
- b +=
- 'hVLW3vNEXQbOYdcHYT/yZqO6pZTJeS5UGbxEoHqMkkdY3f/EcqB2lY9ztQ4rOjwFFCTaWh2Vu0M';
- b +=
- 's5zoX0VxSrrKhM3PLa9O4Z1fvruM/knrNs61334+k3ob93t2JadsvRA+jzrMnMFLgJcEFQChfFK';
- b +=
- '4jm0qkfPNRSStBi4jnT7dWTMNIP+kF3slWYLcwOTU/InDA0MZCE2DGjrUphEgYqAcoy+iQ8bh+N';
- b +=
- 'izVTVOG6/Oslifu6ApH3L+lgAAtQGQXOW5Q+lgvX8ZzE+IIwmpKuY6uUFOlrTgBsw15Yd2OHAQa';
- b +=
- 'bA7Q0SNNMqNNMs0mEfqd0DxPZmrKxeu4J16nqt4LGJjWO7OO74KHTtBxZt41L4XqicgEISl4pL+';
- b +=
- '65Alq4SSnC7dtHzRXQYNHDhMpAVJrhtrbeNsRJNOu65S63EahGQqFJqw9HLTrAtu2QNq2kw8Dbn';
- b +=
- 'hxxIa33KJFCpiLoq3yjHXvSwHo+tD1ec4N7yC9ShEvJTs1vtb1HLoWYrwrxNDDVt2PtHExKosbB';
- b +=
- 'YFim9h5NDYditGBG6ZEVjucGpHVjUA+bCDPypFzk0Ua0IeQoGNGnLvA8WpIWjJIcaYaVzjpzTfN';
- b +=
- '4MTQVC8iHgZkuVf0uKEeArsZXgGrDHKWEsOb6a/bE9kRRUQKMeyZGozaesAEoBaKZTgPyonOaK1';
- b +=
- 'dW2vL1gbTT8uo0mUUyR+Gg55WWSbQtaZlfm1PScxTPGVPPmbc7GwtzRaCQ6tc/p384LL3PJBXj7';
- b +=
- 'uQ86fceCZzUY2qsft409FC7viQKyRqvIj6LYy8AkzszPWIr1qetDr8wWYZ7qVamUjZ3fTV+qh86';
- b +=
- 'F6wiwKDnew9eeQRWRE60NK8SB1oUUUdzhVjaMMRJCeRFn4yyn6Eo+zRQ81R9tChH2qUPXnohxll';
- b +=
- 'Dx5qjrL7D/1/a5S9N/Un3j8emXT3P9aiH2XSJUSkDZn0jf9Yi6BTtEsmmQQWjrfhVru6lym49lU';
- b +=
- 'P4PoQ47msVw/JdfEdo/IrMhub+VEkCjXRMSQ6apxMewK3Ci/TNnPtfgzNq16Ln0gz3ynXxe2h5+';
- b +=
- '/wae9Gou4p0lIS3v9Y/WwTo5kPPMZn+0Qj82GfmULyI7jVaQjJX3us7ksKyU88VgvabS0+tsV/u';
- b +=
- '1Huycfc01NwvuPx+ukpON/1eP1KKDi/7fFatKbgvL+RJRmtaBm3etVn8JPz+aqHcX2MhTZ6he8o';
- b +=
- 'Hu2EbzzOTjiBn9g29nHXCdHoYLiDW5VqD/c0jcHwFkS0xgdDONrKfV+va7j36647zNgrQaJk9ff';
- b +=
- 'Z4baXUup3YuVjLxqkqzhXhfk71XaBFS0gUVhJouHpNeHJIHXL1KtD1dW9YUhEMnBnBPv4Lyy90I';
- b +=
- 'i0JMKShdymqCmsDtKfoRPdEisbLn/1IBaMMpFKbWPUXvVynOEvA4Gn8ucVEBI1Pc9oWAwzhcxEM';
- b +=
- 'h9U5bgVRtIYppESpHFgG8o9oEF2AyPzg7Y+5HEsSqIeW+PDQQIfiXAZQLftcNE4029h2jSAB8Go';
- b +=
- 'PqQvRbiO5y0WIv2TUFFJ7oeKJAstEHtogpa8wMVHLWRIp8/W0LJ4tdQA3ir2lRWQexI1Fn2JtKh';
- b +=
- '9w3y1YQu1Ty2ltYqrW4YWg0zdKPzGStJ21b5RUxLEhZPqOjM8OwfwcqgEqFdyWbyFcOIrHBceWz';
- b +=
- 'bSrfq++JCEJ2dXqZ/ZxGEjygRjr71yvuYmwHmc7evQ9Tx29KgUqvlmwu0aJd1BSr9hasyphmc4y';
- b +=
- '8/0IDzXyX1dlaPHsBHJACpTox7LX5iO8hdy6LQtDKDagLN0YgQgROtxFXoBCnSpjG5Z03mAsIkH';
- b +=
- 'i7j7RLkADpSmmHNDRUkl5AtR7bA7j6g/C0BI+RWk6jAqtwGrzg4BRhl0GmOtY8daqqJ9KhFt57e';
- b +=
- 'zo2MtRUFdkKSmSokXV1sJA+90nDl3aa5Rx9bzHirZ1hMSD0CIPaUAhKNtqtAnACG2wJXEAxAUi4';
- b +=
- 'FdnsWKA1aZYoR4jIB8lc0+CtlHJDEE4cocv4HEmuvFPK8s7cGRrWu0uA4r6iupyKY+idcyRVjk8';
- b +=
- 'trsGYSf95LOJ+MwVna8owH4QB4OrMDDswZ3echfkhsabYLUxzPHBH7PjHo5L8m+nsAYo0zvgz9B';
- b +=
- 'XjdsH+4h/WNsbbDonkazqkeKyFZYuNhCJjkfm7vYXHZ3LhZ+5y/3vlmC1SyEXIPDVRsc2wZH+ns';
- b +=
- 'zhOnfuXekzeFom9XodpVmqwGub7lp3mg2PhtrfEkLlGSk5VnzAbRN6FPtw8qtD/IwZIXQgpzQ6J';
- b +=
- 'rWFBxdq5rCY1xrdDeG6pPedkquR3j6+tg1WDDShftG7VjqbvlCrEInrMsVPfBATI7H4j2RO3tmT';
- b +=
- 'HG2vaIayt7esNrtDcMq0tsPB8NGbCOJ3HBp9Ex8lTRQI4eaZl8jTd5MIzdEKmOaI400+0wzEdx0';
- b +=
- 'naWJTjQSHRlJBFdNF2gidSXhoxuJ5I40XVMdaqTaGzZTgQrbFnX8lEXJHdcDe6JT9IDcqJ6jaZb';
- b +=
- 'iUzVc7oi8yETHohXdpN40YOZuu1LvLnvu/dGil6Pxoknp3yzagAWfEcUrwEseNIoDtnAWOnYaSf';
- b +=
- '9kjvrJHPUjmaM+BvWLk6eojIzJwuFplzNn5sCXQBp0y22SkxeTeE6ReNuWjzmfFyEk3+St5dqW4';
- b +=
- 'Tko21fyidvzA1g9VNQ+lyJIQVsL56pJ2eUmZUB2YAl0oEvuXaM8XgjQcKDbYbauZQAG/7Nke9Wd';
- b +=
- '+44EN1VPf++7Lx0uVIu3vnzXyxYAxrR65NOn6uLldkupShWoUvVVFKBzkUX4vtrKiloBz1p2ddP';
- b +=
- 'WIXR10L1KrQRgBKM94PKCkWz8IYGMbTxkqCAL2VBKDCG+EEjLUG1PAl8neZvzfk/+Z93S99dYal';
- b +=
- 'SIrD0pKFAe9tAyyUpOlSifPAq7OVIQ6B6NDO1AgpbZvGrDWWem5LayGdxhGwuVtIiR9DMO3Zn0S';
- b +=
- '9uVI7sj1i4SZNo5EodmR077mrDpmOdF9OUio5QHGRt4RfcXoC2HSgebwfOjXEak/EzLo0Dl02+X';
- b +=
- 'SsrAr+1FGMUbI6JaNkbXQem+Mboa+EL1yHGMzB3wQ3WOd74hccUL1LlFyRqWzCC+uWQte8wguXn';
- b +=
- 'Q0TPNQXYzgYud6+8DBQtPQG8GIBEO3yOcpA7ym3EEi3B+/X03W2wmkkDKlCT7jBQiXxe6BgexN1';
- b +=
- 'P8zJA251GqpN1e7DaqzwK3Dw5l8fcQ/x7h34eNTzI9aF0WnrCBYpBeFh63gRwWl8dsIMAHDbP2s';
- b +=
- 'kUE40lcprx8EpcZLx/HZc7LR436bnFqvKX6cnfYVOkthg3iiFINUOgky9mfh04VWutAVUW3GDZ0';
- b +=
- 'dNZj1oiezjrNGtHVWb9ZTl8n672sb0/Geoa86IGX00Me5nhXYmSRKOowmQoa/reMv8NpvwrOD3c';
- b +=
- 'dvtzHFIw5+ek6hg5fwiddjFw//unL9VxbZ2VE7fmUva2TMqKWmlFayO5P1YUs4vpye9Lu1KkaKk';
- b +=
- 'ZCTq3KhfBF2v3F1zM34TL4t2nxrhQxPOATAeLeyDph+9u0by81NtJUrl13HF4OivtcisVPMYQXF';
- b +=
- 'znteTlslm77xFZwtK7g6EgFnJo56bGAnYyswk02v7T43ZH3u4dmvjtSdReTv9u2x9bw7khtco6O';
- b +=
- 'tPfoaHs7CnF4kR9ormObA811b3OgNaAO6lzMSOfK82InGCp0rPONH8eoO3JgfNQdOjA+6pYP1AP';
- b +=
- 'mgQMrRt3xAytG3bEDK0bd0UYhDx/4Hxl1XxgddV/MmkPuHW7I/XVzyL1jxZA7cUBe2jtdioc1ND';
- b +=
- '7kXNF+vL3Djbe/bo63d6w+3r5lVoy3d42Ot3c1x9u7RsfbuxrjrW7s0dHG/ijH2xey4u0j4+1kb';
- b +=
- 'OIdvPWdrB86HVfxyUxVXAEsDyVMytyoVJsSzLTFd7NBYPlyKWzgSDlaqKKrevCebJRKVQlq/yyh';
- b +=
- 'WUtEclxwJb7S9mHg9GaOZXiQXKmMudASx0Bd0ky3wSsb1byyUJuQTxfmzDiXp+QcFH+QQ2/q6W+';
- b +=
- 'DeTLfsglhcVBJomy7uqHzbe5YgAO9Jgsw0nwCxov62I1HCPEII6rmmF8irujQIXSPEK6kxm08Ag';
- b +=
- '22wEVbd2Xke49PDtDFHsfPC2ZZkdsMWWFJF0mi2EZuPjdz68WdeHAt5U5Xyh2+FPuKpAGTnUnHU';
- b +=
- 'bBJ+6e4w/Bc5WUL1clbPwp+JsKr9SkGUWXIoLR1YD8dIj34oBgmW/h0IhGq2h+qUIOfrvpF66rF';
- b +=
- 'Yt75izgMm14g9FwuKP573OSqLPTgcGpY/ENtY7Y+WGMZZcnKuN5dnJJL1sZ9ycZ917ISOl7Za3u';
- b +=
- '5rV0+9j+nyFbMRb/mPBJgLPxL2I9J7Ahbu6KOfyviSTnYWRmfWSbUaJSaFqiN2BZe7IFtYrYyb9';
- b +=
- 'rIu3M8b9rIuxheasYzJ43MDYZbzZw0Mgcr88Yur3ZI0OwQM9YhkefRdQTCdGehPMLFvBKaxernJ';
- b +=
- 'Dof2zpJkPBhRaomlKhZdURexdxfTSsZalQR6KIjhBSptC8unsqajg0698fKjVrru3LrlVPkWGva';
- b +=
- 'RS+cMYNQjoCidkQpAqeLTrm1wfpTdHoUidXbqjGpIx8ytQFIRN+B7i6sS1ZkWTQ2y77VskDvZTU';
- b +=
- 'zqvfKXdOY50Qd58tRrVbeUDIted3VaO0aVP0W6mVwyam2Vjb1UGir0KBvqiq/oERiDwWnUGAdMa';
- b +=
- 'vropy+bE+jquNh7fORd7Qmp/KyL6ouJV7txXldlga9igxBde+oijAWraqsd/9ES/qvX0uajGtJm';
- b +=
- '68DKlJb03J0in5cdmrUoFEAVsJXyB4ibao+T0TmuTvA/nxun2TRzwU1wvrgp/pkuj4H1Pbrgxnw';
- b +=
- 'uq8P1sGGen3wnD6pr6FgkJ+zQaKwPjijTzbqKdBxrA/O7Pfwc1Z/Aj9r+5P4WdMv8FP015CMur+';
- b +=
- 'WpNP9M/Az2Z/CT7t/Jn46/bNIXN1/Dn7S/jR+sv7Z5B7vn6O84zP4Sfrr8BP3fwo/Uf+5eEp4Qk';
- b +=
- 'q34jccnFuF27YoaffE1i3AmwbluZDupreW68qfotnZc6tiK4zNcIh1ThVuLWfgtqo8u2rLzelqL';
- b +=
- 'fKtk3szIOyd2lqeVcVby+dUsaQ5E16StgBmGEjM5EJ11tbyDFQ+xXrXotItyrw7ZWudLAvWusbW';
- b +=
- 'ipWgh1onWGuXtXa0VkgXE7bWFmpts9bc1gpcfdvWmqLWjLUmtlaQ6me2Vp4pwyuhrTXoPBibrj0';
- b +=
- 'UTiiuwE09zrdvgh6pjD3BCj1RlVGfmkKCOXuOS5/8J73hYIJqOhVLyq7KL13l9e9eo66RvI8fWO';
- b +=
- 'R253XRM7wjk9+rUzXhiHmInlSWeLEHJV6vnIAp6GR14s3KOzCYUJ4X+Sd1t3HwWVwLgmfWqW1QO';
- b +=
- 'hbwdCqpcdc5kbJiclHG6j8qG/YiPQ+VhvR8K0NHPiJt2DEsPpAqUSm0dnG1dP+yehqyMWgHgLh7';
- b +=
- 'fTx6pd9ZgXyaUKJyk2VZmEWxRWdMKFU5+D9M0Knul1Lw0JAIU/l5JLiql1UfYCxI7T+oV0mnOqB';
- b +=
- 'Xcaf6iF5FnWpZr3h++8g/Hrw1uihog58Xw+TYmx1xwySj4m2NqImS+Amc0cjTSkkPsCT0gwxPxE';
- b +=
- 'FHeeK9pLBfvN9S2N9ppZSlWO0hY51uiz/BsTVmwqh4VcpTC1XJ71He48ju7HmjcDfg3755I3c3w';
- b +=
- 'MrmbsBUb08Eo5JYFlct9Ug09PlmbYGHRuNU0V/HoZgHpJhZ204kKp6O9ZzHt7V4bT5oEHTqzVGC';
- b +=
- 'To0bJeiMLUHn1XL3cZogoleYEozBER9vrOykWWi6Wml7kO8OM/QttsVpSx9JfTV6FxUbzVH8DOi';
- b +=
- 'ejG1I8Rjy3MugRBZfy1x7+pHPLbflJarusrTRxVuwd46Lb2Z61iJ78Rh8sh3dC5Goi6vK7thklt';
- b +=
- 'e/CTgxpJ+wkqxIxsVTBFd3da9XPfItB3PETW7XjYdI+dM2q0qFVlTy2zknoS32umt1/zY9yBQ9Z';
- b +=
- 'VFTSujIjQ2txLgdAbxhkAMwIY+PQx4w6GZ08JJgaqAupZrc3CO2JsPk+nSwsEXmSMj92TId8SlA';
- b +=
- 'PKeLlGtpFJmg+IRuX+jJxtEzW1obefKUSJZ+gi+YwC9gX3SjornDjjVIc88Hy3K7NS0w/yXV7Et';
- b +=
- 'InPVUQApGLdzQKr/wOhNJdaOrKlYG8sd9D8vz3TdX3i4v0EHK6oJ5ovYUmdd80aZZ7EtcsWGzII';
- b +=
- 'v8CNTCNOQ+prMz9h4e4iZU1CKIpF4i0nZgMeM33yYzxu+oKW/uHCVa04cGCi4hTs4fr1xl37RRm';
- b +=
- 'w5DXR8XE2vOUCbzZbQZnjLUOwZq+VZIFnwytmE0JCDyd3WlV/Qib9SgRcDN0TVKZd8tU5SRKHMx';
- b +=
- 'zL2GwEZNKWxnaugqSaQSuAKeGqRVDCsFQ8AOfd7GK1qrELp4NjjzInqFxsYAe9F4OBsEF9FKPdV';
- b +=
- 'k1ePvOyhrtzpbOonrffcfDIqnZGGv/vReCf50deg+R9rP9ib6zMojHtNjNIzshrbROKXmt+4eVr';
- b +=
- 'a084NIHcA3e8zY8lYUBsciHfUI5dwOxDoI3lgPAt2TqN1FIDvZz4Y15hyuSgK96HGaoKuSiIYv2';
- b +=
- 'CdbtpjAkkR1406dE14yLnCKk++piwiRC3v0Mnf6YpRLa63lzmIuaAXflzJHqW1EHVOqb8MEY5nX';
- b +=
- '8S7Sjt49k18ohF77BSenr9Z57rbOKmPCwIw6FjJ8BOxU1/zAQiLVbjiNhbaZti3QWNjZowqtZnN';
- b +=
- 'aGXD4Cmr2iicNex9IfdJXqDPSizi7WxrcM0/fENKPIm+jZ3RdkJd5SQCUmbGcTkTF/qsZF8W/5X';
- b +=
- 'GxO/x/ZVy80o6LZc8vSdb84vGspjYH60fxV07NH82Gi6bnTVzk907ohSE2hd4KRn7vAo2wi5XwH';
- b +=
- 'caKnLQKFKl0lyx0pa0wXK1CW5XRY3Lq+3wty1Zy9BVo0VfXRavmvRy6o0ibqxlcdFzt5XAVZnhn';
- b +=
- '6DFGDu+MPVz0PmPP8ZuR+31ko4AHfOT0CDl7qfTyuLx8I4yguRpphcsj7igiRUyrVIiD9Y3eLYW';
- b +=
- 'qO6fre9ONe0YRyv5eUd/r0Bs3hsJ3I3uIGLmhQG3GcqLwhIZJzZJpGjepuXXjHH4Jb4z29RbWEJ';
- b +=
- 'Pk/LyBKXZic3yCkZpA/hb3JYRbNO9oHDRLJz68HDTjHmISl7p4N+LuZ5zcqfZ8RDrs3XU6uVMsY';
- b +=
- 'EiFzfYfDZvtPxqOtf8o3ZQraiAcurLWB0+aQdx8AklSvCZrtuZ9oUIVXJwWgnT7ZM9xE+j096W+';
- b +=
- 'CB1Nx0dHzgk3+I6PDp4TbqweHxk/mL4eCHXw3LgxAvzCN6d6UAePCD9w5tBXBvFZG4954Jcxykj';
- b +=
- 'h8LZ43LefHtysD+5dnNNNQajhB3bNIYj55QF3YHRAz9XomXMWIXgLtzeUWSWCOgkAdHI7wcGvTK';
- b +=
- '00YMYZC3IdW5yjnW+Go6HiRKbey2JNirkU+hucWVf3vv8gzgMv6weqpVJ/U4EexsZXquTX7Qfqa';
- b +=
- 'w07v1gN7HDMSIS2iLfeUhemIGvCwBmJ8KQPUGwI6sVnSfHZrWK5cuIYC26WaX74Mh2AfrUO4BQl';
- b +=
- 'XcWzI3nNuetbHJVG2reGR4XOTI6sT7Kki6Ruycqvsv4Ei8M02wi9Qzi6doRzV4jED70LmP9Cd1A';
- b +=
- '0zXr/QT1+qzLFCRTLcdB5IgrTsXM37C6Lr0XNc7dc33aL3tISFquTz+djhdrTpwyk77lI6SxiPe';
- b +=
- '10BbQH6qdvA091q2v1qK1Fz19Vb6zAsVKsyom2FDTv4VaR1sMxdy+1Q0hj3VnPBcWHrSuUZuGfW';
- b +=
- '1m4vn9XMCjkynTzDHeH1w3vm3va7Oy3VI9nDYSw3b2SxIKucn002aA0GlC2tAFqAjP3B+/7h8P4';
- b +=
- '/+zrYThTB/8XOI6tks0KhIvJ0o931Jpr31ImrH47Pc53/NmYlHzSuEW7oOQU/Vw0/UtRPheoc3p';
- b +=
- '1jy7FzEVwKR8AnOY9jXUeirxuITkvoCmG7jkGGXf0OvRy189I4DecslPHI/9HMqIHOJTGVsxAb4';
- b +=
- 'r9itpvjA6ehNInfnqkrKb0Bg6jKb5rpROl8UvH+2KCKURsTUngV1Hfr7SvTS+6eKUjZazIqM+jz';
- b +=
- 'wDmzbIlr7Str9EhPtpljtfYsc9k62jpS1Q7KupAs/lBXp37OxU4ZV52EzyiVcGv4O1ffdOMNl/S';
- b +=
- 'DFemudqncUMiKvPiM+ojmKSYtq9pR/tpGQ7Br1JtgpEBv5llq8o4MOS5b4A9VcZxYMu6rkyLJWo';
- b +=
- 'p+VbvjUyL4A3OVJcE5+p1MYguCdbqdTmQeTdRppltlwTPVVIZufopvR8P4GXvkmCGzNgTcnWO3s';
- b +=
- 'ix95bgNBmIutvgoE838QMozOH1EO1ub4OvPlytlasz1NxKrtboUe02nPMy25R0FioCBXfOinp6Y';
- b +=
- '1q6HxVxzLKitt5YN2izIlXYo6KMV6goJe8WKop5hYoizSbCCSsiLTIrUqKd6W1VtED27y2XBOv4';
- b +=
- 'uGeBmReGbog6mw86BQeDMHHeSp+DeAjNmGvGSTZfM7Y0Y5cN14xtzdhiozSj0Yxh5+FIBfQNbuM';
- b +=
- 'Wj23cIN7HbtOmZBoES6iVmdsohDrouVEIG5u2tLlp+/Lopi07fTGkuKZYGo/v2brNPVvX79nszi';
- b +=
- 'TUPHabafdsE4092+lqjRp7Nt2xSbO5s8L+6PSP7Vp2T6grc1cbdn7YkIflZ91QbUvXDe3uAiAFj';
- b +=
- 'Zqqo7o2qmuj7F5r9CmNjcvrOEen0vm4fbPHI6+6lfnwiYxLtrHOlCXmOGOKb2RK2h0VX0h1rxdB';
- b +=
- 'Oo+sp66b9fkgahdfQidAaDVVf6ihe+HiqZqlH6Ow2sXD3Hv5F6eY64MLRDh/FaEFYTMh4bOIswV';
- b +=
- 'KypNGhh6TnmD0ovvLQ1Eea58IPRJB02h9u+zp66Fo2LzDuCMMyZ3qgc+ICP+QaabwUAAUPGur85';
- b +=
- 'FaHCs+4lAHh9QSJW626Ij1fQZ6UXSZl4l57s67A+6Or8e4viS4jhZ2NlH16OHlQP0sMgn6+jgl5';
- b +=
- 'w9EYVelouOWCQIynyOqSQh8o6Eq0U5YQQP4yaQ58aOBOgFpuT0oTv9029nvuJ0mqafbuj/p6E+3';
- b +=
- 'ySUh6R4MhpxOkq3D4p9swTY6L16hnBD9Htb6G/oTlibbAqXLiWupiY02U756lLgD6fIjt8lreCV';
- b +=
- 'MTfqTZc/fOeqjy8m58vZdCsgMYTrbQ1t7lj7Z+p6aBsN/u0GfMOiVnQZ1wmCi7I7TJmhdxd9BYI';
- b +=
- '7xSAOFs9p01Nf3fAB+MV1A2RYiT3XRwsrZUjvdjgIE7V5S3tv7IrUS3x9yy+PoEl48ILnSbw8i5';
- b +=
- 'RiPdZL7zVLtiJVAT5050lF3gF6W5bAsluAMGtRuAWiRqDSnWNEtHiU8bzZ8CHyu8nvEDCAqAGe/';
- b +=
- 'mQf+s+EybRuY/hAvM76etIwVcFZeScYiHLcNnTzJ0xT5vUktmvHI7HZjyRyNApcKS4xo+HiXBMv';
- b +=
- 'G3Vk2lvYw0Dz7YP0QkBxxlUT6cKZByWhIfMf44pfUq6xpECEG1rOsafAgBtbHrGnQICJOXi94DP';
- b +=
- 'UUYX/ILUoZbZrsVKX82/0ae5iyJwo76hCFtCvPgObj2fGyYKcFn4809/AGZzn3lJQCBhm9k+Ejy';
- b +=
- 'stQPtyYZtcQb7tM3dXUbXgrgU1KtnlGxnwPBl/5fdvLFi4mbtk+mIRV0yStq3Ja+0hZbedyJcbn';
- b +=
- 'r/zy9kMCm8sQMivedIzBTUv71JoO16YMFrTLbwkwi2fJOxKo9qBsIoDVB2k5AhS+eIQbJYRUSZ9';
- b +=
- 'vKqno8TScF2PDQKMaMNIm1UMfkxd5UnleB4G6RInhGiDDzxQMuaEgzTV3SHfOjyLP96yRV6LJQ3';
- b +=
- 'vyQ/EYjkyQm3mL7yYVznXC2QFPm84byEBhI+RTY/HrsBBvHURgoGI2uYrmnKEY+eQjul0pA5rnt';
- b +=
- 'bbDsIVHZ8oXFiOndb7SmitfIVsp57GtdZ1zWpSJ0H0ymdsh7zNWTubYnrRGNE6neQpsb2ivyAqa';
- b +=
- 'RbYtr/Hkf7KUEO3rYLmkHnxsIeoKcDvyhGqibnlxQD7GTDElDfmInpQ+rJ5f7XtQunJnEnT+KFr';
- b +=
- 't1Nht3uJB5NxIU1+jvuCanhfgcTnVA7h1yoyxfYErWaRMaGVGIrbqZUP9vdH+vljPu4byX9/7cc';
- b +=
- '45lmsaMHhtk6hoq0xveKDMlRdppnw44rCNB2nEUyviN7ha0aabSCJ8xYI6otkKJzdRj0bzGf3eU';
- b +=
- 'Sm641dxIr4+eOXiHMywTHF3Cjo5ylI8MAyhagEzXqbUeSE1UdM8Fq92P3gQotlloOU4JtfV/wTD';
- b +=
- 'yWF118fl+sGP21PC4r/F8EkggtmnskBx+WG3gbfvNuiRrVr+fVY29ORSRD5XpjrwJpBvU5fvSfX';
- b +=
- 'm4o0QfKGm+Zb3C+V5BowKxxCUbxlOhFFMdI1V3RxQ3jb96KeHxQncWaf6y+ok6joaq/pgakC/wN';
- b +=
- 'aRbReOrr9A47ypvro37ypNCpKdH67D4yU6t6xrPF7EHDyynHKOFljxbamd6J6P+ViVVxeFYBR89';
- b +=
- 'E3LyiRYLd+Jqw3auMfRuA/GVFbMWlVqd7Qm9HI0Wz9QsdZ6SXyGyc/QKVUfJljlYdDjt6Weq+l1';
- b +=
- 'URipJHhEXxvEB8f5oGs4JqJYz8i3kG4idos2XSxv4JuRlfhoyr1MbQjNOtzlxc01a8NqtdCBLiR';
- b +=
- '7+fOL5B+M1dY4UVvjFPNNytVntBXeNfOGMd4rXTc2jFBfOafPG8bZrzaoE2dLF+1MhvXgwdvZFc';
- b +=
- 'NVlqUVK1MxYmR3JHBugikJSeMTOxqlT4sPZvX6iMd5Z6QI3b2R2zwvRhj1HwEACKp9o1HFOxCxz';
- b +=
- 'O2GRPM+70Fzz3uL3GNExYPG2us0M+rNEnAu3j+qOyIbO1a4K0TNeRjdLAUnVNq8YOjb27hPe52V';
- b +=
- '1cAsSFMZV8+kptprhr424L4bZeF8ac14WWa8va8ztqDQNxiF2oJCB+690BZkhr7SRdd7y9ooopI';
- b +=
- 'ftOwAxle1l9uo10Ym3jGyEMnC8OvQcpX5zbgyPjq9uUz1Tjpnbr+Zvid+Q1FIqcsjFzcPNGPo9B';
- b +=
- 'ST9H++uRfhkFmvaABkYZcGKEIuzjR3tm7VOlhnJPlw0IXu75eutHhIBLAdwIhvw29OKRuGhEIb/';
- b +=
- 'OUAyShb6G5i1dqyav6C+ioy1S9IrmoDt3rYGPLSaL7I5iMhzfAgVl/YVMPUNzn4q/IrQqJSOUFB';
- b +=
- 'oEAm+2jNZ6we/ZJnWILfhmZIWXFkO+8j5ZO51OTq0zRWbQnkuSaEiMcLhPb+wibqoeNNVNGGlxq';
- b +=
- '6kj0I309X85QDuhaKCuRiiuiXUFIGl5ougHdQWXNXIHfmL+IZSUxnDgYoAJY4TU2lamMSzLhvIv';
- b +=
- 'k+mc18glDLi7Q8fpL4yl0evlgNTPmiCl9UFUEgQ2cAIxvOq/WKL1wbW9nGKvd/bKupa/CFAq40i';
- b +=
- 'EaKpVcZaU8Z4ToEVSJ0V9VTXxDJoF8tet+Rhx9hxPFHXMQfImJQHXAR2pzzAAYbcgdbxTU4wELA';
- b +=
- 'OvujHwDvWAXaEa4CJziFlnDi9FrC0xUDLSFX9JVawh+A7GhqCZ8RsuMZawlP/9iuZXebBh6QQtu';
- b +=
- 'UqgmDi2oF4DorDHjtX7P1ZgyRYbV/lPBui0wq811VVHmxOy0D+SztdV8kxjfg1JKBqJrSi9jdtu';
- b +=
- 'DMyqWXHcE8ONbxNciaOJyvTjz9u8PqpQvVzcMBIJfhppkymFc+LADZQPjr8v7uEO4XeT2IXOxQN';
- b +=
- 'hVFV70gh8X3MmvHCCpmUL4DPGHZ+cBACkPB+QUkS10TZfUsPpHBqQvU46WZl8l2Zgjt2vwgnVfs';
- b +=
- 'm1qHooLdYDBN3c9meygTqG7OTknyAaH3arPSAEaWxnVfNLxGRQwYpKa82E1uMEwKxl4Xm2F0dpI';
- b +=
- 'JpJBzwACxz344RwPvuGD8swncZ2PcZ5OXauDzg5Tr4ek/m9MVcxrlet78bHL/2XRXUa637GfTbn';
- b +=
- 'w2p6v19J/N6R/btexNVrmec7Q5qycZcQ85KItpfi/dVbTl8ai2/Cil6712y7rBszpGIwe99D+WO';
- b +=
- 'H0aGDpidTxHNRqVMpke4A1a1R1vUyx+L2wesHWtmnATaXRjNWExpDkv/kBfbdmix9CAVwoUKx0E';
- b +=
- 'U4TS8SzKrCKN1K0phFYc+clkfuCtMr+/AksDdlXcFhUfSBul+WlJjw9yy1ppXxP3b66sw7asGhP';
- b +=
- 'ULCZooIN8lkea1U/jz7rR6kUgkU/zQsC2g079snGQ4ai24bZJirr3rdYd7Ft+NItQ+KNZhJ7h13';
- b +=
- 'T6RSh8totQ+EMvQuGqi9Cr3SK02uo4tuaEq6w5YXPNeTKUTwj6j4ZMB632VnrodK58rDgcoMG0R';
- b +=
- 'DLQ74NCB+ZeA7nuKbImgPde/QRam+U19OC7mY4h5WsLvQ9a+EMm9XMZb1al1xB+F5WtOoRSjeZw';
- b +=
- 'gZWC6XqxY6k1M7w6yV/teUwG2R9DHOrBQOIxJ7s26lQtv8PaDOkDEzJoH3SoGRW5xtE9gWVoEC4';
- b +=
- 'PetAWBWWbQHc2tXMlWaqfDhbo30ieeAvpuMIh01SHIcD9XLX7MY/4hpxnVOuUVQYmXYm2H8fxZq';
- b +=
- 'HzXrsLXQ5WKtvIzxyDnzmgzTvnvtwppGTpp0IqAIA9oKQ5G7z3I9VF1q9aFZwfvPMjlbpZk+u36';
- b +=
- 'XU4dyfc0IUbqbeiAX0IpUftJmKabiJ+33JpR1C0yIbgfQepaAmrOw2s8EImhFKCCF66haj1X4Zl';
- b +=
- '0kGE+nEwFrrapQnsZ1PrnsPgPrQ6Rqs2WtnSfa6yNxjVr1EpG1QnPiIzs/WJgMi7ll142te+wbe';
- b +=
- 't22yHpT6NqVjmlaz5hzPrOcPfIJNnrDSbyhtM9U0JPamppqikOxGaZIfU3tmqZ2VVXwSxvurWFB';
- b +=
- 'RS7cAmbBsIz6GTre79trZTsoD74Sqo7DbNDCwGK7HQJ04CT0uUdckOElJsP2DcFjr2X3unwRBfb';
- b +=
- 'rYuyWWg+YrO3MbzzRL8DedKEz+fqJmINLY6/K3aDfr+RgYcR4bW7y6T7mAbwpEnePppGf19x8dF';
- b +=
- 'O8WhnRjZUqmJf6hQV45SFEhCtfhKzMdye/93dIWFCMqzxcRilq5Sx+4xt7gLZIv4vKxHrsH34Rz';
- b +=
- 'BuBMeCzvSLwWzdgBD1Mwy6g5y4D1a6koY6KQcysXvgjfshPxRu6JBNkPm2GxG1rYmHa7xWQiTkY';
- b +=
- 'vpFXeqQyhs9CbAOdTpY/xYGluLKa7zfQ/5ovEacW9dv6WstgnAfTPy8/xh9chRbkulk3JuM7C1T';
- b +=
- 'aoZqkkZJ6v6efjFLJnAL/rFiOc0fwGu1gflJcELwHK8UT6chOgqfCiKsipVb4uAfSLV4+pG1j4L';
- b +=
- 'EsyGG6rFv+Ujy/Xztd19AhaNIoJSgGcS98l0vh9aFVvoVWyhU7Gpei0cFu+sVUXhqApNbt5T36T';
- b +=
- 'vv4Z2rByuTEOgtdU1BcNmdDNVU01mhs3okVT0GacV+lRmpDZJcTRoatKaSZyuq/oKk1iaHUWVe5';
- b +=
- 'xI4eKKOs6xMFjgb2j3l4t2jrSQCuN0du9UKJZW/d1QmXiUb+yp0H0uhXsBARUw3p5q0SgT+WKhJ';
- b +=
- 'leLi/G1/EYNrJ0XzRbgokL1Tn4UIZJOV+k2fzuBWkPpiGA+R4ME0rfXJSQuzzJLoDrHjCbJxov1';
- b +=
- 'tY4WsnZblS1Ux7Ucqjq4sQC3o0U/Ff/B7n1kNiS+0rFqg5Ev8+uqiIvE6MYWoxspRjeyGN3YY3T';
- b +=
- 'jEYxu7DC6kcPoAqi2MawZ5qXWqzpPhCrs7lfvpA1qZ3wc1kYu0hDO7mM6Vp1WvlKeXHuj1mPB0J';
- b +=
- '/KNuPcyawzTVVLXngADemw95JgN6ABS7QuBXXg6zO1VNWgvRUVu0I9kkS9sJi4eqM9vPAGtd6so';
- b +=
- 'hh6w1sfNz30lro2LuQCRX2Y5yjV8lNtJN0VuoNnF248IsONx6MirazPsWmeaE0fYhhTyEh/kzVP';
- b +=
- 'KP3+z2NNrX1jUL1/10fdvmAd3RgagPYi+LiMy5gICjWyZEorLmPzyJXpCj2e0R2OqtciBaBzOwg';
- b +=
- 'Auj0FldbdCRB6iKO/wOKeYXSIj3v3+1Vd2PCcaPdlQW15ryholxUDeTO/0gacPKydSfmh6o106T';
- b +=
- '3arICTkzVnYPSZdgwHOheUAcsO0Bm0g/QQXxF5jn9ApvufrR74M1mA/4Y6YoWFRx4WHiksPPKwc';
- b +=
- 'LXocLDwr2JXUUbQVTt/upaBPVQKVQjI6SauN+CUl897kM1TtZ1RmdxPQABFVzQUSMC6j70HmBBw';
- b +=
- 'lpyLNA/j4RYdzsjIIX1CBgQMjFFlZurQZfRxuBXYq0IP5KxbX74rv8ECaQDXTq5RL8pDERnswfR';
- b +=
- 'NgxwEq/kKZtVUHWG2qu2nS3iFPX8GRz4ltB3E8LD1rcgCg7mNiTt8jLHmt7BP4q4FtibOK4I66Q';
- b +=
- 'rK1PJK4H19J6yNc54VWPCBaBWw4H9W4W+/2pQAJTgwFrRDUNV+NUIxFrTj4xxrYOBZA3G131gYI';
- b +=
- 'dLAXoguGIvfS6ybTfWc6ZCG5xV/lVoPmZEmKPYlxX+WywPgiPnAcuDsVhzpzIHQlo3sT5ri5TFl';
- b +=
- 'fks94xPvYTKU90imKfGsrLIB9RsxfxlB+NVV815HD8RgI2c3cMD3ZeeRrhbfQ8YzeYCwIKVlxAn';
- b +=
- 'UGzuMgQm4h6ZPowf+Bl/OtKyLlLuz6oONCOK2D9iIDPI4a1hnnWgo0lvm3w9xv5bRDbe7PiC/L5';
- b +=
- 'D0mbyqi8KreYWt2uW8whbpYvkFadCTf0OJNINX86j4+1Cjy1QP0TNrzZfUi1BmWaSTeg3K1MwuK';
- b +=
- 'uXmQ41WjLfuw6u27jrfOm1nuWo79yntL9sZj7fzb+1nYIUdQoKCFcIOZaCuk3n0xiItQZoCycSI';
- b +=
- '1NMdF096DanHR06Op5oYF2J640JMF0KMZS6EtpJAptieiBdPGGWt1m/U6ewU7FI6E85mC3ojklY';
- b +=
- 'XkpYtOrblz5fmWi1dPvnHGuXbUlUvp7pYsjPSHENlmyrovC80+S1QRNHLLoWqQXzzIFGPvvQkGw';
- b +=
- 'yy6+8b5DcPWiAeBj0x/aySgDhSB7rqmnaQKPVwArbiCGTDsSUhjtQ9LpNNjydrjyYrNVk5lkxd2';
- b +=
- '8KlM3iM48soRcekDKYqVPFTO8F3vJ3KYTh8RbrcpwMIPwHZMUrFXdlJMUnhk0yxKNA93LizbG93';
- b +=
- 'CaPLSEQUMc26zkHptB12sz5JQ37rMYWHIxWc0gy5+ebaHYD5iUtbBHfddM6jvsw4BOSZQItBXbQ';
- b +=
- 's8zLpgIc895N8GWMFi0ihmOPYFfYf0daBiFyybceatTAglNDwZBKxMV02qvcSHNpsU8WsSLvgPq';
- b +=
- 'JIO+RmPiaAZ5PVROR6qNuivo6I1mD11NR1RawdnOqm9txWQnGmkDf7pB7203zSoPPwyKf9r/mbP';
- b +=
- 'v5j/qa//uy+6c63ocyqFZAiXli+lynZIj34lYPw3Wb9jQ4SmOqkUFYEWolRd9Ld4Vykov8LhvAa';
- b +=
- 'FDiVoguQKCCs7v2KyozqtAqzekiRgUo7rgcXIMa5nZ2lLjG2jDzFZZaEBAoTdaEaV0e+QnUE26R';
- b +=
- 'ZVpAZzw5PwWc8a4ueRdGhdSdGidrqALtrYnWsPXfwqW8fO/z77/3L6jbnXnvu0a988ralI7d95e';
- b +=
- 'bbdl23si1GBXDrljT1DkmjWqMYdb7kxLbYWUzyPX0pUnNwb2nhLKXVRLxLc+Pnq0lGVN0f1qbUS';
- b +=
- '7SXiBR/628w6igTXFxbUJAfXW8UV8AoPWpWuBuMUYhz6dYH+8NBrFU+rNGRyGahr0gi1axjpHpN';
- b +=
- 'Kn+LL6bWxvne1DdckYUXj5Sz5C06aNe6K2oU6E4JR22WLx42TC9gs0zqo78JTatBq2acAZrMKzx';
- b +=
- 'd5dtxqPqYxxqZU986/2ewxwPSp2xdS0PNjAeEHZhqdqk97MHKT8QRaDBhTRiXOvHh2CarD+kyHN';
- b +=
- 'vQnDe7wtoCitRPo7vk9JmSjk1ddqpyS/X3YJ2ozQAzmAFGzfBvOFPRaG6Psw0F5ikaNRXteVPRt';
- b +=
- 'lpc4jCCUF3Yi3atvWjUtBNkO4ovhI4VrvPp0DtE9470FMwXKcuYAyRON8D3o4j6vHYGfQHhiTga';
- b +=
- 'Um2xWlH70uCMlFBu2cJeAJOPrRDAeSS1dQsNERmiTd6W5qJlLR94wnkB2f7hD9UuNqqqUEJsMHQ';
- b +=
- '0wKXY0e7/zrLd0d797WW72ZW2PPAdBy71W3eHWsxXohbz4Sp4+iZqkeZeR0LHWmxZ2kcx1+sGUV';
- b +=
- 'UoLUWJDWgguUGXXNxqvSUGdEdhHXPINDasnpb/N1Sfl9F2TzW5IPnbm2ZkMaDpIjaZEGGK66Gxn';
- b +=
- '4t34y3Yo9xFLLzyF2d2shhXh1ThyzKhlITIUmy0xyanqHXjj6vSjiMZLxXnuWiqB/7W7etHg3/l';
- b +=
- 'dZ86QKvnWT+CwdzSZ4PfoKBFGu3nAYkqmVvAjA4S2dODaBiJFgc5fm65+R6ZN+hl8NHgJbBu3lp';
- b +=
- '9SqoZXhgEl9Jk5ZYh5gq5e8O8phtLEQOHD4Pxpw9+/sL/1E/g76R08PT8Hqn0qwGRd2yEFDeAHY';
- b +=
- '/EW6eFrDc5Zfn2LEatmkfKSMZS6jETE+ywCTYMlfEFlv4AprsShtXz5JuTTo+d7+y483+HJt5hE';
- b +=
- 'cyJG6P4ihb03L4y2yA1boavPXWyg3ljpq8gvDlYNZdU58Gh4gLweNOKCcQ5Br5LnOsRypZYlpwy';
- b +=
- 'HRZHQmtpLeLHLw949nD1tT0tBbLMLyuWnPnC4msJEohU1HNnL9JhlI6sxgRmMqTBdlCtQJniXBX';
- b +=
- 'diTAJsPWXf0tv8g5/ZcooXgs9liR5QalLopEYIIq3boGpdOCnpG1ltkUmeIqurhZjGeVGI5TGvV';
- b +=
- 'r09SSKYu4shw4uvkxXWBd791cb/NVs0w9WubofrHLEDVbovEqlivTOsC/KTukJq+ne2LrBaro3t';
- b +=
- 'j6wmu6N6UMKdnpz6mNppV+ooOEXatwn1Lg/qKYvKCiQiVdb6QPKPwUtP9xD/KQH/0d78LA9xXhm';
- b +=
- 'S5KUOrokUf0CmZeLQ9RYkgIsDjEXh1hR0lgcwCpfbKJNZbwNSwUXBzIdDYLVFofILQ5RvSKdotK';
- b +=
- 'NP6Y6RxekYHRBGg1+9ln15i8EY70JDEy06gIfjT+ZXWqJJ8A51zaeyxfX/hAL/Clq3fjjqvRZLP';
- b +=
- 'Dvj561x3OLDJg4+xQ+z58zTciObq3VlKfYmfLF8mjxJQQk3L9T2j6tN0x1GKEZF/oaQue40K27J';
- b +=
- 'HS2C/0hQl0XejtCZ7jQfxsJHUZowoW+OBI6NlLKkyP3Xn5bM7R0W7PMP76t2bIPI3SZC30XoSkX';
- b +=
- 'et3tEnq+C30MoQtc6AmEznOh339Fs763vqJZ3/0IrXOhI6+wfdb5E/kMqEGce8/7v3nXkXte88f';
- b +=
- 'd7TB8vv6+uR3bB9hqGP5cf992SXPyo2/95J+88+AdHwu2y9xloPjbQd0f7UaRMNKEch1d17gb69';
- b +=
- '1Y70LyKODxbKQEmdOh1EPcwMz95afu+Op7Hv7nR27aCT9p0iYl9zFzuz78lQe++LmPfPPAjp2Dv';
- b +=
- 'AzRkJT+0pAkV0QnVI0hfKlBfya3eI80Jaz7RpQZI2eE6nCiw0RmYwRFYYjiSvvQyXZZijqfVIwR';
- b +=
- 'CQG9C53dUpseI05VBYknBsrpNKOH1nQizDOEoHgloK/IMgiLN+ZqnhjzKnee07E/meFMGcHQawB';
- b +=
- 'UIb3OFIR9SIEz9FaEymJXhdocWLi1uaLWyawDTAjOc4Y8PS/1rLUqqikSyEh4xhpIhOr7MHahQJ';
- b +=
- '3I7KYrG5QEVza74WZGtUHTWkHhzzbpcAS5pzvsBbZMGb6m1AzC3p7sQGO9doeawKpKBo69seNPd';
- b +=
- 'eOfKfVCrlzHLYLUlOKn2+8o22KXDwB3hDBonFDq2EllayzIN9NfQ55GUOnj5wyEyj4fvOyfqZjL';
- b +=
- '85RJJrypsrPk/MDIhvUmRQWfWU6VZ95UmoWblP/+jHJteYYNg1lmTVmUa2wYQ2aynCgnbRha6B7';
- b +=
- 'Iz20Y4w7AyI4Nk00G5EU2jDELI6jMhmkoAvnAhrlWhU2wrsx9o0SggYJdDZVuiTrj8ehvy2Ssli';
- b +=
- 'gj9hNmhIpdUfAKe1tPXy5NBi6WeO6w2n+ryMa/qvZMxoPcZaQX/4XnD+pARlGIxQnjweYAGv4XV';
- b +=
- 'GLTBKNpxm0vlPJ3LM4htAPL+hxbxb3DocPStmsVMlHxVGYZOTvOTsphaz+Gr9lyeFuHSBUdPQBO';
- b +=
- 'l+nhPggi8m2/NQjnt1UYGLJ1m68uIwKPNjKFGjysUzwePzSIL/JJ11a9SpYnn47sFqVPtg5SngN';
- b +=
- 'EdtgXi7C+SCQLDDAMuKESzhcVTzq28KuDdx99ZZEMNeKUS5iVU8kfVT+1rYoXSBGfEodwBancYE';
- b +=
- 'FdhqzDFw4xGEHMUdCCx3YSIiGxnpLGaqLFPdE0EeO26oTfduwSI6sI9IrxLxqK6lpV/TynpcZEk';
- b +=
- 'ShiTfW51a14p27gigxxleU+76cSAPjXcmdh5C0qGwuI5vjTuZYWWmrOB9xz+9peSrkFopG6p+K5';
- b +=
- 'vRpoc9Rbr79ov3Swdf8OHAKLNRWgzO3NM32tQFYGGB8YiciJZ6D1P8Wk4SCz1FUACYUlD4EyWpH';
- b +=
- 'hZMiXrdb8z2NYVcyEIkWUXNrVvU9Z+ORn7P4d9iyGWCVp9fOVVfwCCV2Mr+aCYXX0e/LJHYqVnQ';
- b +=
- 'b62e0codymYBlGGm/obKBOvwDHvkxx19PLUifNBWC6HQ+iItE50iph14GZ7nLF0rxAfXhdrOQlr';
- b +=
- 'Or7iSabGmjbSlp1GyUhiy9iO0uYKgRah1T5dlQZavBidQHQaBs2UxcrHYuvwJOvpHyY4sMZkTu7';
- b +=
- 'eJgUFTTEPKrWxNUJ6QwReFnT/u/L9R1SHU33P/T/m0Opv49XHBpZ8uDAk4g/k3MpC+vsDqu4uuO';
- b +=
- 'd0k3/NbGWKfw05BX5c6fDdixucBwGRHyDYYS7sWP6gSVEV+Eg6AKvbVoGhzwxQ44OggwoMW9U+9';
- b +=
- '8q1X6T5AMl/pwH87BqGbHvTSxgrbgvVXVwbd7yKZymwvqM1mQKLHzhQp9qqeryBXx4EnENrecvU';
- b +=
- 'NvwdJvkUo1a7qs/7qqnyzGlPpAtzdsk9o/JkcDZOGYBS2/TRiWltR9wGDuWdOStPo9aANGe5qg+';
- b +=
- 'COn9QTdk9ceH7Ny4t+HjcxDNeU6kQTznKZEGo77Jk2oan2p176e1NQ6jOkg9Y5KDqBIh2IzKIS8';
- b +=
- 'mnmFJnaMvGo/ONcNiKfNOPweZa4R1SZ43w2MNu9w1THJWB2zbZPbzTAK5V5iMNOBy24CjwUgLFC';
- b +=
- '8rn/BhFDVZBrU5PFytpYrVlZ7cPwoi0Y/42SFmn8EnHXnEbBcL2Q/+tqJxxOwPOQdEfgbgySQPx';
- b +=
- 'YJ5mKfT9kHmgsf0qKyv/gpkBhg6ZjwlSAtoO503MSFhvCNuMFuMc5zVLGcBcJzKdKvsXfzegvnq';
- b +=
- '4eAlfSWmoKqB31hqcXiQM4on+EVfQGFDfdgECh8dZP5siY4FefI7yBsHTtzKI7KlAyfAdRtbN1K';
- b +=
- 'HZXpyLZlzvZIcLV4BLg/sxcOBfv7lkNRCZA8D38/AjFKHef4JNHUDTHU+s1PWi5/ThpzA9d7b7N';
- b +=
- 'rxiR/59AcypFdJ6f80Pvc9+aofMPd9/Iea+z7emPuk7rtfbesemfjuR+xbxye+B199uolvV52nM';
- b +=
- 'fHd+epVJ773h96sUCUa+IksPmhFQ0t+OUphtD5IZKu7QdmPu+oblG7O8D2vl8+z9t+J99zTDZax';
- b +=
- '1nhhl9gJSzycb9a9LDeIIf0TjGT4PDIkaic3VVc11aNV25mNqgxdXlqKtpGkRCyfKfukn6fLUXn';
- b +=
- 'yj2Nvje2EXP99cFWPvjW/baSqqKOyllUCvNoiCPlBN/idO3+Nb9YrxyOK0/GYIU3sFWYAfqwDee';
- b +=
- 'sCgQ7qNpl03Ym3qQlJ8ebNWa5wTo1jb/xiU78Sqj8zmrrHU511/bRTk4DPkO/HG7+QxJ/GL/gk1';
- b +=
- 'PiFcTR+AfKQ7tJSSJMRmYDJEAQjPRq/RPjQ11nPCypSkswntPYthh+ts2+JavsW5QEuE5eS7NTO';
- b +=
- '4IXYcUfx8/fW3GXDClO+caO+dq2AVNM+ilhdUgY0bOGAmbnrn/ToOay+ESg+xgFjnMHbbKkwHDV';
- b +=
- 'za+Et3y2ZqHyTiBwRy4h4rkZkiPgKIvoawVH7NCLO0gi6vnjDP0vEWo0g2/o9iFivEbRefQgRz9';
- b +=
- 'MIDq7vImJWI6yOKV7xXKE+1+Fvuud64pk8lyNGLZsnu44Ai1p/7LwT7WC6K1KjvhQjN3NGYAkWE';
- b +=
- 'ztgb5M3XcYw/5KtyAxNEprGWEYZ2fnGrf1n3Czjdh0o49lS8tWpQ6nVh3G6yjBO7TCGc7U+EJOZ';
- b +=
- 'DuPUD+PUD+P8tMM4ONUwdjMn8Y0cboEbuNKn9/xkKzO+lXE26o1NS/WTjvpJR/0YOsqsilr3AMJ';
- b +=
- '8yxW9FTuRwHZkYHciQb0TCUYePRjpv2C8/wLtv0B3IhZ9Gow8SDDyIH5qb3Z4gO48vmolvg11rX';
- b +=
- 'FfTeNV+jpfdajQ+VBsclo8zLymtqvrfDw0PShRIflYtyBP3jpHIprq8Vs/qgeVxh1WDsioGdJ+T';
- b +=
- '4lBrddCqk6tq7ltxR+SfCMuDsE0JgUtZybLBWljsnnZsRafyPo5GHdaSl7Tdow7HUdn0y2z4mOp';
- b +=
- 'cpEBB9QCXKBddoZldzg/3GQPSDI0985dc9gFZcUrjUV+XBTe4dykyM2Oa50IvMUf5FpmcYdLPBv';
- b +=
- 'etWtOhP+L+BtZuqySjMpg2+QIxfaEhyodaHWD6ulz+WfzzEXhvfAJ0rlTcRFq663wF+csarIzKi';
- b +=
- 'erh4ZAvmS1Bldtr+Vw5quBrrJjNyatTT1/8n6FCrj0ahFXLZCpRffNtW8ZkFawgszqoN6W5CEF3';
- b +=
- 'Ckm6NueGYfNhtmCR8p0TaF9V/sGUp2ylT1LeKua/IAFaEl1gaMVSK8oDPq4V6Achqur2oCIVrkS';
- b +=
- 'V7wqtPZGEKYHUfFnkbdhgoXT6zKbl8w2JdzC/1ntRxsFvC5bDWiiKRRkotgSW6ziTVYiTNLi9/L';
- b +=
- 'iQxkdV9JOa9Ss2IyZFJumObHxd8ohoZ0J7K640bj8kgAv8ziVIV83srtyzhuSauKl0oCzX3qT/I';
- b +=
- '223aSOH7ndG1oz2WrypdL4nqRIq/a2m+iKUc0oaJuYoYSMJWQogZlje9iYIHPCzIlmTtxRlfqoR';
- b +=
- 'GbDzMZnhu3PeKWOFAoikeyaJFfEXJHmitnqFbXhuOb1+DRIU7zXeI5Ox5WqhrvOA9kQjnaIHIyt';
- b +=
- 'Da91juYsU70XMutaVs+TI2IM6Ud2kHka1LBp6drwasuwFJGqF7Nso3J4qv5BindM6nWhPktYD4e';
- b +=
- 'VRY5WqSU6kui6/aoPe/MKmO/oEV5VbLLsRcXrk2oHMcD4s+n/Ye9d4Kyqyv7xfTsXOAOz1TFHod';
- b +=
- 'xz1ILkMjMMMwOaupHhEiokaDcLh5kDzJlhhrmA+r7kjDoqqSUZFiolKSZ5KSo1LMvBMLFI0VDxD';
- b +=
- 'RENzVL786bWaF7+67mstdfe5wwzCGh93p81nL3WXnvttdf1uX6fYejkJnrU7CMuGQfQ9BBhD4Ap';
- b +=
- 'gN9m7E4WJG9ej0w/me8CVDnmbudc3IGOPh37nm76nt+7XskJ7JGGW4VL3CALlSMJu5VhxQ3/EMK';
- b +=
- 'pVulB7JSMaQ3ISPSQvwHqBbsTaLD/EqTAHfMyZbi7AhxZkZHGwK13Tiq9MJ2EZTuE/JnFDl6K1v';
- b +=
- 'Vxf62ZDUK53OqeANT9WlPMVWsKFq7O+mYblRMX/ss0InHPnmhUg814h7QKY/9RjIxbnaXXlLq3W';
- b +=
- 'PwOSLvfMMkYjaorDkbdlXlukJeUecHsAKZkrUkT59wsIsKq+RIXXw2HcyK1OqIxJoOZsNLYIc1a';
- b +=
- 'TCqNXcngaUrjJCmNjbxKY4xJIoG1UDm8SyqHTVYOm1qgRYxzZGKgRVTsQvdKb1QgNkCB776EuDQ';
- b +=
- 'IFMVEHqly0evTCMMuoWSzqFLh/LEueKTlaMgNTqAbU/rfD6l3tu5376z4IHpnbQ6rQFInm+wMgD';
- b +=
- 'D0d/Wi46eps9tIivqIIcSeVAzRV+TvzlOcGQiSXRtI2iIchvRPvgosy1aZJRSDVbpBGWmKZwliO';
- b +=
- 'mNqiaGQemTQDixHQD4AXEbSMYxyNlyKHSiQlr+cJF92WGSQoptbn8m9WRLASsDhRBLjFYpCcSWC';
- b +=
- 'ms8ntDPM/WnMTxCQz2jD9akpGDz0kInGLH8QiAEs0K6fRrYyRJGsjQVzCMG8/UFT0U9FPFfse+4';
- b +=
- '/MGIylX02rhFDgnD+pkPifAR3ApO/5beTcBcoUSrlb1RxKmHPt1ERXoxy7kFQ5MisP44LACVBvF';
- b +=
- 'WMI3AZAN8mRW7ANrgXJYgyEjPnYu4TcL6msAKoG0jHvBCGRpLsFcIgGqgbSCfyoWgkVah6zW3My';
- b +=
- 'XUuk4HvTe1lmnOZBOKA6PNbDQ5tf01CWv0CYivmIwgHEnEx3Zo3rpvyJlTwBoddThwOVfK6GYkB';
- b +=
- 'pTnfWNqV5nyDCjaAIhieJaaJ4BIFIQo2ZJ6D9geIiOKAp40TeNo4ytPGYU+bUWxtk/VhIY0Cze/';
- b +=
- 'y+6TCAcMPkCcO0xdgjUOHbXFWthU+zVBoOMphxlCbhnKYMQwZH+nf76tf7/m/+NV7Hv6/+NWbnj';
- b +=
- 'r4X73DBOQUOmREK486TzTocMGuOH4CmBnkYkz5bzJN+ol0XBRo9WLtsLMBz4XYpQUyoN8gCjk6u';
- b +=
- 'J1igVqtABneKlL+x84T/xx2HlwOPq8d4smkGUJ6kBdjHi8OKCWe094q7iehQUlsUBIaBN5ExK6Z';
- b +=
- 'UJeJdZlQFzgZelZ7K/wLTzrIar1j5pF6HSxtuxnStpsDENYdIG27LvSbyt7SKMu6LCAINbUlA6F';
- b +=
- 'KtSWqKvHzrbAO0lChTCFGn8V4pxYAoEInfSRaGl1EA2EliMiIYAvypCoUwU5BGQpSFFSHMrj7UA';
- b +=
- '2i1CSI0nCD8rwY5EAmRcT6a6CHNJQe0kgt1w7wABbWfchRQhRBn37f0smT04awxQiYXCN5MTxw9';
- b +=
- 'q4mA2bILQpyS5E9xtyCwAtcUKaz4KDGdzxgp00ExRHLd0QIyRsCfqiTGMyLVaIgOLA52J/bG1eR';
- b +=
- '1mdFsL51Q9gU7luidIpAacRyv5xnxAoVax1pDVEVE3UOwUFJos6GBBN1CEnlAFFno9+cRtRRdBY';
- b +=
- 'HCTqqgAg6zyJhBpN0NnmmYpcDSRfo8GHShkg6Ow9JZ6VUuHkk15BIBhrPklx1mMaziMZzgmD0KX';
- b +=
- 'L9Fh1xH0+J3OhD+eIg16Bf/QhrexeFle6shEvPHuKES4Np/Ahrtyjl+DgG4hJydtFzYH4hLiW27';
- b +=
- 'iRD6WBBebl9A0FbWQr1Cnfst0U2OgJDQOrYQOoHew1qb248Z4qavaNrEguGxWdYp3B8bI/x6EjM';
- b +=
- 'ZlKeGaDRWYzXZaT+Ed5X/89sqN8ELQqqRTwMQgVwrQqZ/j2DNSVdzvQhMrOrK0k2NIa/dUO7YJZ';
- b +=
- '/fjw/iXl3Py3yYnrO81d2ZP3nU3rWjetE1o3FetbO50XWUD3nwlb/u3sGT6UckT631d/1+8EAzE';
- b +=
- 'rpdS+Dh43f9QqEhTL9Ta+K3wdsdxEKvYHP/s03lmT9uPyE+zqz/p5LOqZDX5hYwWX/K54Y4T8JP';
- b +=
- 'zda/huvid8fWe4iIJzM/zQdHOyQ7lpnPxRq3+CdVJ0pbFTuo98/2MyPNYjYGI4YJU+zQKQ4SzDb';
- b +=
- 'lv9Xg+CMcRfuaHO/JvarsXBigK8GiGfGZskQ/xWxE9rk+QuYjFzRLiM7aQ14HNEmsl0kL5auz4i';
- b +=
- 'FAjvJ5j09LHywAPzKgnqAKU8CAJY1SRQWp510ma6mYgRtXJolCwoHW09Nxo+RiMeORF6mo0Ucs9';
- b +=
- '8KhLj6RCApi38Rzin42HcB3FdMgk3GlGESnwxjnBkKf9qRCNESLjqpA72wg0LPhh7CZPbHy8BoA';
- b +=
- 'UQ0YiVSb5LbSHGA0Gz5x+qbL9S1W9W1Bq+80DNm3me6793LM5opyWsmhfnUJE9ITNscSNlJA/Ii';
- b +=
- 'qWtAOtCYjgMFjHHdTQ46l6SgduikyyCPxgkmOpyfYFrkQpLwYiSWA69bIrgwNnoMQ4avXktoyOl';
- b +=
- 'BiP6Ms1opMWA0r+cANBDMEWNLQxTvOEVzB22j47/9PQXpTD4Tlu9EqlCW15co2y9mqJB9YXGXE4';
- b +=
- 'T2s9jgP8bzGgx4aAQBm20U8ULrbgcrGvekowgJKEnBttIOz8qRlkeecGQnyBYwjJeK1sO25kkAE';
- b +=
- '4msZEZi8Ed0THBUBD7LAx2KoAMAz3JtHARzghcroMB5JlkfYzWkj+JVf8e9jLjpMaI5cldi5J0I';
- b +=
- 'Tyn2ke87UpCaRFADogIFV4PGSzjZRhuDUM8IYh/3evDKAEEpQoT6nZ4zTPyA+Cg5Y5hvuNfZui0';
- b +=
- 'siKVos8DgcmmbSEJ2aEOxXAGtLhYzqbB/xX1hGBXTDohz+wmLAUbkp8tQgqm9f/Qt/8kf/WS/Hy';
- b +=
- '0oolhAT4IemVWzqqkF1NQkwtjJMLRSrBcKVRsNU6tC1Io1QZj0DlmwYfCHmH90liUP4hyZgjDnt';
- b +=
- 'ugyOIXinhNgngFutgohytG7ZNBQC53DVegJgF5NuldK/DgaJ4e/V7Bdb8alVP0907JImemicDRq';
- b +=
- 'BssfLEZqJq952o7Eeh+DbUUzUzDrBNQhKzUJYMnJ3YsgSx3SYIluvBCXG9wiCpVaZYsxC5f7Apc';
- b +=
- 'zc8vZqUmoEJ8kFv9XwFHg80OMSZbY5ED19/Nf4kGI/3VeKt4O1g6I5zyJ8MdBNQqyhzi5XdE+94';
- b +=
- 'ZpmWSXDi73AAKFEcY6CHJkMdltL6MwYecLahE+FRigGBybaKHaC7/uq5aEBjkNYdKPz4IiMRawn';
- b +=
- 'mKHwylxmMwtYMN0zB0mc4vYMh1zB2Ml9CBYr85KD6pCq4fhnIu8JguSCsBKHTkmUchBH19TGjQg';
- b +=
- 'FTQR60TH+dTL8NlJ3RxfrJokTHH4QTVxMeyt8JPA+Pbg/Ao/g8CmBI3jcaEtS6dIZR0D12UHXEr';
- b +=
- 'B6Rkt5wHlHkLfEuKhR5iMohBu9eCmAY7Vg9Ah2vEG4b0kLFybERWTCJSIMZVBUjdNoiiChhtzqi';
- b +=
- 'VEY5VdKi47gVE32BrevUAa26euzEvYKOLGXwYbDky+2PRhQ2NodWv0ZZjKBrcrnpGGqb8dkMEt2';
- b +=
- 'sauEg+hf7uyp+qj9vWq9t8NqHaUq2yA2o9RdrWm/8dnlG2uRs28Y4ag/Ii+H0GNKSWgu1UIhe5z';
- b +=
- 'wAyKYcssIiI8oCzkSQoZTJjXuJUbvOODWykadfDTw4OYHXf0UiRWJBMqoFGSWPZUUI7hWUmKYVA';
- b +=
- 'O3GQ6UeVNDiiqsg2qMoMqe+WNHvYD5GdryL2UDVjFmpiaettU/qGoCxJH1dPkB0D2JRhIMK4rTA';
- b +=
- 'Nsd4IoB59KEKkixlM66f7BokJg/XWxIIqnonbePF1sdA6oCAdjqAb5LIZHahMP6Y9MGWKniH8vS';
- b +=
- 'CPWmw3xGQyMkGwT+M+ubgb/QcihPTKFr4Co3x1toLXD+DEwZ9mO16RwC4bc7Z43dbgbGv5qJRov';
- b +=
- 'VVcjdAm5x0GZHT6k2BIJjIIoSOJ4tBLecJ/oZkS9cQj1JgZ4MTG0SXI4MnUBjUcxu1kp1BuLZN4';
- b +=
- '66g3rD3XUG3Td8hhxAUOEHL0UwAK/H3cvseQwp15i+kUFPgZdn6Or30BqBqdaoKMD+jId18kIm8';
- b +=
- 'kIg1DmZPRZQ8NxG3BEdLagLuQo7DaEtnBU8HN6X0zFR6d0XIVQt1RQXMujjulkPLr/gC/9RuKAf';
- b +=
- 'OnBnLev/O7Dmre3x0GnK+ftayCHYR2MyHws0QTHkjjdjm5lmfAI5KvjAHDoH7U0m7bkXQeFHEch';
- b +=
- 'JG9Sy09q+QVafoGW72r5rpZfpOUXafnFWn6xlj9cyx+u5XtavqflHyu2qWNTe1j4JIMn6iqeajo';
- b +=
- 'mShExFofZX/de4HMOue7lIOb0e95D72uk2HvhelsXB06XI0GPazHShytphC6aAMqmFAgOy7+UxL';
- b +=
- 'o45fkow5PXVcdVkqBsVy5HKxKsyHafJ5u0E5V0xcu6/4jJEITi/N3GesqtaiIXgtVXCVp9QSvFi';
- b +=
- 'XQ7hGMy8Raw3DbJ4wopJIjJOkoMfVYIKsc0ivnFUYynjGCz9pitjTLGL9/0nB7fWZoN0JM5WLeZ';
- b +=
- '5ZdmOd7JUgpI7PiFrVSFRcrLTk15CU0uYZNXIrGeha0IpXK/iWHgP/E3A2JXdaKrIkfTAvNQ8Oe';
- b +=
- 'MS3NJBOizs6i2MPGE7aQot+BXo4cBsSJhQKxIGJDAUhHt3N7vw9wAkQ0uqDKUCCAhv2wq86OYLi';
- b +=
- 'Ulo/vO01hiDKaqHM+DZls6PkQygjCr3bvQwa0ArHTRLghZF3RgxRhLV8URIgMIEEI7dNfhAw49Y';
- b +=
- 'JBrLnN6bLoMSleiFizCJzFVviVj/PlGOE8yhg5IwMksS8YiRu7gwHzsPfv6sbd9CB/7d2SBlwUo';
- b +=
- 'wPbPKQQQR/508FwAnXm8MR3377ZAJ5KYbPB/tUNsNPzt/DTO37ssmD+JyWs2v3zpa1ue67wZGVG';
- b +=
- 'Qyw2VojaE8X3KYQ1Y3Lc7/J4rNhrZ420Dwo3KuhJe8mYy2xRXN6UT1/Er93TOQ5o4T33oGEkWdQ';
- b +=
- 'kvcb1nDZtA8Lk8jQ/4AG/Y1wFe/yEM8P+YIaVpyFz7AY6zRDbaD7CN9h4jarFFeWHDLsoLS58kM';
- b +=
- 'bVY3H0UrLYwmsjDILAZgibLmM2bp+OXkJW2F+zHVMoKlVBW10OyoolseE160Of529YfmRtDqqtQ';
- b +=
- 'jyHVVUgxpDZ9BBrcKzGypfnZfUeIexsQLlKUcDdB0Z4jOMm3bPdbsBi6C7N00/0x0DJOlqTLItv';
- b +=
- 'vSWC1MXEBUmiO8gSvk18oy9uRsipsk5MVTZVhm47EAGVmfvadmPcLUVoIdJpg3mUcTNPv3iXIgI';
- b +=
- '8PgNfesGvfOHnktXug9uP68WHlFyx/Tr7g8X30Yd1hGvumlLVCWjgjql8zQ0pZI59S1gxp0Ix8S';
- b +=
- 'lk7Wq0VVduZUbVdNOA8hpR9yYw6QqNjOdmiGn6M8LcTA9Ekrf7zxkBYAT39DOss0Uy2xIjolhJZ';
- b +=
- 'xnYnurY4656kKYnMkJJou6waXllAb0jmrTlSnzaOr5gKXc5WehPyODNpM0Qb4QRZvpCVLISwIpA';
- b +=
- '5RJdj8IACQpcbQuhyQwldrpC8+V1ClzuE0OUOJXS5wwhdrkhHl8sSmNxhXlGWSPJDvEOzRLQXek';
- b +=
- 'TsAlTc0CwR/imPyF4w8hqcJeYBvNiIvYhhWHWMlsJGW88wgSsxA3K8Y6IuMeCYYilvIyvip2RF/';
- b +=
- 'JSsiJ/SB+fq0iMtaUPQL6Q3ZovyX4FFeeG+WZRv7Q1ZlAdenWkb1SxsU26SGbtJOdKunM7mHLty';
- b +=
- 'Q7MrR6hSZVduRO3KDc2uPHQz5FYpB9XTjhkEugX7qumkGgBsSLMDVDlA1CP1j/wzXoE7CmCzdnV';
- b +=
- '5032rg7wsKcCL4zsUwsMSpWAeOhwmpghF+CiH5PiAcYwBWwQ80ha0bCmgkDgcHt0hzRD7MhBFYY';
- b +=
- 'KaxfBBcHw++bfbDGZYyWNN7Mv+fV6v0YTfd81Nm5J7+T5R7D/0A7st+sDnru619/KBoth/6Adu5';
- b +=
- 'xFc9fPHUnv5wO0f1gju3N8PtNUKFJQEpEIfmJQfaHf8h35fAY3f7U/c9oSxlwEs+JDG78DuoH0O';
- b +=
- 'X+w/dfisYHpaexk+a6Df57i/O5Df94Jp5GOR+2CTTQp1Qecv+K8q6xTfdNfGie5GRhlkZcgomwQ';
- b +=
- 'fI5+xcp9JwcvNXJaYrZAL2Xw4fMeUd4z+7pg6Ue5KXbghg5sbUZomRqSwoLNqgKiJUT0xDOwqen';
- b +=
- '8VeLTFgKKxAjMyEztP85IjxzymaFCGYAWecjGNorFCnnKWRtFYUYrG0igaK+opF5Oect+y8pk9D';
- b +=
- 'hyHCZiAHa8JNpBc3fzd4trdZUpwpdfh1iEauNKlr4sMVwNXulbLQHClWyAjpoEr3QYZcQ1caT1k';
- b +=
- 'JDVwpQ2vBxplZEy3QsaReRhT0/8L3DrMfxvrIEub7jdEmy+zQh6Eu3kGrFDh2JcDjIF7sS0NgJb';
- b +=
- 'TKG6laKpXmsRpWmONr5onmI+Y9ATFHS4xlYk+hOyaSDJjMX+Nx+DOE8r5j+8QRfyImXUfsaVhC0';
- b +=
- 'KN0Q0HqmW0BYWq7D5lRRCV2Q/2KqKWIxb16IucesIMBcMF1TREfQJptnsGuHlqkdUsfzd+wVXYW';
- b +=
- 'ignPnublbYhRJnl32WSNEwUco8UvzsQ9QGDy8qsbowrKwpCDDPseby9I8igQhzTDNmEc2D3nGic';
- b +=
- 'S6/01zwGag22p5fNIMTFSxwVZ/ZJ/qxdeURdCGmseK8uk0RdPWauqKvHzBV19Zh9ibp6TAqFQYX';
- b +=
- 'cr2IYsCzlBRG4gTsLi7pIzhUuoJiuLpOZrl0SYsLsUwSkpD57FcNs3rlvch5cX1t3RsDL/rlz4I';
- b +=
- 'Kf9c/KNz66j4IfKbH0JO4jWsGqgOIFmhuQDZCE7LQxBJ01YsS22+xf46hgb+Cek0bbU/encQyqZ';
- b +=
- 'ihPb3QJISsit5EdQghogH3gGAWy10pbQ1AwC3mkqjFQSer3kB85iV/B+5scPEBs4chg4Z6T+p1S';
- b +=
- '5XqB1nqS0lYHUeC0EHA4baVsE05k0OTiBIJIpqDGjd25DBSrcL0sHQcFLmLIIBCBo02s96vXJlo';
- b +=
- 'AgJ4ui000PP6c1IOsgd9jyW8RJ8GabWKOsIBVjHSPn1iSdtohOnkM5PO8HAeRDW+XOAsToA1GXX';
- b +=
- 'OvyaHfeqXQgRaWyAeRLDvgQJ7jPohCl1DhPZZUvqOEXnx8ezqOEVzbevzOT4PO+UFHimNl1DvRM';
- b +=
- '1uD+bYvxBsEvUuSlq/dP3opo7gSxUYo9A6sheK9kGsxVDUiuXZAydF/iy965EB+0SOhPYHD+Foo';
- b +=
- 'OZtOkVadtAnfA0j04k98hYXnfBKv6HucgIbF3WQ4xTEEkzsj+B6bv4dhWy3aS95A8MuCEpO2hyQ';
- b +=
- 'ZmwZG07RB4kegh2EN2bLT96L5tXuvY8idIPVu8D2xYzm4x0tdkzD4ZiVcUXRN35gGp9Zo467uSQ';
- b +=
- 'wSiiaNdxEi1ghrvbiAJ9YD6pVH0eL81+8lD6wY+2IBtepMNIaTHWcR+4KJdwk6HqLZ0UvRmYr9s';
- b +=
- 'WpQNY3zxIUIrzH24ivg+6JqsENHby6xV4oiXCkokOOAqhXHCn10fhOtBXfilEGeKy/H/w3G89kD';
- b +=
- 'O55/y5GL4snokGD0HRCMDoogc9hKIAqUjiYlFXvaZW+KB4A7eQnEo4v9b7yJFSANuPpNyILHA4G';
- b +=
- 'pRcdfn+JS+kjBgUg+gtp1CUFgggBdSj0lzJx/MfEX+j1NIrolYHiVVwiYW2A/4ejZNHoYZkiMmS';
- b +=
- 'CdgHzCK330bNJ42MpQsphDUvDoWTx6Fo2eSSbcbxB0FXpkWHL0WL1i8+jZweixh6CVM3psB/4hf';
- b +=
- '82zB/ZrdgRcbCEZFeXhYUssr5CmXyHYRheIH2RoC/GQxbDPcXcxqDpA8SGuUhA9xxsqZp7pFQaM';
- b +=
- 'bSHNvD7ZWinNVzJ5ErnzzDOC2SVj06mZp99LiXYxh/YYj5WLbuFkpRCQw8m0xQM2UwLcGhTMVgz';
- b +=
- 'hVTeRExGtdUalROpsB5rx24AMhM7YvA+AacF2gqeGUaUII7b/ivIkUtWgwt7WMiD2hoXAixh6xF';
- b +=
- 'S+RrLOFHIYiDT9qql7uuvOvKONrWKjtnyLfBEvzA61HBMEKgDMJ26RxZglPbHBl1wKTvyuJEpO0';
- b +=
- 'uh0gFvNcPopBqe5ZBXacrFemFx30UNM1G1j3dIFvTDl775DjMjx/q57xHe/R1a4XUn2KVKuwCa5';
- b +=
- 'Apv+nl9tZDWhdAUGvsnfeg+7Ar9m5mKkwUrYdhfy93+MMTrTDkinIE2Bjv4M6UJIk5XZP9R9G9M';
- b +=
- 'X3S3SCUjTylqu0gTTfvXdGHZFpOP8xuvuDt4oLiYaJkgrxENwlUgx8iNFQgVHApgHhImIxhnQUR';
- b +=
- 'Rc2nfgCo0zwO6YTDLi5HqA7t/AcoPzbX4pWh4ZmiNlaJ6JcZ3ksCrRmaNsTAiVVRYNRGeouAbZW';
- b +=
- 'X47k4jwbN8sTaTEbAOzAK7yHIqanBpsakrmpdLy9Cs5BqbodeRIwMZoLfDYCOJB4FfwE20R81Q0';
- b +=
- 'cHffSNCEFozcvQmoyZZOr50ESVUD8YLN1mGppyK2l4JHBvfUkVbPr04hS9atlN4s09spvVWmw4I';
- b +=
- 'DKyI0sKKeWSD1AMmIBrkg0qU6MANG34l4cvGVR3aZ4v0b4P1kArr9Vz1AUO1KuNc60sgy9Rw4t0';
- b +=
- 'gWM+TTDNIC9lgVjx1vJ90uxR+bI+1k2qYogHNYc2rBpE/ClkeB+ti4VwYc+7Yt8ac8+yQK9KXJo';
- b +=
- 'PLVChLsfmtEAXDeWtUJ93seO4YGMSRuG0YEkKgfRQwri0EEEKTVxPUoCqcklMfPbYbykFgiQ7Tw';
- b +=
- 'akZuoAIQjOQJVCDfEoQqoEaB7ZtEEkELBoPJq+IQwsfjwYGd2tuBnaIDO0UHdooO7FQfB7YYv1R';
- b +=
- 'wTKc+oGM6JY/pN8y9C5hJuJyUwmVNfgUHx9Ze2Kr9/4Ef9kXs6WVpLcmPn4FbgzT58Yu9uNtL+X';
- b +=
- 'EQMMD0X4VbQ/y3elleLViXHVL2S6LlrjcD4TOKvi59MxA+41F9JWQM0fyLVr2Jp4/0L+LPvsekK';
- b +=
- 'HaOz0w2RdJKxxvTCXBxnjGMzF4MiCKSQM4LQpqpXhGMGsIfew7SLHFtOtqiNHodxtnrME5eh55D';
- b +=
- 'XDNhZcbc35uFQdJxLwylvgChRsUUoY4OZCB3A1XFaKWFMzDyu/SfhNgzdmsaQHWBk6+hm7A1E8Y';
- b +=
- '3m1nHpnOkF9EgiCW9rDVtkcu02Eam4WKCD7no4u5kU4mFkfLYTBHNVWx63BGvKqHzjKncLFrw5X';
- b +=
- '2XkXpU7XW7DNbZoLW8Z7s3kRFnbLRxIlptjsYH/SeMwD91BPCbGE1cOmeAf6LFGFNoOGPLwlDRy';
- b +=
- 'WDtJa7GGp8C73UIPb/ZkMC1HixA8E+E7B6q0rCR4b0a9ESO+zxulrGR1ikl8UAyH6+y0HGdNu9f';
- b +=
- '87LZqoH9uNfEFI0kpq7nvmiyKmlUVmY9ZkmFwagh7OFbShA9EPgAvNCHB1DHRZxVFGQVcFYBZyn';
- b +=
- '9gv+DO0Fx4v4kn5ohR72wdb8+4vF/p4/4SUhSeyCktCyh/Qo4PYOnzQEX1IJUJR6WqjBiAYhRAH';
- b +=
- 'qchWwgjSGmUhLvNhHvtv/22z14rNj+9rdJgI9C1q0Q7hCId9FQ0E6TIV/CYqcp3ylJegnfEUfQN';
- b +=
- 'XDq+WDdB9sbKa3TjiBU00nU35okZRGbUETq52hSP5aq/EhTq6sRcNQIOGoEHDkCMRU5VgFOHJCo';
- b +=
- '8BjUHjXW9Ju22714q2e3yy2MbHj/4xr8sLZUCWUtzkzcXcjEcVTlzwGFwOyoL/hgw11NKtmuB9D';
- b +=
- 'F1UQYQVTpEBk8AuijDqCKXED8wBNTxv7CiJMuRcME7ee3TEK2uFb8TsaqwL9oGl6BoeUpWJ+/9S';
- b +=
- '4SViFouOXutih7113MVm4OKI7E3qioBFFRCaKiEkRFJUJUlKCdEgHtlPiAaKeEJCJuNc3BrO+jM';
- b +=
- 'YEAbW63Q463DGRrtVG8T7uNw7vib3E61kYRROP466UTbRRUOYm/I9KD8HdUenBbjQdmqgBnuDUB';
- b +=
- '2INgffIxcQG4jq1erBXmS6LVS7Z6g1rRh21KG2hqDORasKFPmcZB4OMvuQeJMcXHB3x7LC/fHnD';
- b +=
- 'rccWtG4pbNxW3bilu3VbcuqO49ZjOrf8yhznsQeD6VU/0gNbcTcnwjTAXNzyB4RJhPm7X7veg2r';
- b +=
- 'xX3gweoFCKdHvVkxxq0QzuGcAJWnqsgtKQxa5B+nMtVgHZ+nqKBfwhN1+6i+rRDPYtDgJzudURL';
- b +=
- 'rc0wuWOyEZ4VYO/1/1a0v1agoIooDfgT61QDAWyKv5RID2X/By4srALEiM/PukEUTccAlyMaeQx';
- b +=
- '9LBYjU5QPFTQa0NqGWOfoH0J2g8XyLBwBABJmmGLI8wN0SR2T1A8FrlC78uhcAgnCwKY/MlX2Cy';
- b +=
- 'MpqOjUPk7noJj9Vhx9ZCE0CKHfpb+b3uKQa+QliFBcl7cq4sIPisf7lUfUFdb2QnzV9B6if02sP';
- b +=
- '+RImHoEYcF1kCDUwVDhha6hxxaVFR0WMq3ClO+Lf4c8RcTf3HxN0j8DRZ/BeKvVPyVib9Dxd9h4';
- b +=
- 'q9I/B0u/j4i/o4Qf8Xi7yjx99EAtC211PdaAdDt3fcSrX5yaRso/mNtqfsDuBokc/KROJJVMVVQ';
- b +=
- 'GzYuQ6ZLUOMr47SNQ8RUh83Q0okwiZKIkChWDolSmJeI6vn+RiaiVn9/Y0BErbyVj6o7efqsN0M';
- b +=
- 'oQwjp+RLHRXGfN3VIz4V4Ah2bZRg1ZQhEZSU0JxkKHatuSrkwiC803M2mfnA3iyTu5nq0P7k7j7';
- b +=
- '+cB+b5zhAGLE3bcgxshP5yuN85brgDsnP0dc9ScBoVwV68XPkSyosu5blnU2h14vpAWG/05UsIE';
- b +=
- 'WJZdaw8326XvezkAqdKAyJ3dVzv5TssEs2OYFsnv9viTg7hnwLdoe4Uh7p2vRVB99dDABAyx83x';
- b +=
- 'ELbpegca+wO5o5ih+AcPkd08mX+5N4Qaez61FXdWgOHZbigzMr2tnnbHDbV12d6bKnbrNQyJxk3';
- b +=
- 'ditPhNjMCzFsQBuYNhGnI9dt9A/MOTVv+O+8PmDcPvq4phWyaaO0HIdMp8RoAHFEIfX1iZzEE3w';
- b +=
- 'gNResXpjLJS5sK6kRhaUmU6oLAz75At1ZlpDUKvJ6sZDxc96KEAuE6cE39+cFu6oawthvWuv8To';
- b +=
- 'OIAZhIaNNFIouBHbE0rHfTkQVmyQ0puSP0ai4t58w2b72/iHHiXynwQMil8k/tbCzJVJBCfRVQW';
- b +=
- 'EvdimUcaIF8PGwPL5+zUj7mT1yj7zlUR+85VJJXYRfadNwT2ndeZJ5g74UBdbSrjzh24MteEjTu';
- b +=
- 'fgzsvoLnkjqhx504z676U8Gh9uz91+ANW5zXWXIPGmqsxwBR6zBHoEEWhldGiq9HVFLGIOVq0Tf';
- b +=
- 'Giu63mtJGlWGMY/FXRc7GIf1ks4l8W02MtdVvky4qRnQ2IHWaQpA73Wpi1VmjW4h67ilXZLsfWU';
- b +=
- 'HPNN9xNlpzRaZuPJ8YlLJbweb/Ih1hXXKWgCQvzIlpu2SQRLbdtIkRLfM9dD/aoU1ePgwwTDbWn';
- b +=
- 'YYNKZ6hlYDA3QSv2dm00MIgVAW8SZ2ekJd4TPk3SYNQHzKNrDKdtuDst8mHEoxF0HrAJUzBvYpl';
- b +=
- 'taCzSGkVUhVuMzFVk6wpOhM0cPCvrPpvgUGrfiHky1hrdF3N2IQQqQ+BVVBGuiDEKq0fx2GSWYH';
- b +=
- 'TuQK+7hTCVuQzSDWn0kJ3MWat/KNbVpsD2FuoFxeLFjjoRvm9KuEw3sASkvoKdG5sxm4wwBePqo';
- b +=
- '4jbIPxDGzHqlEZA7FcAJwrHBkoNCJYKpWNov0IYz5Lki5OdEkqjCOXZQeDLRxjwzjIoKBadp1NT';
- b +=
- 'N/AM6DJ1vBUZkE9QJ/574oNL/adgdhS2ph1BowzznCyJnjsBCkR84nS0HXWWisECEhOVq2CVmIa';
- b +=
- 'KTycIYtPfAKFy1pA7tulvJmEAvgMsg0V9jW5VCdlA0njnNA6ReGWsRs+QjasSb4u0DZZlCcuREM';
- b +=
- 'UEVKm+O5MaZ2DjbG6cvZfGGbJxRrRxqwfYuKeMD6N11w9wXKs+hGG9OTjWlTWzQ/Zqyu3b8BMEN';
- b +=
- 'T8aOEMbdgaPWIZtyznkkQcwi89bFCbueksGWRqVhWfg0TH0KO57WMMINo9dTmGOoQYrVIOM3iYa';
- b +=
- '+Z1AoSrN8SwCOrWRrYXUUrfbRmG0NIouQDtp92I2oStmAwOdyLBDRIaFiPfDA3sVhGUkm2730oR';
- b +=
- 'OgyK1oKzr1mjsNm0vBbS3PedI84kCbOuJWQz1zIeXLbYtyDg2yNiCGaMkEpKN3BverYAExpIuJT';
- b +=
- '4KOsf9egAlyXedEMiGBFn8Xl874L/P5nd9YDilGghtuxokTpvQQQEtIimUCRyLRDlMQdxz0eJ60';
- b +=
- 'T6STbtzEchUZJWg25bpHz0DD3qHkJRU6N96JNrrGQoDoWAgAOGqr0kAP2pg6rt5NEbiiHlPEbIF';
- b +=
- 'QwwJhDU8oFU2GcTuqgxytlHDayEvy8OL8IzB8AIl4V7lKB0R3w2ph5QyqI/2dVkHuX1fH2D7bgY';
- b +=
- 'UH4XjqokUugmay73KRnq1lAPpCMbSRPUaYZ5WE+Yp6CXFzzTAPB1hzSphEOM5IPw1WwEIFk0bzx';
- b +=
- 'c/YnotRrBpayHMkSrrXBj9KutzgVHHdqA/yEmIUFdvYYg3C9l5AFK3m1A23UiQDJh1clMa6Savk';
- b +=
- 'QHTUJrdyKhqKOJuZOg1lHs3Mj4bsn6NDOKGhFcjI73h+mgkvAbxinfFK3ABNbKBpb9zD2cZjUDR';
- b +=
- '3m3mi8o9ULxUsF54FaBHGRPt9WekYxwqTLp3BnYFATCL6V+xE/kcJJRX7JSPIJ+7ZmfE8uDOncr';
- b +=
- 'SQbM8uDFKiD/BbjcGKlFGgISEAMh3PN9DzoEjYCI8Z7FQHR1xlNGkxl8xqj2YVT2pXHkKmOcU9b';
- b +=
- '0eqU9z67GVW48N+0/kjJGQi9J4kn17/myzZw9aAABHT3cx0I7JvjyIDE2BdrQQyYT37g/SnICec';
- b +=
- 'mj/DrsGPYUWmOyWY6XuChmVMpXP/IGty1yQO4DGDKFAJ8gdYDfZBATL3AFzapbm5WCRlmvLvRvZ';
- b +=
- 'pthyr0jSEWG5VyXdV0wkKoxQ6V17K/3NQBCjx/hytWhfGiAk00NI1nhSIKCpGK2IitGKqBgtXcV';
- b +=
- 'oSRRJeZAqS7z/16iBNmqlhIpJKuNJXhMADzVVRQq3/c1xwjvcnCBnS6CsIGr2J8SRT8JBcSdwhA';
- b +=
- 'IHJwnamSS8z3w3GU+Ikags0Q4WN4SPOs/UoH8kXjIHOiDjDUFZrrhVQlPy7j8q694LFIq/7lZGp';
- b +=
- 'xQ7xS64vm9dj0KndLMaXmhwKKIKyaVdpBgXN6kuzNQ1+z6QIfzTPgfj/Y/xv2WbrsazFpVcZG/G';
- b +=
- 'gX7I/4vNq9DezJqBZCREtsXzxrOyowRDcso0DLtKGy44iBFY5VRZysZS93d+mhQmMbYvuymOxqX';
- b +=
- 'iNY0qtgbiIt0S3mFZSXejrWn0fCWLQZWdOGWv6cwOTTriUxzTsZgj+67Ii2Eeko9pcuQdSz87CE';
- b +=
- 'zaVMFBlAU/HqX4zg2mZ441nRqpuwiZ4n8vBxkedKshZHiXqCRAhgchLCHDJwGxCu4NJtT4FBkFA';
- b +=
- 'SuWIlD3wYT7Poih4ZXd0DQZtRyCfgCmu6CmAM9dUFP58dxX8HRjr8uQl/OekJfzHvZy7jXJCMl9';
- b +=
- 'xGEvKPaqVEB4uCs4DMKXZBC+PDfZ5XKPqbtcpm4KkR5AaCBPcO8fxWofJuiUIUHAYsY3i/oMW+Q';
- b +=
- 'zvOOP0mf44f59hmt4KvqvwHsceA+SR3sgaQF5FKY+NHOuPiO6mHJPSjtaRBcCvXVZGTucI7qYFN';
- b +=
- 'GFA6mkTbV3uemYtA8jKh2GFI2utUArFDCI2NvrzEjo66QuQy3gwBYUABM8frYgMEUS6XNyLnKJM';
- b +=
- 'i9Q5F6Szwn3d5aKfJYvbBvJTJNKZsph2zb8hmWmN2qnAQfIYCcn33OvjZVYaInkg6mB+zhY2zsg';
- b +=
- 'XkxCeCubo813P61C0UfLilHLW1bcKc1iEHnPX/m0ClbvAPLuRjkraTVcGzVg8gyo0KRzyqRzyoR';
- b +=
- 'zygyfUyaiB8M59ZeYdk6Zec4pk88pM3ROmWzq4FL0RpLdShX7uj6YiL2iNq54Trz2qDBzAPzEbc';
- b +=
- '8F/MT650LMQQ/cKsiLeLHlObShfvI5tqEGq+fnchEvVgQttXVnATTqY+n2N27alJyB6rleowni2';
- b +=
- 'UiIVGsI7wiO2Pu/57DkgMhtyLoJs5AOhrAoERBE5v4LyX0NHwCfoqsH0CIwR6IWxTo+zAYlB9yg';
- b +=
- 'ZG6DkvvaoCQ36ApokM/MB8lppJuMxbju6Gxj+RvuZ3h3NDO1Ue3EBi7gzo/eNuDRv692QcqiKNU';
- b +=
- 'FbVHWX/Z08pOdge50VgfGyFoGGiQTUiBoFSnDPgXj9tkgRnIoKI5NMi6wlMYrBBp2oLSjYggDsU';
- b +=
- 'LOQu+ZbCbimwOawRAnxaTxsfqeMOtyJ8wP3s+EGfj49D51sMdnxcAm73sG9Y7d9+y9PXf23vF+Z';
- b +=
- 'u9V2oxBE0qxGf7JmIGxR2CswS4EoCLI8qPDX71a9NFYwzjBkBSqyN9tNKfh36ZGtCUJF0N4D5u4';
- b +=
- 'bxKltWH8VDhCwAKWCFMC7Pxq4MGmMCxYakQuHP5qcPe8nKWjJvcBWnub4JvA4O1RA2b6coiJ55M';
- b +=
- 'qWWzGU9JxtI2hKFaMDwwYomSM+/WI2R5o2R4E7YJ42kubE41PkGPyFBmYcgRK5j+R9beKQ5IEMH';
- b +=
- 'f8j9ji73fIN1U3+rMik8eKTB5LN/ojs7wrtfbg4U/0vPu6hZGPwSaZlXzu7+OYBG2/JWPF4H1A3';
- b +=
- '3cfIjoFYSAQFAK09A5o6V2kCYLHHHBP5Zpg/ByOXmOlLsVY36hKZfQKqyMbIMoaJLpGuihO8nWT';
- b +=
- '9UBkRFiD5vgUhALwuePTh6UT2XRSdGHM3eQEnJfCbfYSjaIOsBIkfTfi9l4WodWAVfEAQjoRYJH';
- b +=
- 'uj7mlItUMNHZBvF5/8y09TACu/b4Y3l85H1I7lv9YtmP3j7kdl4DLAVsk08Cgj3RgAyYRuSmcMg';
- b +=
- 'b1sVIYFCjGjtkJ/zygh46YAcveszv8b3Z1Oa01bC1sZtOWNP3CcD4mG+litFIvAQt7edgf8H1ZJ';
- b +=
- 'FEA74nUb/nsjeIDsTfqDozQKcASUuUOB/J0fx9DslfQ5U/FSyxiA44lpdfwYFBUXMY+9nR0DrCS';
- b +=
- 'VSTORM7bmj4M5OUc6KhT8WM28mMkl/GmDpGqM/deBOOB1TlKzhVS3LG3jaY0Myhe9vCQn41Smxk';
- b +=
- 'hgH1SKA7g/T8/qO+/Qjpbi+67v5OsDePk0HljkKRwvrMwzoz0+AwwQHxUeRBGIFliYSMnGk4ky/';
- b +=
- 'SnZ/Pl/qATslMXBAFPGIuH+BgDOJnHAcnNswPfj41sqpWH1QHHDuBZ2LcDA3FxOELp20Ex7kw+T';
- b +=
- 'jp112zU5enROw1fQQuCZgCxE3AbBXcNaX54vU2KJzjD0jG/04sNc7fGChQSSGGKN/YsRbCk046X';
- b +=
- 'a7733/IBvn85b5FwfBnHsq97EcXsLKAt0UB9i+IJDf/kLNmafTeh8YSQHeUJDTLz0dTbsG3AFIZ';
- b +=
- 'ARyi1NPjsMsWuwBGMjvXA9vZYSniY8Cgx3CPsYEwUY6KYEkWYKGI0Hky4lCjARAElkphIqkhJTT';
- b +=
- 'yPEQCjCY6ur0CQGi2mZRq24LjYqXVvLjFOcanzTfD0SkqL3UGoncYpBpHakqhuSSrbet3RNOKF+';
- b +=
- 'oVUsxm/EBYQhSy8BNogL+MXphPihrc8nfTENTTLhNSgC5elY5O8yzCgIvRg0ht0IUVHFLkYpKp7';
- b +=
- 'mTfYS8y5cxmoni+EjfDCZcuq7KTocukZGhhZk0Zym8JW/NwQpJHO4XCn7OIvhnSLtHayaUMqYLX';
- b +=
- 'plhD2ouW+llAi2qheliynv5NXDDDQoNIBL3/VvYheeeO9bCK5Bi7W3xvoDDeIa/ctJRbYfG/gHY';
- b +=
- '0U/mNYQVRn+O0+nLTzAwuCKGLDs4Eo4r5npSgCRa5bng1EEdiI7c+qd0ZlEy/DrUHU9NdlNVrDu';
- b +=
- 'oKGRZkWUzItuUyKIBggxIrOpEDWj/eFSYEHgEm5OCAp0OYd1NvTh0hqfroMAeyGUaPoRE/SlOGQ';
- b +=
- 'M0xJxZTwLUbCt5i/fR0J32L+rnU9jNglPuOOH7Dw7SJug4rS7g8FgsB037MQVlFFzsLjdWjWXZ1';
- b +=
- 'Im36aDroSf/Mjop6baATx9soYPeaRppI21u2PkMjN4CplZCuMi/6BdEPvc7Ibup7XumHL89wNH0';
- b +=
- 'Qb9nRt5Db0dm0M2rDpoo0fXBvW3yrbsOFWrQ3d6z7ANmy5XbZBYvdgG9bc8QG2Ydczqg0Pam1Y/';
- b +=
- 'yduw3Lg2PWdFHcrsto1JAQ1RlCGgxDWyyMYgwniq4BllRGUQkETsy3KuspGT5YaNmiypXWVGVhX';
- b +=
- '+UV09f9aktuSzhxdBjgH5bouyPCR7gsxNm4SlJ1SCdt68Ehx5bIUzc26V9hpk45KdHAx3atN1nW';
- b +=
- 'jMuXfpye6cg5/FceIAgp7FsMhuI+b1Ae0J7v3UAheIoptJooJgPUFh3U/TPmC7liZ2zHPKg9StV';
- b +=
- 'p7lHc3GsibpNQCl23SbWgUMOa6PWZIJZKjD0lmpVJEV4a4MGIma0J6WBOyVAe69GLuN4HzYwAu8';
- b +=
- 'rgWQ3AzSdDIS4FZwJgurigKeSngPhJ4Kfgc4Twe7CypZX0cndfYdM65O+P5T82uDQM5NVds2Nup';
- b +=
- 'yS9fP1hJAcjKgkAbwQnd9jcldLMMMIS9D1w4NgzK0k1CvO1JcpJvWRCEjG9AADIjCCVmi/fBy78';
- b +=
- 'GzIa//lEJw5s20DssyAC3wD1mNOclK5qzy47mbHeiOVtj0ZzN8VBOqi2Ygsr+uYjsn12yVy5Aw1';
- b +=
- '1px1xaSaa4qG+txqsCjI4Npsf+67f3kDVzKVgzP2thLlgzWzJEkWelGpWpQR+YZANBE6P1iatzV';
- b +=
- '1wCc0ZAxTxbDDVG/jTctxOAUOouj3vgWuS+lQADdJgzjaAaXgGArfCxq7on4SIz28Tx6F6b5IdE';
- b +=
- 'G4vowvFdukD8VVGPh+GSRT1ZABQVJB+EMKm01nZPSnWELHoN5RsEWxlKiUEz7f9UOkahToNcs2x';
- b +=
- '2zSIPerTCJkC5X1MeFZTFwPuVTYljqU4bGCtzWS55bugAY8fbSQxpYVNE1dgEO4ku92DyDH1tcq';
- b +=
- 'RVwazh9ivzrSA/ha5Mlvs9q0SS6WJDaRYbCkUOc0h7L/hZgiiONWKMdJSxmD4rTyFaQ4p8UE9nN';
- b +=
- 'T+JUGyesM5EkqSIuSCeAK51kkN4hvioNn8pJgRRKTL8A8oSEcrIRewh/xcm7UL3mTCRY7htwUSO';
- b +=
- '4YYFExk2Nn/LLjTLj9FEfsEiuCEHCZyWiAwRuRUHQ21JbNIOD48qlLNbHsEMoSE+Iy0jj2pRgHT';
- b +=
- '3lxzHDkSPb98gNq7/tUpYG4/iiVb9yGbzDajwUnKFYwKNDUjZcGD5zo3ScICJNBRVMMQtLZaTZO';
- b +=
- 'wCqIqsMTxaNfUHYoXuFe/vg3pJQyRiiEOzwyYCVnTCdwHbHMmeRt9amkanrz5o5BgKdZMUTQ7+Q';
- b +=
- 'KhbJN2ZP7DPwbG/K5Z2QrJp0OWwzwZKo/ZFWI3bF3w94ueiqFp23FZT6t3wiHW7Yc/4/wwClaDU';
- b +=
- '0KwKJwo3LPc+2OyvNgMZKh6DWOxq9OZ8MeFugzLknVYHG0Yf/pPsOGnrjpPQTuk3aYwnWhWmcQl';
- b +=
- 'Nawzp2ZkF9KrADXIh9Jsteq3EUV0WHl2CctL6y2XoJtlLNl4lw3Pl2PBk8FJNeR0RbgkcJQi0mA';
- b +=
- 'yRqizN4xaEWO6t5BMuhv5q6TzrkuspEZFhDKy5faixjbAam7XaeXTYrMEWNdCs+rtFGJwWYXAui';
- b +=
- 'qqmSezO8Mame50dgGGx0jmLkXevs0kbSwQ4HhKPJ+A7pBKW4CINDh1BC2iBMol0lEkk20EySgHa';
- b +=
- 'QqKiKmQLqawcCYzcJitHkWhUqgfd1LEuHL6CtmgTHXJF03sIgFyzMbPRDwi0ORiHAj7mIZthnZR';
- b +=
- 'oWcyOoqoAGWteH++wlopX/GYgr9jc3yv6+oztxoA/4+H3+xkx+IyNA3nFb/t7BZILBhn3Gcg3Vp';
- b +=
- 'IPFV6DShJ+SVnspC3J/U3RQKId4q7E0qKAwZZf2AqCcWJ8LIgsD1Q9TBHcCFTkBd4dpM2cg3smL';
- b +=
- 'CLPbvbve0CcxKthcTsUWsEhWC/3OotDAbt/sjn+QWHKX/MAxDbyr4KnAIM5izs1IDuh/YY5g+w4';
- b +=
- 'zCnYVOQGW+FfF/8twn+L8d/h+K/HmE6txAijXdpjiax/1NIsohqhQVMrID6Jk4delcyjUjfcf8X';
- b +=
- 'JZx9/i/n3WP4t5d8T+XezgRdsAWGAwJ3066kzDH8socykjUZxMSXb6ieXiIvPiIsecPoU1/d2yt';
- b +=
- 'xPZ1uz/i7Ovk5l39YJ+Z1ZMbN0UwqpCEbobx9DFJlSv6bE+XSCCRanWvk6i/P7lRBmIKIBsHlER';
- b +=
- 'pdR4zmLM/ImS4d0pgnpaB6RThh2AdwCgULTnSJxE+ZdK6MTg7kmGMmwCUZS2VIYBBONAopfa+YV';
- b +=
- 'SVmKzCvY7rku/2n8M1udxl6WUn2exu7z8eg5vCt0Dn9ZVzYgXBYCglpNJ5hDYRAAgBTsszA0zFh';
- b +=
- 'zKFvjAomKlgjAwYNe/zFS9QEigXT/gRmUicBnFCvr4h1v9bDFcSk5LZlkMWugYrFDWhofq8CTRm';
- b +=
- 'GQYJbNMHgSe8ou0JGqNChbsY94CuAN9hG1kwBx4V4ObHiXNZNMlImTEYt66009FDG3MOt3rxXXu';
- b +=
- '25mIUu9ZlWHFQ5RcJbI8uDiE33YTPYWntnUKGi7bIkZxMGThAebIYvXrbgT95DeO3gPqevbNXlA';
- b +=
- 'vsV3SW7cU9x4UnHjpTSzDsqHbH0QP2TVQ/whmQHoiFREQZMiCnIRQTzF+1ANRXVC80IUuCkpcNT';
- b +=
- 'LwkBLpBVWXn+LrG5VxOukgigKo6w4lQzEIdbIOXkOxIGctqBb/63Z72kblt0HkPDJCLW6N/H8mo';
- b +=
- '1SXdO9MVDXMOt6bngR9mnp/9JT0tr8NwOJDhasv4G+YHXvPsWdD14wN1doGwBckew2oPcQlMkpU';
- b +=
- 'MCBDFal9PAGIV4htCCP8Jcja45Hk4ObjeLg7igHQygARvfRQQHuekF36X/B4nmCAxCtnurlt+Sp';
- b +=
- 'nuvGt3D1q54dePXvo/XbXjio1S9/8aB2znao3s5f/Repet0FW4L+q9iGBJfICTA3WP14j8EZ/Ah';
- b +=
- 'IT4mJ/ZajnKfPyjk8T24Vt9rA2QFS8aUqYyhmdO2yW/2Cpf4uyBqCdQ8hq0/3z46cjGeFcBdNWk';
- b +=
- '2KfkwLpr2gmak9A6k9gvKw3K4EriKFlSjOya/F+GRLfUFaX9HB6CF/CQDPKxhrU56LJXQGE4gIG';
- b +=
- 'fyhUgMyRWHxivMJdSgpqcSz1RbGy1901Mn7bOAamMay0uizeap9NH5w6t16AOrN1w2nHJzmbjtI';
- b +=
- '3fDEAaj3rAgsCC8tQUpKuxBDrTYNfxgXpZtGgGFtaXbydP58YDbGkjY4g9lryZIOuhJTTcbwZK5';
- b +=
- 'grx6/X4gSj4r3EmsNpdNIz4v1dTHBFqQNGfbJ4AWIdl8y9I5muDLwqr++r1V/KRx9FOio5RQiTh';
- b +=
- 'LUsJGO0ihntOt55WeEjQNwlCbANWPuyg2sxZdYcploOCdB4V+ZxMhJ4uoKcfKyJTDhmZJUn33q4';
- b +=
- 'fh9U7RXBii66l4ZoIgzVsuMc4PoO/upFHbfdfIpe78YNljCw78mYoPNElI1LdiCEUPJCg4x6b+8';
- b +=
- 'UpwFx9NBs+7aHowkaqlp7gWczT4FnlEKd6jv/phcPF+OwIuBwgNiZH6WAwBvvyfA/WJsMQoCDEK';
- b +=
- 'QyQD/xZhk7o0oERSZBBpG3N6XALWO7PADgBuDAG4MBriRGnYGuDGUkp1CeHEwNZzEYSV76nPh45';
- b +=
- 'A8Jv+sQPySxGRQswb7+DNomMR6RjlpLlePZ9eZOo2M5C/y22/aROViBhg0Hs0KHfd5GyJ3O2jNH';
- b +=
- 'Qvw6igauL5Lleb3px8rl04yQNTYRnwVI2o8S96nwFeZkk4130etq+7ov9ZzQuoMBHb8scJVjMnA';
- b +=
- 'qtABs2R4jaTPxgmmLHolrR2IGZlEx1fWYMxiUVwyjfIfC52xcD1mwcHLtKVPUOcU1tSBk3ahkuO';
- b +=
- 'aWErbqb8UKPmZfgFvk8eYJzP8QVgPB1ZCWc/apwFrHPP8VdvBiPJpZdUg1joKFPaw5cLZUeNIpI';
- b +=
- 'wo/kkgMTJ05AKDVxpMmafQA0XuD0HoxLP6RU8FkTt6K9Tkg0S1lOOBpRwPLLGa7bxsC6F4sZOMN';
- b +=
- 'cmqQihCmxCmHZ6s7kqCuMJATV1dPTRqJkjqeFmcFhGuMOq3GOwfWAEgOcANwXHMscQVWRtQvLjl';
- b +=
- 'f57pZCtwc/oS4O2KTWf3liDQNxnsYj5tOnMg2Dcb8rq32LS650w0zgcq2QrTs++HeeuLZZulqym';
- b +=
- 'kfqbbanZ/ww5Hjoo4WgBrg8JVkyO2w/5q4l2rLCnTm5mvQmup+/A+1ddly/ryNnC70ew+tE8Vft';
- b +=
- 'OUFZ6Rr8LYUnfzPtX3ZVldsKnG6XAUc/yWt8VIl7u/AnIjTtssxV8AldQhgyEqrZhkcMd9B0wh4';
- b +=
- 'rCZ2JCNm+pn8EDnw5zUahyuk0QufIgTwmDnFOnV4+DWQ8QD+Z34xXykzI1wWIb/usHmyl+Fc3mo';
- b +=
- '//o32fxa8H6rIGv5Ss7ohTvrVgb22OtXgpqdgkSw3cJpUc0dnllLCYcdZvJpskUOm5tvUvLpHMC';
- b +=
- 'vGaSZMwkzA0HySQfs995HHqUQVg2Uc+LBQDlHZy3HoLdIOZeadoC0fHtp1FVb9rVRuaOxVY7GS4';
- b +=
- '/AHu6/9gh3/utw0f0op8SmhBmXQkaSRmPblr5GY1d4NL4UjMY50dHYlm80KN4Cr+cI9totNttS0';
- b +=
- 'IZ1OYcLYZOIoL4AuFwy+zNzTh6SlfMWJjZa6XmQrNID5kGsC9VAjaiJsIukMz5Tg5dgdbFd7L/9';
- b +=
- 'D0AbI+TcV94Q11f9U7m8cCHFfp2unzn81dIH0CRrxDSrrt3NFsW4ZUPHZAhpHBv5aVEbTUFWytp';
- b +=
- 'MNGIgByMdmzqEBAklIdAv4BQs9tCMNUJn2jgeUYkzHZvwpfJMELvU9GFpu5H2LKZF7Sxrju1ADo';
- b +=
- 'wTW/9QJ4ReDJJHRwp9/5IPutipCiS8M6ITDwfjf20MAOmDKOhxFgVVZ1lrP9qoABw9PO4qJhoj1';
- b +=
- 'Lw7Kx+FghIXf9ceBkXJdb7YvYd9OMTK6N2T63yRp1Zw1zpiah8V59b6Up5aT49oy5AbBTrpL6bU';
- b +=
- 'l4ExnOJJLdIL2IonDflpnJErySsgSR6o++9DftTGt5CyQpC/a3YylCqSLS/QYcySuzPycG9M0wa';
- b +=
- 'RFnSGjRDx/FcuY4ZNfPSqyxXDNiOiswtXt0269XF1juT/RGelUTvnv351Dxj7Ql3TImvXzUb4SM';
- b +=
- 'nfudKJSRD178bk9hCs1tMik1gZZkfqQS7Rzp3FtqHN4mmaoX8e/QFRDGmLjJ2k0T+bTDfKtQfA1';
- b +=
- '6cH5zgKJZTQwm70rJmknxANetnMNXv2LOmlhYYXSd9ITd8fp2eQSj2fcO+ITzQ83I0k+ShtwGdy';
- b +=
- 'QCMS8JsqtDRagWg+yQ4Rk/CNQEZ+OkRMKZ3OTivHhmUr2bBY1KGaKYskpD6tUz3711VBVfvd6zP';
- b +=
- 'kGTWI0D8Mt4FPJLeAAWJxQ/df6XrAcG9IYlwW952E+ypDNoGkR+x6YD8xkC98dWDNmqzjTQYWI3';
- b +=
- 'U0BAgD+TzbEVmkLk9qzDvrzKblrBrR1pUxOswMVushC7My5tkhK/4X4zrBMc3IsQjDOEAGqNeG6';
- b +=
- '/ZfUcuwsOWY/CyaTjRJ0bVeWcjSDkWOobgzbQLy5/X4URqd5efh59yZGlasVF+IXvUwxr3Z6n4j';
- b +=
- 'TocPMnGzmF/y2IUVAfqL6cqtIhdVZc8Y2AKaZLHykaWwLxtss9IqOgKXiXZoy61pukIiRQNUU9n';
- b +=
- 'k0Ppz70uUaMEryBoPiDup7hXTDljwtXEIHuE7fhGfJmSyG5wcCiI6zNPbqZN4RsqACw5B0UBU1K';
- b +=
- 'WoubBpIyghXRBi3KgoCVb43AshaxMzHta6w65/bT5mnDeA6eGzWWpYDHCiDiYbCqENFip2XwMwb';
- b +=
- 'IxGezWqluBcqckjQQNwMUNaEiaZnyK/hwL3TTsA6FascU14jcG3DKefYvqkIm214amEmx2e6pfF';
- b +=
- '5SI7NU9bIBAtNsl1H0C7q0FSnifoylZm1wENgltyIOqYRB5t9nQtVLpcrAVoaN3IdCuCG5G9uL8';
- b +=
- 'FLLOO8RwUNB+AKmYiGyWNFUi2aDISrZ+kuYzgRn6SpfUyXhUZ6Pr3KZQ5NIOcFtkHC/RwVbDRkQ';
- b +=
- 'V3kgZsOJFRxR6BvZMClqikyRHXLptieZsTAtrjaME1gIX59yxcB4HznyPJkKkReiYHkm7PTyQk3';
- b +=
- 'Y4fkQ6foey+HUeS3yMx2omGdC+HcBdGEN0C/qE8GGiUqZ2SttoRZ6HVs9onGqfoD19BTCNphTDy';
- b +=
- 'k62I7Vnw8Kzww7NSJ0cp+ArYPP9uywg8FVlNn1uAUXTOQbxtptpPj7K2REBv+wuID/yn/4J0NGx';
- b +=
- 'B/i643vOXgJHt/Qu7eQfnSr/9+cpbsj83v7WX/jyJF75HDmqeczrS34KpIm8oSMTcm21iBAV1x/';
- b +=
- 'utZyLH9GmKS+huj+OJZhNklW+MtNd//RSyoHYxuU4mk5hcI5PiehVe4wGnAtbzaTBVsxpCRLE0T';
- b +=
- 'nkCWZZyfO10xdOEVo1FviAGaQTda5JGilaVjYtpfSwdhmgW6+ehHn39TIwKbkrZHu7rjhzy0qz7';
- b +=
- 'oi0tq39vKTHNiftBj36YDweGDBrJqiCEkVh4xJFooCqfhBfVYdYMdmCL/eMwYboPmx7dUNlIUfi';
- b +=
- 'RmfwMmtFbHgf1UbDlxQHMuLTdYfSdkzUSIgl8v5wvnRQ/TpPvKiEJkTrGVMAROiWXR4XZI/jG3t';
- b +=
- 'vEwrshJjHAdGqRN1E8QE7QtbAkBiPmGaM+mKwfSGJfu3c6IejZ6mBPusTK3dAwr0dGAOIAopCtP';
- b +=
- '9jXZhbI5GlqYnaqKs/nuu84kjk3UD+TdffY7r8c3QOrOvSVnRjNnYPUPhnAZ6EASHy29omfyn2h';
- b +=
- '6f7IITafqYLXkfqkaJnhzt2Hp80TzP15OvCFkE+frJ42jo2EQgZnSwyDjGbiYlaTp7uTdV9Degm';
- b +=
- 'fnwAm1GLPXnqKgQejQYVQ5Ne1rBXC0ExJW8PYNBDe2uFBUhAUgebaYrdnA8NWyqAHh8SMIYQ/D4';
- b +=
- '5vKS9WmGKnEZNiC6c+BVAoyxBlRpA9wOwcbxsS+5a4MYSRMkl07lZgkGa0enAn4vRye9nIu5eNv';
- b +=
- 'HvZyLuXjbx72ci7Vxp598blvhmJNyLq/ImzF64Lu6uPR80BPHrCQI3VlQ06RDgj66KTNJ7Y0tyu';
- b +=
- 'LeV2bTHLaeVzu56QTyn9lj0AwjPvk/8ayJNV+Q6nAZxMfQ7OXe9/cN73o4Z7z/t/9Gfvv8H9Pyp';
- b +=
- 'OhAsVLQ67N6gHJENp6Awl8vGIxVSlgquKvXI/p9QJ+bgaDPjTv0C9zx7b8P57rP9HT9DQ5W3N6h';
- b +=
- 'pEJGvjrDj30Oo6h2iboHS2RqAncXTVC0mVnrIigXD2661jxBhD1p2eeeeF6ditQA8ifYk+maCiQ';
- b +=
- 'hBRQRiD3GG/XvVhPXuKIq0ICE0yCQYxCWL/2LSRj6Q1m8idFwn07ZvYWuvkqAUfB1rcuZGtrImH';
- b +=
- 'LKA4n8PJHqWIdp27BE1fGZrHJO01StRWd2ecZzGJGpJyCp+ELnskjSmx9MmBFDzxA+57cTS9z/3';
- b +=
- 's9/nW6ohPr0U+vSaJZRGMpvf+Hrgq4CswiDlvQA+CKpIexCt+8KTIMl9/B/emp+A34VmRywpNuD';
- b +=
- 'L9tfeI4TnP0HaJHG2Iz0T6umc3sjQQrwQ1/yA9O156/G6VqPIsr1WyVfLIB6pOaiqTqdJ82hzy1';
- b +=
- 'v+VrWADLBWALDWW/JH8o1tZySz2LY5+0cH+tIJObmONspUqz8OCkL7oW30xHqUgNxkuA5elbX8Z';
- b +=
- 'vACxowlgWnzkVbCAMMrBsqmp8RTTDyBnJSigxjIVZf2wZzPLXyvRfo1AmT1aKezva5JjtKTtlNs';
- b +=
- 'v6hDHRSSuxJNLrwU8q7fdgDAseDo87BxlpCoMRcKItv+GojOZ7kNxksu5f48TyJ67xuKL71g4oH';
- b +=
- 'nEC3eAZU2cps9dW1g/F4gR+njqa6BFP4SeWvNozlNjcy3esRmfkPLjXmnKQ0M0lriK1x8TNR0Zs';
- b +=
- 'CpSXhI1Hdrn+vv4ik1gY08u7/7Wx3O+ogwmTgKZNZPxqGMzUKBOIl84lx1/UBD2r6/3bHw16OPN';
- b +=
- 'r+a8p7/hfE0O53flcN5ovb+HynLJBnFq2iTK5e1OMDuh8ScjkLDJ1Mwhuk0UdoA0lbJAtZX3PT9';
- b +=
- 'y9vKefX9ibJ4n0Lpnh/7Mmpjcvfssv30fyz+9j+X/p7/ykY3sKVNjPdfEJAHVZ/k/7mP5Z/KXHx';
- b +=
- 'dopP0eMji2UO7ct62y3O6lCNm9JoZvuM9G7wwzV202Oli46ActLWK8ALPE/Yy45G2hr0/YqX/Cj';
- b +=
- '9QnlOdgCpEVPmiN3K9aeczy+x61v+qjdk//o/ZXvUn3hEZBqb3dp2PKkUUspTzqSe0A5R2ErelI';
- b +=
- 'zHsbxZfRl8FeH1hx+z4+sG5fH1i+aR8fWPWn3Ac+md9j+nJyHHay7tXKRLLfot8YeNH15oCLXqN';
- b +=
- 'qHY3ktr/RIJsrtMfAuL8w73LCW5UZykgLZdW0sPxXVrGDKm+YNOeAjU99khVFMwntQtCBa6Rs3V';
- b +=
- 'aVkzXSqAh5ZxF5Z8qYloLYukhNxFGBdiIIlev+yWRlMKx1+EZSRZRr4E3kej80bhuWZVp2ikIcd';
- b +=
- 'zCCbAl+uZnFDZyd6dOWP4J65xN+7z8lbJoGoU2qgdH5Dkua5zfmzpG9lL5tX0rnWxJwbLOFn4Eh';
- b +=
- 'x5SdQZG/+rmNZECIAEYkOSNIh77fkW+Oj2eUkSL/B2RwZIZqtOgEjcnYx8yplEmUijQDUUR8ISy';
- b +=
- 'S0lnKFyL1iQg9icM8XUp6tlhSTz8iX7k/JXILjo16GKoAGO9C0IHvY5Pd/5FgQcA2h30H2X7BRH';
- b +=
- 'bjoR6QY5IkA4NVHr+XSYysCkEVuc8ljJxvw8NjnSUhGb4omzx6nwjjkeEGEwQjWeC7D8TQqpDH8';
- b +=
- 'Hjsd//t9957LzGDQqKCqAeqcn8cT5NjT2HK7U6KtkrLYrGuPbPNt9p49mfTMh9ycBwCSEdzhpS6';
- b +=
- 'Uhxkg0yW7Y6sbKZSqZvu1yDm59eS7uFoHvBTSx6yn+yz5P3mgIv+zIoUHRkdV9E0bWjd55Sf54A';
- b +=
- '+KSY+acAFB/7t0O2TlHJrklJrTVL0C17JcoYqZ6hyhipnDLy+Ut7+ADXS8h/g00Es9J6nczdAWN';
- b +=
- 'mflAbvXTvEkjjUf0X8uM+SRtUAqBKCwhfzBpcI02aChnjUSpssKrwSwdQlnYUYTX2WvdUaeNm1V';
- b +=
- 'K8xkLLfzq13ZFTsAB5iq+VeYcNewYfScQZFh5oxxIhCLJDdP/bccdEdiCM4wwL9rXJF2Vup36lS';
- b +=
- 'n1BTzpF+AeTAZ9RIj2TcRj8e8D2Eyk7Tk0BXxbYzA7Eh8ANwT8jxmUTpL1ulEqqCh/6WdKbzhLB';
- b +=
- 'zJoQEi5AkuK3IBK3ogOpTFqb+IPbDEkeb+5hDGx/5PaWOicjvTN9zkV51fyNtAGgns3lTJE1Ul4';
- b +=
- 'xnwRJgPM+PiS5SUUt0eR4TDsgi9s1q0VV/iOMuy9ravuv5YZ56+n7Xx3O+bdUvxSQ8HD/vhzL+Y';
- b +=
- 'erYPFXxPrlv79tLRUGhgU2Yj4cM1fDu2jgd9hYuDQNLH0d0i4XWfmw+BrHPkJxwH7PJpq+EFxkr';
- b +=
- 'GDwM0qkW2Fpbbti0HyFVJ5n6gDglRfjxavW4aGq061+It7LpX4qclV42zakR0vpTHpdk5wxhqsF';
- b +=
- 'OyaRjUtBRA+uSYwyKOu/4F7YqOlKdqTTlj5aE252TxNUdXwGLu0+njWFY10VmKh2dEe7VSPC4D6';
- b +=
- 'jZkFvkeiry4F6K/Aw1ae4vY30X+TPVcsteinyVivza7LvI1xORyVuSU6QaS9y2l0r4m99STTmGs';
- b +=
- 'aNiOb7IQbi4j7HAB/q3PY00XGMb2H8evRSgwD4uiSHdfcuQSM6kj0bOwboQIF3Bo8KadPLlaftS';
- b +=
- 'z/6KuOw8i0bIU+J4oJJG2p5n3bkMrYawiUn8nLATe6NnzlQz+xkndQCKPNt/kZ1Oqv/GHq2OF6y';
- b +=
- 'nEfBZEVANIeba+nvHn8Q7RkRW3Jo/EtzbH9WKQ8/05tRR8K54B2K0wWUThWaxpw8TvQ67CUES6d';
- b +=
- 'vAY4kaMFF3+v1WO0WnSV8DjMNbbAygUPKDLTRsIIUGDaTQRwdYUz9d+aIY0pLQcEyXzuzimPhjj';
- b +=
- 'Maj3wE7Tjo1Q9RKw9/9wEaDZpnfs5Eu3UvisGaReQg4D3LDYs6jJIcUgqkJHpDbjSb3q/EUtiN/';
- b +=
- 'iVgHFui7it5+qyjYW4EkMj39vKPb6q8KbubRklJxfxdLs9GtqQOC9vkKq8P9Or+BAy2lbS2AkiC';
- b +=
- '+mrKyhtwCyaDAcZpVtum/CefmEWKMEHZkBcynw2HE0n1PMZxgcdis9YpW7BYsRswdifVcCwnHHc';
- b +=
- 'knPopyya4xx3YRJ8ZK8OP7wRs9BoMwDPMP94/wDAjNTQUehQI9eoEhfiEX+Kjq038klNuCVn8fH';
- b +=
- '8KWSamPav4cJvAT+D3uGJQnpYaxgAPxGgAuPeAI93rvo0YgX1WCiqRbK6ih+23tndowS4fg/HcR';
- b +=
- '421lX3fVs0cYET8XFAkUpIaHd2/UHiLkKNA9HyMl9gYgSreixFy863aWAHmpw5X5HgJ0g8Xd21b';
- b +=
- 'qI5xLNuKqv4fBsz+2edoFM1Td+0kf97ANMHgjrG1dkwTr+m1R+bBDHEHsHQr9C9o4cymAaR49ZR';
- b +=
- 'i/PYfuGk4ByfwVINkaGpZspY7EvioiKVXojnystxcmceSxjxiBG3c32h4brgk9HThC6SzREYbSs';
- b +=
- 'IbyXWwx8NMwVRpbU4dJcwneU2H4DiPp0K0Om1e6VzrQ/eRJIvble+KMB586jNc5Zo8ucTzBTtFA';
- b +=
- 'uRn8948J91Z0FOv7PcguqQbmyzs8ELVw2PLRgiPOX6PSygNxHeRFyhXiltchCTd4awiX3XBPwpa';
- b +=
- 'MQE015Zki71A5CgS786KVimb1xnOy3hWHHM+U396FwcbX3g226u4Qmf3G3eg4vxygZBLuUB4l9y';
- b +=
- '10hRa8BmZI+FmAQJAl3lEliuQSxIK8q0QzCyCz0NACzn2M0prhYsqVlg69ELde8Fcq42WbMnDlS';
- b +=
- 'l+nvabciDcX0oiTdu986NIVWy/d+RWw8TUmbfznmy9t+eZPHvPBqr2/2kIHVe5tSVuK1h6fOiSc';
- b +=
- 'sSUhcgIrNTRO0x9K4kOFEdMyeqkmg3ZVp1piJfhGaih1KExa989O9K1/HWDDQqBu4kApgZ769TW';
- b +=
- '/uLj7hV2X39BJXXXLNY//793r37l+EXQVlnjjn1es3bb+rc0/5RK3d1+08uardt/0sSp7AL2dty';
- b +=
- 'F6f4icw/L4ypAvldiFW8VuqLqMedHUEE7Z4u7UATTTDX/8SK5+uO+2+s5SlfJa/Rilgr4Pp4ZKc';
- b +=
- 'BLfc6+PackSSIbL0gryH5BYPKkCefvyZKFaJP6G+8RxNJlLy/QlpqqMbMtzU3hY4rRUVb3yO/Ho';
- b +=
- 'lKAqTHeHquqWD/NSpxku8fu5JOFPfSXyGjcczuYoyli3NcjgunqorgJKlaiKw6+BijEIQuQ14ZK';
- b +=
- 'D0ZUXJ0HKIN2YH5tC1++CtHaK/nWPxvodPdpoX7bkYFpknS22rRTteN9MHmWI1/oEad2K2Yg+1l';
- b +=
- 'rDI0gEvmw2CShVynT/m98rUkfZnSAQgheNZ9pG8NyQLDNUUrXxW2KOBvWIjKlYVHDvsii05RhQG';
- b +=
- 'B5jYFvce8VUd9+I5UncBokX89yhRv7ezvPMzWJSuH+K9Ve1THCHXW1SX5r+bjhlDoG9BZM990gy';
- b +=
- 'O89jYo69YYeuB1N178UK+RJEo3wpOmMadoa/6r4eAm/kZ8X1HbQQ/e33462fWfIh0z08tyq9VtM';
- b +=
- 'tlFMe10p98LpCmmODRZlvO1rHbXGCMp8I2rDN1Mp8x9YSv3H0Fwf5KxPULT22uPEP/RVruP/+/k';
- b +=
- 'cO5Knde8bSEi+YqUG8KGq07F/pZR7TG3ap/prb9WLf1Zv8N/2Zx/Vnduhz6O96w/6gP3MPTVVKf';
- b +=
- 'Ep/Xn/Nc/oj39YTN+pN+5H+mr/pDViv33lVv3OpntioV72GZgfsN53t8tIzW2mnoS0oaDu1w/0V';
- b +=
- 'TN1/xLC3RW7CCObA57W6ex0auJXrNgL1JdfB67cBVG14HF+OaW9p025cY3KjHP/8VnVpysuC0OV';
- b +=
- 'SuWh+R00CVmg5XRJ3gyed6d8HjKolUsF7LtM7pcsMPui/5KS23O12cP2OKb/+gYS8WmnLq40q7z';
- b +=
- 'IHrmBJXJKQV9001XHtCpoT3+X+Ie5+n3rE3w4c2b8sWUVw9SvV5VepF3wtjs+PNk6BoUpCVRfHa';
- b +=
- 'Dv01/xWVPSOhbmi6HD5zO2q8dck+OlZ8DRndqvX/EF90Z9MWcvpWlZQH75vw5PifX/nD+qx3d1x';
- b +=
- 'dfm9hLp8Qb3oYSuVoGlGCxdZwkFSVS7u4amDOSBSsqkDDXejjSfSCGt996Qa+uY7xZMJ4rX4t5H';
- b +=
- 'qTlLaP59+3XegXhBlm/l+DbcrQb8XJVJxkl5gUsx2/P27KbLFr4dJMev4N5k3PdpwUw7olPL9Yx';
- b +=
- 'v05wgeBP5Jynt+vn/gvX5Xl5MSH/qh/D91TdfFXYYJjegxUpd3WUuamtqWZGqb2jMNzR2ZtubaJ';
- b +=
- 'i/T1tbSNtHLQDpT7y1pbsvU1i2sndeU8epa6jNjz2rPtLWPrVvY1tA+dkxdbduClrFtmQUN7R1t';
- b +=
- 'F4xtb6sb29Bcnzl/TF1bbUemfUxDy+jK+WVV9eXl8+bVlo0vLS2bP1Y8X5+Zm21vaR5dNqZ0TFl';
- b +=
- 'pBT5XnxnT1l5uuMaXDcO4zgFZkWHI9NUi/XHxaxr0H/xa4k/0vZEUfw7/6fdjkXQ8kk5E0lCP+I';
- b +=
- 'oldR3e7IYFzZn6ybUdtd55DR0LvWov05RZJLqkXZRxTdcoibx7EDzbsGBuxwWLM/XisbntWAP8W';
- b +=
- '9uxpC0zt31hbVsG/5mLHdTUUlfbNJd/Lli8ZF5TQ93cxswFUElz7aJMTkMay8dXUmOqtMZcJ9py';
- b +=
- 'nHj3PPFYm6iqSYzYuWdm2pc0dUycuKT5vLbaxSNGnuu1NHu1zd65NW1t53pLa5uWZAZrfZYSf/s';
- b +=
- '/qgsz548uHVMxZhwWb2qYJ0ZT9I/lGmeL+h8Sf9BOPe1Dn4mydS2L5jU0w+sXi2+cW1fb0CG6r2';
- b +=
- 'MhVNAlyh8tykF/n5pTfmH93ExdfXvt2EUt9fg6Y70o/1Hx+11+n54+5YB8Z13bBYs7WkaLDhcrR';
- b +=
- 'nzx+DFl+OASkRybaRZLpKF5ATZmj3h3VryzS/wdIv72YXiMgsj4DNHm2tAB9NsGm/rtKO43PX2O';
- b +=
- 'lh4m/k6MpM/W0tB3IyPpk7X0KO5nmT5C/JVp6Qni7zDx95nj6t5+4Lf3vtb93SNuvfOtF+97j/+';
- b +=
- 'DtQe/+z8u9Q0LxKIZDfvJmKqx1D9isdUubhhb1zF3aW1bA2xh0DfLHddoFO9dJv6OPSBzYp5Yxo';
- b +=
- '2j5y2ZPz/TRi2o0FaBE3ONc8V71oq/YhhDLe1p6R+Kv6JI+igt/Z3I85A+OpI+TkuPNmkPlelqk';
- b +=
- 'f6Ylh5vUn37//2ZpqaGxR0NdaPrlrQtzUAPjBszHh9dWNu+sBxz6XJ+Q6apfmzm/MW1zfVzF7Uv';
- b +=
- 'GHv+Ily5Ttw1LhFt+W/c8w2VXin+DsUN+gCcOwtry2l0KkPzA95/m3jfl8RrJvF8XfDioOylP1z';
- b +=
- 'wi7bXmk+c+MbMWzrPHPqZqxbGbrj96UuOPvL3u77oijJyjR7CbYTnar3JDe2Lm2ov8BoWLaZdur';
- b +=
- 'ajQazvtow4BsRWDgsdT1hxsIpuyNR1ZOqbLsBxl+fQ4TAmbUvaO+rGllZVVldXlVdWl46vH18/r';
- b +=
- '7S2Yl5dbUXF+NrKyvFl9aUTqkqrSyvKMrUw09pqRUeILaalDr9O9AtvRKsSrjFD1Ll6EO0dH9H2';
- b +=
- 'kiP2cV8qjuxLR+51X2rM2ZdmJWlfOJ7nqkxP4D1epify3JbpE3gfEsfjRE8cXutFPpzvd4tfUys';
- b +=
- '3m8fh1JYlTfXNn+jw6gT10pHx1EGslf0i0wDRsm2ZupalmTYxhPWq7LnyDJJluZA3X4yk9oBXGt';
- b +=
- 'Q/j2kOmZ4/0DrKgmcWch1nZEQHZrRi0yd7TZna+navo8UTdwRp1ibudXhESXiCkjDWDXKNcdr7W';
- b +=
- '5hOaeNx83jcYI9pny076MxMnfhuuD+H78OZ0Ia59Jwc/+Ha3Jm5GGZ5dO54557R0pzhubMv0wzb';
- b +=
- 'W83v8XguyHlWcoC2gyXzOpoyo8vFCV4aolnuHewanxfvuN+i/joA50Nte6assg5Op/Lwy45NuTg';
- b +=
- 'PgXY5Bs4jLS3pI9muNeLeYJ5HcEantT3jGD7LYE1NbxadKKaRmAMe0KPbxHOwX8nnj+e1KtPH8p';
- b +=
- '4r07N4Tztt+py50ybPnVHz+bnTxQ+s5c+dPnni7Gn+aLiePfuzZ809c+bcM846bS5Oaa+5pcOrz';
- b +=
- '7Q1LM3wNGzENkwtIBpM1v85/jY9PUhLz+H21eA2ed7CBuQ8msW07xA7GlQNtc5va1nkCaLTkzTX';
- b +=
- 'RJgnq8W7yrS6zuDv0dP6u05mmkamp4q/T/T7brHm9DeLFxcPcY0xWj2TeUxkehLTcEFHiXUs9sg';
- b +=
- 'OrUrasUd5tfNa8G2LRZ2jtDo+xXU8+8tNI+c9u3r7itLu838f23PHk2NK/nm7d9MLFdMudz4aL9';
- b +=
- '3xce1sgm8ZwXviyAjv9MkI71RaVj6uYnxlVfWE2nl19Zn5pWLulpaXjiutKB1fWlkKZ82EstKys';
- b +=
- 'rLysnFlFWXjyyrLqsqqyyaUl5aXlZeXjyuvKB9fXlleVV5dPmFc6biyceXjxo2rGDd+XOW4qnHV';
- b +=
- '4yZUiKOqorxiXIU4wCoqK6oqqismjC8dXza+fPy48RXjx4+vHF81vnr8hMrSyrLK8spxlRWV4ys';
- b +=
- 'rK8URWCkOuqqyqvKqcVUVVeOrKquqqqqrJlSXVpdVl1ePq66oHl9dWV1VXV09YYJo4gTx+gmi6g';
- b +=
- 'nisQkiqz+eQfKAff23eyjN39Hir1BLj+V9SU8fpqU7xF+Flj5L/FVp6U4eTz09TEvP5zUu0wvE3';
- b +=
- '5hI+hNaOsv78wdJS28r/GBp6VlumJbW056WlrS0nj5KS38n8rykpfX0cVpa0tIyLWlpmZa0dFOm';
- b +=
- 'eYFg0eGMnt/Uct6HSVrj5J57iIvz6r/E3zT4Kz919Myza86cPf0LNaMnz54zms8DuS+MOiBjuDd';
- b +=
- 'KW4zLoWFa2xgAve37lVuv+vLj95+wZtqPXtzxw5+/+174v4NJDzx8aJgeCO8nde1zaRDUflJxGK';
- b +=
- '3HUl6/ivb05tc2AAkk9noxPxrmXxDdcYl3lns3nMnj9pOvqDiIfMWew8J8RQPTHaLv208rcvE73';
- b +=
- 'u/7YMbg6+Yv6pA9e24RvQ/W2pADUXfdwtq2sYsyHQtb6tvFC+4T9QOt8Fic6z8Aks66MrEOqlhE';
- b +=
- 'tLilobmD5sjww2lOZZnW0dNHa32J5PBEb5Qnx1RscqtEWTiHbhW/wIMtamhvByoENwDv3HM38f0';
- b +=
- '/HE68kayL9yZjd+T5+iWLBa0GnA/XAPPvIy7SgLKO/e7rdvGKzNiGjkwbdsAIUT/QYo/EaF7K/2';
- b +=
- 'o7OjKLFnfAEqlvWNpQn/HmXeD9V6atpV2wD7VtXsuSDq9lvtdW27wg08+xHTrX9b3iXZY7Hez/z';
- b +=
- 'A9Y3njuESRvXMH0+wE4fIBQgo28ckw1nzn/tagWpvAO8S6QIz7I56ienqylH2C6SaYfZhpGTx95';
- b +=
- 'kPm5rxaH9+8Ti35QvK30zxeY97w69+1rf77EPW7eece3/+uC35xVdcvSuSuKB5997SOfnf33Z87';
- b +=
- 'ZfeTPd2/49JXHvVbyzPLLXnr80i8tP674vdZL+5tXOjMkPqpBLL7/yjBjO+dIF2m8D13b0k4LcY';
- b +=
- '1oz1zRnndjJMOS6ZIknT0yXZQk+flX0v896pz0OeecM++c+ec0n9N2TsfEtnYUDgSaigOqBwF+8';
- b +=
- 'CgX+ZRzjqL9asFRtH8t5fRF4hfkOMv59+qjiF+6jp/LUaWElSqoOunvHfYwkjf1WzfU+G+zdyxu';
- b +=
- 'a1iUaRHj30aEI+0ctfPnC9KFzqHV4rtqUadFvI2eLtFkCXBU1orzp83zagXP2tLegNSH4Q13cd6';
- b +=
- 'Ui184M2fWi5m/ZNE8UVBs04KPaOhonyXuFWl1EQXBxxHQzOL+4cH9aZnzT5Vvq6vU+NPxuG7EJ4';
- b +=
- 'tfPb+K3nsa1seVzMZ3UNZB3oPbF9KRZuwW35FhPr0kkj5ESwPd+zEtXSP5Pk5PO2D798DPjtUfD';
- b +=
- 'euq+vuvP31Ofzz1umvKLqx9YccFkx698g9nf6V9Jz8OrEoX/Nra/vov3lvhv3fEnxPZd6Pr5r0B';
- b +=
- 'nO9va8/bWr7D9/qTsewvbbG/z/fX//09Xx2R436Qcy3pRfSiC5c0N3rtcEguElSmNy8jDs/m0UD';
- b +=
- '1Gd0enZf73z6xKwWNKx9Tjk+JjCWKJl/n0d53EcsS9kqPauW7xR+cCbXt7SAmFNsi8XkTvUVitz';
- b +=
- 'vxU157pmn+GLHdjRh5kD6jtmlBS1tDx8JFwMYYLSWuUc88P8g8ZPq/pT64thmIE6CXYJf15pEst';
- b +=
- 'VZ0fF3tknbxiV5Duyeo7QViF+9YKBjL2jGyjivZrqKudnFtXUPHBUrSAXMqTTzD/vOYSzPiV/A7';
- b +=
- 'c6Fhc4FpmNucaRfcDw7UnDTZhJwgdYMD4R8OTKMUj/8X0YbToD9TB4gXjfBH044J80cTNFntRP5';
- b +=
- '2Pe/Eg7+G1Tm35ZjwOaenD9HS8pyTaXnOyfSHcc51Hxvee8z9pNP2v+1AMIaoM1zImY4GXcKHbT';
- b +=
- '/lOGr7am67TK/p58yW39ifDG2NN2zhlLF/efajs9Z+tr35s1+K3O6cjSw4jbM8O05iHYpMnxJJD';
- b +=
- 'z9IfHXi32F8NEJ618ddlNe/wjoCPQ1rxMeis0AAdP7JrJNxWA92QUOzuCk20ykgfqkh6V5Z6fnl';
- b +=
- 'lbSGZF+euo99dCD/W3VEr/Xg2WuMG6/9mlX9syb77Rsse+MD37PPGRm3zv7x36wdb15oXdfyMWP';
- b +=
- 'DNtd+95jXzU3X+ebh16fNu454x/jkpG675/6Z1tJrD7Fv/vh51j1DDz3g7duXfvmbea05fPAXrc';
- b +=
- 'POuc54csY2c/qe1ebEIUPsv14w2brXH24syxxvfeHnHxtwG/Vhm6yNV83Bnn8kExt7njjmxpXT3';
- b +=
- 'nzuSNdYBOcTn439fUN/e8KHNd/K1v+x5nrvmy91/val1qIrbvvU4S93X7N7RdNLv2/cdmvJ45eV';
- b +=
- '/nr3/YN/0DmnZcTyoeaTF566O/p8a+emK354V+vhv4m/8Z07koemN0XKjzr7x59a9/vMU4sqOhI';
- b +=
- 'PDh5xRfS7H73k0LvdzY/uemDCQ19/+96udWtvePW8d/709BeOfvTmk3965uo7Dv6+M/Az7XPHh8';
- b +=
- '+0bce72AagDc4SpUeUnj9y1/EkG/nz8STP7W/cp0XsLw6mLHzEKJLPXco6aZlezrJDKb/uqF2g7';
- b +=
- 'vWwfk6mb2B938GUIz42KmIXcoBpvhNHE833hURwnvctD5cStYkTyVbhv732liVtdZmJ3uyWRZkR';
- b +=
- 'I8U8GE0yq6dH05iDLY73FZpXJHc0DKj8Au+C0XUtLW1iQolOOXgjfegY6r/BFtGFs2tOLfP82We';
- b +=
- 'MKZNSUMNYNobkSXiPmrqgrXbxwoY6bvEYmttSLeoheeThOwJ7DCyKVQjupB04Mszx25tBv3aatk';
- b +=
- 'efDucqvmZWY117dege2o5AxTVc79lU2awZp84+pjrc8oqxJOPie+GWg30HCEO9RbVN81vaFmXqu';
- b +=
- 'Zji27zFtW21YlMXLwgKBaZcQf+sHkv9A58yK/IdMzIXnK5eoOoLsrA6UUh/7jNQl2zF9HpxgjXM';
- b +=
- 'bxBsn94eUi+FB+qTpSTvmz1rxvR+v1aw980t5zWPXdLcvmTx4pY2UGMFnz5z+uSJXkbUd4zeFu0';
- b +=
- 'D+P04eLP38s0zG+rPoje1oK2aXnZORD/5SumB108aZWH9JKThP5CYTq45U6zcjgzspfVl1Hf1sN';
- b +=
- 'o6GhZleGovKyOZc8viTFutJkdYWUb2W/PBGAk49/ktS5rFB94h8kF3SCMDb1iUaW+vXZAB9r1Bz';
- b +=
- 'FnQFHeIDUHpDkd5gt9fUtvkGZvEs7DX/k38wl42fexMNbbJcpJ5w0JHwjQjVYf1De3AD5+XqR8u';
- b +=
- 'ygzHMtLwkIuALSPwAeUk06W2kcFTbXNLcwNYAV5AKxVmQTu0G+gWUR7sHOeXk62imjswPYD+LKc';
- b +=
- '+yzeVcAKBrb8ocyTuHXO8mVM8lHur3QDORW4T6F5AtCFFF6+XU//m7ceOlhavqaUZbG0KxpFef1';
- b +=
- 'bN6aqvKsZRX4khw3UiBk0sooYMzL9p40ge0papFS3x6lsy7R4JXrDlaLbZlmldgpINT426US+eG';
- b +=
- 'xt8K5x7nphimdXjqJ3aeciydsO4axztC4Hy3ws+RxSEDtoqyoD8R5sOxuvjaPzfEb9gE7ZAtM+t';
- b +=
- 'cHHN5OvrSKWlIIsfXkE+KB1tYrpCh+Pqr4X9uB60AFqPThS9QyOPq6F9FP+KflhUK6Ya9vNpoj4';
- b +=
- '49y+oIB3LRRX03cGcCFqBWjWedHeIch+TtnuNDbBEUE40ivcA0GNJzcWXtb0B9N2TxVqcI5biFF';
- b +=
- 'xxU8Q/Z7R0TIF1Nl0tJNlvc8VU158HGSCtK7hD75T3wAZ4eks473Oo65Bri3QU9C9QOOGydXRuq';
- b +=
- '7Uj9rg+97svR/a72ZmOmbwGZvJUh19aqLMyi/Ty8PwsNYcn4xQ+E+ftnNoFp4sR4zeJ1Bk45VjP';
- b +=
- 'ItJnqSknf2GOsX+UyXZs1D9YGuuBUdffD989h+cPqNF4mqhpcVbH/Gq9POiNzoaxp44zGiIyiJG';
- b +=
- 'TZs48rcY/Y/oZc2qm1pw5afocb/acM6efMXXmqXNq5PUZZ5122sxJn645dY43fXLNGXOmT5lec+';
- b +=
- 'aZNf5pNWecdXrNmf6cmslnzZlSTbqk2TWfOavmjFNrxO4iekD0ah3lzxL/dIC+lpJzMjBVzqfE2';
- b +=
- 'YJga1Gp6f54ujhrzqkw16ZmmsWSB+VwPSTPbmhvUNVMOn0WXfizZp02/VR/zvSZZ3hf/JIHcoPv';
- b +=
- 'VdFe+EPxC328vZLoO9D2icm9VHRdM+klM/Vbqmh9P1FF+9SpM0WHfG7O6Nmzak4Vn3uq90XD2FN';
- b +=
- 'Fe0e0vllnTj9b9AEUMYZXUz3RMmJEBXsx0TulmvbvKdW0j8j7QHMCPbooMqcXRdYI7KmTatszlR';
- b +=
- 'UBrbO8mtoF9wL9Y5jIU3uxOPDgVu3i9iVNtbBTiW7vgLsLcRa3a2cXkNBnTjm1qqKyGgqAqtprq';
- b +=
- 'p2XafJ4Z4VcPs60nMViH19Eenkx4A3N7fIm7XcjxGzCzWxkqE3iqdFBu+B8mAe7iqAhwsVa2jv6';
- b +=
- 'KKdt6eHmyoMdOiOdNoybJ7joI/nwBOp76k8xL7S+boU5IPtS0rU1Wr/NEd02Dbtssuqw0+BttNB';
- b +=
- 'mcSeI3xq9tZPkR4nvyHsj2CXmiA/AGmWG3r427Xzj+UAjEcmUs4C3oZpwktraHtlf2jV5eceB4d';
- b +=
- 'FhoY0Wu69gdyZIXUxbXTvxtW9PJDvHKrYNlukTOS3oloBG1u4vOmB2vPnaR9zs6hPI/mYd880z5';
- b +=
- '2XFWAQMAPCPyROJfjnyRJpPr0wkehbsdyo4rz2y7/ptdTwGoh9EYk5Ly6SGBTBoZeXVk8EcoIZH';
- b +=
- 'nU6EGuA/abjEgVvT3LJkwULxWLs6C1o6PkBZCtEitW1EZgN9ppYeqCfBVu9TRJ+uPZFkLoXsT1A';
- b +=
- 'rrRoEvSPt7KaJsodp9+o/RfTMgZYbdHyK5AZvJXL1AH3KD/T1VFap1lMkmz6lrqmlHcxXxc2WRt';
- b +=
- 'EXgt5fIjjhpRlByYvtq3Y+7MvzMkj6tbUsXixm85y2BjJ0bRej1twIV7VSpSh1h587ySWb8f1Wz';
- b +=
- 'bXVnjdXHHuiN7pPIr3cD00al4s0e9qLxd8l+2lP230Q7WlPOTlsTzt48OyO2rrGiYPFf5dp33E5';
- b +=
- 'y8b25zu+ehC/I3lK33bB9acceL77/FMOsF2w+JSxi2HltDWjj4OofyaMR5z2Sj1doqXBhq4oki7';
- b +=
- '5/7l7D/goijd++HbvUglVepGgSJOyvYQQKaGELkmogWN2d5bElDtyOQggEhBsoIiiWFABO8XexY';
- b +=
- '6AioC9iyJ2f2LBSnufmd1LLiEhF8D//33f8BnuZm9ndnbmmef5Ps8880ytfgHUIaAg5Ceoxh+R8';
- b +=
- 'z1K8FyiQPSM9N/nPud9IvUt9zl7LIaCcuvsTAqiUur5C1MLuGEt10tSA5Sx11bEGbDafqFKVSXn';
- b +=
- 'm5k2s+p775lkxs+cfuKlhVWXCogYqczVqO2cmRF6wCHgBDiSczTZiO9YlJtv5IYwKECgE1C3SMf';
- b +=
- 'gR4BYaaAoChz2yAtz8NeHfPDDejqWkjrenNipIv4mkWs13K4rW+3u0KJ3uk0E0DY7DOA+BHoV6L';
- b +=
- 'rRtblGkx5EmR6LxpLuOb9fn4ISu2cRMcGSfZukIcBTSwOziN811EX3k9EOqVSjQe8sRlW5yEuGo';
- b +=
- 'gChq2FXFXZZM9BaEVEG4A1MjKmlpQyuwMOh1qJwcUkqVZJ79KYXiX+5czktFeT+P0McLH98iCOv';
- b +=
- 'EjIdn8fmmdX9yQkSTYPuKCqq5p7ukTIdO0n1+6rfk5fp2K4uymx2huJP1OHnSnmfg8euyHT8dT5';
- b +=
- '3fRsj+f2Mw1sj+e9r/P4b46xLRPJ/Mo5Noervlwucz64Dnc8pzufAlc7nFa84nxf9TT8rlvYly7';
- b +=
- '6evS1M+rn0gzX0E7/5JvlM9a9jybLvd3NGqORzw+r2xfA58Ou13Ab4vPbsbVvfh0+p2x+FKUM8F';
- b +=
- 'V+o814ZNMSz7sNlk6Q5Qzw7x84qfmnTEM+AVTMPTP5yyMAVj5d3erBV5viD+98/0H5U5nXvjYnf';
- b +=
- '80tF5p8jv9zB9nk887HbPpo3pPyHzFVsj969lqcOlb3Ck4e25Axllx47MPujK4cubtG537fdXxz';
- b +=
- 'a5YNv/v2CPzT0hxXr9CkZPYd1fSjxioNX+4e1KYl7/PGnrh+29rVh53x1z85h3os//OHWvceGLR';
- b +=
- 'mzoxQNFod/lTpvzz8t8od3KJg05Kk2tw9/eH3rXu/sfnt4p5FrD12+JGHE3Xmv/NrTHDDi23bt1';
- b +=
- 'X+nl45A677YVv7HPSPm7Wz75/uPfDpi9MI9U7YfbJ51e96QX54sHJa1Xcz56e74i7Py1j32aPel';
- b +=
- 'D2eFdq5fx3/9ddbKtNcTL5nRYeQt1iWvNulw4cgXj3425220bCS38IaWw595ZmRGyWdFRY/9MnL';
- b +=
- '3ay2vuPzLrqMGHWl30fftpo66f8D4/fz4a0edNebA1Axr26hJM2/7dczCf0YVP+UrWf9pv9GZv7';
- b +=
- '984MD35uhWD/3eacaBm0Z3WBu8O9xpz+hVyL68oNQ75o9/LvjeO04bU/r3yq+2GSVjhh/Wmzx7d';
- b +=
- 'MOYdvN3vtXzuQ/G3HFT2rCyzY3HWncc2LRz+eCxA3Z89v4zfeeOTdFvWFHw7+ax9w757K/FHfeP';
- b +=
- 'XbX63fCGO1uPe/zprLOWjx49rnnLJj+9/+Dica1vbn7vrg5PjJt2/L29L2z4cdzNLyzb/+TQLuM';
- b +=
- 'X9ev+yXlrcsf7D/9y4cEjV43vcJtyfavPXxxvZPr+vqXVH+MX5MY9wUzrdWFx7ivNvyyfeeHOXt';
- b +=
- 'LEdmtWXzhffmnTvq2vXVj00uQ3GrX2TNjxa9/nr+kgTdAfeKa49JyCCTum9ExqWnjHhE4fPo2/3';
- b +=
- '/DOhK5je7xw5/LE7C3otwdWPJCRnbJw0v/a9Allj8vb8t30v+/NNh/90Aj/+Vn22cEd05OeaZFz';
- b +=
- '3mj98eX5w3P63nH5hgcGL8xZ+Mrq87ZkPZKTd+ifkraffpMTmv3UVWdf3zH3u2GPtv79kwtzN7S';
- b +=
- 'd+enBCZflvn52+Tubvn0294KzzrfeCP6a2+RDecCxXedNbDH20l0DBk6b+Eazt+/olrhq4rHV24';
- b +=
- 'dzI1+dOCDtqSlb1/470e561lN/rOcmVfyvTbfQ69akL7677WDTozdPWvHwy3/0zNg76eB0MfTYG';
- b +=
- 'N/kQtlzbRekT351sOdQwdOByc/2rND2v3Pn5F7Suu0f7/xwsjxoRHnzw02mvNSjz48/5A2Z8mvp';
- b +=
- '33efJ5VP2bJyTtN+gx6YsqvdxoLnvts/5YJ1Lbf9tKHN1HE72/1x7/IxU4VO3D8j5i6ZeknXi9U';
- b +=
- 'OrZ6cenufaXHGxz9NXXJk8pCFiedMu7N/v9Vrr5o4bUVy/6eH9Fkxbc0327JHrn1p2oDUJ77L8/';
- b +=
- '45bcx9X50jLT0/j8vafcM6AeVd/MmgZ0csuiFv2oQWP7Tf93revNCot4NveKZPGv95/Jhj0vTiA';
- b +=
- 'zeM+GLARdO3PTC9z2Z73fRw+8e1SRXvTm+B9scXr0uaseniMV0zfQNnvP/JzD65cWUzdrV4unxj';
- b +=
- '/P0zFk36tnXuiH0zHrxxfF/56rP807YemLckOMJf+uP0tneuuMTf/dG0g1+3edT/qz+pcN9n3/r';
- b +=
- '/9+QbQye912nmoQl3LJ9494SZD3e/vO/msZfD7OiRNumc52aya6YsnSP/NvOVI4Hz3n25Gzp0+I';
- b +=
- '2+V4byUPnCC56Td65C7+et7D0kbTtKkR79652dh9Hlnr3zl07njfs9S2/++jFsvOv5+vjZ59xqL';
- b +=
- 'E096M/+Y69x93c/qPcJceaeDV8PnbAozXxp2YOF168MmsKsW4eVP3qXeWzg4MkTv/jIvCO/519y';
- b +=
- '72bW9pd/LxuiZlrlj3ITWg6dZ038Yqs95cYHLSVF+eKv576yhqwc8mF4S1vcMpQz9p0Px+Kfdhx';
- b +=
- 'qtnT4pfi7f/hWuN1TGJVfMvX5zj/jAY1W/v3+O+fYKbsfeWLXFZPslYv9B45fdLX9z0PP/rzPeN';
- b +=
- 'nWbrvohzWH/7Qvy4z7euEzvWe9O/LcB685hGZd2emnqY/MvnHWj13v/fXsJrtmnTU3cdI7VzD5H';
- b +=
- '6x+vXfij3J+47Sj6uu4MH9E5jHj9s7r86e+99zhZbPey3945Jb5s15KLnhw7ObNXzw1sGCq8cEH';
- b +=
- 'bb8tK/g17c3G+1I3FryfuS5/ec4XBSkTdw5+oKDlRSsL57/TbmnWRaH4KSNSv150UeJdah/p4KM';
- b +=
- 'XJV+9TGN+/O6i0b/cc9lL53Uu5Cb2OHTT3OzCZwsFflHuFYUb4xcd/fyi5wt7WYEZb7C/F8oDGi';
- b +=
- 'mXvNK9aEnKNa9Mf2x60Vs7tFueufa6ou3/bB/4vbSjSH3q72vPZY8WnRu6NW1iF6H4x3GDX9t0v';
- b +=
- '138zVfXPds6Z21xcHd/+ZrH3ipOefmqlx/uEl+ysrSPePbG/iU3zzqyb8LI2SWLFh9e8+3au0v2';
- b +=
- 'oX8XdvF9UtJ74dafV+9vFpiztrBXWoehgdWXxj+eaMwPDGjRdfbQhQ8FdrUufvPGtQcCi/J2Vmx';
- b +=
- '9pV1wj75wb2778cEhV6zN/DF1aTBn4yutuvV8Ovj9aunWQOhgsPlnnpfOu+/c2RNbDuL7XTd5du';
- b +=
- 'GUVUefeeKa2V99MP9zSXhl9qdXt2v98rG/Zmf/esetpcf6lL7755D1CS8YpVceWn3layVrSjfx/';
- b +=
- '/64YOSbpY38F4euHsuG3pwzbS+3Xwktzin1PXdLUWhv2Y5znvhifcg3Yd6mrya/H7rsnkk3djzY';
- b +=
- 'qKzlzj8/mx0eVNZ2flnu7rfDZbff9NYPi4dvKjOPvyw8nPJlWfoLoUWfjWsVbvTg+H3v3jkyPKv';
- b +=
- '4ukb4norwi4lzxx7b81j419db7j/q/SH8/rHRWy4ZnDpnRca6yWdn58zpN3bnz1/PunLOs2j+Rf';
- b +=
- 'teemFOq4UrNpz/0e9zpq7tt3zOnh5zg5ce7pPj9c/tJjy3tqVx/dyHLvnplZvTds7Nu/1baWDWs';
- b +=
- 'bn/vNysy87/CeVP/Z7TM+3+WeV3cxsfveL628pnzRgZlC9+u5z5M2/X4A4J85aIZYvO2p8+j193';
- b +=
- 'X7/RjUvnDdh5Xf87rr1n3pj5c5N3SJ/OC26+yj6yrvn8FZP6VPRPGjY/sEWbedXyBfNx0bkXK+r';
- b +=
- 'D8xcN793Bt+zr+TOm/NVl6DftF3yyJk3+cc/4BW8PuJL9xrtswbCrz790X+YzC0Zrhx9uVPjLAn';
- b +=
- '/8/Nt3L+t68Z+Xtx02+N4pF/+bs6fwysRrL9Z6vbJ9U/K2i3ccCj01sfE/F//967X25vH9FvZf0';
- b +=
- '/7FwuvMhckDujwUP/emhaNX9MzbuXr3wof+ulk/2tF7ydqw54r0A+ol3us9G0d9VnzJ/mkDR47b';
- b +=
- 'uOGSj0v3dvwq54NLrl3pO9ChV+NFz3y0pOTCtMGLel577utf75yzSCzbnN55weZF63b+uOz3XV8';
- b +=
- 'uqrnTNuz+GWUlYbs0fMJfVXSNhv/lef7f/3dVlN2O+HSvgHR1w+K5/GeQnayXEsTef7yzt369u9';
- b +=
- 'c+kt/OOLaPSH4P4/ihRvJvMM7etUj+Pcb1mXbz3djq5TNYx5eIqefvdLzcmP8P0ESkP+7xOvbp4';
- b +=
- 'w388zCs1xcXn5CY5F5IbpTSuEnTugvU9/v/5b9YbJgds8+8DXNEdnUbZrT97K7sM28/eyq7uv0s';
- b +=
- 'Ygyh/iqotBTNMwKBIkxCNM3sluOsA/bLidgCHF8KQjcDa/xGDSM0ag71zpqZl+Os40d+rzLbzPR';
- b +=
- 'cnOPaAdzfXGu656Ycx2+xY45jgwiXFJRFYkQ95F5zeJVzdVuO0z8leC5dKHPWQT2eD3Mce0OI+F';
- b +=
- 'uUmPiXHMe2UYyCHk+us6aJS8LFKbkR3wf6nNICVFLWNrd6ne5lT+9cx1+nLBwsqrrq8WTmOuuz7';
- b +=
- 't7Qyh/ycp02hEXBc1MU/70Z0i2uD2P09bVuHJLba1y/w/X5X1+DNl7MPfO08W5uDZ+mGDY5Rbd1';
- b +=
- 'Q8NkCn0e+Yu0KVRmObIk0M8JCYOtfsRkNbeULH+E8guKHdvOTRMdnxHCpXvSsSwju5MqvaVO8M8';
- b +=
- 'xAyUlZO2UmsrtcKjGlRCJChEqi96PXYLL5gZKC6MvRRWhQZuw5UR2olexhSwLaiLrxKnwgEiO3I';
- b +=
- 'LmQOdFV2oRn4jSQCEuSQ0WBLHbfFREZOG8VFwOUjVU5Rc2l+4wp5FyaG2pVgHxwQqUzisIRecqv';
- b +=
- '9CHUl9PUmGfQEnRvFTiThaaFyrDxcRAGYLbiMtTMbYKwsVRvxUFAsFUukjt1FZlW+yB+87qmxqa';
- b +=
- 'V1xEuCO5r2eoDBEfNfelqMNaPiqxiiqNuAUlwXBZlXdh9Ao68YSziOWXji1dpCoJVLYrBPwWRgU';
- b +=
- 'XEqIJl5BvdJM8eUZUa4lJFlVaPWkDqAcX5drY8ZBNNcKhebgcm+GyyiroNQv6hvSpWRoIhfpYeE';
- b +=
- '4B3ExfjgboI9vRSWXFqGQevRyKNJ/UQH6Fp4TJEgw1x1e6jlWNG931XxoOlhGfyEqnqhPtuaQ+1';
- b +=
- 'wRejIth/AI0+B+1ZYZLSKgO4iU5nxSgSzs9AiH3G6H9yBx6dYrDU/dOcXhqhJqAUkvJsv6dUdjk';
- b +=
- 'rtrnHHwtCJAZljLV2Yf5A+uscbiRbILE+YUwapCN1AdPm+qseY6a6viBRMod9rqxc8oseDGy5E3';
- b +=
- 'XVyp98+ZMdXgp8W+5O2qt6x4Sp8Rdp46+fj+kjZA2Uf5C9zNGr0oic3YYqDW1OFyGy7dNbUZ92G';
- b +=
- 'u+H5BMv7koVNyvb99oH7d+hARC/WhRylx+gvKKu06eVGs9JWa/AAgVuFua5vhF7nXvj84T32NSN';
- b +=
- 'zCIMNBIxP2QsIdSMuNLQUo4La71CaW4qkmeG6c569Cr3PgxDpmkUjjh0BrQjutb54yVx7NzmuP/';
- b +=
- '+Nk0Rz7VfAotDNUfgd9JTI8cF3+4/QsSocCeR1fFg6ikwEzNDwQKI1tH6ZVCSgn5hMq65jWjsYd';
- b +=
- 'qPqPyPnjOzDynby53+zWSn8U6MXAi+XzXX3xz1PhvcWVixJ/jgRr5B4k/KKSHSSwD99ojkB6FFE';
- b +=
- '33j5E9ElVjH3H6q+kKN6SS0U9whEX0BZAVI0BW5FbJhbEOA4y6UnX/ICPypCEROTEIJENWCahT5';
- b +=
- 'Av8MCgiHdx6MkE4DKbCYTzIhkHONB5KZcIkIgkGE6oi5TIj/D4rVPW98gtxsCAigPj1jQMJMKyS';
- b +=
- 'bVZ9Gw1cPJswcffR5JcRlIO7bh1ZhIG734mjHvFcs8aFyyYRpj0VeHa2w7CHhYuK4IHZLp+uesK';
- b +=
- 'FhEMPdRk0uZwTCIwm7HmCy54HAyceWsmdyR3kSqbLm4cQ3oxDmZQ5h6DsGODGowkzdhs1zOXFg1';
- b +=
- 'xePBq6iTwiQLyDKtlvlTvS0IANzR9nj6EzaBxhtLnRLLaKe4fCJjwyZIfJKl4f6rhNFvpofBfnj';
- b +=
- 'mLkSFoDpghMbsdZNYoveTyKvxndV9MsKm5wMzed5eYbu3O6lUvvjdzvrVx/kybuvd3cPTrt3Di+';
- b +=
- 'Ke48Snbra+P+1sSts6U7Pzq415q5sYBbuc9o7d7XyK3/Q8BU30H6B1KjScDHIZ0PKQPSeEjTIRV';
- b +=
- 'CqoC0AtIaSJshvQRpL6TPIf0Kqc3kZp5xkPIhLYK0HNJqSLdDegDSq5A+h/QTpH8gNQZ51QoSBy';
- b +=
- 'kD0lhIFqR5kJZCugXSvZAemeJg+EhfNnVTCzcf6Y9m7jslu+8X+UyJGoNIXORIfye6ZRu5KdK/K';
- b +=
- 'e79iW6ZFPeZZ0XdG+nDOPd70+nQB5C6Q9IgDYc0EVI+pHmQlkG6BtLtkO6H9CikFyG9DukDSF9B';
- b +=
- 'OgQpfkYzT0tIvSApkAZByoI0AdJ0SPmQFkFaDmkNpPshPQzpBUhvQPoY0v8g+aCuv+EzDmixGaR';
- b +=
- 'WkB6PwuxPQHqSxHCP4t+16am1xQBINxyfsVTD4d2tWacfUKor86mIKEUAH+tzWPE8XcNH5cS2gK';
- b +=
- 'IC7dhsOPLKYD3V5HylPgN6XT+rYJ6fKqSO/HzXcM5wiMSDPVGtAfZUBFAyYwAJ6Vx5/2j3ftadT';
- b +=
- 'zuJbAcFNRUqGtjY66lYCpKqD894Xv6xkWe1DF3yUuC3y86l77H44OZl0wYV9/nZF2UX6nzRC9b/';
- b +=
- 'tJL/rbn340N0LbHtibajjBv6Jt28z3tUa9W034Gyc3/6Y887iZ/6tn380Jtb2y0S7/F26/z9WDY';
- b +=
- 'GG9TFfW+advk7z5fe8dGHl/dr1WL7+M8LgyUj9zT98Ib3SmY/0u0he/uWrkqrTlPfGZzeJOe4+W';
- b +=
- 'Iod1ebg//g33pszf1rx6cVn/6v5NDug5/6/8qOq72P7aIywcLUf4bwz3n9LJAEAepDo1nOnoaX3';
- b +=
- 'P6L5P9150gkT/Q3pdbxAPXPUS/JkIwZNNmfnTXcn5k1PCsnO6r8fHfenVje6gu4vayvmY/NQmz5';
- b +=
- 'Q2GjB1wqKAmHehJXnJCzaS5Sz7xY6wGtDuoJFlWvprKe8pPUQwqlZqRykXvnnuyZpKHk5qh3nVN';
- b +=
- 'PG6PrDrv3RvKzGceXqLIuyE+Kyl/qjkMkj5nq4zTKjYcayTdhqtffuEY+pUa+UY18spvfN7T9AO';
- b +=
- '+e9t+8dHjXMUKzr2+/ZUebY8FNnx5+l+bHfbr1+SMPzz3+5+FPaT7l/cJBB1dNfL75kQM0n35k0';
- b +=
- 'bVbOu+9uveRn2j+0lty+R55F74z7Mghmn/8tXu2rNw8+zZ05AjNv7H853PnnrP2hwVHfHSvc3F2';
- b +=
- '+cBVWbseuPFICs1P2v3E9Hkt0pc8fKQlzasTD49RVjd7+Y0jHWl+3E0jtMAPN177zZGuNL8jbcl';
- b +=
- '5bywr+8BztDfNH1rzwpo391y2rsNRiea/3tyrzU3J0kH5aDrNX/OI3OvwLO2R8Uczab7/Bdvf3v';
- b +=
- 'fuzqWFR0fT/DNvvtO+e+Znry47mkPzN7523rO77yi8ft3RPJpferexsGvR5k+eOWrR/J8f+xtPt';
- b +=
- 'jfd+d7RIprv9usrn1//9/7fDx4to/mnKo5vvG/L448nH7uY5pePvLgozm9cft6xpTSfzb0kzTy+';
- b +=
- '9bULjq2g+dxuz6xasWzsjVOPrab55y7pGew69599ZcfW0vzKp75+6o7n9t2z8thdNL96YdkVe/z';
- b +=
- '3/33/sc00v+fW+1ZeH8x8etuxx2i+sFXTF/7+JfGqfce20vwTPI9zz3vozX+ObaP5zYsW7N2+/4';
- b +=
- 'KbWx7fRfPx/c/vta1Z3oG+x9+l+XeuCxXc3LXrxqzjn9J8k9c9l/72+OVHzeMHaP7H9s2vsxK/3';
- b +=
- 'nrJ8Z9oftcV4wNJu7auuPn4IZrvjdvtn9zmybcePX4kam/7wLW7j1cx5WZ3v/vdd8dT3Jyx+dUf';
- b +=
- 'y7d43RMaliat/rtcv2Dx2W5ki0dbJby2YPeaFzU6mzyeYN4PC3YLl6zMdj2E8iu+33SX9vZ7xW4';
- b +=
- 'k1qHn3NKmW/dxd1xBvcA9nu6Ht73LbzD/t4FGTQQ9d8vOFRr+/KHnqKTxeD7Bm9pfk7jj0g/pjh';
- b +=
- '6P55ZOswf/02n6tt/cVabJ33a4p3fBmOsaMxbN/3B1sL31M/Nxd6aI5kfOPXjLzXcWbxjMlNH8s';
- b +=
- 'sKFjy0oT/otj7mY5ue2/Wze+gM5j81lHM/Wl1+9ddp1l0277DpmBc0PmH7jzlez5Z2bmdXO+65b';
- b +=
- '82/eY71u2MGspfmv/Otufu6OYZ9/ydxF8+et0D+RXr717iOMs0U+746b7iy9ZfufrdnHaH7389/';
- b +=
- 'nZL/w6ZM8u5Xm9w8657c2vx+5YjS7jebvLs9759bdqbtsdhfN78vusuD3qa1vWsy+S/NpXOc1nz';
- b +=
- '6+bv+t7Kc0f+OjX+Vlv/XRfU+wTgiA9Mx77/ro4lsP72V/csYy8657R4+e8+yP7CGab7924BMHr';
- b +=
- '9m0PN57hOZ7L510T7ODnfemen10iaYnv+r7r+9qdmt/bwrN35aydv3hW5t9m+tt6fx+qL/xUWqP';
- b +=
- 'zUFvR5pftufe+TNGZVYs93al+T6fbfYOPNDlhbu9vWl+5fHMGf3WzrrmRa9E84OeWrH2tjbiux9';
- b +=
- '702n+/g5fPXbdJ+1u/8ObSfMfzd33TMkLN/7Y1Dea8dSFZU6Qs7NKC0Jh54yAQicO/UIXM0XyhL';
- b +=
- '82ryeeVeTexq7eH8kPZOrCSK6cOT8izNJTe/Cp6empCt8zqvyDruyJ5B+okd9SI7+5Rn5TjfzGG';
- b +=
- 'vn7K2NSxWxnPvFVuhB8AQKcGkl79GRcPYHMqu+8QEfd4XmXMZ6Bg5t6Km68yeP58o84z+u39I+0';
- b +=
- 'QWSd/o3kFbZ6HxbVyH/O1CO7o7oyUuYzpvp7f1oj/xXr4NlI/iDkR0bld7n5k9KUY/fvy/U9sWV';
- b +=
- 'BVFoWqsJg0qFiZ8/283XiEOjTadx0wCFGXncuj8Sqj5R5zi0TyW91833OH4vGFpTYXD0AsBiV07';
- b +=
- '2WkfKLWAef9IxeECGxnEucNZGTrHH0JX3jDTj2ysHUNjomXDbUMUwS3E/5zrSq7z0Cjj018unYt';
- b +=
- 'Bwf2zQgmhei9JYXIzErIy7N1Ns7lEbNaPAGZIsxvJmz2cS5Ea4A3QUcm+XSgLMH7qUo/YzE1B0w';
- b +=
- 'oMsAUKcAhYaqempmEbbLUlNLC2bll810+y05NZVcTUtNdq6npXpeCTjrcO/AJ9Frfwg463bVC5I';
- b +=
- 'SblH4LVImJeh8dgw6ZSJlyU2R/hkRdPrypSh73SuQtrnxgVPJ34LU3vBfcu/khakLe/SAz+rvuB';
- b +=
- '3S9FoHDYgVBu22oBtH19XNufL/v5xWAZivxnjvcPVMEiv5uxLnvSPrcdxp/kXq+zDOsbna5CjIs';
- b +=
- 'lKyvFr5rA5JTtzASL5lkoP9e/SsY2dSMS423WBxGaUOHW9x9b5IfpUbG456+KeGyoC1uORfzfef';
- b +=
- '7uymlUZtrKoodebEdfB5TmUdZOnEqWFbqUOjkd+d8s5v9EkhMlPprINCNOM5APcS+8+/pe7arbN';
- b +=
- 'S5BR1nwucp3IPP517JL5zGQmaQq2D1W5tG3Js7X3gk5yvsLekuu98uMzuo6VGVqOjjfXEnu60NR';
- b +=
- 'hy9utfFXLetyqkg1ucLtBX1hFVEmRoyInvUN/eli9CzjrCYDf+c3S+R1RejnfwRCRv1shbbn5a3';
- b +=
- '759p9N2uaNZ4C540v0LlXta+6cSAxBZGQ0RDJLaw3n5nqQjZhJfgtwyZ+1qZpmzp/WyMsfWd02Z';
- b +=
- 'szdhdZnTnwaeVVBClp/J8PcgX3qmzs3HznAQWxNU9mKZs+6+u8xZ23+7zKGPSB2kIdW4M21FVRt';
- b +=
- '8YYc2IvfX2qfuerkUduaI190jcMK97i6WfsHItnE3blfYiaHQ3o1tHMlHzmvyxDOMl/GxcQkJbG';
- b +=
- 'JiEpsc14ht4mvGNGdbxJ3VvCXTim3DtmvcMa5TYmemK3ORr5B90Pswu5Xdw77FvpvyXtL77Afsx';
- b +=
- '8wXcV+y3/q+Y39O/cX3N/uv9zCT0r1/xthxK2+//Y4Fy6+/ccMjz1z2cHxCkjIgY+Lve9/ytWyr';
- b +=
- 'qBMnLdr4wIPPyV+0uPzKa273NW7SvEVPXkobOixr5NhxFs574skOHRMSkxu1bKPoaffd/+FHSeq';
- b +=
- '1q+5LSO6fYResvK55wP/CzwenGoeOHM/OueXWvv2698i9bd36O++6974tz2zdFt8opVWntAuGXn';
- b +=
- 'jPvbveXJfQrv0552Vc8O1PB4+/ut2Xeu553XqIWtqIkaPHZ+dOnDw1b8ZME9uFofKFi666a+ODD';
- b +=
- '72494EHSwLPXz/jnAVxXl8fr+1l+vWtWNLJyzft6OuadHbc+XGZvia9KjbGd/V19fVIlBqNHbJY';
- b +=
- 'TWqdnNi2/1DdayYmca3jung7xDEDNd+ouH6+5ISkhIGp3X0pSYo3La59gi8lYXyWKjYWE/omJi/';
- b +=
- 'uNmHU+Ym9Wrfv1rFlm6Sx8IDMxu0SkuNHJHZPCjcanNErvn9ccvyF8UxcM29cxXLj7BGJyRX3zD';
- b +=
- 'hnaKPk+MZnpcUnK719bSqeTreyU0YkJQ8b2mFEYnbjrITkij+HJXfyDs9SvU0Sk+P1hOTFSruE/';
- b +=
- 't6OE5mmQuNLb7XDjSq2XTXabLyUa9Z65cYlw9c/vURP6OXLi++WPCy5R9xZSx6ahkf59ITmAwlJ';
- b +=
- 'rPk7cen7vZI2fLtYbMp0im/iS1y84kpfYVxjb1JCs+tmDk8qS6/4MzmUGGw1bH7LlJYpk5LaVVy';
- b +=
- '+eLh32eCmrZaO7xwfX/He+XEZXZhgH297H7t4YOfmaXHM4r29lnxT8VfP0b5kH3tp88zRAypeTo';
- b +=
- '9nfLlxHSR2cZPePitlYnLFA1qnxr19SQlsk/iKWy790Nfc29g71+ePT/ExTVN8Grxcj8Rzxi7OS';
- b +=
- 'ekEbVESm8CtSQkVb5yXvDTew3jj4uLj2YT4xISk5skdG7VLad+4WZOUpr5m3hYtzkpqzbTxtWXa';
- b +=
- 'edsndGA6sp1bp3rP9/Zp1JfhvDwrMPey97MbfZsS/2UPxx1lj3mPJ20pn7f86g3cpMnLV1zb8bM';
- b +=
- 'mTUeNPnykb78L8qb79y+9+ppV193/8DPPvrr9tdc/P/D1cY+PErSa1n9A1sjpS6+BHx975tntr+';
- b +=
- '/ec+BrTyW59yf0PsPCS1fdettru/c0bt4TLmVNmpY3w2/hq1fdD0VefW3fga9/adx8aJaFK5Y+s';
- b +=
- 'vX5F9774JdfL122/K57nn/h1R17Pv5kxE3Pvbl9956sseMmTZnhv/KalQ8/8eQLL23f8UHz1m2m';
- b +=
- '5f3517HjFcWzP9/XpHNJoGMn/8JLHnhw0bNbW7c5u/Ow4WPHEfq/ZNHjr7773qe//PpHaWhlWfj';
- b +=
- 'Gbn373fvgky/s2PPBvlsGrrmJW9n57Xd3Hx87buq0hMSmzbr3+/lgSUAdcMHgodeuyp4V3vna3r';
- b +=
- 'c+/OjbY8c9qf5zluzzLclM7OCLb754c5OKTXGdkxZ38LZLZHz9fJIvwcskxCc0Tx7ftEVCboLX1';
- b +=
- 'zE5yZvoTfCyXq83xRfnbRTPNGkVNzahQ8KkBDa+Tcp43xBvH2BPzeObpqT5Op3nTy32XXRexc64';
- b +=
- 'JQ9528cvOeqdktA6qW0SIbiL4pPj28dPSTg/blhybx/Qhpdv1NvXPr6Rt2Iz/NSPH+OtuCsx3dv';
- b +=
- 'Um56gJZ4ft+R487aJ/Zr38XZp2qVpxQrfkjXtGrW6YnVcv7j+QGltkyqeP6cspeL99ilxFcfjKv';
- b +=
- 'al/HabV01anNey4qnEijfiktv29ybHa4nDElPiyxqd7Z3qm5JUcWnbjsmtk0b7Kq6K33RXShsfv';
- b +=
- '963+ONuCSlxcRX3NFv8RwKT2isefr3aV/G8t4O3aeM6ebj76SfeK8DGuy5oRmXmeNePIZLPc9eW';
- b +=
- 'avogn1Cvs4WPCoSLFziyX3LXkvLCCyqvGe7ZcrXqcUbBLAchg061wImHs9n1XD1RpSoJOL4gtWi';
- b +=
- 'hNHI/aKFSLZqY442SkcrllM4bBqgjqySiLlXDra9Hxf+Ivv5GJEYPCepCv1BM5A8H/WUBuvTjxN';
- b +=
- 'GJLkOtQaCHX+pL9ayKm+mZftY6T4s2qZ1TUmd2Pth73fm9uNTegXu+6M3eN7PP2Ydn9vUcS1VuP';
- b +=
- 'z5TOcp8qTDJXdSujb9UNzVBer+263WuIxrx+9nrRw+U0PhfLlp/4bhAlwm3bV0/wbMHZeO31md7';
- b +=
- 'Pu6S4/niy9wH9qNJPx3oMmXvd+unpHp+nvILs2iqJ+hJ8PRhGIaFf8yIRlyrZgyGOcCyjO9c5uw';
- b +=
- 'O0xqlJSUxbX1MEojruPO96Ym92jKpKhTwJQKtJySznZg0UtyXCLcks+0ZltVBrvtYmFvM2ayXaU';
- b +=
- 'TycXAD05JtDVI/jTwL7k7wJrNnM/2hbAqU7AHVQ63eOJh1CWwjWitpEjyUJfmOrM5WPaUTM4LxM';
- b +=
- 'VA5k8hcyLAJKYkGwyY1SshiO1DPZrUJA0+Ma8R0TWJsHxMPjWLbsT5vM19j+BrPNGWg772d2LPh';
- b +=
- '30CWSUhk2EZJDMx4Jsyew8zx+tgkJt77CXQCtDaB1MgmxiezDNeZ93GQj2N6JKWwqfCSjFdjaEO';
- b +=
- '8aYkse5OXacwkkAd62e0DPcwrXTzeq5mZqZ74AtbjY5JT2fGsh+Aeph0bx6xh27dozHRLbNeor5';
- b +=
- 'djSJd1Z4ZAz7NsCrxXP0aEWlk2Dt67F5vI/Ey6jQHCb9aMqKPMfuaGOIBlbJyvh9fH3A31e9jx3';
- b +=
- 'mGNeN8CRmnaE94z2ctDnQnMAG/XOCYxg0lhpSQQeIzfS7oSOoW5jfEmtqI9yzCtmSYJ3rhXEsnL';
- b +=
- 'tCG9Gk8GigzCj9C2ePjswOYmkisXMbQ4g70wqHGeJIb9A8YEKIK5Fp7nY1KTe8TTkYpnvX2hwz0';
- b +=
- 'J0CHMhNbQFKhlfryX1Aq9OII8ivHA6EpxceQbE9/UA2zQw1zguxCue/qybTzQB764xEQ24Wzfaq';
- b +=
- '9H9QmJTBOmdRzTFGptTmuMs5h1UGaAD3ogoTjBM7PiF4/nisXLKjw+4jfBHK2Ar68mehTiG+U3A';
- b +=
- 'MfPwiVpaX7/XPe733HO9c/CZWlp+ZIBwlNEModUAyEJMf3rLOfsRfeTGBH+UmxDYUO1DNDDLUtV';
- b +=
- 'DJ1XFXbQRSF/aF4oLW0Q8TtOS6PPIFXQx/kF1caihUzelCxOECSoAtmgumvYxlg1TVMQvMNrVOG';
- b +=
- 'oZJFanJwfS7pmG6Yg2brJWxJpiwC6u2iZHLZ1rGgy58sm4VMCRdjv8CRq5vETpyc35GZaWgmeG6';
- b +=
- 'mXbN5HhoVUBWuaaCANyaRSTtJFzjRk+BRkTjHjJtVbaYgGfXCrpRm/ImuCqtuYmCJ401ZIt5sKw';
- b +=
- 'qYuypzAIRnr8ePrrtiJqOTW6PxsazKvKCqyVd4wbZPUKHOabGimyemKLsmalsDXOZBl+SA0oIim';
- b +=
- 'iooGjxcEVYPmcIm9ycl/8Arwvwx1En2V+LzSTL7M2wbQiKYrJrZ020gaQSQX9GK4OC3NtT+S13e';
- b +=
- 'M2mlpzuox/EQ9B/yhfOI4FSI0pyIFGQqxpliqaYli8tAG1YTLkUmqMW3BsnRRR1iQkcEpjcYX0p';
- b +=
- 'ZWhViGSmiM5bQ0EmQ5LW0S/J/tXikOF0GbCmx6ICbxBoIaRck2DYO3FBgxJBs4Jc0qKqb+CmlR3';
- b +=
- 'zLdb+mDMqAa92I+MkUABbJtIhELIo8a56d3Kwa1tGqXDNQBD8msOlSqNH1CBomhSG858dcMcqky';
- b +=
- '63f80eFJugiUY6uqKhpYszWtyX/2JI4zEa8Kkq5wPCfxWlOt7h6O6ldCWjonw/gqsmwLhqIozUY';
- b +=
- '2ZGxKsRU2sZ+4mEBdigrTGgZF4i2Ns3Wj+aiTkwtdTjmB7vyBIHklQdYtQcW8wZk8TEijxSh6Sp';
- b +=
- 'qfTBZK8c65kGlp1Q8/r/zJHxW5N18RZcPmDSzokm6oKjqrrsqCsVQG01ZUOVETEVIkVW2pOq8JL';
- b +=
- 'wYVODYf6Oay0myMSk2AcC4Dy5cxB/xX5XkZBklQpFYZwRP6mh4N6H64/WpjvzNWCmcAIxU4W+J1';
- b +=
- 'TUBm66HpFqnd5TuUr40C1kEIyGmSXQxd6UauyXCz+YogqpA00+BhBkiozaQ6OiNyhG9a2ghrFJ6';
- b +=
- 'XSY+cLk0fkuFwnHAZ9lcdJAa32wi4L2+LHLAowZL1tlw0pbutLEaFLu8kD1A1UzU5WZFASGjIaj';
- b +=
- 'eu8OQ9QsP1p6WdEME/Qs6SxmHLFnhF1EVNs+X244N1krPz6XbybN5PeEsIutrlNja8LGE1qqHLJ';
- b +=
- 'gycbum6js0OVzLpVed9wYCTTTf+6PqHzg5TU+WgrNAY4k6Sk1+KMRmTkxcLYURQfxoNhTyo8gfo';
- b +=
- 'buhvZFmUjE3e0GxdsFXMcYrQsX/907yAHqpNuJFmWRKPEKeJOm8YVifDHdzIWfdpaemkL1Ldy87';
- b +=
- 'RqeTA77SJka9ABU573DLOwTEge8gRGoSbKBYnIU1VbI0XNF04m4+aGtRyG5GLoOL4abM0kNcaiB';
- b +=
- 'cbqNEAmdiZr0GNJ9KZxWOeV2QkGZxgqjKXqtXL/W0YAijJW6bEi8CSJQFwjSJ3GdEQDkXlmcueR';
- b +=
- 'EUBRGNjk7M4ldfRORNOmXJDQC+UsWjAVxBvyACUVEmx7HO1qNY5Cmda2uCCWaJQLnGOYAwG5gqE';
- b +=
- 'WQLvVjlgDIpm2TD3uo6uY0pHTtGthbO5RwaSdti2BdXYHAA2QTGM865jTnw5Ot9cgnGDhEeqDgS';
- b +=
- 'hltFQOSodQp/iRlkOlKaeWE+wNEDQKp1s4yu/00kA41ZEjfEGmdlYkjlojqkYoopVuduK/xvz0A';
- b +=
- 'oAIdKxEmVTkjiFExEnypLafWiDXi0yo0VsGLLEAZrhNYCHao/cmp1ZdTiN+92lqqoDqIHUAyR8a';
- b +=
- '/poaGB5MalWsySOJ3hbFUBtEPSevaPkwbDIrhAirSyKcS1kYJFTRM0QOUvpJUbNWrqJgry4n36j';
- b +=
- 'sbQIkQgmj2xJ1RVLVERJ5M7n0+H+mqIHG+FZlYJH4izBMCWVMwlSx3bvoelROKfKVbwe+aWaOoh';
- b +=
- 'xC0AGVkUJKX0a+/2lFrAT7OysGFgPvgKeOKuEnJTtRJ8CrmAj0xR50HMExNsW6sdH10B2AZCeKg';
- b +=
- '0B86KWIwK4QPGQFBXmCbZtZKnc6U04CXCbDizNNmWZAxY1uBqJ1k1GVBa7QE4BmKmC5iKINsBBT';
- b +=
- 'bjj5JPW6WA6VekdaWljwkXp9cmTjFOaxU4LdbJMC9IBI9OyJdDeBsemTbh8jucI1WkA/QFb2Jwq';
- b +=
- 'GRo2pcFRhEL9jt0Pf1nAD/UVgAzwkwBfgZJKdUSykGCbHCgiqoSQJstp9bJZx0xHIJxtCZJly4Y';
- b +=
- 'B7FZEguJqRGRWwK3OGdeVXQwX4e0dooHWwFyARlDpYWMLMAqHJEC4oGmrcp3z00+3/pYi2oNYVU';
- b +=
- '3AbbKlQnnR1obVCSCj5UxaGnRGZWhrgiM0yRZtCckqBuRvCTCJC2ZRlW9YQTndZgJCl1RV4ugZN';
- b +=
- 'rlKeo43NXhvSTR0C7rPThsae+9HqZU20jhgTJyqyQISbbH/I0z6qbA9yuuG0gtjQrMmF1vpI+DO';
- b +=
- 'HKpAnUp9lVVlVF1346kD19Ggp0RZk0xONHXFSB8bK7IUXWRZAvAFByO40tB1ReFs6EoDODWSBwx';
- b +=
- 'wwDyJ956Wg2bVwwQtzJkKKDMSpyJQRKSMc6Nupjs7CZmJGm/xgiyLmNNtTb5gYLBevBjKL41StH';
- b +=
- 'VRtG0bQLWMQKQIeODAwgbWICAgNdAMRBVUDpuTBg2JTWmpJjmQySFdwbKpcSDYTH5wRu3zhb64P';
- b +=
- '7Lt0fJTVyoojwEeIV4UBdWAhnDGkPS659uJpZFmg85mKCbMGlnUuczpTqBbvxPoNi0tHJHo/uKA';
- b +=
- 'VTn7a7uHnBOU7ncRvXM3kCWozQIP/EQEZGvyQzMKY5vVodkUQQNqtACOYA2IwQSuMOzMNo+zgNA';
- b +=
- 'sGD1D5yWgpuHZ0Z1nhAuKLCrpxiNrkIWCZLdp9aGkW9YyIoNDQQVwMkVRVUUDBiSCbm6OGBCMxW';
- b +=
- 'BRVhAsIhqAhgUFqbLAgfiVdMRnWfVKrtqYApV+WVRByohoStGkK5syBsms8EB2Ii+PtNKDZ/4pH';
- b +=
- 'ExMxeZkZMgYsCAaNahebcYCZhAAOEJPdKW2YSBNoE/BNJEhCeLoofVCoCDGhX7XS4aeIk6qQRxG';
- b +=
- 'qmTpSNUFU0JjRjQQ01aiYxFZhsTzgGRUkeNtcezAGEm6SlsFRKYgDMyLGEllPG7mKetXVEelji/';
- b +=
- '+cIm7n4SOrg21I1lQLcWSVXP8BdGdFiLsIKL3UQFuEdL1k1ioUDVFwIJqShjmBlIUpNjyhYKrOe';
- b +=
- 'ej+cVEFDoadEQ9pg/lDLI4qasW8EIYLWWCQGOH+wMFFnk3k5rTyf9lpfP8JQ5YEAAg6Ipkgo4s6';
- b +=
- 'JwhZY8GpA23FwQIWrLIRzbd7j2abHomxsPIr9VnHtAPEb4q1gC3qqAscirHazmT02sSyxgUHES3';
- b +=
- 'YJ5ojKz8KYMYtcrLiEbuD2H6boatKwjgPWjDMGY2yj1jNQMtcJwM/2EkWMA2JkpuT2dHsDQFwnS';
- b +=
- 'gnflImb4EfBthW1ZUrKuGNSlYTWF0TpWE/q46MhJqqW0CBx3qzsQRO3vkZmqOjVwko6srtmrrMq';
- b +=
- 'dYvGTwyuTBNQeKuiMRdORE2fAX2ADMglQbINudyfhYoq5ZBsEapiFw/JRB9c9lqpu4IWKoTVeUs';
- b +=
- 'C6B0AJ1wsDC1MExVgGgJ1BC5yEAbVPUFN7mdVPXTFOdlnPK84+8LZl9ZEg0xRYEhTfgDZHA83l5';
- b +=
- 'J5BINp5dF4lU/hQhEew8J0ImADR0kSMgVbCJeXP6lUwtYqGWca9t0MnpavA6QFJDnUOUnEF36sv';
- b +=
- 'GJpEEhXxGhOzck5b8Lq3kIwkBZhIFAUuYFxV9Rr4rNQso0ECOpAwRe2iQEn96Vu9hGVWS07mN7u';
- b +=
- 'AMOTlURvBSlvuNPDdQRKedBoq7bOmWYGuKomkAvE8PS+PSKijtdDQ1rPIyrwsqBvVLB2kzc2qtA';
- b +=
- 'CJawTw5wCBqlbOgkG/JAg8z1NSwYhMLN9JABass6J4dDn1Wefo2jE7YIHYv0B+AxnWVKDS2YKuG';
- b +=
- '6IpLRyOh7LuSjReUlNDpoQPsAI5KFG4VYcU0uVp092oWf0tSAKWAjMCA0ixTsGpHWCV4VgMQVuX';
- b +=
- 'd+cRQg3hZsURb4Qwd45HBhkjLalLNFkQFaE4wDcPSgDLsyado4QSAQc7JmecvJb6ahM4ESzMFJA';
- b +=
- 'OYB3GHrVlabTU7mrKr/7lgD3OWJYuqaBqarikGzj+js97iNR4JgDRg/JHB4YL0+tcCMWRgfCmfg';
- b +=
- '8GXZJBXHAA9xF10RtvGC6pqAZEJimYiXtILs9NPNC1ll5WSUBGVVVf7kfxSyZ+d7jSwBuwDASoC';
- b +=
- '+abwStEZbbKgQG+IhmQSdCOYdrHgDLPrhOWKMERxHiU7Yk/ApoJ1oA3RBqkncyVDqxBKtJ5Xj06';
- b +=
- 'rCSoQLOh3Ig86J88Hhtd4dLQjGCFdFMyHthObCiYkWhQIFIaDRFdXVeBWmkmkoAVwK5hWq8ZCdc';
- b +=
- 'xsdw3VnWD5wEcFTRQ4Q+EAICry7Ixgw7QxEP2AnU1NR6YCOLi0X01VKILHHJtRviiYAAc5xAkCs';
- b +=
- 'DPbDml12O1CZAe/6Z9fEPRToZEv64JmaRI2TEvFhi2VZaV3qx0ZngQVOl0v26DYQj0IZL4IYCvs';
- b +=
- 'tpqu2dAJY+ZTA1dxKf2Sr3O6pOigkJsiKC4SnlN+iuCqDjk7pE7JCqTJSZLMC1iQNc2W5rrLr5U';
- b +=
- 'hb+Dp1JXO7/jRVfJ9w+aQbOgySAlg6IZU3t9Zjp90Un3VHSUQUKKhWAhrGMSMzc0bFNPaLcipyu';
- b +=
- 'cjTcQGJlBU0xDS+Pk8gY7QxFI/ocmygpIQ7WGnu4NEz0Ugc2XeNCzL1jUk8gv6uuzMcQ2ivIN+B';
- b +=
- 'sN0/c0WeYUDSUq0BVsz0MUT0qM6x/2ABtkBoq/D9yz4Ws+stDVVtixe0QTDRrIsLVx8GqiqDihd';
- b +=
- 'C6qqBqyBxkzBkGTMmaKkauYlsYJi1whJl0SQAGyek1RFFDTNWGTVKp8jB/TEKMQd3RI4szNP8g0';
- b +=
- 'FwVQEDm1KMA6GVMEMj+paKiqjze9Vpi5qVw8rUpWBT+YVyZBULNiSxnHCYqZfzZqgIpr1QzmiJS';
- b +=
- 'EO+JYi2IIiwxy2lzA9DXq8EGFvzkF/lbQoaIJsCIYmWqBPwTy6lKkd0hD6jR3SVN4NGpuEVU3gR';
- b +=
- 'IVs4VKFpWe4flsxZVMVLAUwmS5Y0rKG9bMoVPazAGxMRSDybFHVZR1dxgxrSE1a1IARnwxVFFXE';
- b +=
- 'AxwxLmdGp9fi/0AF4RBytsrJpx2nGjynIKxzmCwH4yuYC2M0OJODtUnAT38JUS9LMBH2iCzv5/M';
- b +=
- 'mwB3gIzpAB7KAdSUzrF6sFC4hIfj8NLJfpcGJOGtIALYEXbRhTkpXMZfWxhRiUhCpbKJngaelDQ';
- b +=
- 'mUWPTcUHJ6bTYgE5MiDepwUvkLIBXyA1UneQNJQNqypCJVEZYzw+rlC9H+U84RM1TpxqZt2LIAC';
- b +=
- 'qoqycqKGDoG2DURMtU7xuQt2cISAnWMFwE/Xc0I6XRH1sms26LAi5qhgFIs6KCWaNcwfN1Ohu7/';
- b +=
- 'Om/ImiGJCKYBLxvaSqaBouFaZnJ6ZNWHtMyPggVE5qFgkHTJELg0ycmkOysqkZtzg+RAZUIZ9Av';
- b +=
- '1LhUM0wC1UCFuCLK9irmxlrXHaC20dr+BuvRUAg7GFRbXsfRYY4HS5cmBwmJSCdmjaoqGySNVBu';
- b +=
- 'XjOqY+NIYxjzQVy7Ih2pyO+OuZ/0xxl2GCI9XSRI7XAMiYq/+7EbmBGRzroniVGcm0OB2mhMwJI';
- b +=
- 'uB6Qb+R0euG0VmOYCHhFQmnEYB7GYAWRFWTeV411jBZ6UFc7C+1TXIeaIPUAstGmmELgmWJmoVl';
- b +=
- '+6aTtSOHBAmuQvOyroiaaGIOtGtb4oybmZHptc6TWDCgpIKqqIuCYshk7MRbzmRlt57JytYyUq1';
- b +=
- 'sp0bPgoi2iWVVNASYHli7jRlVL9srBeYLqMIfLiEGS+DFs4pdezgIKyzC+FiGKCpIs25nLoyyEE';
- b +=
- 'QLUarHRqYImd3wptGCmdpxHdMBwjxo0KppaIoJyO8OZlD9aoaz3g3o0VnvlzkTwKvOcUiUFSDod';
- b +=
- 'Uy/6u7ToYBNoAhos1aYLl/IooxBDcKEJ8uA/Ncz0sl1MkcfM3lQhzjb0FVVx5bAb2B611gRMOCN';
- b +=
- 'I1wtn6A0WQVNQAMixQp/JzMiVo5IvhMbSyRrY8KsNJvXRBtArnYXg8+8qzEZDkvEAlYkW1VFxFn';
- b +=
- 'K3f/Rc0Cq6zwQElkbM5DO3cNw6d1yTipEbVCUdMsyBIt4ESrcvUyGo1q6Kkc17TIbHpURvTJEwB';
- b +=
- 'EALYDDwO94ReeRfB8TsyLO8aANExXeUBRLNs37mRiWM6PM4ragKlixecAxugA0sZG5hnEqqF1QR';
- b +=
- 'tsfBpM6IufyuuuTYwtCZePhm+OtUw+odvRrh5QqWySLCqeIvG4KooAsVdrEDChsyBtpoADoOkgA';
- b +=
- 'VeMAUKHNzEoXEjT0jWqqhqf8SirMTk5FCkgCBEIRb2EG1MoGaM7vyFbH+OkvF+h0VUCrkxTC4DA';
- b +=
- 'I7QeYhtgPVFEG/iyZsqiDQq1KDzL965XIuITw19l0RYfsoRAAtplYBTDzENOnZmlKy5SnEvHLmQ';
- b +=
- 'hEsC3x8D/Ay4cbOhlsUDlERTEE0RAtjTMfYc6n9qMoI0sIl0UgqYFFS+SRYfAI9E5DerRemIVs4';
- b +=
- 'kQFjMRUyWYm67GITK/NzFgQ8kfl8jGHeGTrokL9HST0+JmUnE/AqJ7UD6ca05FFUyZrfrpJVoFN';
- b +=
- '+UlmRHo+Lq+EN0S2jcDlMaEcSZBlbGs6R2zFov0UM702WzGxM9RrLXaVfWhJlceiICIDY0MlKoM';
- b +=
- 'lYeFpALY1h5RGeYhoGzQacalrJxqP5hUFUJSTjmtQGhwoH4Nzg0TkEr9+I1BOOKluENs0SFyiHm';
- b +=
- 'LlGSYYGaA5ZI1gIjZdBBt9NRTEpuNPTkAz6K2hMmKQzobLdPMrXBxLr6Xn9M6qtL04cDtfBG1LR';
- b +=
- '5JMjl5AhsQ/+3/gkZjDoOaLCkwReFG8lcmoddlqcMGsXPolyg/BoE4SILRB4bNNXrZVGJPnmIEx';
- b +=
- 'WrUq9VbA5zxIfZMsu0swWZ8HCNHgvRzO5hSV+I9aMOk1zGNJk15gYt6d4rgyk0A9xLEXaMzmJdl';
- b +=
- '8kRmc7jCdBmB9A+uiKWiCoVoSQiJ+iRmVHuUhUfP49Po8hUHjBeXFsjEngc5rvMwUnXFljjhquA';
- b +=
- 'odb2NiqNSxjg0AYuYrzPxTdxiaQLdWpZ9U0mVEdmARUkDkXWWMZF4ybUXbVhsGqWPhgiyE8QB0A';
- b +=
- 'X2AgFSwzFn2q0xa/RKfbD8opKZtXbU4zeDhwaBzm9vhzQv/T7056Pe6qmGgPQWYqI12MMYp+yq4';
- b +=
- 'bm/honAINIhS9yAO6vCtcxonKCIge0kxrZ3MsDqteycVGbrKawIvGCCWdZ6XrNeYYXXAzAnIKij';
- b +=
- 'nFcdWHghR6xe8e2TCCgKRPaaoAl4hq26vM9IJHK/3IOrKSpbH/HOpkzcoKbyoyboh8gZoDKr1Rq';
- b +=
- 'XhyI04Tf1+C0C/mOVuPtVFC0SSBjBAl0Al2lVfARBeBkh1lQMy4jSM3ozB+GArkruXyPW5BJAFq';
- b +=
- 'p+OMc9Juizau+t7qoI4kVNVXrEAS4uStSc2nc0QgNsgS5AQz/GCwO+NHfUTaQMaHCcJSDQ13XiL';
- b +=
- 'MLxgYUGDGB7WJFkAKQCCW1dBnLzNqLV6lLuQNlxma37oAerca5mGRWKqabKMRPEdyior1Wu3DZW';
- b +=
- 'xH+pb5TE11eBMUzYlEyNOfZcZdzqTiNKNpSCyU03Dtq7ZwnuxDYjIaZosmMSVQwZhwL3PjEuPMi';
- b +=
- 'O4r1UjIsbJNUNN4YA3cJIGkBHG6QMmoyYpTUBzq+YLISg/Kg6UlpFzCah/hq6LkqbZoq0qiq5+2';
- b +=
- 'NAKVAHLxK8DCaDiWZr2UUMrMLDKC4pliYgHCWMYHze4AtsAFcLSgdYMVbHMTxpagSUQUyUwd8sk';
- b +=
- 'oyp82tAKbES4DSBtMk8NQ/2swRXYkgWg0tKANgjy/7yhFUiColIObsgaQsjYVx9LESwkYRUbwPk';
- b +=
- 'BFen4C2Zw7W7jztYOej6Zo3TyfqcmuuYCfNYSBEmzZaQh80tmeOyW0Gp0rEmWrYiYJ/uOMbb5/c';
- b +=
- 'yMGNfcaze9VLe8UDOGouokSATQiMAZ4lfMqAY6AIO8jrQiHzQzGXG8LXO6BlxFORDb/NckgquJP';
- b +=
- 'zMAQEmQvmaGpAcLzVDDbMacqCuKKSEdVEx4G+6b/8hQpVoCh1RNNrBkWQD8vmU2MHV539exyBlB';
- b +=
- 'l0McH65BlpXe7aTYJxYLSFTYfIeBAbDTNZgB0E5V/a42aw4ditHUhSbH0bQr19kEQVBlQ9Z1ixN';
- b +=
- '4YGDfN3TqmQA2ZE0QOVOUBawoPzS0AkGQQTmXSTwFXTYF/CMz9qQVkJPlKKK0An73u5/4OjpaLc';
- b +=
- 'Vzsko8vohHBi/o5k+MWlMbJsf7ucowwU4RYwdWZUUFslJ4k4QSlf93uk2BSWIi3cS8Cd2saPzPT';
- b +=
- 'FZDBHl1gwTHw4vJBhJ5WbY5/iAzMJbGkU0vfneh0NQ4zTJEW9SJBEbol4ZXoSkm0kDOqCTIiaJo';
- b +=
- 'vzJDTsY4nTAWDucUqzinCXq8pvEcoBtBkW35N2biKVtE3MUtZ9LKmBMNHpHgMaR643dGpGNPo9k';
- b +=
- '4mjM5ZgzUTfq/6TjOa8jQbVskBitR5SzjELORSY/WtkFvwEVQgz8y0WtnJHT61laOOLNjethTTc';
- b +=
- '7s91OUNbEAlACHAKKqdq9CmTnkm/uOwEV5DnEmwpIscpzxR70wH/O2yNsw+DZIekv9k8mvlceYx';
- b +=
- 'OkkejGHXhhXasXElorpOokkI2TymqHIIohY4S+mosZe7pPueK2aAGbA3S5CsGAMsjBiwqFe06Aq';
- b +=
- 'SrzEcaZOIvT8zSg1RcN4YmspHevaWmjn0lVbybCwhYAdarIl8P8wQ2JdWo1yr0e8KomiiDgJ2bK';
- b +=
- 'C8b+xzxChaoaopkA4EfwzecnmtcPM0GhrSezIApCtYOmWquuyImjakRj8KBxLFDl3MXrJWAGQZ6';
- b +=
- 'gyIjEMLCQcZU7m4xaiga0UUbUVE4CNishipHmMWezOq5PFoKCTIMpF211gG+/staE3F0BLa9knQ';
- b +=
- 'oig+s4c6mCGZEkwFUnWJVDErOPM7BO2pEbMF4TOChzidCwZ4yMXGgq3JBVwCjBKCySQZVSw//0z';
- b +=
- 'bVtRLAPbBidiBShvMTujLr+sGH2yqH8CCVNGi+RrJieIiCws8xaHbWkJq5xUejhnPlMHS0XhMSj';
- b +=
- 'SWAAuqyiXsvknNQGdhtsQmbpIhdaZMlAcLy397x4l6ZqOZcvmbc7EtqgtY3vW9NB11jZID/CWJU';
- b +=
- 'kG4gH5WpItX8bGzBOi9A0V2IGiCYoGjEVAtn45O+OUFfkS8kxCOdShnxxfQWYaaH8WMnVRJBPFw';
- b +=
- 'lewD/xXcpA0/AzIQg10OBP4GhY4DmENXcmm1QF/LdfWhv2RiZevk5UdXTRlZJjYFPWr2NwYta4T';
- b +=
- 'IyyMxbOcjR9ktDVQsSxVtkTVwJomLWdjdtGpcmpVeAODSm+JxN2MQ8IKdmRNSi4qIOFTRsP/NUR';
- b +=
- 'ALvEkGoHLq2zvmqZInC3KssRhbKlXs92rrYTBu5hllGULlkaszCB6LF1WJfmaWCc5jIOtA33aPL';
- b +=
- 'GZyfJK9uTrmBbSJQCBAARJgDLOvpYd1cCtbP7IoXnk6SDcDF2DGc+DNq8Zq9j6VlFlS4EhJ7Yoj';
- b +=
- 'AzlunruR4plCrYoqAJSYHjF69nY1ngdxVcwJckCDqjrxPBlqatZqfa1CrLiAAjJdFyjAcGASsfJ';
- b +=
- 'OsYwbpx6Q2zFZCwAk5UFE3Eyr3LajeyCWOYw3RabHdMUpvJ2ApCq5RBZtBhCCrZ1jkS+EBTR0IU';
- b +=
- '1LIrdpzxGUQcA2DZNMnkxsCpVv4n977bg2Yah8bpCToBHBtZvZv/z1UfTMmTECQoCtC4pqnwLm3';
- b +=
- 'XS9YioTqPXiMAC/ZZiYZDWlqWbOiLL/YIg3sqOaEj8mWijj6jyMLNk0B41iZMUbS2bFouThOtdJ';
- b +=
- 'NigFSgS4jRDsDntNnZkva7YowNzKRejpFgQ5dct60DZIrIxkBiZ9rezWfVWFmGJTmVVrt3ERRxU';
- b +=
- 'UVnWbEmWkHJHDHVVb5gWHcpCUUjwNqB9Q7Pxuhhesnq7ol7S5sgmZ8mUTMEULY5fz45rKBXUiAG';
- b +=
- 'gk8NSbN4wRHhZ25Y2sH2rNhEUO3FgXPcCSsT5FmcJGLi0JUqmBrzoTjYvpqW/WGcx8H5L0S1ORr';
- b +=
- 'Zhyvxd7JT06juZqm1kciNQuLOtHnqTDdkyNAyNVjlJFpS72c2nHYgmevPs6cWhoRZHu6CoqNIpx';
- b +=
- '9JMkJu2yVmqbSqafA90dfDMdbUmciYPsB3mCznVh7v3zI6kjG0sIR1pimXbqqjcx+aePjAlvaIY';
- b +=
- 'uoJ0TGSubQr4fvbUQ/EBNHMcqInXKchyCRRCxIOysJEdGIMzQzWlWjE4XcCcbJLTigxV3MQOOjH';
- b +=
- 'yTT1mbNPSFEUHUIYFgPQy2sxeEGs0AMvdx88Jkq7Kgk20K8vmtrBDYvL6WbDALAqEQIIvXEiX2A';
- b +=
- 'VTIEFiVUz2skoPsP1PpjC5omouCBAaKMNQdc0SkWzYEsBV7kFWP3lp+CVSFli3RewDoq2aIqCch';
- b +=
- '06j7MPs0tp2qdQ0fNdlX+rWsLBnVbYmUTURxroGbAwo30CPnIasNkBvJ4vOiKwmqoLyKLuw1v5w';
- b +=
- 'Hl3NTlftZaaFRaF/6uisMYOzp8e0ouC+CxbIghaxhBrYUjjjsf/DzxcAjZs2JjvJEYJp9ThbVJ/';
- b +=
- 'zH9XA6DFJJAwPfKRHXaeHWhF1BT7SwyHCuDIyKm/PJ17IOkh+DsumJZnmE6xwoo05Yt6LuNqpUA';
- b +=
- 'AUBlOyNRJdxnqSjdmVyjGiAHYBhc7UNcyTI9XEp9jY/M9FHcCAgDhLIlHHxafZoelRNrKYOZelY';
- b +=
- 'MM2yQ4OHt5A1p9hzTPqKugEtEeibgsCcYa1iVOt+SyrntR/pYysx7hr0dCzJo9EeEtb18ytRCuM';
- b +=
- 'xbvVgal+MwAMgkQlpVKVBAwGldCyAfIIvKA8dxqzU0WCJYmqLgkKRwxgzxOxUa9LSPVQZ4iIeRv';
- b +=
- 'zwGttpOEX2P4n1a3pj/Aq/gIazkBUBUmSiAKKLUPUXmxQaZlEwhAUgWwsBx1feqlBpU0EEhMT7w';
- b +=
- 'JQgyzNeJkdc0rmzIiDE3QivARUZlsSMmT5FXZAvXFBzOJg5V5cG9smaOOiYNscx5nKtga9DUwAj';
- b +=
- 'QRDNUyFbHXXXj3Nt+EFWVU54NmciHgZW9sbOK6cDihA5cnQIs3awXYvKAsgmFU0jlBVrJN8Xkey';
- b +=
- 'ppuaJhicIajKTnbQSRbNaJwParX0B2x/hOuppsXZBiInK/IGQug19immbiRYN5PvFls40VPo1zr';
- b +=
- 'C8DhnJeiqQLfhSAgJ+utseq22izGEZVYt50c2rikqlm1AOPAfT4yxb/x3VgPdItt+sCYKEmi+SN';
- b +=
- '3F9q20Mpc5h+um52REztclnErgRMswDFCGdM5Axpv1FSAbSmwVk+gBqqEjYTebGSN8nJsPLQ8FE';
- b +=
- 'Z1IlqlhTRB1XeB0XtOlPWysy0PuSSRmoIg6UYIKYMmKJiqKbeswC/bW2bnzC6D9UwuC6YN6Dz6h';
- b +=
- 'c0+8LQsokN5aOd1skZMMnjMIS7cQx7/F5pzi9HV2o7k8RdVsgxwgoOgk4ImB3j4z1crAGXTiuwv';
- b +=
- 'MSlKx8Q7bgW4jmEOtvKKETFMBUaxjYOoc9y5bmF6PwDuNJQtFRAAykWFpiMQXQe+x+knlMmh54V';
- b +=
- 'mo1A0QiwzBVjld5GyYQML7DSirGapNIlghTiLucvIHpyGHNQEkBxaxZMCriIb2ITvxdA4W8IcA8';
- b +=
- '1BfDZ3TREkSkS3oiFNl/SN2ZMMiUUTboxVJU2wOMJCCQGyb9sdsot9Po1yKn7CD6l0CrQZqyDS1';
- b +=
- 'NM00CQQ0iVep/Sk7LObNKNWdSGRgTSqIK13RNMuSPwPNNQYXrGp1YFPVDXLUgCQLumWizxsk7jR';
- b +=
- 'sCSDGFIEnG5ixsI+N3lA0qHRW2N10So4DmsOTNpskcDbwOYRA7HHKF7UaL+qwKM8qDZC4QcPJR2';
- b +=
- 'TjWUa1/WwAyIHr8JJi8iLosOjLBjdof4NLfNXgEgcaXOLrBpf4hnWDPgeJDY2eMUUUgSIQFXVO1';
- b +=
- 'wzqrixj6D1TkRA2kY2+PUP1fHeG6vme9denSFYX7SDUHI45lPIyut86o5K1EXEtazwRnLwgqSav';
- b +=
- '4x9OsaWcocoAYXmLN1QDoPmPbANDPfx0OvYG3gZ9mxdIXAodS9b/2MknM2nSmeSPBCagEyrTzUT';
- b +=
- '2LFeurCKBk0CMgrbBSRYI1Z/ZKTGurNY/X5FJTiUwJIw5DoHoPMjG7NavAtwROAskn4kFXRZ+Yd';
- b +=
- '1t7Mg55ywa7lqgogG/JsyPfqFwdlpO/1T/9IyoX/ORqvAq4jAmG2qBr/7KijU7vcoSHzlILZ/ER';
- b +=
- 'xZNC0sgyURN5X5jS+tzyYqS+fBiJWU50J1DZ8fkmlXmp1tNZSxoAM5AdvJEhsq/s+kxhEIpIEFN';
- b +=
- 'qQ1CkJAmcRjZMujnonyInZF+QlzdIWSRPQxzZpILnetC6NHLhpHDX0BcSqIpg+IvwRChP9gBJ3f';
- b +=
- 'cqrnAwWFDJxvvNdVGnGn8yY6pXE9wgrISNALf6EpBKdWw6OJBafqk6FC6BNTSnfgKbwKd8Zptgc';
- b +=
- 'Ktc3+xfR3aKAVsQwbfQeNuMDK6S4wjOE4XDUMTAUT+DSCYvgHhJS6NRTsak12cgVJyPhyd6A1xf';
- b +=
- 'DAkG0SwpsiaRLQG6x/iHlCH7SvLKs84eZQarIMoRqpAtrgjCf/LToxt9aFWkoyiOJ0TMBZMSeBF';
- b +=
- '1dIl4fD/CTIn25plyRBFQIoItJoj/50qoigaOdrINDTgArxgHIWOKzwTHSdIigA9pqigqZKI0sf';
- b +=
- '+u3cAaClhEyiJcEdF5o6zy047tm5OoL7IujCOJ8TVNQwEQlXhBB1wuIUqvP+Zfk4iytoGlkwBaY';
- b +=
- 'JlocXe/6x7kQh6JchXQeIMidOsJd5pMWl4sa28SdgWDBtUM83keVviLvX+Z6695GRPQu+mbcgIV';
- b +=
- 'Iil3h7RCqAT0LGI+H/mK6agASNBGoLGgYxb5g2eMUs+tT6daM3ndMDwvKUiQQVIZdmXef9zPw2F';
- b +=
- 'BxTG8bpAzgtTBO3y//6RqonJYpsO+BNksclf8d8/UiNBfzQMUNowFN7irvzvH2kTRCUY9LxXWTb';
- b +=
- '1q7xTHG2Xhg/JCYCmO4QcVdWgme8Gu7ZM3jIMFWQDb5BVkOXe2rf2Ozv6C8rmFhAF34l87Jx/wG';
- b +=
- 'vIMnXdliQkW7Kwwjv5lO0P5DzeKKMBoDIOc7JBYBBSVP1q74j02mwsNWYNUTeAS8D/GZFMvq0CJ';
- b +=
- 'sCaAXhK5lVeu8bLRZWwwyXu5udhJZWbIEiwSBq5XSHx7Tl9pVeujnYm0E9owVB65mqQRLAjDA4r';
- b +=
- 'gIEt27ANSYNxu9ZbVAV6XCtY7aDHsRU0EPiooHKJNvFmV2QMWtgqb4OMwCoxfNkaR08L1BTzOm/';
- b +=
- 'ZaUW3rSHphtQh2zRL4oH/A7a1ZEU29Ou9MS37yYi3SSQVsoRl8ba+2ntGAaVzKhvlxyS4saUoko';
- b +=
- 'Awp5C9WDd4T/e8uiJy5DGwLFm0yCkX5GwpVeZu9M6tQ9RimIhkuhK1KfI1Path8j1Ee8Hpc2xiR';
- b +=
- 'SeuDYrEy9g213iFujWzyIFxNgYZIoKSiARZBbF6k7f4jIOQ6EYiHtA70AXoDeSISPVmb0OMaWQz';
- b +=
- 'FsfZooiRjEzTuMU7u47WDsclQCVmdn4YqDSr94RTbzEAAE40FNki4XBt3bjVOyY9p27+70CCCOM';
- b +=
- 'n/C+jOliQQI2XdOA5lmoqlqSv9QrVAlQ7qGVaznS69zFcUkiNdpbIyWQhi5NFXUHKbd6R9fr517';
- b +=
- '1HhoT10E1QOzWdl237dm9WQyKTVD8IUZJtkQSst0RVki18h5c7cY2OBmeHeYoD5IBzlbNUXsAGO';
- b +=
- 'fvQUHW0zjuoWge4EMc5YxXYQ2mZs5pHrAlU96QHH8jYNGUZMInKW5q43qucEDrbWdE3iHYe8kfi';
- b +=
- 'uwOV67atcJYhc2Sj0QbvBXU/nNj1T3i0RM6iFHVQH+AVTMW+0zug7hqc0pTXRsob5OQ7WwZS4k0';
- b +=
- 'VKdxd3rF1j38gOM8fvbxC2lFcECpGZWZ+pEKYSBS0yJbCkaN47vZeVptCcxIHn7rchGLSiqI9Wk';
- b +=
- 'hQAgwwmBzbjnjrHu+Q+o6fdINBhMLAnlyHNVUkp70Q1C0LHFaEe72Tq8ECeGbAhU5Z8DWLOknGB';
- b +=
- 'hNUSdEJIhJBC1Jlg7vPO/00mb4Tp9Tv7r3CWBexDuhRJOqljO734pgMC1HNNoj/fXZ+6aAQ8XeJ';
- b +=
- 'IH/nKDpEr9HNBKYh2QjgoiDrqoY2ei9lGvogdyPHIMtyH9Wtvgoih6lVNgMZimlLukLUSlWWtE2';
- b +=
- 'n3ozssNGQZpDw2VW9YcCUBIQEgtfUDE7d7MUxWSUa2usivCOoBLapk62ourTFW2uo6Ab2emFDe9';
- b +=
- '3UNGwjLMuqirCFrAdOvRlRvV7Y0F63ec0SJcHSTdPWkGw+6L0gxpPRIqGWFNCvORNjwP8c2YTzk';
- b +=
- 'Dd2h0jMcVBQNYD0BMHE5sNepfblWWfDjhNhlAIQckCwanCapemKgbRHYi6oKzrHqdi0TYWcCvao';
- b +=
- '19lmH7EnOxZyP826wa7dbfZk/zoJtmQLyASQrD7mbU435DuOZ+GSuSAlHveembWfJ7zSSbSYSnc';
- b +=
- 'KQBPESoM4ntc12ZCf9OamxxRji9CRbRMJAjoE/cEZl1IcLKVTETgs5pEuc4QFqk95S87ESWXILD';
- b +=
- 'vhoDInIq5q2EjjTdCcRUFSDP5pr1V3P9bvbF+TFMIatbrkY6AZUcAWp1gCKCbGM976zyWkqIcsp';
- b +=
- 'RHoUxKmSidZiDFNRKhXt1XOfNbb4sRz4bfWBtxB6pOl+8o4ubKo6SqAaUHReVBkxee80omFrHAQ';
- b +=
- '6iQCKlIM5qoh/j/NfVd4ZMd1psbogN31rj5r3/ZhVw/rWckiqcpBgoYcjiSKEpM5tNaWloYqDuD';
- b +=
- 'BABACyVl5P1M5S1TOWVTOOeecc8455xz3nLrdjW6gw+0GxvaDRMwMbt1761ad8/+nzvkPrBWOp1';
- b +=
- 'VO5DfNqRq9AhFxea8BtKGCv7FC6TfP3WK8RmB/YnvIDgghMHNjOQdu+BbYO5PSHEut3lLKjDgpH';
- b +=
- 'YHvCx/YvXXOjtoOuF6vWewmgZW+A8kEhbLpljqvw9vwrpOL2HByjcoeBb+Avxoh9Nvnzh+2NHDd';
- b +=
- 'lkBNJx+hi/TL3y1lJTMAXWANADk00++Ym7axelVeGT0zwRvMZMwyEfnOuYfNgO8OuCmcyDIQwM+';
- b +=
- 'ocKNj5u8ahvtLZ84e7neo1qYoAZIKMEnTd8/VzZIlPEYaqAewwbRi6j21rzTJpOQpcgS40pL31r';
- b +=
- '6SEs0MdY57RhXP/H21r5QUfBnmt0kWjYnq/XPnYkkhRiniCYwR9EB2py6hRIKvWjuZ+OKp7cLkw';
- b +=
- 'ZpHaSkwKgkcIXxgrtsMbvP0aih9NTs3LwZuswqnBe1d5krkDO4J9ugH58LCCAlN/MqLwWGQqcIB';
- b +=
- 'A0WOYwkfBYzPsHl0NgwcmvvQ3PWHpqoi7r19R/hs4fBoU7BwbNjSPYb/OdIvsXy8Gx4vEpYVGcF';
- b +=
- '2rSlp68H3AjKMH567y0wSlt3fuHDzdssnlo4UDd8l+KnkSFtYyy5T6owUOX5kbmuW476L0uZmzQ';
- b +=
- 'O/cgRvweNblYD5EimYZx+FNzt5sG/mgkb5iHImR4Bsf2zueP0zstEJ4Sqb6JMDFwB2wLCPz73q0';
- b +=
- 'LTDTrV8dlmz2ReTt5pr8LWANIFtOPOJuT0C9zv+G+xv+Xl4bluKFGxSBNzqospWfxLobSdBbgOA';
- b +=
- 'DbzcaURt1U8XxjFvjuBk4CmBl1AvmMuEOVRh/NTcnRaGNuWd5SRBRmo1vL8MicBE+E/P/cPMGkb';
- b +=
- 'FMfR5akds4uCoRUqKshA/Mze2oVg5nxOEGTBDhiVjAf76z865hcFATHm1YyWENlBFWf+dFQb5VZ';
- b +=
- 'BEG0aFcJ+bW5oxs6p7CoTj9/KrBjSYhU2WKaAHQGpg431+7tY16dSA2jk2ywwYY41SYIbnF+Zu0';
- b +=
- 'ztZrCa7l1093swDtQTnBaAaj+aF+uKM4xBDEnFKC00KTv3S3D4lxsAlAnIOwMQIWN/Evzx3zuBz';
- b +=
- 'VUH+nSQV43JgNkgtZfJZq6/UY0iU05goIF1CGDeBf3XsZdVNS/qzB3QPSCdkJo1nX5u7vIoWj4A';
- b +=
- 'A3YVyeQL3u/q/4ZeO+uUyD/jnReeXS1U7MbAAiWUxgPVUX58TE7B3pYNNwQECwYbVpKki5htn7t';
- b +=
- 'Q/YhxWZU4tcGsA69+cm6JY3uioYbEqqRwTPLtvzV04ylWtrq1W2i2XrK3eCX6onFt/pQ3xDvCai';
- b +=
- 'YxxAH7p23O3qk/UCuyDfS7AjGpMPvbuO0CM+3gV+vDN7qaf5hgP1TAQUFJpKAlafXeaCSIphYSt';
- b +=
- 'tKMEh2/19+YOrnJcGG9iFgCro9PG++/P3WhxcSOudAIZONsp/mCqz5ksoY5gVAiYeSA/nPurPZ2';
- b +=
- 'IfzR3WZ2skL7cjcvcxhZ8tJI1VFKGijw3wN1EsT5G+h+fudWdYE1g60guBQf6b38yN6YL60XLm1';
- b +=
- 'tV96jlKt8aeC/zSgFIdClw8dO52RP4B0w9mCYnUc43IzPi5mdz/zTzwL1Ge13FcLcOfPKa5VOu4';
- b +=
- '6EFuELKGNGRJNio8udzd1z4p83FojN4FA9m0bnN4mKZkDEKpUhCthXcL+b4aIIP9GfLlb4MPKNd';
- b +=
- 'AzxpPA+O/fLM5U5RIYFF5JBt0Mk6/qtZYgFaiWB5gP9hbb/Qv67nTTgAAqOdRtlZAIv0N3N80I/';
- b +=
- 'cfvOO1UGu21zsIpIlIsA9MuOAYxPtlfvt3H0PjXA/BSptdsnJBB+Fb9bxUIWuDEVCPbxbPJchFt';
- b +=
- 'h3wBCt9jTT382tn5ED277WBcKh9poF/EMBcwT7+zN/SxcQc/MggrCGMvKHOTPySG9zfQWcgtvqU';
- b +=
- 'H0huScJz3Mkc0HFP3YXxphLS26yU3BlUjaj3Ef+09zJenXN8JGm74LiVHCRooZqsjY7++e5mw4/';
- b +=
- 'bS3tdjiJScOeDl5zbq9tkL3Osesbc9XtVQJWArYZoiYcINrdG1cMBC6KDdgsudYea53BItVRnNA';
- b +=
- '5CxvBbnMYOyZ2j0bdWPSM5WZgwuDrY8sPYHjeuHs27jqFFNRs99QyK2k5wWYdSjp9r8ad9i9Fsn';
- b +=
- 'h1cnhwwSPVRpkIuEBksF33bpw7WfdjAP4DgjKKA36Rmici830aB54s1Z/UIwnXgGaCkFhjGPx9G';
- b +=
- '26CQsLO0w8e3xceWyVm4ubrz7zM2NtUYeY9ihza+8E9pup1ObzeYqDIQgVqwN8oRwDMAoK/f2NU';
- b +=
- 't5ewsraKNOdY+e+06UMdH4yiAUYDPmU+gOm0D2iMVUkYVEdY6D95H2dFbIZ3gkVKqNGC+fzAxk2';
- b +=
- 'HaJrChygl64JIlwy2oM8kmwc1HjDNyfKu2u0hsW/gV1Wo5nj5GUM1uxrO9eU1UDCyNDBsu0aN5O';
- b +=
- 'nBjesOrc9QRL5eq4a8nnpICElwY4vAUVAiPqTxmGlOgQcf7CDK1nceLUtM06I6R4/BnPTQRq3kP';
- b +=
- 'wLLz5IoSoMIzcJ19S6TEm6WOJArrjEV4WGNO/S1Pev2l7rCnaiqaCY4DRWIQKLmGLgi2BYPb5w1';
- b +=
- 'POy/XhJKjGKJZJ+Dx/R6LR7R+Mdh1qR/SezJ/L54ewv3bVVvdWXX0nTwgQHOyFnWVCRwKy48slE';
- b +=
- 'vSzVEoX0ksNMENsKSj2pcNaUu9YwOKSoig3TYw4kAhw6Pbpye/rBqxnsDPwOerLxUgDUZN49pUL';
- b +=
- 'Te45PhTAwCs8k4KfJvj22cV8984jNsl7Mwn2MMlHgbgZNylR/X+Ju9kc+Oy1wiymqSgR9bwZKj4';
- b +=
- 'vHjfjl6AQYzeqbBhQounjDul3PQWMtPsDUknn08sXFeRwsez4xQBn4RFvLJSgv+IvipKCxgwVtf';
- b +=
- 'eQU1wG+BqvKkczJPatyur2SukL3jpze30qnSs7n3D0erJM3iUjp/tUQMzTraCLxJehHikxsjJID';
- b +=
- 'XXaxktzdQIaAKJKxvpLxcfAYDDJe5DhHcLVXiKY079I2Swf9sDWtqX23qsqUAYva+NaPwesJQTb';
- b +=
- 'kSzsmndkcbkiwwUdZ+iRNBpTJAjKVzsNWe1ri4Sww7/7lgZc27lZ3lN2q6Op2uEwNHw5QX2gJni';
- b +=
- 'k8HGDzzeJ3ATZG5AoKcMHiEFN6TZzRmzrI33MLyMiaArVPgw5/ZOHuEcez0X/AOJshSPIL38L/r';
- b +=
- 'R8KY/VGxbijBYL9zDiZPJi6tfdaZvZ1BVdCYLYvg6axTzx6BZzaqgwRpjfBaa4qhyecc8Fp57pl';
- b +=
- 'ZK8874Md8/gGP94Iz89ovbNx8dAwKY65LGuP7HgUROUeVnhdN2gmE2SR99IFJ5qN5MTz4zIdnO+';
- b +=
- 'dmBhsTMao9tc6xnF5ywPP70jMzvy9r8GGjdv7YkZBbkhiV9tiEGnYZvN3La0IfJ00k3HqO/YnhN';
- b +=
- 'V4x091e2TgyGk1fvYwcFLAoJmZmV2kCBEz0STRbbKFn3Ktmuu2rZ7rqNTNd9dqG2H0WF9y6C8tb';
- b +=
- 'p/vLtIzEFtqO5wTLjET7usbZI3LtOyUBWYOxZzTkABTZ5Nc3/mWhak+9Q4+Pl9bUd3QbSI8LmNj';
- b +=
- 'DoOEflxHsXbq9tb69hb9XRGRXq0DBVZ1/XaweZVDjM2LTe1jHHJOCtTRvaNBx0dayagRNimYgeQ';
- b +=
- 'AMsN/WG//Nn/pN3afum2e3CWah73ATvqTOLHiVJcnO2TfXuAY4gVbUwPawRpFo3lLjGqUsDYkzI';
- b +=
- 'gnmeou31rhGGy6c4sHrwAG8src16mZQcYa92zwXGcB8MuLtjbC35dlg+dvGeAGGjQH5hc7Jl7XU';
- b +=
- 'oSSmC4HB872jkUfAhY10Fa6Zq6YNr3Qj0pEBR81BUS2dZuydjdtOIDiD/KaXci2dNywCxnfw6Wi';
- b +=
- 'm7wJzP0UV0J42CRFIq0LaIqTARtfvbugah6XlRAwrVyxwTOmEUs69p3HWcHTf+XUXRJTJAhgPBv';
- b +=
- 'zVextXLkzs7jyFuLCQRmhg7Zlk4MtWv69BFg5fMZb3ea5QWEXyBFeEpN7fuGSK8Mmw5CZNaeYET';
- b +=
- 'D8hgAbJBxrDqhBqhWLHi1foCG4NPhoAkOBC/GDjSTOX+9QuSZigDjxQnyBt8Iw5NEmog+Y+1Lhk';
- b +=
- 'yrxXsAZrp9Y21peWcXEsEa6sh08sMW9fc/HhxqkDfeHdL5BgCVlpDPcak73FRxrHF07WTY4f3S0';
- b +=
- '56ZCFcgCCMLXAfbRx1sAJeGlLUo7Otk1BjJi5rDGXPgFmUh9rdDS3u5o6F5X/jo++qxAVam0C9K';
- b +=
- 'TCu49P3hbCOmIYIVmxIDlxn5h8icbTPemV1Cp7buInG0cmC8lhAlgvcAE0GrshKu98Ilp9qnFev';
- b +=
- 'QF28uq5pERjWrpyGZyn+XTDTk717tw+SMDmtCQIKUqj+cy4IEug2oEhd+DTgmYqf7YxdUtBl2F7';
- b +=
- 'sAT+l8gcOfvc9EMA3cQemMlwAFqZ6M9PP0QGqsws4xQWo/aWfmGGISKjJESvvKeRZPHFxj5zuzQ';
- b +=
- 'N3gkHb+UjgQn60n4HNEC3XGQhCEkEd+rL+x3QZ0ALKieVPHAaEb/SYCOy4vpTyaTxACuFdFIaQt';
- b +=
- '1XG2e+O5qmKMpESQZsmIAjfq1xrONWu/3lKgnGy3buN9hJroKX0WIsXjAKqFQl8vX9zp/MzhjFm';
- b +=
- 'KDgHxxx36h5NGAc4QA2AteEWhG+2ZihkWfG3iIS9VKYs+Jb+30VwGHYrjATWAw5yPTtxj+PjKvt';
- b +=
- 'KRXvKuthnXhHdO/wFWcNSV+tqlvL6crAhUsyoIQtV8BVEtVWf6dRK0WrY7KDLCklsDuck1p/d5q';
- b +=
- 'LjeWAs4SQQWM6C/veNBeDU/GBBKeEZXgK+P2pHtsKeGWOHeWyj07+YJqLvUQ+Qq2ihMPW5T9s3G';
- b +=
- 'xoC6yKHLDsIqw05oK1Gh71R2N/GzVxnASODHjMAKD+8djfBgruSWLB5BQTTfEn4387gbPIAjwTj';
- b +=
- 'c5r/dODPmLSKFkP0xJ0SIlH/7M6No27hFrK4Aw5wbLYn5/pp/pF479XCrAlURDnHPOktYFNkEPO';
- b +=
- '2f+y8eADK4uaSc/LJCc8h2WjADo6ZX6FmS+7Ad6ptLnpTqTFSiwE306IbLBSJWZtf90wY4QYSpZ';
- b +=
- 'XTxYSLKkyHMhU0jER/5vGObs3wK5ty5k0gD2AgSnHRfjt5AssxdPl7DSASC5+N/ECYKUplsZbSl';
- b +=
- 'IWf9+wk9Ike70ejXOMazDzRAmWZfrDpJupJLSDlRFYxjIf9scGH9dicqXcbolxZznLDLgfbEEV/';
- b +=
- '9T455EnQB2j7ddKp6jz165ZiKdXO2u5n5verPqrU27jZBVzWI27/+r0aqjKSA3x1gdVhO0lz39u';
- b +=
- 'bC9Mneo8bNmWvXVhOdKvGmFhJOYqTJk9VUScWPBAI3wmYKkyZdc2T525+xaU7LIxJAQ0ijTkuzd';
- b +=
- 'JlQVftnBRtDrS036oMiQ59dSjjqQGH01svEfzlmNTUAZjZ9pQsNgZ1p8Cl2btPZvnjL16yWEjhO';
- b +=
- 'wEFQK5B7tX8/ya5RZ90qwkxgTw2QH4jbgX7928YGIDtLL4i83b7ut+xrAvm5OCZ66ttO4+Tb0rs';
- b +=
- 'NMNNN2pfJvlzW4PU2ENwwK0kIjDDsz3bf7V4uLVnSTOxeqE9n5NPUz4tJTGoMlDgZXtzVKoS2MS';
- b +=
- 'nhoAFoYZku7fvKTOYeGAkN2FA9lSCbAbDBkBcFClyAOaf1+/0HwvZ794e+VIByAugaURXHHs3Qm';
- b +=
- 'vrvID9zf00RirQAAyG1yLKsI+tcHwnB+0v6GPb/sjnUbES157kzJQJ5mz44Y+uHn/QwsHpG+Cf7';
- b +=
- 'hg223E2rJpwjEKmAhbvVjq1UP2+7m1EzmBKcfO00C7yEObfzftgBUq2IUG4PGSkNEi6E0y+eua1';
- b +=
- 'x7a5zoaJjQy5PojvfXGbanXA+oC6JlL+7DmldM+wtikPxK9JSqDd8Zu8oY8vLm6cKI6qF7saJ91';
- b +=
- 'zq1Lwj3M4yWVhPTg72ymu26DZU07p9ydv0AagRp8qx3RsaUQpArATX0ySjvKHtG8omY4eex7BC4';
- b +=
- '5BWwiUGMpJfXI5sLEYv8+YCMMrCElhCdCKqfdo5o33wujsDoQWNnmYtG4wxo9xQDfAKxP3D+6ea';
- b +=
- 'eF3YD6Yrd+NGDD2IXLd9Po3j91S4GKNtriZqpqz4GlGq05z4kLSsxjDnJwYTJKHUWlLGAznx57k';
- b +=
- 'INnpQDjSKDtBGA04Y870MGNgf0ok+FUgwm2j28e7oPniz0LtsQzwHQFZga2TCTMP6GZDjYlt2Mh';
- b +=
- 'AGkACQf8LQQPNtgnNnfxBWMDzy4YIF+WA6x90u5f8CEAdwuaC5UUEeLJzX8cLyUyTQ+xI0V5OFE';
- b +=
- 'TFBIE5SWlT2nKYW75eDpRIY2ltZWq6WBWMWotCzTgzD21SXeHLqp7LvaCFkteEQ9UNAKk8JJx+r';
- b +=
- 'TmGU5MfHqzBmuMLJkQOJ4ZeSsVe8aZfqpnNtWYk1+M52wtFSYGO8UCeY9BOZVCJtejg5mlqL487';
- b +=
- '+UpbsMqGZvJW2JM+Gs9y6cBzEiOpUacC234s5pnDZOB7ZV3epMlE5YIrTEH5dn/Dnzic5rnrdeD';
- b +=
- '0YBg1wrWQgUjsK3ZY5sDY+Nzm+fXHKL0l1lfQRdgAU0FcJ0U+4bD4zyvefdDNV/m4CaDRO6oF8R';
- b +=
- 'hSEJ6+vzmxetTlHDj8ljcXi1KhVXaDPdGcik9sRKwT3pB81Y1x6tQbAJjFoMwwiudvc8v/HewQF';
- b +=
- '60z2cAlD7FM1TzwAxQBSYysxxlNOWLZ7CfL2mSwQybdE1YQqe12DXbS1kK2I2MKM08uET50ma9V';
- b +=
- 'pcZEA+PBD4UMcK6lzVvWV8PEjsDWphg1GZW8Hrh5U0+1AwfRjvcLRZZsuiILAvWaIAfhL2ieemY';
- b +=
- 'mtgrqsQM8NFx7VSFCS5ZO7aWNvAJNqvzBooClCliOooC08te2bxRHw3dSGWSXjXDxL+6ef4E7po';
- b +=
- '3Ulq8GqZ4cb1LY7NBE8qttQnbFsfXNC/ZTcyXdyvE78kc7u9ObqgRWRLKbAKgnMJrm/tqlta1+E';
- b +=
- 'ZG6jlQwixIJIS97mCG9RoskEdtSBYdoPzXN283ItsibHbvUyTV4FWv6espWhJXtY5A3S0saBmUf';
- b +=
- 'sPsQwWdpHSWYx0hkEP/xuGm4Iy6WOEcp7BnMNaSRTZvqu2vNu8KxLqcrEWsbcFkHq2JivrNtf1V';
- b +=
- 'X+SIRWYkCzkSw2MO6i3NW6/PoPYBW5c7oikqAnmr5FuBMo5ThhgZnlg4PO6yI73ohUiRupyICNw';
- b +=
- 'C4HZva9qFbc5q9fiQIhoXOaY/o26kenuzri6W6KC7nAWn0hIakqUxsHfMtK37CgI4rIOYNLAk4Y';
- b +=
- 'M27J1ATqaq5ev+8t8VGdieHuzu8KRjxBjgxYF7hyjnXT1vsisVbscOKiedBmTnHLhwx8m7J19iG';
- b +=
- 'LAy+H0rNVeSqfdMvoTG5ID9x6hQN0jz906+RHOJ/ZQsS5I5Z8z7/pXm7P3NMFVXhHQN6hlU7uk2';
- b +=
- '+DOGGvqS86oTmOxyDLAMPE0akxk+UOPLwARzZ7LzSijqwwf37Ty9CFRR+GKUwQfn+UPN/7VTwVb';
- b +=
- 'FO1bcZqEI1Jb0KuUMmnf54eZtF+589Mo9lLlIZhTC3NPNWCiCFgnMWMkFDjbHTLwBQsZZEB+Z/N';
- b +=
- '6W4qGtBGxDMsk6f7Q5ra4d0cKpnLFogqOH/tj0I4CV40nqEJjSSfiPTz0CFv8kyQX10hir3CemH';
- b +=
- 'oETGqM0EXXssZjjk9OPoKlymkpvlIwy+E9NP4JNOqNuAMt4BJ8/PfUIlsH+UsZh13JOgvrM1CME';
- b +=
- 'sOYCVhEqfWui+WcnLyEus45eJx4Ch20dPtfUo9UOUPl9swA7vNI4C3MtlYZPByD787MufO6SBAR';
- b +=
- 'HifDJqqC/0LxgR0un/1jvDjARY/PemAcTEBm1YD0BqPIvTkSqBZ6WLJIdpArwHV7NZHgxQBT+S8';
- b +=
- '1LF8bkpdSI6csYImVBAYZWClDgl/c9olLaUwLWIjhqknNf2feImmqHKeUACaSPzn513yNaYogLL';
- b +=
- 'kvvrE+Ef23fI3pBGRUymqytzTp9fd8jBo2RL1Zl3ahAv7HvERN2VJQKQK3j2OTnm81/3H/noP7m';
- b +=
- 'F5zwYGiinGkPhiZ9a/8fimauGZaTSGAmUX27+X9Hy/YVvz2tdt/iYvevF7Hh0GBEBdXGObbMypl';
- b +=
- 'w8p3m/5twc4w2Htz9fcCGjy6BA1fKx/RdsGLebSaqsH55ioR3E5WITiQAiCoJ6b9X23qzjvWW0j';
- b +=
- 'MsSJRWswQO6ftNseDX1lYmiaoA8BPCEvC/4EZD+gGsuAOSioDJKkrbGdtQAsRHIQDJfgj2GadIi';
- b +=
- 'd4UbdabI6YFwATNKCdZGRZ/1LxN3ZEGJQw9khZwGw6bu2X64+bhAeWr7qJYct44b0mmxMUE6Oon';
- b +=
- 'tT8K7YavtTNBenh1p6jV8qcHeWTDaCYCM4ZkcBp84M/2e9jLWQ6CRw8LOXjv0s/3OyDAWhKjzlL';
- b +=
- 'hQQHTv2jebTY62y1kqEFqd9L+qbcUyBDROnkhk/vlvm0dAWvPFKpowlah3v1q3yPmHBRTsWQURy';
- b +=
- '7jr5vnT8pf2iPPtWSVgDfEI3rJeEzyN83/1Cf599vmecNgzBUbKXWgzErKW6fWNlEzcbkUOGmUR';
- b +=
- 'onZcHDB2F37d81j0wa+8euHrKIGForKuMKr3zeP1FViKEwLXIuQGvaPAm4RgnV/aK4OMe79wYER';
- b +=
- 'Yq3dtAscvMQMSpJp97Rp52wTJRmp8SliTyYfzR+bdjgCLheVRLJe4NYHg0lDVorMFDP6T1Nci8n';
- b +=
- 'xATeewRJX5f/cnIcPeGJxbe3Uta1zh309/GSbS8t5q6REb2HEtLvpDI8a1rvMwiRuA79769IJML';
- b +=
- 'YAhB0Uu7iWqxhsqH5lyRhqgmNSqKyADad7tG7X8bIhYbXG+Wtgc68GzzrZ9nIGSxTAtQDDJSIL9';
- b +=
- '2yx4Vl+/QKUlHgaOVUSvD3nxNyrdWSh76rJd6UEME+S+GUpNuq6d2v0Lhuqx3ek1AMXYhBVBAgV';
- b +=
- 'mb1P6y4TrOOgJs/e9ENYgPD7/bpExqIOuLDgLKVI5L4tOqSofGvj8k4XrlLNG72x2LjFMO8F0fd';
- b +=
- 'r3XzY53YrYBQXt0uqr8JAMmE2COYIT/dvXTp9UXhMfWXmGgi8AALos7dAHdMDWnK4ElQRvKsCwh';
- b +=
- 'j9APbnJCFJK4Qt1DywdUmPunWUWTsq6wPiqDtbeKDtdXk1HRihwWZFkqLyQa3/AhsJe7N0Tiwe3';
- b +=
- 'Kp9ntnNfbRC4qYUBrhIzJQ/5MCn66GtM27XrAH/myOKEkqmr2v900HdcO/NuOQKJUWoh4/rLHlY';
- b +=
- '6392Q8kedtjJjnoYL/qriWgHTI8F/vADn9ZHtG7Yd2SFFu2RB36PR7XIKPOM3VfL0YDF9eODALL';
- b +=
- 'NHHWPbt2633od3TixjStuc1JJbI5Oe0PwNM4AxX7MeMvZgbqOp+xIsigCJKV7bGt0CszQvIqb3P';
- b +=
- 'Sskd2KjpQzAOD8nASCrVdjUI9r/f2EG+w6xxwOakpuNSd4KADYyAsPS/fxrVuPTt/pmpm9DZUiG';
- b +=
- 'EamYdqygQlg8Qmtq4dJAS32TM3Qeqyy2CdKCO0q2eKSCmJZYB4srrRPbN3tzNwZT6X33j16V1Kn';
- b +=
- 'JXz6xOKTWn87jeDeUIlmA/6J2uyANsEKpOrJrf1GyklOUQpGBeo4GeKfAk95cp9PGSkKEPvAtYq';
- b +=
- 'AW/hTW7cd4nwHXfVwwpmJlUEKxy0PKvGntSbWzgakGt5iBUg0LsuntzplDwXJdLpQll5inWaPEi';
- b +=
- 'ANEQ7sg3EOHOEzulM6tYRVZxUsWRlZxD4mklgU6npm6y87PrBMwvWt/9r/x46oy7Na5y70DvyW1';
- b +=
- 'uAxhzXUu2QNM0NX18qbCmtIcpxrkcCv8Gfve4Tn7HuE57aO1tZ666ZO5JAdd4kEH7wyjD6vRRf6';
- b +=
- 'vrFbPQ02ehUXxdbpdUDZlf6NF4oy5zQxSbnw/H0/+Qv2PcILW2cP+HQgpB06tpFyURjmShmBsE8';
- b +=
- 'nFfOL9n3HF9fYDsaDB+KJEKGBzIWXtNiQS3Ztu+wYyrNHYI0AuLh/aevwoNPuJugALxFgkTxQ1e';
- b +=
- 'gIFS9rHZvUzWPIMybCBVEAnpkRDFDey1sLk0vNXa/BADytVRpPjmABaWVe0RLjIjxd2M49BVqjt';
- b +=
- 'YCbM0H4K1tTKPL7TAyTVGFnipyteVXrFmOVWAYyjICiGmYNVw77civ66jrfJIDhZwzzUKhGbP2a';
- b +=
- 'yd9eBcAexKUUKAXfy19b5z5gr1HsTWFPTDyTfF1LLhyGl94VGLtN0QhOsU+MIQiVKNM0Um8JfX2';
- b +=
- 'NXcydc8bBrseWXFmlN9S4xngF9AxVB7GbiMhvrHFNiEabaDWxYOuNSG+qNREwC0FlMEsJwE+gb2';
- b +=
- '7dpt7a3j2Owebh3Fo8ZFVJv6WVD1pYvIrzgiUEZ0Npohm7QvG3tsSYsEPonpdhNI3Ak6FVYsLat';
- b +=
- '7VuMe6yleQ2dg7bSJTMkyS8DRR1C97e4mMu7l7FcwTL4VBhVqoo/DtqfEOPS8RyyjNhxir2zlqG';
- b +=
- 'TBpcYVlQF403+l0tM7akce3qtNGpnrOEEE5h+8gM00nNu8dfuo3pGJ1LsRt7IDwSuDsHzPue1oW';
- b +=
- '1Vs4wQ4NNgIHLWZhb60LI7z3Asd7XmlhDSGDiQoZpABdiLHHvn3wJDdwLAbhbWUFIsB84wCf+YO';
- b +=
- 'voHsGqvk9RbaO1UuRbRepLhaih2EEIuJsTmaoP9SISHV754ZaZBMt7+b8ETLbWgSlqYyLxI3Uur';
- b +=
- 'fK8eELhd5TeDsrBuv9oa6UWG5hRuBeL7R2XHFwb6sC4j7XuWj9JeMZ7YkojVdz6pAF8y/Dx1p0n';
- b +=
- 'Vz8Nr8m8EOVri8ZYL6sdQEZMWEYYfDQs5k+0zMmany1bgjE97gIFciDUJ+tc2knPo95zHqTH2nn';
- b +=
- 'wOJ+Cz3byzH225GGxlkRTESlsvE/vm98lRgBnROsRJUVDP9NyCx5Vixf9ds446Pn4p/PLHxbKz5';
- b +=
- 'jWdRYma9StT4MdkQz4HkySVcnEz7b+pX6bhnptiocIBvQ3LZbYOdt6ojARKjD6udblMzdt6K24C';
- b +=
- 'L6fEWGx62gmSn6+dfspZbeWi9LAVimpM9iomqaAGiecii+07jDlYJ06wyKahF8zgw3Shkinkvpi';
- b +=
- '6wxXNrqYmEb9DpOoldJ+6UzfEOhNAGiRM9ACQAryy2f6htFSrQ24GQKGxhvxldb/2WWcVpZP+YH';
- b +=
- 'Wo0P//SL4/ypHFxZSr/R/KSgF68hn6TnLJtCvHqhxzDB2yjYZrbjRyX2tNblCtG9xAoshsJ6UMJ';
- b +=
- 'EmGczXW+MaaJb7XrNYJYJXdwc0BwY/eSako+IbrSEFpnDNzn4F3qVgMli2YHYEi99ssZFXYFVq1';
- b +=
- 'UA4kwi8HzCg9BE+07daf7s3U22gV8RAdGrhzudf2alyO3plN1QlIkNCTSLQKwWk7NsHiFa+c4Bj';
- b +=
- 'fbd1yzrstEOJpUjOwTb1SAmAXn2vdUGR2hhC4CYgaGKDMAF7KVHmmTLfb/3Hgp0KB/nBqNi72yz';
- b +=
- 'B9xL81bCsogiCaOOl/2FLjiEIp05hWnPx9lFwabXSxAGCVvlHrcumP0OtfugeohIJKw6mU6qABT';
- b +=
- 'Hqx8O5Sq9YdKtK1TNE5xypEJ4FychPpvoQ3GbGgBnDBsHCEf3Tlu0L8OTt1VDF4m+7emkxUoAfV';
- b +=
- 'hbXyo9LIaG2MAAXCbubOvez1gy5+f2SGNrGiId9zDHNpXY/b108w4BmZ7zgAY5ZqxTQOJinX7T0';
- b +=
- 'aHWa46nTw6/YG2xAzwFJMxF5DPKX08ReNFybIswK6rZGw38107z01Sxoxn2MQNKNZ/Clw69b/6P';
- b +=
- 'v2AqFLMEIb27hyVkxT2njN63zJiWJ9HeyK4fXJDDMDYb9FJzU6rf7H+J3rQtHDjE2TwfHAkaUaD';
- b +=
- 'AqaEHB0Py+NUPaCxhNp7RiXEZOksl/mByTwvpalDEl2aUkhP7j/qfhT6271B6iRgD/SFV3ilkkz';
- b +=
- 'itjMFHtz/t/ymvb+x7i7vsf4h7t28/gkjrGTOgQgUUx5cGzUMLv2b7+0MK/zlHe4uI0Tct0ACOX';
- b +=
- 'kktBK8Kovlf7uWfqQYed/E33sFwRkfEwI+lsPWX33v9Xvk/7aKX8MCrLFhAFmsnj26dKyh5mvjh';
- b +=
- 'w0ZlSTQR4XPD6951hjAz405hs0CvwTNP92v9t4KSrOnfrBDjv337IoaEAuIPch0Lszr8VyF8wLS';
- b +=
- '7dmi2+Fn1VtdilBksKWy96p7wgQfPoHtC+aooD2hp13Lt6ke2UcCvhPXwwmC+iuMsPbB+f8caXp';
- b +=
- 'BPlQKMsJEelcap0IpCGxAe162baxLVtX6m7OkLBLwOVgMcShD+4fWR9PI2uGiHktFg9g3BZ0QSY';
- b +=
- 'OkeTOGEPaR+tO0CvHJQpRYGLxIAttrPPD4WFUg1SLYndAYP+VypZ+t2Fsbv/XJ2FgkGFmBarZ+s';
- b +=
- 'VFQuVQlDe+ugMTea6f3dL92HtW9aIaHVnGJWELGAwHxzsYkUeXudq+MCdDBxA0NHB/qYC4Btjj4';
- b +=
- 'Btc3L2bXOy9rZR2DveMZoylVIa/ch2RxxucNqHKcPd+Ypb3viSK3dOxhi2NeLaMxZ1IuZR7YnAx';
- b +=
- 'cgsOA/YOksyw+yj23c5IMn0nqqCI/BNYHRLFPVJs8e0zzs55Qa20gLVECEYLQ2L8rGTXyxwsEJJ';
- b +=
- 'aW+k4MKFx7X53kv2NDpwWGoH7oZIGjk38vHthx46OdMm3R3Zm3mXeqo5qlJIix0/iHpCjXcnChi';
- b +=
- 'ht4I7ZrKyT2zriWGTqsrVluNYQWAnpKxTfFK7xnGUU1nDDGfYcgwWU3py+6I9opFTlKxQ5ZyE5z';
- b +=
- 'dYTGZ1fsrkF6ZBOGW9C0rSTCR7ap3HJiZrD/vdAJFlABOe1iZDgzV9ASWJPUokYETJsRo/Pn3yo';
- b +=
- 'yl4suBhT0qegsvuGXUezepkiSXBJQxQSP3MyfchOnDvLZAemcCip+vr3Ad8awaX5lWQEi7Vz6qx';
- b +=
- 'tsBMRB0UkyFox9mza3wdQNYBFpSOzrJE/XMmX8JgsSsFTtepqElOz61hySIhklAlCJLokJ9XZwL';
- b +=
- 'ATgLJY4DsMJFRh+fX+jokWCc0IyI6AkbpBTXeh8IsZ0O9joTDH15Y5z4CUKfyXFhnDQtCvGjyfT';
- b +=
- 'B6oC0gZmYtKoG9ePIlWNoVMfRIMVTs80tqTUHyWDqReADcYKN96TDrehGeO/dbV2VzJvAmkfIMe';
- b +=
- 'D69rMbacYFbT4jBEmju08vrGINc4lI2elzZ+hW1FgIsZws7O2ONbXDmlbVmQRKeKFdaArjUMr1q';
- b +=
- '8sNlICGKA52JEX7k5NV17pNgbVviUC2Ru+DUa2r5MiOYjIIYRFKaUPna9i12+Z+AyUZrJch8bOt';
- b +=
- 'Y56cqJwswNwHrAHPJmVWOvq7exa5IzjPAuLDMJZAvB4+cXt++16HRV49ugzz5jpVbHUw32yl74C';
- b +=
- 'TGIGGjUg5oSIo3tP96V0FelWISFZh15ggwl0CZJ29szxA1ogCjOQeDYAgz4CTe1P6bwZKPraWNt';
- b +=
- 'au7wT6U89HC52C95869uX3ryZ1M3EYpCj+92O1VvCQdZYQQqhnYCZbMW9pT6NwT7zAILawOOYGZ';
- b +=
- 'eWv77xb6aH2nTqJ6wWmYP2yFkCKKP1CgXIG+rf2gQ0MGnhihqGK8AyGInpTRNM/jJRWWZBfADwn';
- b +=
- 'g8W+vYa7BhQAYz0YayY0g72hPEx0XWDIMiCJmC77FyHdOdbXmVjGPnTR8JEqpd7XZuCOC6jicZY';
- b +=
- 'p4FyiyJwAT2bvb45KkenlONGgLbCtlAc7TG/6eth17dgBoCDP/NlaL0i5JFgCpt0kLcNTvnXAtb';
- b +=
- 'LvFvOJObBYN7+R8xO4GYCi80u9r72pL2FH76ouv4DZNjiiO7Rq1DOCz39++1eSrNrZ613MDcAeQ';
- b +=
- 'FXg5B7MVPwBmtJMCOM7IM21hc1kjpHHJxQ/WWD5gpU2mAHa01syzD02+JBmhrQAbL71wxNoP17g';
- b +=
- 'kUUKpBXMTOXU+faTdOpVOhfXTH61+OLX+sfLDZtr6OHiZKyalOsKKT9lb8LWZJWbsJ+pchC0vAK';
- b +=
- 'SYbDQ2M5OfrHORUQb8SmAySWw/nj9V5yIKv++1w7pN41PIn65zEUDUyNBvRvDP1tvP1LkoM569l';
- b +=
- '9oCjFKZ0s+2/zrnDsnrV1RPOmkppMJqs8CY+1x7YXLaFG6hqwrXElZgn0ybJVXwCd3nxwSV9khi';
- b +=
- 'dh6BapOYdYnhVgxZfKF955nyoYYLcUXvwW8mErJNLvj0xfal9UfvTdmRvhANShBKlTD3JII9ll+';
- b +=
- 'adcReaMC5DG8fAPgD+9FCfHnWEXt1ed5YCe7Qi8SUSVZ9pX0+auqltY2itTQk36fUIA4yRSoEw7';
- b +=
- 'QF7PoN+Mt+tX1hp8d6Of0/hV4e+OrJrQ0XSmy9xJMxp3pzaQ1sVt+/wQMZDthCSycFTFv82oj1y';
- b +=
- 'FKCL+adtiSBJwhfb9++VgRr6CxEirZWBs6VMFyKb7Qvqz0YuunUHXEL2yKtl2pBapQDJ8Wx7Fc5';
- b +=
- '8s328RkjbP3xYZcys7D8A5eRWW++1V6un6V1YmMNS1fL9+089zEMWFS/tuerOoHdLFkGyOSyD/n';
- b +=
- 'b09xrREZY9VvHegKIqMlwTZE1Swrsj3WMmiRo+k77lYfq32wXnL5i43RB1KPDQLsDVsOeuEzNkf';
- b +=
- '5wVwkelTY3G5XeaGnrqLBdAGdA4oUi5Lvt5x0aH1IczQCmazBZYGOtKdrhCJ4DOjSA/QGSC6Dm3';
- b +=
- '2vfafoAaGcZXYD/GTBOUgnplUrSYhue+P32lTMP3p182E/dF1piRheMHURKHMb/QftDh0bvqGmm';
- b +=
- 'eVewuszsuDy1bXPWflZQ73MY4OGYjkcBEIFDkz9s1+1vQlBj0yWgctQYMF0/ah+ZnCvWn7xFhCc';
- b +=
- 'R/BKsAmxbRn/cPrfOAH3mQRENzsMHxzWQIO1/0j5a9xF62WACVRZsACtOGImZ/7T96jP4SWcQkR';
- b +=
- '2SstpVGaAxS8VISiQqnd3P2mZSut3pTqJfENRQic1bXRIwxM/bNx9RetsTNdeOC+IBdzGdomK/a';
- b +=
- 'B+r0/Z0dwyYBIZnYMRZ2EtO/rJ9bp0wRzm8Wtn0pQ6G5SCJC4FH45n8Vfsmu2IM3Qda0gxLNqLm';
- b +=
- 'sMyydf7X7cntS/PyNYvra5vLVT7Vkg42ecNgnRETuNG/gRW2q+imKrcJa9t9SHFxc2Xt6sV1Vx5';
- b +=
- 'DYhTJMMVQWA1o42/3A00IkCodJHdOaC/T74aTwC7vXNneXFzLebNEXawz4E+jZ1iPJZT8fXtchc';
- b +=
- '4p5Kw7FyvOkksRjXYORKY/jCW88D2BCBXlU2+8dF4QGrhi7o9tNeay8pmrC30GikVVxval2ED9T';
- b +=
- '+0DSCz6c5uMSJurUuYK501G8hiCQ0UNEq+d1yMuuRiFoUqiXacvnk7EeQkfiHEbvbz7/O3q5ejd';
- b +=
- '7W5XlWT+czaXlk9VTbOAY4BVooJErzhl95g/gJe/50EMcq95ORhkg9WKgv9VCABLoYsBWUIl4JQ';
- b +=
- 'kCQYjgSLde5aboxhbRr6aQ4wqqvvMX7EwUkalRzIH/hH/BY3+iVUUwK1igcbggXe0gqE6kqb3nf';
- b +=
- '/PlcpSp5DnfvNqgs4SSniVwJu3QKujjBEriNP9J164XhrWLykA0FxaCxsDaKTSD5g/MlCSV5mU5';
- b +=
- 'dW81pFpu7D82GlRWMwAo7AVgQa7mIi0D5w/t84ARf2iMmwmOCzoMCR4C5STPmj+aJ0Rgltd3F69';
- b +=
- 'ermEnWFjW5MdTYKDD07hwfNx2g4CPR96dPPylBfuvM3ZLW9sSg8Zt9kpeAaembH5cCIZbH50D5l';
- b +=
- '/+qHZmuQNvefCsWHAqf8NKobS+4sj/SkFvad0gWXwkCZLYqwS7qHzt91DQAClwp9OJnBSl5Wf75';
- b +=
- 'BOFy4Lo/QwpgfyB8BKWKoUMExx3fw/DICa0RBk92nqkb5M2w74ziyiOS0Nd8GpPWz+74cWH1S/P';
- b +=
- 'rk6oVIJ4wy9C9ZtCuVRnQYb+jx8/nDlKTfWsKAI3tGvFaILy8VQD0xfgoGIWTxi/kYdl1eEZauU';
- b +=
- '8EfOL4zzE1h5sY5CZ0tlly8ZDwwIDCbLsBbBPT1q3oxzbenUjmMjMiuHkUCuwC4w8uh5PWETdxP';
- b +=
- 'BMTkqW4qBd05oIo+Zv13fQxdEcvz05lY6VbS1e//QL0mzkapWE6hqRwhYJCFEcNo+dv6iaYcqQl';
- b +=
- '/rbqPTURRrBKUrZ+BcPG7+glmGK+FGkizYcpqdzkzwx88fn3YkNBkbCZP5e88ngxMsGKG1jYrm/';
- b +=
- 'IT5y6cdtSvlU+GtEuN2QN8BpUQKpAKo8BOnn8N1bADblf42iWtrsXaCc2PFk+avOzRatmb605Y9';
- b +=
- 'df5Hdh++wN92Dli6CZpeo0aP5sEymrVUT55fHP9IYSdhrG9orLBdXNtAJ17c584xDhBcjvqe2Pe';
- b +=
- 'EOsP9U+bJyDscLpZlSRsVjMsaIIJkmvinTn/J0+ZvNUFsaEcfrjxllFJb5Hwozu7I03vub9g8oF';
- b +=
- 'HcLSZEZATiY6MEK+QcM8+Yv8OYJ1jdXFvpyr10quvX1tAEwP+X70JtspZmWwpzhXjm/D0OdK2UW';
- b +=
- 'Rt7MHekZIokE6j2DMwIB9R0/RlfHc+av2TCdytlFJ3J78TELlzd6n2G7HVOTEhAzVwaT5+9z4Xw';
- b +=
- 'nHk6+volV316cH6JZ5stLMOo83Mnr1ealIvgMWkGOigpeR5Y+hp6qsN0QoEGBQdeA1YLpZLE549';
- b +=
- '54sO5VJeAj3OcEmBELCsC9vwF85eNvmZ0yptZrNr4lUnQGkujMoo9c2vJC8c9RnUwvJQkOFgTg8';
- b +=
- 'oZaHzUL+pSo2HXVEiOkivLZ9YyA4d28O7Zq6RfPJ9GXzljwW0RMSMmG4rzBFAkZ/OSqe1CsooFa';
- b +=
- 'bM0BrO6wkvHjHC4hD92jwDsGrOeqU7AXpM2L5thBINC+oqAqTeR+ZdPPQInnlvA9ZGDn/BKvqLG';
- b +=
- 'EhdBeMY9dck6wEOvHLPGhuq/DfTFKGsMC29zDMajTnN2+VXj1hhQs4pv8qSVEgmVlqWQr55nI6+';
- b +=
- 'pVnNJXkNrBGQRPlzK1r2mxo0MlzRpbqIhKTASXjv7lsbmj8wUXQilwA69bsxsd7aSBbiHrXIcsn';
- b +=
- 'wgo6+f0u4ZhcqBPFAVEkvMv2Fau6mAl2tNQo7wH8XfOH/B6BnDTIqRHB3MIbVS42GQkda4N80+j';
- b +=
- '7D+BJGYFxEB20Tz5vnl8Q81KCY6kGxztFI4GFrpUj6ARk2WIEz0Lmkb3jJ/85H3uslNi21hyuYo';
- b +=
- '8CBVClgwb62zMrXwxCUAo5lhky3ytim/k6PYTUYlwPLBAl56+/zaGMs/VOEhrK0vY6D7WPnvMFH';
- b +=
- '90se6OzE+Es9QAMhxbFVE3jHlE5PociSUM5nApzN+g19fe+21N/gPwAKxyntj8y/mV9zqiW0A2o';
- b +=
- 'calwPpu8Ffdghiimf703NNJILhr+k5mp9Dzl5dPrG0tXL6xjchWhmjYdXemBHGzybmbKpv2rrar';
- b +=
- 'cCvt8g51J5D/hLjUmd34lLwd+wcI27wArz5DYFWot5/TiW8vfkXN7shrB6MuJ19oqiGbt5sHoPf';
- b += 'Z6drtv4/pNVxPg==';
-
- var input = pako.inflate(base64ToUint8Array(b));
- return init(input);
-}
diff --git a/packages/ecdsa-sdk/tsconfig.json b/packages/ecdsa-sdk/tsconfig.json
deleted file mode 100644
index f5b85657a8..0000000000
--- a/packages/ecdsa-sdk/tsconfig.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
- "extends": "../../tsconfig.base.json",
- "compilerOptions": {
- "module": "commonjs",
- "forceConsistentCasingInFileNames": true,
- "strict": true,
- "noImplicitOverride": true,
- "noPropertyAccessFromIndexSignature": true,
- "noImplicitReturns": true,
- "noFallthroughCasesInSwitch": true
- },
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- },
- {
- "path": "./tsconfig.spec.json"
- }
- ]
-}
diff --git a/packages/ecdsa-sdk/tsconfig.lib.json b/packages/ecdsa-sdk/tsconfig.lib.json
deleted file mode 100644
index 89653783eb..0000000000
--- a/packages/ecdsa-sdk/tsconfig.lib.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "declaration": true,
- "types": []
- },
- "include": ["**/*.ts", "src/lib/ecdsa-sdk.spec.ts"],
- "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
-}
diff --git a/packages/ecdsa-sdk/tsconfig.spec.json b/packages/ecdsa-sdk/tsconfig.spec.json
deleted file mode 100644
index cc0df4c6eb..0000000000
--- a/packages/ecdsa-sdk/tsconfig.spec.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "outDir": "../../dist/out-tsc",
- "module": "commonjs",
- "types": ["jest", "node"]
- },
- "include": [
- "jest.config.ts",
- "**/*.test.ts",
- "**/*.spec.ts",
- "**/*.d.ts",
- "src/lib/ecdsa-sdk.spec.ts"
- ]
-}
diff --git a/packages/encryption/README.md b/packages/encryption/README.md
index 320abcf6c1..82cd8d9b38 100644
--- a/packages/encryption/README.md
+++ b/packages/encryption/README.md
@@ -1,18 +1,9 @@
# Quick Start
-This submodule provides encryption and decryption of contents (string, zip, etc.) respectively using a symmetric key, with the encrypted content returned as a Blob and the symmetric key as a Uint8Array
+This submodule provides encryption and decryption of contents (string, file, etc.) respectively using a symmetric key, with the encrypted content returned as a Blob and the symmetric key as a Uint8Array
### node.js / browser
```
yarn add @lit-protocol/encryption
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/encryption/package.json b/packages/encryption/package.json
index a74ab46523..2dcbc213c0 100644
--- a/packages/encryption/package.json
+++ b/packages/encryption/package.json
@@ -25,7 +25,7 @@
"crypto": false,
"stream": false
},
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/encryption/src/index.ts b/packages/encryption/src/index.ts
index 536bf61c43..23436519e2 100644
--- a/packages/encryption/src/index.ts
+++ b/packages/encryption/src/index.ts
@@ -1,2 +1 @@
export * from './lib/encryption';
-export * from './lib/params-validators';
diff --git a/packages/encryption/src/lib/encryption.spec.ts b/packages/encryption/src/lib/encryption.spec.ts
index 8925c96550..978d752295 100644
--- a/packages/encryption/src/lib/encryption.spec.ts
+++ b/packages/encryption/src/lib/encryption.spec.ts
@@ -1,4 +1,4 @@
-import { isValidBooleanExpression } from './utils';
+import { isValidBooleanExpression } from '@lit-protocol/misc';
import { AccsDefaultParams } from '@lit-protocol/types';
const conditionA: AccsDefaultParams = {
diff --git a/packages/encryption/src/lib/encryption.ts b/packages/encryption/src/lib/encryption.ts
index f591549e02..6d4d7c304a 100644
--- a/packages/encryption/src/lib/encryption.ts
+++ b/packages/encryption/src/lib/encryption.ts
@@ -1,23 +1,12 @@
-// @ts-expect-error jszip types don't resolve. :sad_panda:
-import * as JSZip from 'jszip/dist/jszip.js';
-
-import { EITHER_TYPE, ILitError, LIT_ERROR } from '@lit-protocol/constants';
-import { verifySignature } from '@lit-protocol/crypto';
-import { checkType, isBrowser, log, throwError } from '@lit-protocol/misc';
+import { EITHER_TYPE, InvalidParamType } from '@lit-protocol/constants';
+import { safeParams } from '@lit-protocol/misc';
import {
DecryptRequest,
- DecryptZipFileWithMetadata,
- DecryptZipFileWithMetadataProps,
- EncryptFileAndZipWithMetadataProps,
EncryptFileRequest,
EncryptResponse,
+ EncryptUint8ArrayRequest,
EncryptStringRequest,
- EncryptZipRequest,
- IJWT,
ILitNodeClient,
- MetadataForFile,
- SigningAccessControlConditionJWTPayload,
- VerifyJWTProps,
EncryptToJsonPayload,
EncryptToJsonProps,
DecryptFromJsonProps,
@@ -27,12 +16,11 @@ import {
uint8arrayToString,
} from '@lit-protocol/uint8arrays';
-import { safeParams } from './params-validators';
/**
* Encrypt a string or file using the LIT network public key and serialise all the metadata required to decrypt
* i.e. accessControlConditions, evmContractConditions, solRpcConditions, unifiedAccessControlConditions & chain to JSON
*
- * Useful for encrypting/decrypting data in IPFS or other storage without compressing it in a ZIP file.
+ * Useful for encrypting/decrypting data in IPFS or other storage without compressing it in a file.
*
* @param params { EncryptToJsonProps } - The params required to encrypt either a file or string and serialise it to JSON
*
@@ -60,11 +48,16 @@ export const encryptToJson = async (
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'encryptToJson',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
if (string !== undefined) {
const { ciphertext, dataToEncryptHash } = await encryptString(
@@ -102,7 +95,14 @@ export const encryptToJson = async (
dataType: 'file',
} as EncryptToJsonPayload);
} else {
- throw new Error(`You must provide either 'file' or 'string'.`);
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
+ 'You must provide either "file" or "string"'
+ );
}
};
@@ -116,14 +116,10 @@ export const encryptToJson = async (
* @returns { Promise } - The decrypted `string` or file (as a `Uint8Array`) depending on `dataType` property in the parsed JSON provided
*
*/
-export async function decryptFromJson(
- params: T
+export async function decryptFromJson(
+ params: DecryptFromJsonProps
): Promise<
- T extends { parsedJsonData: { dataType: 'file' } }
- ? ReturnType
- : T extends { parsedJsonData: { dataType: 'string' } }
- ? ReturnType
- : never
+ ReturnType | ReturnType
> {
const { sessionSigs, parsedJsonData, litNodeClient } = params;
@@ -134,13 +130,17 @@ export async function decryptFromJson(
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'decryptFromJson',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
- // FIXME: The return type of this function is inferrable based on the value of `params.dataType`
if (parsedJsonData.dataType === 'string') {
return decryptToString(
{
@@ -172,64 +172,69 @@ export async function decryptFromJson(
litNodeClient
);
} else {
- throw new Error(
- `dataType of ${parsedJsonData.dataType} is not valid. Must be 'string' or 'file'.`
+ throw new InvalidParamType(
+ {
+ info: {
+ dataType: parsedJsonData.dataType,
+ params,
+ },
+ },
+ 'dataType of %s is not valid. Must be "string" or "file".',
+ parsedJsonData.dataType
);
}
}
// ---------- Local Helpers ----------
-/**
- *
- * Encrypt a string. This is used to encrypt any string that is to be locked via the Lit Protocol.
- *
- * @param { EncryptStringRequest } params - The params required to encrypt a string
- * @param params.dataToEncrypt - (optional) The string to encrypt
+/** Encrypt a uint8array. This is used to encrypt any uint8array that is to be locked via the Lit Protocol.
+ * @param { EncryptUint8ArrayRequest } params - The params required to encrypt a uint8array
+ * @param params.dataToEncrypt - (optional) The uint8array to encrypt
* @param params.accessControlConditions - (optional) The access control conditions
* @param params.evmContractConditions - (optional) The EVM contract conditions
* @param params.solRpcConditions - (optional) The Solana RPC conditions
* @param params.unifiedAccessControlConditions - The unified access control conditions
* @param { ILitNodeClient } litNodeClient - The Lit Node Client
*
- * @returns { Promise } - The encrypted string and the hash of the string
+ * @returns { Promise } - The encrypted uint8array and the hash of the data that was encrypted
*/
-export const encryptString = async (
- params: EncryptStringRequest,
+export const encryptUint8Array = async (
+ params: EncryptUint8ArrayRequest,
litNodeClient: ILitNodeClient
): Promise => {
// -- validate
const paramsIsSafe = safeParams({
- functionName: 'encryptString',
+ functionName: 'encryptUint8Array',
params,
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
+ 'Invalid params'
+ );
return litNodeClient.encrypt({
...params,
- dataToEncrypt: uint8arrayFromString(params.dataToEncrypt, 'utf8'),
});
};
/**
- *
- * Decrypt ciphertext into a string that was encrypted with the encryptString function.
+ * Decrypt a cyphertext into a Uint8Array that was encrypted with the encryptUint8Array function.
*
* @param { DecryptRequest } params - The params required to decrypt a string
* @param { ILitNodeClient } litNodeClient - The Lit Node Client
-
- * @returns { Promise } - The decrypted string
+ *
+ * @returns { Promise } - The decrypted `Uint8Array`
*/
-export const decryptToString = async (
+export const decryptToUint8Array = async (
params: DecryptRequest,
litNodeClient: ILitNodeClient
-): Promise => {
+): Promise => {
// -- validate
const paramsIsSafe = safeParams({
functionName: 'decrypt',
@@ -237,128 +242,77 @@ export const decryptToString = async (
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'decryptToUint8Array',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
const { decryptedData } = await litNodeClient.decrypt(params);
- return uint8arrayToString(decryptedData, 'utf8');
+ return decryptedData;
};
/**
*
- * Zip and encrypt a string. This is used to encrypt any string that is to be locked via the Lit Protocol.
+ * Encrypt a string. This is used to encrypt any string that is to be locked via the Lit Protocol.
*
* @param { EncryptStringRequest } params - The params required to encrypt a string
+ * @param params.dataToEncrypt - (optional) The string to encrypt
+ * @param params.accessControlConditions - (optional) The access control conditions
+ * @param params.evmContractConditions - (optional) The EVM contract conditions
+ * @param params.solRpcConditions - (optional) The Solana RPC conditions
+ * @param params.unifiedAccessControlConditions - The unified access control conditions
* @param { ILitNodeClient } litNodeClient - The Lit Node Client
*
* @returns { Promise } - The encrypted string and the hash of the string
*/
-export const zipAndEncryptString = async (
+export const encryptString = async (
params: EncryptStringRequest,
litNodeClient: ILitNodeClient
): Promise => {
// -- validate
const paramsIsSafe = safeParams({
- functionName: 'zipAndEncryptString',
+ functionName: 'encryptString',
params,
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- let zip;
-
- try {
- zip = new JSZip.default();
- } catch (e) {
- zip = new JSZip();
- }
-
- zip.file('string.txt', params.dataToEncrypt);
-
- return encryptZip({ zip, ...params }, litNodeClient);
-};
-
-/**
- *
- * Zip and encrypt multiple files.
- *
- * @param { Array } files - The files to encrypt
- * @param { DecryptRequestBase } paramsBase - The params required to encrypt a file
- * @param { ILitNodeClient } litNodeClient - The Lit Node Client
- *
- * @returns { Promise } - The encrypted file and the hash of the file
-
-*/
-export const zipAndEncryptFiles = async (
- files: File[],
- params: DecryptRequest,
- litNodeClient: ILitNodeClient
-): Promise => {
- // let's zip em
- let zip;
-
- try {
- zip = new JSZip.default();
- } catch (e) {
- zip = new JSZip();
- }
-
- // -- zip each file
- for (let i = 0; i < files.length; i++) {
- // -- validate
- if (
- !checkType({
- value: files[i],
- allowedTypes: ['File'],
- paramName: `files[${i}]`,
- functionName: 'zipAndEncryptFiles',
- })
- )
- throwError({
- message: 'Invalid file type',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- const folder: JSZip | null = zip.folder('encryptedAssets');
-
- if (!folder) {
- log("Failed to get 'encryptedAssets' from zip.folder() ");
- return throwError({
- message: "Failed to get 'encryptedAssets' from zip.folder() ",
- errorKind: LIT_ERROR.UNKNOWN_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_ERROR.name,
- });
- }
-
- folder.file(files[i].name, files[i]);
- }
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'encryptString',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
- return encryptZip({ zip, ...params }, litNodeClient);
+ return litNodeClient.encrypt({
+ ...params,
+ dataToEncrypt: uint8arrayFromString(params.dataToEncrypt, 'utf8'),
+ });
};
/**
*
- * Decrypt and unzip a zip that was created using encryptZip, zipAndEncryptString, or zipAndEncryptFiles.
+ * Decrypt ciphertext into a string that was encrypted with the encryptString function.
*
* @param { DecryptRequest } params - The params required to decrypt a string
* @param { ILitNodeClient } litNodeClient - The Lit Node Client
- *
- * @returns { Promise<{ [key: string]: JSZip.JSZipObject }>} - The decrypted zip file
+
+ * @returns { Promise } - The decrypted string
*/
-export const decryptToZip = async (
+export const decryptToString = async (
params: DecryptRequest,
litNodeClient: ILitNodeClient
-): Promise> => {
+): Promise => {
// -- validate
const paramsIsSafe = safeParams({
functionName: 'decrypt',
@@ -366,261 +320,25 @@ export const decryptToZip = async (
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'decryptToString',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
const { decryptedData } = await litNodeClient.decrypt(params);
- // unpack the zip
- let zip;
-
- try {
- zip = new JSZip.default();
- } catch (e) {
- zip = new JSZip();
- }
- const unzipped = await zip.loadAsync(decryptedData);
-
- return unzipped.files;
-};
-
-/**
- *
- * Encrypt a zip file created with JSZip.
- *
- * @param { EncryptZipRequest } params - The params required to encrypt a zip
- * @param param.zip - The zip file to encrypt
- * @param { ILitNodeClient } litNodeClient - The Lit Node Client
- *
- * @returns { Promise } - The encrypted zip file and the hash of the zip file
- */
-export const encryptZip = async (
- params: EncryptZipRequest,
- litNodeClient: ILitNodeClient
-): Promise => {
- // -- validate
- const paramsIsSafe = safeParams({
- functionName: 'encryptZip',
- params,
- });
-
- if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- const { zip } = params;
- let zipBlob;
- let zipBlobArrayBuffer: ArrayBuffer;
-
- if (isBrowser()) {
- zipBlob = await zip.generateAsync({ type: 'blob' });
- zipBlobArrayBuffer = await zipBlob.arrayBuffer();
- } else {
- zipBlobArrayBuffer = await zip.generateAsync({ type: 'nodebuffer' });
- }
-
- // to download the encrypted zip file for testing, uncomment this
- // saveAs(encryptedZipBlob, 'encrypted.bin')
- return litNodeClient.encrypt({
- ...params,
- dataToEncrypt: new Uint8Array(zipBlobArrayBuffer),
- });
-};
-
-/**
- *
- * Encrypt a single file and then zip it up with the metadata.
- *
- * @param { EncryptFileAndZipWithMetadataProps } params - The params required to encrypt a file and zip it up with the metadata
- *
- * @returns { Promise } - The encrypted zip file and the hash of the zip file
- *
- */
-export const encryptFileAndZipWithMetadata = async (
- params: EncryptFileAndZipWithMetadataProps
-): Promise => {
- const {
- sessionSigs,
- accessControlConditions,
- evmContractConditions,
- solRpcConditions,
- unifiedAccessControlConditions,
- chain,
- file,
- litNodeClient,
- readme,
- } = params;
-
- // -- validate
- const paramsIsSafe = safeParams({
- functionName: 'encryptFileAndZipWithMetadata',
- params: {
- sessionSigs,
- accessControlConditions,
- evmContractConditions,
- solRpcConditions,
- unifiedAccessControlConditions,
- chain,
- file,
- litNodeClient,
- readme,
- },
- });
-
- if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- // encrypt the file
- const { ciphertext, dataToEncryptHash } = await encryptFile(
- { ...params },
- litNodeClient
- );
-
- // Zip up with metadata
- let zip;
-
- try {
- zip = new JSZip.default();
- } catch (e) {
- zip = new JSZip();
- }
- const metadata: MetadataForFile = {
- name: file.name,
- type: file.type,
- size: file.size,
- accessControlConditions,
- evmContractConditions,
- solRpcConditions,
- unifiedAccessControlConditions,
- chain,
- dataToEncryptHash,
- };
-
- zip.file('lit_protocol_metadata.json', JSON.stringify(metadata));
- if (readme) {
- zip.file('readme.txt', readme);
- }
-
- const folder: JSZip | null = zip.folder('encryptedAssets');
-
- if (!folder) {
- log("Failed to get 'encryptedAssets' from zip.folder() ");
- return throwError({
- message: `Failed to get 'encryptedAssets' from zip.folder()`,
- errorKind: LIT_ERROR.UNKNOWN_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_ERROR.name,
- });
- }
-
- folder.file(file.name, uint8arrayFromString(ciphertext, 'base64'));
-
- let zipBlob;
- if (isBrowser()) {
- zipBlob = await zip.generateAsync({ type: 'blob' });
- } else {
- zipBlob = await zip.generateAsync({ type: 'nodebuffer' });
- }
-
- return zipBlob;
-};
-
-/**
- *
- * Given a zip file with metadata inside it, unzip, load the metadata, and return the decrypted file and the metadata. This zip file would have been created with the encryptFileAndZipWithMetadata function.
- *
- * @param { DecryptZipFileWithMetadataProps } params - The params required to decrypt a zip file with metadata
- *
- * @returns { Promise } A promise containing an object that contains decryptedFile and metadata properties. The decryptedFile is an ArrayBuffer that is ready to use, and metadata is an object that contains all the properties of the file like it's name and size and type.
- */
-export const decryptZipFileWithMetadata = async (
- params: DecryptZipFileWithMetadataProps
-): Promise => {
- const { sessionSigs, file, litNodeClient } = params;
-
- // -- validate
- const paramsIsSafe = safeParams({
- functionName: 'decryptZipFileWithMetadata',
- params: {
- sessionSigs,
- file,
- litNodeClient,
- },
- });
-
- if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- // -- execute
- const zip = await JSZip.loadAsync(file);
-
- const jsonFile: JSZip.JSZipObject | null = zip.file(
- 'lit_protocol_metadata.json'
- );
-
- if (!jsonFile) {
- log(`Failed to read lit_protocol_metadata.json while zip.file()`);
- return;
- }
-
- const metadata: MetadataForFile = JSON.parse(await jsonFile.async('string'));
-
- log('zip metadata', metadata);
-
- const folder: JSZip | null = zip.folder('encryptedAssets');
-
- if (!folder) {
- log("Failed to get 'encryptedAssets' from zip.folder() ");
- return;
- }
-
- const _file: JSZip.JSZipObject | null = folder.file(metadata.name);
-
- if (!_file) {
- log("Failed to get 'metadata.name' while zip.folder().file()");
- return;
- }
-
- const encryptedFile = await _file.async('blob');
-
- const decryptedFile = await decryptToFile(
- {
- ...params,
- accessControlConditions: metadata.accessControlConditions,
- evmContractConditions: metadata.evmContractConditions,
- solRpcConditions: metadata.solRpcConditions,
- unifiedAccessControlConditions: metadata.unifiedAccessControlConditions,
- chain: metadata.chain,
- ciphertext: uint8arrayToString(
- new Uint8Array(await encryptedFile.arrayBuffer()),
- 'base64'
- ),
- dataToEncryptHash: metadata.dataToEncryptHash,
- },
- litNodeClient
- );
-
- const data: DecryptZipFileWithMetadata = { decryptedFile, metadata };
-
- return data;
+ return uint8arrayToString(decryptedData, 'utf8');
};
/**
*
- * Encrypt a file without doing any zipping or packing. This is useful for large files. A 1gb file can be encrypted in only 2 seconds, for example.
+ * Encrypt a file without doing any compression or packing. This is useful for large files. A 1gb file can be encrypted in only 2 seconds, for example.
*
* @param { EncryptFileRequest } params - The params required to encrypt a file
* @param { ILitNodeClient } litNodeClient - The lit node client to use to encrypt the file
@@ -638,11 +356,16 @@ export const encryptFile = async (
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'encryptFile',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
// encrypt the file
const fileAsArrayBuffer = await params.file.arrayBuffer();
@@ -655,7 +378,7 @@ export const encryptFile = async (
/**
*
- * Decrypt a file that was encrypted with the encryptFile function, without doing any unzipping or unpacking. This is useful for large files. A 1gb file can be decrypted in only 1 second, for example.
+ * Decrypt a file that was encrypted with the encryptFile function, without doing any uncompressing or unpacking. This is useful for large files. A 1gb file can be decrypted in only 1 second, for example.
*
* @param { DecryptRequest } params - The params required to decrypt a file
* @param { ILitNodeClient } litNodeClient - The lit node client to use to decrypt the file
@@ -673,82 +396,18 @@ export const decryptToFile = async (
});
if (paramsIsSafe.type === EITHER_TYPE.ERROR)
- return throwError({
- message: `Invalid params: ${(paramsIsSafe.result as ILitError).message}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ function: 'decryptToFile',
+ },
+ cause: paramsIsSafe.result,
+ },
+ 'Invalid params'
+ );
const { decryptedData } = await litNodeClient.decrypt(params);
return decryptedData;
};
-
-declare global {
- // `var` is required for global hackery
- // FIXME: `any` types for wasm are no bueno
- // eslint-disable-next-line no-var, @typescript-eslint/no-explicit-any
- var wasmExports: any;
- // eslint-disable-next-line no-var, @typescript-eslint/no-explicit-any
- var wasmECDSA: any;
- // eslint-disable-next-line no-var, @typescript-eslint/no-explicit-any
- var LitNodeClient: any;
-}
-
-/**
- * // TODO check for expiration
- *
- * Verify a JWT from the LIT network. Use this for auth on your server. For some background, users can specify access control condiitons for various URLs, and then other users can then request a signed JWT proving that their ETH account meets those on-chain conditions using the getSignedToken function. Then, servers can verify that JWT using this function. A successful verification proves that the user meets the access control conditions defined earlier. For example, the on-chain condition could be posession of a specific NFT.
- *
- * @param { VerifyJWTProps } jwt
- *
- * @returns { IJWT } An object with 4 keys: "verified": A boolean that represents whether or not the token verifies successfully. A true result indicates that the token was successfully verified. "header": the JWT header. "payload": the JWT payload which includes the resource being authorized, etc. "signature": A uint8array that represents the raw signature of the JWT.
- */
-export const verifyJwt = ({
- publicKey,
- jwt,
-}: VerifyJWTProps): IJWT => {
- // -- validate
- if (
- !checkType({
- value: jwt,
- allowedTypes: ['String'],
- paramName: 'jwt',
- functionName: 'verifyJwt',
- })
- )
- return throwError({
- message: 'jwt must be a string',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- log('verifyJwt', jwt);
-
- // verify that the wasm was loaded
- if (!globalThis.wasmExports) {
- log('wasmExports is not loaded.');
- }
-
- const jwtParts = jwt.split('.');
- const signature = uint8arrayFromString(jwtParts[2], 'base64url');
-
- const unsignedJwt = `${jwtParts[0]}.${jwtParts[1]}`;
-
- const message = uint8arrayFromString(unsignedJwt);
-
- verifySignature(publicKey, message, signature);
-
- const _jwt: IJWT = {
- verified: true,
- header: JSON.parse(
- uint8arrayToString(uint8arrayFromString(jwtParts[0], 'base64url'))
- ),
- payload: JSON.parse(
- uint8arrayToString(uint8arrayFromString(jwtParts[1], 'base64url'))
- ),
- signature,
- };
-
- return _jwt;
-};
diff --git a/packages/encryption/src/lib/params-validators.ts b/packages/encryption/src/lib/params-validators.ts
deleted file mode 100644
index f3b7887ede..0000000000
--- a/packages/encryption/src/lib/params-validators.ts
+++ /dev/null
@@ -1,578 +0,0 @@
-/**
- * Param Validators is an abstraction of validating params of a function, each validator
- * returns a boolean value indicating whether the validation is passed or not.
- */
-
-import { isHexString } from 'ethers/lib/utils';
-
-import {
- EITHER_TYPE,
- ELeft,
- ERight,
- IEither,
- LIT_ERROR,
-} from '@lit-protocol/constants';
-import {
- checkIfAuthSigRequiresChainParam,
- checkType,
- is,
- log,
-} from '@lit-protocol/misc';
-import {
- AcceptedFileType,
- AccessControlConditions,
- AuthMethod,
- DecryptFromJsonProps,
- DecryptRequest,
- DecryptZipFileWithMetadataProps,
- EncryptFileAndZipWithMetadataProps,
- EncryptFileRequest,
- EncryptRequest,
- EncryptStringRequest,
- EncryptToJsonPayload,
- EncryptToJsonProps,
- EncryptZipRequest,
- EvmContractConditions,
- GetSignedTokenRequest,
- JsonExecutionSdkParams,
- SessionSigsOrAuthSig,
- SolRpcConditions,
- UnifiedAccessControlConditions,
-} from '@lit-protocol/types';
-
-import { isValidBooleanExpression } from './utils';
-
-export const safeParams = ({
- functionName,
- params,
-}: {
- functionName: string;
- params: any[] | any;
-}): IEither => {
- if (!paramsValidators[functionName]) {
- log(`This function ${functionName} is skipping params safe guarding.`);
- return ERight(undefined);
- }
-
- const paramValidators = paramsValidators[functionName](params);
-
- for (const validator of paramValidators) {
- const validationResponse = validator.validate();
- if (validationResponse.type === EITHER_TYPE.ERROR) {
- return validationResponse;
- }
- }
-
- return ERight(undefined);
-};
-
-export const paramsValidators: Record<
- string,
- (params: any) => ParamsValidator[]
-> = {
- // ========== NO AUTH MATERIAL NEEDED FOR CLIENT SIDE ENCRYPTION ==========
- encrypt: (params: EncryptRequest) => [
- new AccessControlConditionsValidator('encrypt', params),
- ],
-
- encryptFile: (params: EncryptFileRequest) => [
- new AccessControlConditionsValidator('encryptFile', params),
- new FileValidator('encryptFile', params.file),
- ],
-
- encryptString: (params: EncryptStringRequest) => [
- new AccessControlConditionsValidator('encryptString', params),
- new StringValidator('encryptString', params.dataToEncrypt, 'dataToEncrypt'),
- ],
-
- encryptZip: (params: EncryptZipRequest) => [
- new AccessControlConditionsValidator('encryptZip', params),
- ],
-
- zipAndEncryptString: (params: EncryptStringRequest) => [
- new StringValidator('zipAndEncryptString', params.dataToEncrypt),
- ],
-
- encryptToJson: (params: EncryptToJsonProps) => [
- new AccessControlConditionsValidator('encryptToJson', params),
- new EncryptToJsonValidator('encryptToJson', params),
- ],
-
- encryptFileAndZipWithMetadata: (
- params: EncryptFileAndZipWithMetadataProps
- ) => [
- new AccessControlConditionsValidator(
- 'encryptFileAndZipWithMetadata',
- params
- ),
- new FileValidator('encryptFileAndZipWithMetadata', params.file),
- new StringValidator(
- 'encryptFileAndZipWithMetadata',
- params.readme,
- 'readme'
- ),
- ],
-
- // ========== REQUIRED AUTH MATERIAL VALIDATORS ==========
- executeJs: (params: JsonExecutionSdkParams) => [
- new AuthMaterialValidator('executeJs', params),
- new ExecuteJsValidator('executeJs', params),
- ],
-
- decrypt: (params: DecryptRequest) => [
- new AccessControlConditionsValidator('decrypt', params),
- new AuthMaterialValidator('decrypt', params, true),
- new StringValidator('decrypt', params.ciphertext, 'ciphertext'),
- ],
-
- decryptZipFileWithMetadata: (params: DecryptZipFileWithMetadataProps) => [
- new AuthMaterialValidator('decryptZipFileWithMetadata', params),
- new FileValidator('decryptZipFileWithMetadata', params.file),
- ],
-
- decryptFromJson: (params: DecryptFromJsonProps) => [
- new AuthMaterialValidator('decryptFromJson', params),
- new DecryptFromJsonValidator('decryptFromJson', params.parsedJsonData),
- ],
-
- getSignedToken: (params: GetSignedTokenRequest) => [
- new AccessControlConditionsValidator('decrypt', params),
- new AuthMaterialValidator('decrypt', params, true),
- ],
-};
-
-export type ParamsValidatorsType = typeof paramsValidators;
-
-//////////////////////// VALIDATORS ////////////////////////
-
-interface ParamsValidator {
- validate: () => IEither;
-}
-
-class EncryptToJsonValidator implements ParamsValidator {
- private fnName: string;
- private params: EncryptToJsonProps;
-
- constructor(fnName: string, params: EncryptToJsonProps) {
- this.fnName = fnName;
- this.params = params;
- }
-
- validate(): IEither {
- const { file, string } = this.params;
-
- if (string === undefined && file === undefined)
- return ELeft({
- message: `Either string or file must be provided`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (string !== undefined && file !== undefined)
- return ELeft({
- message:
- 'Provide only a "string" or "file" to encrypt; you cannot provide both',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- return ERight(undefined);
- }
-}
-
-class DecryptFromJsonValidator implements ParamsValidator {
- private fnName: string;
- private params: EncryptToJsonPayload;
-
- constructor(fnName: string, params: EncryptToJsonPayload) {
- this.fnName = fnName;
- this.params = params;
- }
-
- validate(): IEither {
- const validators = [new StringValidator(this.fnName, this.params.dataType)];
-
- for (const validator of validators) {
- const validationResponse = validator.validate();
- if (validationResponse.type === EITHER_TYPE.ERROR) {
- return validationResponse;
- }
- }
-
- const { dataType } = this.params;
-
- if (dataType !== 'string' && dataType !== 'file')
- return ELeft({
- message: `dataType of ${dataType} is not valid. Must be 'string' or 'file'.`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
-
- return ERight(undefined);
- }
-}
-
-class StringValidator implements ParamsValidator {
- private fnName: string;
- private paramName: string;
- private checkIsHex: boolean;
- private str?: string;
-
- constructor(
- fnName: string,
- str?: string,
- paramName: string = 'string',
- checkIsHex: boolean = false
- ) {
- this.fnName = fnName;
- this.paramName = paramName;
- this.checkIsHex = checkIsHex;
- this.str = str;
- }
-
- validate(): IEither {
- if (!this.str) {
- return ELeft({
- message: 'string is undefined',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
- }
-
- if (
- !checkType({
- value: this.str,
- allowedTypes: ['String'],
- paramName: this.paramName,
- functionName: this.fnName,
- })
- )
- return ELeft({
- message: `${this.paramName} is not a string`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (this.checkIsHex && !isHexString(this.str)) {
- return ELeft({
- message: `${this.paramName} is not a valid hex string`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
- }
-
- return ERight(undefined);
- }
-}
-
-class AuthMethodValidator implements ParamsValidator {
- private fnName: string;
- private authMethods?: AuthMethod[];
-
- constructor(fnName: string, authMethods?: AuthMethod[]) {
- this.fnName = fnName;
- this.authMethods = authMethods;
- }
-
- validate(): IEither {
- const { authMethods } = this;
-
- if (
- authMethods &&
- authMethods.length > 0 &&
- !checkType({
- value: authMethods,
- allowedTypes: ['Array'],
- paramName: 'authMethods',
- functionName: this.fnName,
- })
- )
- return ELeft({
- message: `authMethods is not an array`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- return ERight(undefined);
- }
-}
-
-interface ExecuteJsValidatorProps {
- code?: string;
- ipfsId?: string;
-}
-
-class ExecuteJsValidator implements ParamsValidator {
- private fnName: string;
- private params: ExecuteJsValidatorProps;
-
- constructor(fnName: string, params: ExecuteJsValidatorProps) {
- this.fnName = fnName;
- this.params = params;
- }
-
- validate(): IEither {
- const { code, ipfsId } = this.params;
-
- // -- validate: either 'code' or 'ipfsId' must exists
- if (!code && !ipfsId) {
- return ELeft({
- message: 'You must pass either code or ipfsId',
- errorKind: LIT_ERROR.PARAMS_MISSING_ERROR.kind,
- errorCode: LIT_ERROR.PARAMS_MISSING_ERROR.name,
- });
- }
-
- // -- validate: 'code' and 'ipfsId' can't exists at the same time
- if (code && ipfsId) {
- return ELeft({
- message: "You cannot have both 'code' and 'ipfs' at the same time",
- errorKind: LIT_ERROR.PARAMS_MISSING_ERROR.kind,
- errorCode: LIT_ERROR.PARAMS_MISSING_ERROR.name,
- });
- }
-
- return ERight(undefined);
- }
-}
-
-class FileValidator implements ParamsValidator {
- private fnName: string;
- private file?: AcceptedFileType;
-
- constructor(fnName: string, file?: AcceptedFileType) {
- this.fnName = fnName;
- this.file = file;
- }
-
- validate(): IEither {
- if (!this.file) {
- return ELeft({
- message: 'You must pass file param',
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
- }
-
- if (
- !checkType({
- value: this.file,
- allowedTypes: ['Blob', 'File', 'Uint8Array'],
- paramName: 'file',
- functionName: this.fnName,
- })
- )
- return ELeft({
- message: 'File param is not a valid Blob or File object',
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
-
- return ERight(undefined);
- }
-}
-
-export interface AuthMaterialValidatorProps extends SessionSigsOrAuthSig {
- chain?: string;
-}
-
-class AuthMaterialValidator implements ParamsValidator {
- private fnName: string;
- private authMaterial: AuthMaterialValidatorProps;
- private checkIfAuthSigRequiresChainParam: boolean;
-
- constructor(
- fnName: string,
- params: AuthMaterialValidatorProps,
- checkIfAuthSigRequiresChainParam: boolean = false
- ) {
- this.fnName = fnName;
- this.authMaterial = params;
- this.checkIfAuthSigRequiresChainParam = checkIfAuthSigRequiresChainParam;
- }
-
- validate(): IEither {
- const { authSig, sessionSigs } = this.authMaterial;
-
- if (authSig && !is(authSig, 'Object', 'authSig', this.fnName))
- return ELeft({
- message: 'authSig is not an object',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (this.checkIfAuthSigRequiresChainParam) {
- if (!this.authMaterial.chain)
- return ELeft({
- message: 'You must pass chain param',
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
-
- if (
- authSig &&
- !checkIfAuthSigRequiresChainParam(
- authSig,
- this.authMaterial.chain,
- this.fnName
- )
- )
- return ELeft({
- message: 'authSig is not valid',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
- }
-
- if (sessionSigs && !is(sessionSigs, 'Object', 'sessionSigs', this.fnName))
- return ELeft({
- message: 'sessionSigs is not an object',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (!sessionSigs && !authSig)
- return ELeft({
- message: 'You must pass either authSig or sessionSigs',
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
-
- // -- validate: if sessionSig and authSig exists
- if (sessionSigs && authSig)
- return ELeft({
- message: 'You cannot have both authSig and sessionSigs',
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
-
- return ERight(undefined);
- }
-}
-
-export interface AccessControlConditionsValidatorProps {
- accessControlConditions?: AccessControlConditions;
- evmContractConditions?: EvmContractConditions;
- solRpcConditions?: SolRpcConditions;
- unifiedAccessControlConditions?: UnifiedAccessControlConditions;
-}
-
-class AccessControlConditionsValidator implements ParamsValidator {
- private fnName: string;
- private conditions: AccessControlConditionsValidatorProps;
-
- constructor(fnName: string, params: AccessControlConditionsValidatorProps) {
- this.fnName = fnName;
- this.conditions = params;
- }
-
- validate(): IEither {
- const {
- accessControlConditions,
- evmContractConditions,
- solRpcConditions,
- unifiedAccessControlConditions,
- } = this.conditions;
-
- if (
- accessControlConditions &&
- !is(
- accessControlConditions,
- 'Array',
- 'accessControlConditions',
- this.fnName
- )
- )
- return ELeft({
- message: 'accessControlConditions is not an array',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
- if (
- evmContractConditions &&
- !is(evmContractConditions, 'Array', 'evmContractConditions', this.fnName)
- )
- return ELeft({
- message: 'evmContractConditions is not an array',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (
- solRpcConditions &&
- !is(solRpcConditions, 'Array', 'solRpcConditions', this.fnName)
- )
- return ELeft({
- message: 'solRpcConditions is not an array',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (
- unifiedAccessControlConditions &&
- !is(
- unifiedAccessControlConditions,
- 'Array',
- 'unifiedAccessControlConditions',
- this.fnName
- )
- )
- return ELeft({
- message: 'unifiedAccessControlConditions is not an array',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
-
- if (
- !accessControlConditions &&
- !evmContractConditions &&
- !solRpcConditions &&
- !unifiedAccessControlConditions
- )
- return ELeft({
- message:
- 'You must pass either accessControlConditions, evmContractConditions, solRpcConditions or unifiedAccessControlConditions',
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
-
- if (
- accessControlConditions &&
- !isValidBooleanExpression(accessControlConditions)
- )
- return ELeft({
- message: 'Invalid boolean Access Control Conditions',
- errorKind: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.name,
- });
-
- if (
- evmContractConditions &&
- !isValidBooleanExpression(evmContractConditions)
- )
- return ELeft({
- message: 'Invalid boolean EVM Access Control Conditions',
- errorKind: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.name,
- });
-
- if (solRpcConditions && !isValidBooleanExpression(solRpcConditions))
- return ELeft({
- message: 'Invalid boolean Solana Access Control Conditions',
- errorKind: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.name,
- });
-
- if (
- unifiedAccessControlConditions &&
- !isValidBooleanExpression(unifiedAccessControlConditions)
- )
- return ELeft({
- message: 'Invalid boolean Unified Access Control Conditions',
- errorKind: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_BOOLEAN_EXCEPTION.name,
- });
-
- return ERight(undefined);
- }
-}
diff --git a/packages/lit-auth-client/README.md b/packages/lit-auth-client/README.md
index 7bb655cd9c..989eb9c448 100644
--- a/packages/lit-auth-client/README.md
+++ b/packages/lit-auth-client/README.md
@@ -1,6 +1,6 @@
# lit-auth-client
-`lit-auth-client` makes it easy to manage PKP authentication with Lit Protocol. This library offers convenient methods for social logins, Ethereum wallet sign-ins, and minting and fetching of PKPs linked to auth methods.
+`lit-auth-client` makes it easy to manage PKP authentication with Lit Protocol. This library offers convenient classes for social logins, Ethereum wallet sign-ins, and minting and fetching of PKPs linked to auth methods.
## 📜 API Reference
diff --git a/packages/lit-auth-client/package.json b/packages/lit-auth-client/package.json
index 87a6445126..ae4d4139ca 100644
--- a/packages/lit-auth-client/package.json
+++ b/packages/lit-auth-client/package.json
@@ -1,6 +1,6 @@
{
"name": "@lit-protocol/lit-auth-client",
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"type": "commonjs",
"license": "MIT",
"homepage": "https://github.com/Lit-Protocol/js-sdk",
diff --git a/packages/lit-auth-client/src/index.ts b/packages/lit-auth-client/src/index.ts
index 6eb05863dc..344070a76f 100644
--- a/packages/lit-auth-client/src/index.ts
+++ b/packages/lit-auth-client/src/index.ts
@@ -1,34 +1,29 @@
-import * as _LitAuthClient from './lib/lit-auth-client';
+import AppleProvider from './lib/providers/AppleProvider';
import { BaseProvider } from './lib/providers/BaseProvider';
import DiscordProvider from './lib/providers/DiscordProvider';
import EthWalletProvider from './lib/providers/EthWalletProvider';
import GoogleProvider from './lib/providers/GoogleProvider';
-import AppleProvider from './lib/providers/AppleProvider';
-import WebAuthnProvider from './lib/providers/WebAuthnProvider';
-import { StytchOtpProvider } from './lib/providers/StytchOtpProvider';
-import { isSignInRedirect, getProviderFromUrl } from './lib/utils';
import StytchAuthFactorOtpProvider from './lib/providers/StytchAuthFactorOtp';
-
-declare global {
- var LitAuthClient: any; //eslint-disable-line no-var
-}
-
-const LitAuthClient = _LitAuthClient.LitAuthClient;
-if (!globalThis.LitAuthClient) {
- globalThis.LitAuthClient = LitAuthClient;
-}
-
-export * from './lib/lit-auth-client';
+import { StytchOtpProvider } from './lib/providers/StytchOtpProvider';
+import WebAuthnProvider from './lib/providers/WebAuthnProvider';
+import { LitRelay } from './lib/relay';
+import {
+ isSignInRedirect,
+ getProviderFromUrl,
+ getAuthIdByAuthMethod,
+} from './lib/utils';
export {
+ AppleProvider,
BaseProvider,
DiscordProvider,
EthWalletProvider,
GoogleProvider,
- AppleProvider,
- WebAuthnProvider,
+ LitRelay,
StytchOtpProvider,
StytchAuthFactorOtpProvider,
+ WebAuthnProvider,
isSignInRedirect,
getProviderFromUrl,
+ getAuthIdByAuthMethod,
};
diff --git a/packages/lit-auth-client/src/lib/lit-auth-client.spec.ts b/packages/lit-auth-client/src/lib/lit-auth-client.spec.ts
deleted file mode 100644
index 01ac9a0ce8..0000000000
--- a/packages/lit-auth-client/src/lib/lit-auth-client.spec.ts
+++ /dev/null
@@ -1,383 +0,0 @@
-import { ProviderType } from '@lit-protocol/constants';
-import {
- LitAuthClient,
- GoogleProvider,
- DiscordProvider,
- WebAuthnProvider,
- EthWalletProvider,
- AppleProvider,
- StytchOtpProvider,
- StytchAuthFactorOtpProvider,
-} from '@lit-protocol/lit-auth-client';
-import { StytchOtpAuthenticateOptions } from '@lit-protocol/types';
-import { AuthMethodType } from '@lit-protocol/constants';
-
-const isClass = (v: unknown) => {
- return typeof v === 'function' && /^\s*class\s+/.test(v.toString());
-};
-
-describe('LitAuthClient', () => {
- it('is a class', async () => {
- expect(isClass(LitAuthClient)).toBe(true);
- });
-
- it('should throw an error if no API key or custom relay server is provided', () => {
- expect(() => {
- new LitAuthClient();
- }).toThrow(
- 'An API key is required to use the default Lit Relay server. Please provide either an API key or a custom relay server.'
- );
- });
-
- it('should create a LitAuthClient instance with valid options', () => {
- const validClient = new LitAuthClient({
- litRelayConfig: { relayApiKey: 'test-api-key' },
- });
- expect(validClient).toBeDefined();
- expect(validClient.relay.getUrl()).toBe(
- 'https://relayer-server-staging-cayenne.getlit.dev'
- );
- });
-});
-
-describe('initProvider', () => {
- let client: LitAuthClient;
-
- beforeEach(() => {
- client = new LitAuthClient({
- litRelayConfig: { relayApiKey: 'test-api-key' },
- });
- });
-
- afterEach(() => {
- jest.restoreAllMocks();
- });
-
- it('should return an instance of DiscordProvider', () => {
- const provider = client.initProvider(
- ProviderType.Discord,
- {
- redirectUri: 'http://localhost:3000/redirect',
- }
- );
- expect(provider).toBeInstanceOf(DiscordProvider);
- });
-
- it('should return an instance of GoogleProvider', () => {
- const provider = client.initProvider(ProviderType.Google, {
- redirectUri: 'http://localhost:3000/redirect',
- });
- expect(provider).toBeInstanceOf(GoogleProvider);
- });
-
- it('should return an instance of AppleProvider', () => {
- const provider = client.initProvider(ProviderType.Apple, {
- redirectUri: 'http://localhost:3000/redirect',
- });
- expect(provider).toBeInstanceOf(AppleProvider);
- });
-
- it('should return an instance of EthWalletProvider', () => {
- const provider = client.initProvider(
- ProviderType.EthWallet
- );
- expect(provider).toBeInstanceOf(EthWalletProvider);
- });
-
- it('should return an instance of WebAuthnProvider', () => {
- const provider = client.initProvider(
- ProviderType.WebAuthn
- );
- expect(provider).toBeInstanceOf(WebAuthnProvider);
- });
-
- it('Should create Stytch auth factor', () => {
- const provider = client.initProvider(
- ProviderType.StytchOtp
- );
- expect(provider).toBeInstanceOf(StytchOtpProvider);
- });
- it('Should create stytch auth factor providers email', () => {
- const provider = client.initProvider>(
- ProviderType.StytchEmailFactorOtp
- );
- expect(provider).toBeInstanceOf(StytchAuthFactorOtpProvider);
- });
-
- it('Should Create stytch auth factor providers sms', () => {
- const provider = client.initProvider>(
- ProviderType.StytchSmsFactorOtp
- );
- expect(provider).toBeInstanceOf(StytchAuthFactorOtpProvider);
- });
-
- it('Should Create stytch auth factor providers whats app', () => {
- const provider = client.initProvider<
- StytchAuthFactorOtpProvider<'whatsApp'>
- >(ProviderType.StytchWhatsAppFactorOtp);
- expect(provider).toBeInstanceOf(StytchAuthFactorOtpProvider);
- });
-
- it('Should Create stytch auth factor providers totp', () => {
- const provider = client.initProvider>(
- ProviderType.StytchTotpFactor
- );
- expect(provider).toBeInstanceOf(StytchAuthFactorOtpProvider);
- });
-});
-
-describe('getAuthMethodId', () => {
- let client: LitAuthClient;
- // static tokens from test project
- let accessTokenEmailFactor =
- 'eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3ay10ZXN0LWZiMjhlYmY2LTQ3NTMtNDdkMS1iMGUzLTRhY2NkMWE1MTc1NyIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicHJvamVjdC10ZXN0LWRlNGUyNjkwLTE1MDYtNGNmNS04YmNlLTQ0NTcxZGRhZWJjOSJdLCJleHAiOjE2ODg1Njc0MTQsImh0dHBzOi8vc3R5dGNoLmNvbS9zZXNzaW9uIjp7ImlkIjoic2Vzc2lvbi10ZXN0LTlkZDI3ZGE1LTVjNjQtNDE5NS04NjdlLWIxNGE3MWE5M2MxMSIsInN0YXJ0ZWRfYXQiOiIyMDIzLTA3LTA1VDE0OjI1OjE0WiIsImxhc3RfYWNjZXNzZWRfYXQiOiIyMDIzLTA3LTA1VDE0OjI1OjE0WiIsImV4cGlyZXNfYXQiOiIyMDIzLTA5LTEzVDAxOjA1OjE0WiIsImF0dHJpYnV0ZXMiOnsidXNlcl9hZ2VudCI6IiIsImlwX2FkZHJlc3MiOiIifSwiYXV0aGVudGljYXRpb25fZmFjdG9ycyI6W3sidHlwZSI6Im90cCIsImRlbGl2ZXJ5X21ldGhvZCI6ImVtYWlsIiwibGFzdF9hdXRoZW50aWNhdGVkX2F0IjoiMjAyMy0wNy0wNVQxNDoyNToxNFoiLCJlbWFpbF9mYWN0b3IiOnsiZW1haWxfaWQiOiJlbWFpbC10ZXN0LTAwMzZmM2YzLTQ0MjQtNDg2My1iYWQ3LTFkNGU3NTM1ZDJiMCIsImVtYWlsX2FkZHJlc3MiOiJqb3NoQGxpdHByb3RvY29sLmNvbSJ9fV19LCJpYXQiOjE2ODg1NjcxMTQsImlzcyI6InN0eXRjaC5jb20vcHJvamVjdC10ZXN0LWRlNGUyNjkwLTE1MDYtNGNmNS04YmNlLTQ0NTcxZGRhZWJjOSIsIm5iZiI6MTY4ODU2NzExNCwic3ViIjoidXNlci10ZXN0LTY4MTAzZTAxLTc0NjgtNGFiZi04M2M4LTg4NWRiMmNhMWM2YyJ9.rZgaunT1UV2pmliZ0V7nYqYtyfdGas4eY6Q6RCzEEBc5y1K66lopUbvvkfNsLJUjSc3vw12NlIX3Q47zm0XEP8AahrJ0QWAC4v9gmZKVYbKiL2JppqnaxtNLZV9Zo1KAiqm9gdqRQSD29222RTC59PI52AOZd4iTv4lSBIPG2J9rUkUwaRI23bGLMQ8XVkTSS7wcd1Ls08Q-VDXuwl8vuoJhssBfNfxFigk7cKHwbbM-o1sh3upEzV-WFgvJrTstPUNbHOBvGnqKDZX6A_45M5zBnHrerifz4-ST771tajiuW2lQXWvocyYlRT8_a0XBsW77UhU-YBTvKVpj3jmH4A';
- let accessTokenSmsFactor =
- 'eyJhbGciOiJSUzI1NiIsImtpZCI6Imp3ay10ZXN0LTYyNWViODMxLTAwOWYtNGNiMy05YTk3LWJlNzU3YTMzNjQwZiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsicHJvamVjdC10ZXN0LTI3OTA2MzVkLWJhMzEtNDcwNS1hYWY0LTIxM2JiMGYwNjgxMiJdLCJleHAiOjE2OTgzNTQyMTksImh0dHBzOi8vc3R5dGNoLmNvbS9zZXNzaW9uIjp7ImlkIjoic2Vzc2lvbi10ZXN0LWRhMzliOTBlLTkxMTMtNDQ3NC1hOWEyLWE5NTE3MzdkMGVlNSIsInN0YXJ0ZWRfYXQiOiIyMDIzLTEwLTI2VDIwOjU4OjM4WiIsImxhc3RfYWNjZXNzZWRfYXQiOiIyMDIzLTEwLTI2VDIwOjU4OjM5WiIsImV4cGlyZXNfYXQiOiIyMDIzLTExLTAyVDIwOjU4OjM4WiIsImF0dHJpYnV0ZXMiOnsidXNlcl9hZ2VudCI6IiIsImlwX2FkZHJlc3MiOiIifSwiYXV0aGVudGljYXRpb25fZmFjdG9ycyI6W3sidHlwZSI6Im90cCIsImRlbGl2ZXJ5X21ldGhvZCI6InNtcyIsImxhc3RfYXV0aGVudGljYXRlZF9hdCI6IjIwMjMtMTAtMjZUMjA6NTg6MzhaIiwicGhvbmVfbnVtYmVyX2ZhY3RvciI6eyJwaG9uZV9pZCI6InBob25lLW51bWJlci10ZXN0LWNmYTJjYTFlLTVmNzMtNGM0NS1hOWU2LWNjYWE5MWZkYjE3ZCIsInBob25lX251bWJlciI6IisxMjAxNDA3MjA3MyJ9fV19LCJpYXQiOjE2OTgzNTM5MTksImlzcyI6InN0eXRjaC5jb20vcHJvamVjdC10ZXN0LTI3OTA2MzVkLWJhMzEtNDcwNS1hYWY0LTIxM2JiMGYwNjgxMiIsIm5iZiI6MTY5ODM1MzkxOSwic3ViIjoidXNlci10ZXN0LWFhMGUwZmFhLTFjZTgtNGY4Yy05MGJhLWU2OTZmMWY4OTFlZiJ9.c-TAC_UNHQZgbcUBWYhBMCfctQAaVrL41bWGC3LifgEzFV-AWB9sPG8Ws18X2AdIi2FytAvpluWto4-oIdA5vghXx99pYnn45MuKvbvtixkz7tKXeyVN9BiXiPNWiHMjx_Iw_rPaF-KTLqQi7nCuS_UHcFr5uZrErDuYMdwfXxZPdl1pC0M_7Eh-wIOn_Fyy8bdftT1vqPlFTjxyTIZ2CLoAqizJi8cfPfAaC3dkxA54GT4LJdB9FY5VTkXO9Dc4BNZiL4MDx2jMNtE-RhY2iDDL4KC1yi4MQEdNSTm0KEoAF8_A7uzGkpHtJKjFyB8bZTmcrzqzgq6m732_nhMUbw';
- beforeEach(() => {
- client = new LitAuthClient({
- litRelayConfig: { relayApiKey: 'test-api-key' },
- });
- });
-
- it('should get auth method for stytch email factor', async () => {
- let provider = client.initProvider(ProviderType.StytchEmailFactorOtp);
- let id = await provider.getAuthMethodId({
- authMethodType: AuthMethodType.StytchEmailFactorOtp,
- accessToken: accessTokenEmailFactor,
- });
-
- expect(id).toBeDefined();
- });
-
- it('should get auth method for stytch sms factor', async () => {
- let provider = client.initProvider(ProviderType.StytchSmsFactorOtp);
- let id = await provider.getAuthMethodId({
- authMethodType: AuthMethodType.StytchSmsFactorOtp,
- accessToken: accessTokenSmsFactor,
- });
-
- expect(id).toBeDefined();
- });
- it('should get auth method id for stytch auth method helper', async () => {
- let id = StytchAuthFactorOtpProvider.authMethodId({
- authMethodType: AuthMethodType.StytchEmailFactorOtp,
- accessToken: accessTokenEmailFactor,
- });
-
- expect(id).toBeDefined();
-
- id = StytchAuthFactorOtpProvider.authMethodId({
- authMethodType: AuthMethodType.StytchSmsFactorOtp,
- accessToken: accessTokenSmsFactor,
- });
-
- expect(id).toBeDefined();
- });
-});
-
-describe('getProvider', () => {
- let client: LitAuthClient;
-
- beforeEach(() => {
- client = new LitAuthClient({
- litRelayConfig: { relayApiKey: 'test-api-key' },
- });
- });
-
- afterEach(() => {
- jest.restoreAllMocks();
- });
-
- it('should return the correct provider for the given provider type', () => {
- client.initProvider(ProviderType.Discord, {
- redirectUri: 'http://localhost:3000/redirect',
- });
- const savedProvider = client.getProvider(ProviderType.Discord);
- expect(savedProvider).toBeInstanceOf(DiscordProvider);
- });
-
- it('should return undefined if the provider for the given provider type is not initialized', () => {
- const savedProvider = client.getProvider(ProviderType.Google);
- expect(savedProvider).toBeUndefined();
- });
-});
-
-// describe('StytchOtpProvider', () => {
-// let client: LitAuthClient;
-// let provider: StytchOtpProvider;
-
-// beforeEach(() => {
-// client = new LitAuthClient({
-// litRelayConfig: { relayApiKey: 'test-api-key' },
-// });
-
-// provider = client.initProvider(ProviderType.StytchOtp, {
-// appId: LITCONFIG.STYTCH_APP_ID,
-// userId: LITCONFIG.STYTCH_USER_ID,
-// });
-// });
-
-// it('should parse jwt and resolve session', async () => {
-// const token: string = LITCONFIG.STYTCH_TEST_TOKEN;
-// const userId: string = LITCONFIG.STYTCH_USER_ID;
-// const authMethod = await provider.authenticate({
-// accessToken: token,
-// userId: userId,
-// });
-// expect(authMethod).toBeDefined();
-
-// expect(authMethod.accessToken).toEqual(token);
-// });
-// });
-
-// describe('GoogleProvider', () => {
-// let client: LitAuthClient;
-// let provider: GoogleProvider;
-
-// beforeEach(() => {
-// client = new LitAuthClient({
-// litRelayConfig: { relayApiKey: 'test-api-key' },
-// });
-// provider = client.initProvider(ProviderType.Google, {
-// redirectUri: 'http://localhost:3000/redirect',
-// });
-
-// // @ts-ignore
-// delete window.location;
-// window.location = {
-// ...window.location,
-// assign: jest.fn(),
-// };
-// window.location.href = 'http://localhost:3000/redirect';
-// });
-
-// afterEach(() => {
-// jest.restoreAllMocks();
-// });
-
-// it('should generate a valid URL with the given provider, redirect uri, and state parameter', () => {
-// const mockAssign = jest.fn();
-// Object.defineProperty(window, 'location', {
-// value: { assign: mockAssign },
-// writable: true,
-// });
-
-// provider.signIn();
-
-// expect(mockAssign).toHaveBeenCalled();
-// const assignedUrl = mockAssign.mock.calls[0][0];
-// expect(assignedUrl).toContain('google');
-
-// const searchParams = new URLSearchParams(new URL(assignedUrl).search);
-// const redirectUri = searchParams.get('app_redirect');
-// expect(redirectUri).toBe(provider.redirectUri);
-
-// const state = searchParams.get('state');
-// expect(state).not.toBeNull();
-// });
-
-// it('should throw an error if the current URL does not match the provided redirect URL', async () => {
-// const wrongUrl = 'http://localhost:4444/incorrect';
-// window.location.href = wrongUrl;
-// await expect(provider.authenticate()).rejects.toThrowError(
-// `Current url "${wrongUrl}" does not match provided redirect uri "${provider.redirectUri}"`
-// );
-// });
-
-// it('should throw an error if there is an error in the URL parameters', async () => {
-// window.location.search = '?error=token_error';
-// await expect(provider.authenticate()).rejects.toThrowError();
-// });
-
-// it('should throw an error if the provider is not Google', async () => {
-// const invalidProvider = 'discord';
-// window.location.search = `?provider=${invalidProvider}&state=...`;
-// await expect(provider.authenticate()).rejects.toThrowError(
-// `OAuth provider "${invalidProvider}" passed in redirect callback URL does not match "google"`
-// );
-// });
-
-// it('should throw an error if the state parameter is invalid', async () => {
-// const invalidState = 'yolo';
-// window.location.search = `?provider=google&access_token=testToken&state=${invalidState}`;
-// await expect(provider.authenticate()).rejects.toThrowError(
-// `Invalid state parameter "${invalidState}" passed in redirect callback URL`
-// );
-// });
-
-// describe('set state param', () => {
-// let state: string;
-
-// beforeEach(async () => {
-// await setStateParam();
-// // @ts-ignore
-// state = getStateParam();
-// });
-
-// afterEach(() => {
-// removeStateParam();
-// });
-
-// it('should throw an error if the ID token is missing for Google OAuth', async () => {
-// window.location.search = `?provider=google&state=${encode(state)}`;
-// await expect(provider.authenticate()).rejects.toThrowError(
-// 'Missing ID token in redirect callback URL for Google OAuth"'
-// );
-// });
-
-// it('should return the correct AuthMethod object for Google OAuth', async () => {
-// const idToken = 'testxyz10';
-// window.location.search = `?provider=google&id_token=${idToken}&state=${encode(
-// state
-// )}`;
-// const result = await provider.authenticate();
-// expect(result).toEqual({
-// authMethodType: AuthMethodType.GoogleJwt,
-// accessToken: idToken,
-// });
-// });
-// });
-// });
-
-// describe('LitAuthClient utility functions', () => {
-// afterEach(() => {
-// sessionStorage.clear();
-// });
-
-// test('should return true for supported social login providers', () => {
-// expect(isSocialLoginSupported('google')).toBe(true);
-// expect(isSocialLoginSupported('discord')).toBe(true);
-// expect(isSocialLoginSupported('unsupported')).toBe(false);
-// });
-
-// test('should generate a login URL with the specified provider and redirect URI', async () => {
-// const redirectUri = 'http://localhost:3000/redirect';
-// const url = await prepareLoginUrl('google', redirectUri);
-// const parsedUrl = new URL(url);
-
-// expect(parsedUrl.origin).toBe('https://login.litgateway.com');
-// expect(parsedUrl.pathname).toBe('/auth/google');
-
-// const searchParams = parsedUrl.searchParams;
-// expect(searchParams.get('app_redirect')).toBe(redirectUri);
-// expect(searchParams.has('state')).toBe(true);
-// });
-
-// test('should parse parameters from a query string', () => {
-// const search =
-// '?provider=google&access_token=abc&id_token=xyz&state=a1b2c3&error=fake_error';
-// const params = parseLoginParams(search);
-// expect(params).toEqual({
-// provider: 'google',
-// accessToken: 'abc',
-// idToken: 'xyz',
-// state: 'a1b2c3',
-// error: 'fake_error',
-// });
-// });
-
-// test('should retrieve OAuth 2.0 state param from session storage', async () => {
-// await setStateParam();
-// expect(getStateParam()).not.toBeNull();
-// });
-// });
diff --git a/packages/lit-auth-client/src/lib/lit-auth-client.ts b/packages/lit-auth-client/src/lib/lit-auth-client.ts
deleted file mode 100644
index 2591d6668e..0000000000
--- a/packages/lit-auth-client/src/lib/lit-auth-client.ts
+++ /dev/null
@@ -1,377 +0,0 @@
-import { ethers } from 'ethers';
-
-import {
- AuthMethodType,
- ProviderType,
- RELAYER_URL_BY_NETWORK,
- RPC_URL_BY_NETWORK,
-} from '@lit-protocol/constants';
-import { LitNodeClient } from '@lit-protocol/lit-node-client';
-import {
- bootstrapLogManager,
- isSupportedLitNetwork,
- log,
-} from '@lit-protocol/misc';
-import {
- AuthMethod,
- EthWalletProviderOptions,
- IRelay,
- LitAuthClientOptions,
- MintRequestBody,
- OAuthProviderOptions,
- ProviderOptions,
- StytchOtpProviderOptions,
- WebAuthnProviderOptions,
-} from '@lit-protocol/types';
-
-import AppleProvider from './providers/AppleProvider';
-import { BaseProvider } from './providers/BaseProvider';
-import DiscordProvider from './providers/DiscordProvider';
-import EthWalletProvider from './providers/EthWalletProvider';
-import GoogleProvider from './providers/GoogleProvider';
-import StytchAuthFactorOtpProvider from './providers/StytchAuthFactorOtp';
-import { StytchOtpProvider } from './providers/StytchOtpProvider';
-import WebAuthnProvider from './providers/WebAuthnProvider';
-import { LitRelay } from './relay';
-
-/**
- * Class that handles authentication through Lit login
- */
-export class LitAuthClient {
- /**
- * The redirect URI that Lit's auth server should send the user back to
- */
- public rpcUrl: string;
- /**
- * Relay server to subsidize minting of PKPs
- */
- public relay: IRelay;
- /**
- * Client to connect to Lit nodes
- */
- public litNodeClient: LitNodeClient;
- /**
- * Map of providers
- */
- private providers: Map;
-
- /**
- * Configures logging
- */
- private debug: boolean;
-
- /**
- * Create a LitAuthClient instance
- *
- * @param {LitAuthClientOptions} options
- * @param {string} [options.rpcUrl] - Endpoint to interact with a blockchain network
- * @param {LitRelayConfig} [options.litRelayConfig] - Options for Lit's relay server
- * @param {IRelay} [options.customRelay] - Custom relay server to subsidize minting of PKPs
- * @param {LitNodeClient} [options.litNodeClient] - Client to connect to Lit nodes
- */
- constructor(options?: LitAuthClientOptions) {
- this.providers = new Map();
- bootstrapLogManager('auth-client');
- this.debug = options?.debug ?? false;
-
- // Check if custom relay object is provided
- if (options?.customRelay) {
- this.relay = options?.customRelay;
- }
-
- // Check if Lit node client is provided
- if (options?.litNodeClient) {
- this.litNodeClient = options?.litNodeClient;
- } else {
- this.litNodeClient = new LitNodeClient({
- litNetwork: 'cayenne',
- debug: this.debug ?? false,
- });
- }
-
- // -- choose the correct relayer based on litNodeClient
- // and if litRelayConfig.relayUrl is not set
- if (!options?.litRelayConfig?.relayUrl) {
- if (!options?.litRelayConfig?.relayApiKey) {
- throw new Error(
- '2 An API key is required to use the default Lit Relay server. Please provide either an API key or a custom relay server.'
- );
- }
-
- isSupportedLitNetwork(this.litNodeClient.config.litNetwork);
-
- const url = RELAYER_URL_BY_NETWORK[this.litNodeClient.config.litNetwork];
-
- this.relay = new LitRelay({
- relayUrl: url,
- relayApiKey: options?.litRelayConfig?.relayApiKey,
- });
- } else if (options?.litRelayConfig?.relayUrl) {
- if (!options?.litRelayConfig?.relayApiKey) {
- throw new Error(
- '2 An API key is required to use the default Lit Relay server. Please provide either an API key or a custom relay server.'
- );
- }
- this.relay = new LitRelay(options.litRelayConfig);
- } else {
- if (!options.litRelayConfig.relayApiKey) {
- throw new Error(
- '2 An API key is required to use the default Lit Relay server. Please provide either an API key or a custom relay server.'
- );
- }
- this.relay = new LitRelay(options.litRelayConfig);
- }
-
- // Set RPC URL
- this.rpcUrl =
- options?.rpcUrl ||
- RPC_URL_BY_NETWORK[this.litNodeClient.config.litNetwork];
-
- if (!this.rpcUrl) {
- throw new Error('No RPC URL provided');
- }
-
- log('rpc url: ', this.rpcUrl);
- log('relay config: ', options.litRelayConfig);
- log('relay instance: ', this.relay);
- }
-
- /**
- * Initialize a provider
- *
- * @param {ProviderType} type - Type of provider to initialize
- * @param {ProviderOptions} options - Options for the provider
- *
- * @returns {T} - Provider
- */
- public initProvider(
- type: ProviderType,
- options?: ProviderOptions
- ): T {
- const baseParams = {
- rpcUrl: this.rpcUrl,
- relay: this.relay,
- litNodeClient: this.litNodeClient,
- };
-
- let provider: T;
- log('resolving provider of type: ', type);
- switch (type) {
- case 'google':
- provider = new GoogleProvider({
- ...baseParams,
- ...(options as OAuthProviderOptions),
- }) as unknown as T;
- break;
- case 'apple':
- provider = new AppleProvider({
- ...baseParams,
- ...(options as OAuthProviderOptions),
- }) as unknown as T;
- break;
- case 'discord':
- provider = new DiscordProvider({
- ...baseParams,
- ...(options as OAuthProviderOptions),
- }) as unknown as T;
- break;
- case 'ethwallet':
- provider = new EthWalletProvider({
- ...baseParams,
- ...(options as EthWalletProviderOptions),
- }) as unknown as T;
- break;
- case 'webauthn':
- provider = new WebAuthnProvider({
- ...baseParams,
- ...(options as WebAuthnProviderOptions),
- }) as unknown as T;
- break;
- case 'stytchOtp':
- provider = new StytchOtpProvider(
- {
- ...baseParams,
- },
- options as StytchOtpProviderOptions
- ) as unknown as T;
- break;
- case 'stytchEmailFactorOtp':
- provider = new StytchAuthFactorOtpProvider<'email'>(
- { ...baseParams },
- options as StytchOtpProviderOptions,
- 'email'
- ) as unknown as T;
- break;
- case 'stytchSmsFactorOtp':
- provider = new StytchAuthFactorOtpProvider<'sms'>(
- { ...baseParams },
- options as StytchOtpProviderOptions,
- 'sms'
- ) as unknown as T;
- break;
- case 'stytchWhatsAppFactorOtp':
- provider = new StytchAuthFactorOtpProvider<'whatsApp'>(
- { ...baseParams },
- options as StytchOtpProviderOptions,
- 'whatsApp'
- ) as unknown as T;
- break;
- case 'stytchTotpFactor':
- provider = new StytchAuthFactorOtpProvider<'totp'>(
- { ...baseParams },
- options as StytchOtpProviderOptions,
- 'totp'
- ) as unknown as T;
- break;
- default:
- throw new Error(
- "Invalid provider type provided. Only 'google', 'discord', 'ethereum', and 'webauthn', 'Stytch', and 'StytchFactor' are supported at the moment."
- );
- }
-
- this.providers.set(type, provider);
- return provider;
- }
-
- /**
- * Returns an initialized provider by type
- *
- * @param {ProviderType} type - Type of provider to get
- *
- * @returns {BaseProvider | undefined} - Provider if found, undefined otherwise
- */
- getProvider(type: ProviderType): BaseProvider | undefined {
- return this.providers.get(type);
- }
-
- /**
- * Retrieves the authentication ID based on the provided authentication method.
- *
- * @param {AuthMethod} authMethod - The authentication method
- * @returns {Promise} - The authentication ID
- */
- public static async getAuthIdByAuthMethod(
- authMethod: AuthMethod
- ): Promise {
- let authId;
-
- switch (authMethod.authMethodType) {
- case AuthMethodType.EthWallet:
- authId = await EthWalletProvider.authMethodId(authMethod);
- break;
- case AuthMethodType.Discord:
- authId = await DiscordProvider.authMethodId(authMethod);
- break;
- case AuthMethodType.WebAuthn:
- authId = await WebAuthnProvider.authMethodId(authMethod);
- break;
- case AuthMethodType.GoogleJwt:
- authId = await GoogleProvider.authMethodId(authMethod);
- break;
- case AuthMethodType.StytchOtp:
- authId = await StytchOtpProvider.authMethodId(authMethod);
- break;
- case AuthMethodType.StytchEmailFactorOtp:
- case AuthMethodType.StytchSmsFactorOtp:
- case AuthMethodType.StytchTotpFactorOtp:
- case AuthMethodType.StytchWhatsAppFactorOtp:
- authId = await StytchAuthFactorOtpProvider.authMethodId(authMethod);
- break;
- default:
- log(`unsupported AuthMethodType: ${authMethod.authMethodType}`);
- throw new Error(
- `Unsupported auth method type: ${authMethod.authMethodType}`
- );
- }
-
- return authId;
- }
-
- /**
- * Mints a new pkp with all AuthMethods provided. Allows for permissions and flags to be set seperately.
- * If no permissions are provided then each auth method will be assigned `1` for sign anything
- * If no flags are provided then `sendPkpToitself` will be false, and `addPkpEthAddressAsPermittedAddress` will be true
- * It is then up to the implementor to transfer the pkp nft to the pkp address.
- * **note** When adding permissions, each permission should be added in the same order the auth methods are ordered
- * @throws {Error} - Throws an error if no AuthMethods are given
- * @param {AuthMethod[]} - AuthMethods authentication methods to be added to the pkp
- * @param {{ pkpPermissionScopes?: number[][]; sendPkpToitself?: boolean; addPkpEthAddressAsPermittedAddress?: boolean;}}
- * @returns {Promise<{pkpTokenId?: string; pkpEthAddress?: string; pkpPublicKey?: string}>} pkp information
- */
- public async mintPKPWithAuthMethods(
- authMethods: AuthMethod[],
- options: {
- pkpPermissionScopes?: number[][];
- sendPkpToitself?: boolean;
- addPkpEthAddressAsPermittedAddress?: boolean;
- }
- ): Promise<{
- pkpTokenId?: string;
- pkpEthAddress?: string;
- pkpPublicKey?: string;
- }> {
- if (authMethods.length < 1) {
- throw new Error('Must provide atleast one auth method');
- }
-
- if (
- !options.pkpPermissionScopes ||
- options.pkpPermissionScopes.length < 1
- ) {
- options.pkpPermissionScopes = [];
- for (let i = 0; i < authMethods.length; i++) {
- options.pkpPermissionScopes.push([
- ethers.BigNumber.from('1').toNumber(),
- ]);
- }
- }
-
- const reqBody: MintRequestBody = {
- keyType: 2,
- permittedAuthMethodTypes: authMethods.map((value) => {
- return value.authMethodType;
- }),
- permittedAuthMethodScopes: options.pkpPermissionScopes,
- addPkpEthAddressAsPermittedAddress:
- options.addPkpEthAddressAsPermittedAddress ?? true,
- sendPkpToItself: options.sendPkpToitself ?? false,
- };
-
- const permittedAuthMethodIds = [];
- const permittedAuthMethodPubkeys = [];
- for (const authMethod of authMethods) {
- const id = await LitAuthClient.getAuthIdByAuthMethod(authMethod);
- permittedAuthMethodIds.push(id);
- if (authMethod.authMethodType === AuthMethodType.WebAuthn) {
- permittedAuthMethodPubkeys.push(
- WebAuthnProvider.getPublicKeyFromRegistration(
- JSON.parse(authMethod.accessToken)
- )
- );
- } else {
- // only webauthn has a `authMethodPubkey`
- permittedAuthMethodPubkeys.push('0x');
- }
- }
-
- reqBody.permittedAuthMethodIds = permittedAuthMethodIds;
- reqBody.permittedAuthMethodPubkeys = permittedAuthMethodPubkeys;
-
- const mintRes = await this.relay.mintPKP(JSON.stringify(reqBody));
- if (!mintRes || !mintRes.requestId) {
- throw new Error(
- `Missing mint response or request ID from mint response ${mintRes.error}`
- );
- }
-
- const pollerResult = await this.relay.pollRequestUntilTerminalState(
- mintRes.requestId
- );
-
- return {
- pkpTokenId: pollerResult.pkpTokenId,
- pkpPublicKey: pollerResult.pkpPublicKey,
- pkpEthAddress: pollerResult.pkpEthAddress,
- };
- }
-}
diff --git a/packages/lit-auth-client/src/lib/providers/AppleProvider.ts b/packages/lit-auth-client/src/lib/providers/AppleProvider.ts
index 25a73a5476..3a6ef00e9a 100644
--- a/packages/lit-auth-client/src/lib/providers/AppleProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/AppleProvider.ts
@@ -3,7 +3,11 @@ import {
BaseProviderOptions,
OAuthProviderOptions,
} from '@lit-protocol/types';
-import { AuthMethodType } from '@lit-protocol/constants';
+import {
+ AUTH_METHOD_TYPE,
+ UnauthorizedException,
+ UnknownError,
+} from '@lit-protocol/constants';
import {
prepareLoginUrl,
parseLoginParams,
@@ -45,8 +49,14 @@ export default class AppleProvider extends BaseProvider {
public async authenticate(): Promise {
// Check if current url matches redirect uri
if (!window.location.href.startsWith(this.redirectUri)) {
- throw new Error(
- `Current url "${window.location.href}" does not match provided redirect uri "${this.redirectUri}"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ url: window.location.href,
+ redirectUri: this.redirectUri,
+ },
+ },
+ `Current url does not match provided redirect uri`
);
}
@@ -57,20 +67,40 @@ export default class AppleProvider extends BaseProvider {
// Check if there's an error
if (error) {
- throw new Error(error);
+ throw new UnknownError(
+ {
+ info: {
+ error,
+ },
+ cause: new Error(error),
+ },
+ error ?? 'Received error from discord authentication'
+ );
}
// Check if provider is Apple
if (!provider || provider !== 'apple') {
- throw new Error(
- `OAuth provider "${provider}" passed in redirect callback URL does not match "apple"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ provider,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'OAuth provider does not match "apple"'
);
}
// Check if state param matches
if (!state || decode(decodeURIComponent(state)) !== getStateParam()) {
- throw new Error(
- `Invalid state parameter "${state}" passed in redirect callback URL`
+ throw new UnauthorizedException(
+ {
+ info: {
+ state,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'Invalid state parameter in callback URL'
);
}
@@ -83,13 +113,19 @@ export default class AppleProvider extends BaseProvider {
// Check if id token is present in url
if (!idToken) {
- throw new Error(
- `Missing ID token in redirect callback URL for Apple OAuth"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ idToken,
+ redirectUri: this.redirectUri,
+ },
+ },
+ `Missing ID token in callback URL`
);
}
const authMethod = {
- authMethodType: AuthMethodType.AppleJwt,
+ authMethodType: AUTH_METHOD_TYPE.AppleJwt,
accessToken: idToken,
};
return authMethod;
diff --git a/packages/lit-auth-client/src/lib/providers/BaseProvider.ts b/packages/lit-auth-client/src/lib/providers/BaseProvider.ts
index b31b003a18..b36eb31d13 100644
--- a/packages/lit-auth-client/src/lib/providers/BaseProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/BaseProvider.ts
@@ -1,7 +1,18 @@
-import { ALL_LIT_CHAINS, AuthMethodType } from '@lit-protocol/constants';
+import depd from 'depd';
+import { ethers } from 'ethers';
+
+import {
+ ALL_LIT_CHAINS,
+ AUTH_METHOD_TYPE,
+ AUTH_METHOD_TYPE_VALUES,
+ InvalidArgumentException,
+ LitNodeClientNotReadyError,
+ ParamsMissingError,
+ UnknownError,
+} from '@lit-protocol/constants';
+import { LitContracts } from '@lit-protocol/contracts-sdk';
import { LitNodeClient } from '@lit-protocol/lit-node-client';
import {
- AuthCallback,
AuthCallbackParams,
AuthMethod,
AuthSig,
@@ -15,13 +26,14 @@ import {
IRelayPKP,
IRelayRequestData,
MintRequestBody,
- RelayClaimProcessor,
SessionSigs,
SignSessionKeyResponse,
} from '@lit-protocol/types';
-import { ethers } from 'ethers';
+
import { validateMintRequestBody } from '../validators';
+const deprecated = depd('lit-js-sdk:auth-browser:base-provider');
+
export abstract class BaseProvider {
/**
* Relay server to subsidize minting of PKPs
@@ -79,7 +91,14 @@ export abstract class BaseProvider {
const data = await this.prepareRelayRequestData(authMethod);
if (customArgs && !validateMintRequestBody(customArgs)) {
- throw new Error('Invalid mint request body');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ customArgs,
+ },
+ },
+ 'Invalid mint request body'
+ );
}
const body = this.prepareMintBody(
@@ -88,12 +107,20 @@ export abstract class BaseProvider {
);
const mintRes = await this.relay.mintPKP(body);
if (!mintRes || !mintRes.requestId) {
- throw new Error('Missing mint response or request ID from relay server');
+ throw new UnknownError(
+ {
+ info: {
+ mintRes,
+ },
+ },
+ 'Missing mint response or request ID from relay server'
+ );
}
return mintRes.requestId;
}
/**
+ * @deprecated - Use {@link fetchPKPs} instead
* Fetch PKPs associated with given auth method from relay server
*
* @param {AuthMethod} authMethod - Auth method object
@@ -103,15 +130,113 @@ export abstract class BaseProvider {
public async fetchPKPsThroughRelayer(
authMethod: AuthMethod
): Promise {
+ deprecated('fetchPKPsThroughRelayer is deprecated. Use fetchPKPs instead.');
const data = await this.prepareRelayRequestData(authMethod);
const body = this.prepareFetchBody(data);
const fetchRes = await this.relay.fetchPKPs(body);
if (!fetchRes || !fetchRes.pkps) {
- throw new Error('Missing PKPs in fetch response from relay server');
+ throw new ParamsMissingError(
+ {
+ info: {
+ fetchRes,
+ },
+ },
+ 'Missing PKPs in fetch response from relay server'
+ );
}
return fetchRes.pkps;
}
+ /**
+ * Fetch PKPs associated with given auth method type and id from pkp contract
+ *
+ * @param {AUTH_METHOD_TYPE} authMethodType - Auth method type
+ * @param {string} authMethodId - Auth method id
+ *
+ * @returns {Promise} - Array of PKPs
+ */
+ async getPKPsForAuthMethod({
+ authMethodType,
+ authMethodId,
+ }: {
+ authMethodType: AUTH_METHOD_TYPE_VALUES;
+ authMethodId: string;
+ }): Promise {
+ if (!authMethodType || !authMethodId) {
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethodType,
+ authMethodId,
+ },
+ },
+ 'Auth method type and id are required to fetch PKPs by auth method'
+ );
+ }
+
+ const litContracts = new LitContracts({
+ randomPrivatekey: true,
+ network: this.litNodeClient.config.litNetwork,
+ });
+ try {
+ await litContracts.connect();
+ } catch (err) {
+ throw new UnknownError(
+ {
+ cause: err,
+ },
+ 'Unable to connect to LitContracts'
+ );
+ }
+
+ try {
+ const pkpPermissions = litContracts.pkpPermissionsContract;
+ const tokenIds = await pkpPermissions.read.getTokenIdsForAuthMethod(
+ authMethodType,
+ authMethodId
+ );
+ const pkps: IRelayPKP[] = [];
+ for (const tokenId of tokenIds) {
+ const pubkey = await pkpPermissions.read.getPubkey(tokenId);
+ if (pubkey) {
+ const ethAddress = ethers.utils.computeAddress(pubkey);
+ pkps.push({
+ tokenId: tokenId.toString(),
+ publicKey: pubkey,
+ ethAddress: ethAddress,
+ });
+ }
+ }
+ return pkps;
+ } catch (err) {
+ throw new UnknownError(
+ {
+ cause: err,
+ },
+ 'Unable to get PKPs for auth method'
+ );
+ }
+ }
+
+ /**
+ * Fetch PKPs associated with given auth method from pkp contract
+ *
+ * @param {AuthMethod} authMethod - Auth method object
+ *
+ * @returns {Promise} - Array of PKPs
+ */
+ public async fetchPKPs(authMethod: AuthMethod): Promise {
+ const authMethodId = await this.getAuthMethodId(authMethod);
+ const authMethodType = authMethod.authMethodType as AUTH_METHOD_TYPE_VALUES;
+
+ const pkps = await this.getPKPsForAuthMethod({
+ authMethodType,
+ authMethodId,
+ });
+
+ return pkps;
+ }
+
/**
* Generate session sigs for given auth method and PKP
*
@@ -173,7 +298,7 @@ export abstract class BaseProvider {
}),
};
- if (params.authMethod.authMethodType === AuthMethodType.EthWallet) {
+ if (params.authMethod.authMethodType === AUTH_METHOD_TYPE.EthWallet) {
const authSig = JSON.parse(params.authMethod.accessToken);
response = await nodeClient.signSessionKey({
@@ -212,9 +337,7 @@ export abstract class BaseProvider {
claimRequest: ClaimRequest
): Promise {
if (!this.litNodeClient.ready) {
- await this.litNodeClient.connect().catch((err) => {
- throw err; // throw error up to caller
- });
+ await this.litNodeClient.connect();
}
const res = await this.litNodeClient.claimKeyId(claimRequest);
@@ -240,7 +363,15 @@ export abstract class BaseProvider {
let authMethodId = await this.getAuthMethodId(authMethod);
authMethodId = authMethodId.slice(2);
if (!this.litNodeClient) {
- throw new Error('Lit Node Client is configured');
+ throw new LitNodeClientNotReadyError(
+ {
+ info: {
+ authMethod,
+ method: 'computePublicKeyFromAuthMethod',
+ },
+ },
+ 'Lit Node Client is not configured'
+ );
}
return this.litNodeClient.computeHDPubKey(authMethodId);
};
diff --git a/packages/lit-auth-client/src/lib/providers/DiscordProvider.ts b/packages/lit-auth-client/src/lib/providers/DiscordProvider.ts
index b7aafe0ec7..27911e9e20 100644
--- a/packages/lit-auth-client/src/lib/providers/DiscordProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/DiscordProvider.ts
@@ -3,7 +3,11 @@ import {
BaseProviderOptions,
OAuthProviderOptions,
} from '@lit-protocol/types';
-import { AuthMethodType } from '@lit-protocol/constants';
+import {
+ AUTH_METHOD_TYPE,
+ UnauthorizedException,
+ UnknownError,
+} from '@lit-protocol/constants';
import { BaseProvider } from './BaseProvider';
import {
prepareLoginUrl,
@@ -50,8 +54,14 @@ export default class DiscordProvider extends BaseProvider {
public async authenticate(): Promise {
// Check if current url matches redirect uri
if (!window.location.href.startsWith(this.redirectUri)) {
- throw new Error(
- `Current url "${window.location.href}" does not match provided redirect uri "${this.redirectUri}"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ url: window.location.href,
+ redirectUri: this.redirectUri,
+ },
+ },
+ `Current url does not match provided redirect uri`
);
}
@@ -62,20 +72,40 @@ export default class DiscordProvider extends BaseProvider {
// Check if there's an error
if (error) {
- throw new Error(error);
+ throw new UnknownError(
+ {
+ info: {
+ error,
+ },
+ cause: new Error(error),
+ },
+ error ?? 'Received error from discord authentication'
+ );
}
// Check if provider is Discord
if (!provider || provider !== 'discord') {
- throw new Error(
- `OAuth provider "${provider}" passed in redirect callback URL does not match "discord"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ provider,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'OAuth provider does not match "discord"'
);
}
// Check if state param matches
if (!state || decode(decodeURIComponent(state)) !== getStateParam()) {
- throw new Error(
- `Invalid state parameter "${state}" passed in redirect callback URL`
+ throw new UnauthorizedException(
+ {
+ info: {
+ state,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'Invalid state parameter in callback URL'
);
}
@@ -88,13 +118,19 @@ export default class DiscordProvider extends BaseProvider {
// Check if access token is present in url
if (!accessToken) {
- throw new Error(
- `Missing access token in redirect callback URL for Discord OAuth"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ accessToken,
+ redirectUri: this.redirectUri,
+ },
+ },
+ `Missing access token in callback URL`
);
}
const authMethod = {
- authMethodType: AuthMethodType.Discord,
+ authMethodType: AUTH_METHOD_TYPE.Discord,
accessToken: accessToken,
};
return authMethod;
@@ -119,7 +155,7 @@ export default class DiscordProvider extends BaseProvider {
);
if (!popup) {
- throw new Error('Failed to open popup window');
+ throw new UnknownError({}, 'Failed to open popup window');
}
return new Promise((resolve, reject) => {
@@ -147,7 +183,7 @@ export default class DiscordProvider extends BaseProvider {
clearInterval(interval);
popup.close();
resolve({
- authMethodType: AuthMethodType.Discord,
+ authMethodType: AUTH_METHOD_TYPE.Discord,
accessToken: token,
});
}
@@ -189,7 +225,7 @@ export default class DiscordProvider extends BaseProvider {
const user = await meResponse.json();
userId = user.id;
} else {
- throw new Error('Unable to verify Discord account');
+ throw new UnknownError({}, 'Unable to verify Discord account');
}
// -- get auth method id
@@ -218,7 +254,7 @@ export default class DiscordProvider extends BaseProvider {
const user = await meResponse.json();
return user.id;
} else {
- throw new Error('Unable to verify Discord account');
+ throw new UnknownError({}, 'Unable to verify Discord account');
}
}
}
diff --git a/packages/lit-auth-client/src/lib/providers/EthWalletProvider.ts b/packages/lit-auth-client/src/lib/providers/EthWalletProvider.ts
index 32f4034441..c05b120c5c 100644
--- a/packages/lit-auth-client/src/lib/providers/EthWalletProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/EthWalletProvider.ts
@@ -1,7 +1,12 @@
import { ethers } from 'ethers';
import { SiweMessage } from 'siwe';
-import { LIT_CHAINS, AuthMethodType } from '@lit-protocol/constants';
+import {
+ LIT_CHAINS,
+ AUTH_METHOD_TYPE,
+ InvalidArgumentException,
+ WrongParamFormat,
+} from '@lit-protocol/constants';
import {
LitNodeClient,
checkAndSignAuthMessage,
@@ -17,6 +22,11 @@ import {
import { BaseProvider } from './BaseProvider';
+interface DomainAndOrigin {
+ domain?: string;
+ origin?: string;
+}
+
export default class EthWalletProvider extends BaseProvider {
/**
* The domain from which the signing request is made
@@ -30,16 +40,24 @@ export default class EthWalletProvider extends BaseProvider {
constructor(options: EthWalletProviderOptions & BaseProviderOptions) {
super(options);
+ const { domain, origin } = EthWalletProvider.getDomainAndOrigin(options);
+ this.domain = domain;
+ this.origin = origin;
+ }
+
+ private static getDomainAndOrigin(options: DomainAndOrigin) {
+ let domain, origin;
try {
- this.domain = options.domain || window.location.hostname;
- this.origin = options.origin || window.location.origin;
+ domain = options.domain || window.location.hostname;
+ origin = options.origin || window.location.origin;
} catch (e) {
log(
'⚠️ Error getting "domain" and "origin" from window object, defaulting to "localhost" and "http://localhost"'
);
- this.domain = options.domain || 'localhost';
- this.origin = options.origin || 'http://localhost';
+ domain = options.domain || 'localhost';
+ origin = options.origin || 'http://localhost';
}
+ return { domain, origin };
}
/**
@@ -47,7 +65,6 @@ export default class EthWalletProvider extends BaseProvider {
*
* @param {EthWalletAuthenticateOptions} options
* @param {string} [options.address] - Address to sign with
- * @param {function} [options.signMessage] - Function to sign message with
* @param {string} [options.chain] - Name of chain to use for signature
* @param {number} [options.expiration] - When the auth signature expires
*
@@ -57,17 +74,22 @@ export default class EthWalletProvider extends BaseProvider {
options?: EthWalletAuthenticateOptions
): Promise {
if (!options) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ options,
+ },
+ },
'Options are required to authenticate with EthWalletProvider.'
);
}
return EthWalletProvider.authenticate({
signer: options,
- address: options?.address,
- chain: options?.chain,
+ address: options.address,
+ chain: options.chain,
litNodeClient: this.litNodeClient,
- expiration: options?.expiration,
+ expiration: options.expiration,
domain: this.domain,
origin: this.origin,
});
@@ -77,10 +99,13 @@ export default class EthWalletProvider extends BaseProvider {
* Generate a wallet signature to use as an auth method
*
* @param {EthWalletAuthenticateOptions} options
+ * @param {object} options.signer - Signer object
+ * @param {object} options.litNodeClient - LitNodeClient instance
* @param {string} [options.address] - Address to sign with
- * @param {function} [options.signMessage] - Function to sign message with
* @param {string} [options.chain] - Name of chain to use for signature
* @param {number} [options.expiration] - When the auth signature expires
+ * @param {string} [options.domain] - Domain from which the signing request is made
+ * @param {string} [options.origin] - Origin from which the signing request is made
* @returns {Promise} - Auth method object containing the auth signature
* @static
* @memberof EthWalletProvider
@@ -121,7 +146,13 @@ export default class EthWalletProvider extends BaseProvider {
(signer as ethers.Wallet)?.address;
if (!address) {
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ address,
+ signer,
+ },
+ },
`Address is required to authenticate with EthWalletProvider. Cannot find it in signer or options.`
);
}
@@ -137,10 +168,13 @@ export default class EthWalletProvider extends BaseProvider {
expiration =
expiration || new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString();
+ const { domain: resolvedDomain, origin: resolvedOrigin } =
+ EthWalletProvider.getDomainAndOrigin({ domain, origin });
+
// Prepare Sign in with Ethereum message
const preparedMessage: Partial = {
- domain: domain || 'localhost',
- uri: origin || 'http://localhost',
+ domain: resolvedDomain,
+ uri: resolvedOrigin,
address,
version: '1',
chainId,
@@ -168,7 +202,7 @@ export default class EthWalletProvider extends BaseProvider {
}
const authMethod = {
- authMethodType: AuthMethodType.EthWallet,
+ authMethodType: AUTH_METHOD_TYPE.EthWallet,
accessToken: JSON.stringify(authSig),
};
return authMethod;
@@ -192,8 +226,14 @@ export default class EthWalletProvider extends BaseProvider {
try {
address = JSON.parse(authMethod.accessToken).address;
} catch (err) {
- throw new Error(
- `Error when parsing auth method to generate auth method ID for Eth wallet: ${err}`
+ throw new WrongParamFormat(
+ {
+ info: {
+ authMethod,
+ },
+ cause: err,
+ },
+ 'Error when parsing auth method to generate auth method ID for Eth wallet'
);
}
diff --git a/packages/lit-auth-client/src/lib/providers/GoogleProvider.ts b/packages/lit-auth-client/src/lib/providers/GoogleProvider.ts
index 2ab7b9ae21..31e9afe423 100644
--- a/packages/lit-auth-client/src/lib/providers/GoogleProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/GoogleProvider.ts
@@ -4,7 +4,11 @@ import {
BaseProviderOptions,
OAuthProviderOptions,
} from '@lit-protocol/types';
-import { AuthMethodType } from '@lit-protocol/constants';
+import {
+ AUTH_METHOD_TYPE,
+ UnauthorizedException,
+ UnknownError,
+} from '@lit-protocol/constants';
import {
prepareLoginUrl,
parseLoginParams,
@@ -60,8 +64,14 @@ export default class GoogleProvider extends BaseProvider {
: window.location.href.startsWith(this.redirectUri);
if (!isUrlValid) {
- throw new Error(
- `Current url "${window.location.href}" does not match provided redirect uri "${this.redirectUri}"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ url: window.location.href,
+ redirectUri: this.redirectUri,
+ },
+ },
+ `Current url does not match provided redirect uri`
);
}
@@ -72,20 +82,40 @@ export default class GoogleProvider extends BaseProvider {
// Check if there's an error
if (error) {
- throw new Error(error);
+ throw new UnknownError(
+ {
+ info: {
+ error,
+ },
+ cause: new Error(error),
+ },
+ error ?? 'Received error from discord authentication'
+ );
}
// Check if provider is Google
if (!provider || provider !== 'google') {
- throw new Error(
- `OAuth provider "${provider}" passed in redirect callback URL does not match "google"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ provider,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'OAuth provider does not match "google"'
);
}
// Check if state param matches
if (!state || decode(decodeURIComponent(state)) !== getStateParam()) {
- throw new Error(
- `Invalid state parameter "${state}" passed in redirect callback URL`
+ throw new UnauthorizedException(
+ {
+ info: {
+ state,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'Invalid state parameter in callback URL'
);
}
@@ -98,13 +128,19 @@ export default class GoogleProvider extends BaseProvider {
// Check if id token is present in url
if (!idToken) {
- throw new Error(
- `Missing ID token in redirect callback URL for Google OAuth"`
+ throw new UnauthorizedException(
+ {
+ info: {
+ idToken,
+ redirectUri: this.redirectUri,
+ },
+ },
+ 'Missing ID token in callback URL'
);
}
const authMethod = {
- authMethodType: AuthMethodType.GoogleJwt,
+ authMethodType: AUTH_METHOD_TYPE.GoogleJwt,
accessToken: idToken,
};
return authMethod;
@@ -129,7 +165,7 @@ export default class GoogleProvider extends BaseProvider {
);
if (!popup) {
- throw new Error('Failed to open popup window');
+ throw new UnknownError({}, 'Failed to open popup window');
}
return new Promise((resolve, reject) => {
@@ -157,7 +193,7 @@ export default class GoogleProvider extends BaseProvider {
clearInterval(interval);
popup.close();
resolve({
- authMethodType: AuthMethodType.GoogleJwt,
+ authMethodType: AUTH_METHOD_TYPE.GoogleJwt,
accessToken: token,
});
}
diff --git a/packages/lit-auth-client/src/lib/providers/StytchAuthFactorOtp.ts b/packages/lit-auth-client/src/lib/providers/StytchAuthFactorOtp.ts
index 85a606b46c..4056d6ef55 100644
--- a/packages/lit-auth-client/src/lib/providers/StytchAuthFactorOtp.ts
+++ b/packages/lit-auth-client/src/lib/providers/StytchAuthFactorOtp.ts
@@ -1,4 +1,9 @@
-import { AuthMethodType } from '@lit-protocol/constants';
+import {
+ AUTH_METHOD_TYPE,
+ AUTH_METHOD_TYPE_VALUES,
+ InvalidArgumentException,
+ WrongParamFormat,
+} from '@lit-protocol/constants';
import { BaseProvider } from './BaseProvider';
import {
BaseAuthenticateOptions,
@@ -110,20 +115,27 @@ export default class StytchAuthFactorOtpProvider<
StytchAuthFactorOtpProvider._parseJWT(accessToken);
let factor: FactorParser = 'email';
switch (authMethod.authMethodType) {
- case AuthMethodType.StytchEmailFactorOtp:
+ case AUTH_METHOD_TYPE.StytchEmailFactorOtp:
factor = 'email';
break;
- case AuthMethodType.StytchSmsFactorOtp:
+ case AUTH_METHOD_TYPE.StytchSmsFactorOtp:
factor = 'sms';
break;
- case AuthMethodType.StytchWhatsAppFactorOtp:
+ case AUTH_METHOD_TYPE.StytchWhatsAppFactorOtp:
factor = 'whatsApp';
break;
- case AuthMethodType.StytchTotpFactorOtp:
+ case AUTH_METHOD_TYPE.StytchTotpFactorOtp:
factor = 'totp';
break;
default:
- throw new Error('Unsupport stytch auth type');
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethodType: authMethod.authMethodType,
+ },
+ },
+ 'Unsupport stytch auth type'
+ );
}
const factorParser = this._resolveAuthFactor(factor).parser;
try {
@@ -136,28 +148,28 @@ export default class StytchAuthFactorOtpProvider<
private static _resolveAuthFactor(factor: FactorParser): {
parser: Function;
- authMethodType: AuthMethodType;
+ authMethodType: AUTH_METHOD_TYPE_VALUES;
} {
switch (factor) {
case 'email':
return {
parser: emailOtpAuthFactorParser,
- authMethodType: AuthMethodType.StytchEmailFactorOtp,
+ authMethodType: AUTH_METHOD_TYPE.StytchEmailFactorOtp,
};
case 'sms':
return {
parser: smsOtpAuthFactorParser,
- authMethodType: AuthMethodType.StytchSmsFactorOtp,
+ authMethodType: AUTH_METHOD_TYPE.StytchSmsFactorOtp,
};
case 'whatsApp':
return {
parser: whatsAppOtpAuthFactorParser,
- authMethodType: AuthMethodType.StytchWhatsAppFactorOtp,
+ authMethodType: AUTH_METHOD_TYPE.StytchWhatsAppFactorOtp,
};
case 'totp':
return {
parser: totpAuthFactorParser,
- authMethodType: AuthMethodType.StytchTotpFactorOtp,
+ authMethodType: AUTH_METHOD_TYPE.StytchTotpFactorOtp,
};
}
}
@@ -170,7 +182,14 @@ export default class StytchAuthFactorOtpProvider<
private static _parseJWT(jwt: string): StytchToken {
const parts = jwt.split('.');
if (parts.length !== 3) {
- throw new Error('Invalid token length');
+ throw new WrongParamFormat(
+ {
+ info: {
+ jwt,
+ },
+ },
+ 'Invalid token length'
+ );
}
const body = Buffer.from(parts[1], 'base64');
const parsedBody: StytchToken = JSON.parse(body.toString('ascii'));
diff --git a/packages/lit-auth-client/src/lib/providers/StytchAuthFactors.ts b/packages/lit-auth-client/src/lib/providers/StytchAuthFactors.ts
index 7c8691b510..f734ce4f2d 100644
--- a/packages/lit-auth-client/src/lib/providers/StytchAuthFactors.ts
+++ b/packages/lit-auth-client/src/lib/providers/StytchAuthFactors.ts
@@ -1,3 +1,4 @@
+import { WrongParamFormat } from '@lit-protocol/constants';
import { StytchToken } from '@lit-protocol/types';
import { ethers } from 'ethers';
@@ -14,11 +15,25 @@ export const emailOtpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -44,11 +59,25 @@ export const smsOtpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -74,11 +103,25 @@ export const whatsAppOtpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
@@ -104,11 +147,25 @@ export const totpAuthFactorParser = (
});
if (!authFactor) {
- throw new Error('Could not find email authentication info in session');
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
+ 'Could not find email authentication info in session'
+ );
}
const audience = (parsedToken['aud'] as string[])[0];
if (!audience) {
- throw new Error(
+ throw new WrongParamFormat(
+ {
+ info: {
+ parsedToken,
+ provider,
+ },
+ },
'Token does not contain an audience (project identifier), aborting'
);
}
diff --git a/packages/lit-auth-client/src/lib/providers/StytchOtpProvider.ts b/packages/lit-auth-client/src/lib/providers/StytchOtpProvider.ts
index f6e1d72c10..af208fbccc 100644
--- a/packages/lit-auth-client/src/lib/providers/StytchOtpProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/StytchOtpProvider.ts
@@ -1,4 +1,4 @@
-import { AuthMethodType } from '@lit-protocol/constants';
+import { AUTH_METHOD_TYPE, WrongParamFormat } from '@lit-protocol/constants';
import {
AuthMethod,
BaseAuthenticateOptions,
@@ -78,7 +78,7 @@ export class StytchOtpProvider extends BaseProvider {
}
resolve({
- authMethodType: AuthMethodType.StytchOtp,
+ authMethodType: AUTH_METHOD_TYPE.StytchOtp,
accessToken: accessToken,
});
});
@@ -114,7 +114,14 @@ export class StytchOtpProvider extends BaseProvider {
public static _parseJWT(jwt: string): StytchToken {
const parts = jwt.split('.');
if (parts.length !== 3) {
- throw new Error('Invalid token length');
+ throw new WrongParamFormat(
+ {
+ info: {
+ jwt,
+ },
+ },
+ 'Invalid token length'
+ );
}
const body = Buffer.from(parts[1], 'base64');
const parsedBody: StytchToken = JSON.parse(body.toString('ascii'));
diff --git a/packages/lit-auth-client/src/lib/providers/WebAuthnProvider.ts b/packages/lit-auth-client/src/lib/providers/WebAuthnProvider.ts
index 691d5a7c16..3bdad5f431 100644
--- a/packages/lit-auth-client/src/lib/providers/WebAuthnProvider.ts
+++ b/packages/lit-auth-client/src/lib/providers/WebAuthnProvider.ts
@@ -4,7 +4,12 @@ import {
MintRequestBody,
WebAuthnProviderOptions,
} from '@lit-protocol/types';
-import { AuthMethodType } from '@lit-protocol/constants';
+import {
+ AUTH_METHOD_TYPE,
+ RemovedFunctionError,
+ UnknownError,
+ WrongParamFormat,
+} from '@lit-protocol/constants';
import { ethers } from 'ethers';
import {
PublicKeyCredentialCreationOptionsJSON,
@@ -57,7 +62,7 @@ export default class WebAuthnProvider extends BaseProvider {
// Get auth method id
const authMethodId = await this.getAuthMethodId({
- authMethodType: AuthMethodType.WebAuthn,
+ authMethodType: AUTH_METHOD_TYPE.WebAuthn,
accessToken: JSON.stringify(attResp),
});
@@ -68,7 +73,7 @@ export default class WebAuthnProvider extends BaseProvider {
// Format args for relay server
const defaultArgs = {
keyType: 2,
- permittedAuthMethodTypes: [AuthMethodType.WebAuthn],
+ permittedAuthMethodTypes: [AUTH_METHOD_TYPE.WebAuthn],
permittedAuthMethodIds: [authMethodId],
permittedAuthMethodPubkeys: [authMethodPubkey],
permittedAuthMethodScopes: [[ethers.BigNumber.from('1')]],
@@ -86,7 +91,14 @@ export default class WebAuthnProvider extends BaseProvider {
// Mint PKP
const mintRes = await this.relay.mintPKP(body);
if (!mintRes || !mintRes.requestId) {
- throw new Error('Missing mint response or request ID from relay server');
+ throw new UnknownError(
+ {
+ info: {
+ mintRes,
+ },
+ },
+ 'Missing mint response or request ID from relay server'
+ );
}
return mintRes.requestId;
@@ -100,7 +112,12 @@ export default class WebAuthnProvider extends BaseProvider {
* @throws {Error} - Throws an error when called for WebAuthnProvider.
*/
public override async mintPKPThroughRelayer(): Promise {
- throw new Error(
+ throw new RemovedFunctionError(
+ {
+ info: {
+ method: 'mintPKPThroughRelayer',
+ },
+ },
'Use verifyAndMintPKPThroughRelayer for WebAuthnProvider instead.'
);
}
@@ -143,7 +160,7 @@ export default class WebAuthnProvider extends BaseProvider {
}
const authMethod = {
- authMethodType: AuthMethodType.WebAuthn,
+ authMethodType: AUTH_METHOD_TYPE.WebAuthn,
accessToken: JSON.stringify(actualAuthenticationResponse),
};
@@ -173,8 +190,14 @@ export default class WebAuthnProvider extends BaseProvider {
try {
credentialId = JSON.parse(authMethod.accessToken).rawId;
} catch (err) {
- throw new Error(
- `Error when parsing auth method to generate auth method ID for WebAuthn: ${err}`
+ throw new WrongParamFormat(
+ {
+ info: {
+ authMethod,
+ },
+ cause: err,
+ },
+ 'Error when parsing auth method to generate auth method ID for Eth wallet'
);
}
@@ -217,8 +240,11 @@ export default class WebAuthnProvider extends BaseProvider {
ethers.utils.arrayify(publicKeyCoseBuffer)
);
} catch (e) {
- throw new Error(
- `Error while decoding WebAuthn registration response for public key retrieval. Attestation response not encoded as expected: ${e}`
+ throw new UnknownError(
+ {
+ cause: e,
+ },
+ 'Error while decoding WebAuthn registration response for public key retrieval. Attestation response not encoded as expected'
);
}
diff --git a/packages/lit-auth-client/src/lib/relay.ts b/packages/lit-auth-client/src/lib/relay.ts
index 9cbf3030d8..da015aae92 100644
--- a/packages/lit-auth-client/src/lib/relay.ts
+++ b/packages/lit-auth-client/src/lib/relay.ts
@@ -1,16 +1,48 @@
+import { ethers } from 'ethers';
+
+import {
+ AUTH_METHOD_TYPE,
+ LIT_NETWORK_VALUES,
+ LIT_NETWORK,
+ RELAYER_URL_BY_NETWORK,
+ WrongNetworkException,
+ InvalidParamType,
+ NetworkError,
+} from '@lit-protocol/constants';
import {
+ AuthMethod,
+ MintRequestBody,
IRelay,
IRelayFetchResponse,
IRelayMintResponse,
IRelayPollStatusResponse,
LitRelayConfig,
} from '@lit-protocol/types';
-import { log } from './utils';
+
+import WebAuthnProvider from './providers/WebAuthnProvider';
+import { getAuthIdByAuthMethod, log } from './utils';
/**
* Class that communicates with Lit relay server
*/
export class LitRelay implements IRelay {
+ /** URL for Lit's relay server */
+ static getRelayUrl(litNetwork: LIT_NETWORK_VALUES): string {
+ const relayerUrl = RELAYER_URL_BY_NETWORK[litNetwork];
+ if (!relayerUrl) {
+ throw new WrongNetworkException(
+ {
+ info: {
+ litNetwork,
+ },
+ },
+ `Relay URL not found for network ${litNetwork}`
+ );
+ }
+
+ return relayerUrl;
+ }
+
/**
* URL for Lit's relay server
*/
@@ -33,11 +65,11 @@ export class LitRelay implements IRelay {
*
* @param {LitRelayConfig} config
* @param {string} [config.relayApiKey] - API key for Lit's relay server
- * @param {string} [config.relayUrl] - URL for Lit's relay server
+ * @param {string} [config.relayUrl] - URL for Lit's relay server. If not provided, will default to the last dev relay server.
*/
constructor(config: LitRelayConfig) {
this.relayUrl =
- config.relayUrl || 'https://relayer-server-staging-cayenne.getlit.dev';
+ config.relayUrl || LitRelay.getRelayUrl(LIT_NETWORK.DatilDev);
this.relayApiKey = config.relayApiKey || '';
log("Lit's relay server URL:", this.relayUrl);
}
@@ -70,6 +102,109 @@ export class LitRelay implements IRelay {
}
}
+ /**
+ * Mints a new pkp with all AuthMethods provided. Allows for permissions and flags to be set separately.
+ * If no permissions are provided then each auth method will be assigned `1` for sign anything
+ * If no flags are provided then `sendPkpToitself` will be false, and `addPkpEthAddressAsPermittedAddress` will be true
+ * It is then up to the implementor to transfer the pkp nft to the pkp address.
+ * **note** When adding permissions, each permission should be added in the same order the auth methods are ordered
+ *
+ * @throws {Error} - Throws an error if no AuthMethods are given
+ * @param {AuthMethod[]} authMethods - AuthMethods authentication methods to be added to the pkp
+ * @param {{ pkpPermissionScopes?: number[][]; sendPkpToitself?: boolean; addPkpEthAddressAsPermittedAddress?: boolean;}} options
+ *
+ * @returns {Promise<{pkpTokenId?: string; pkpEthAddress?: string; pkpPublicKey?: string}>} pkp information
+ */
+ public async mintPKPWithAuthMethods(
+ authMethods: AuthMethod[],
+ options: {
+ pkpPermissionScopes?: number[][];
+ sendPkpToitself?: boolean;
+ addPkpEthAddressAsPermittedAddress?: boolean;
+ }
+ ): Promise<{
+ pkpTokenId?: string;
+ pkpEthAddress?: string;
+ pkpPublicKey?: string;
+ }> {
+ if (authMethods.length < 1) {
+ throw new InvalidParamType(
+ {
+ info: {
+ authMethods,
+ options,
+ },
+ },
+ 'Must provide at least one auth method'
+ );
+ }
+
+ if (
+ !options.pkpPermissionScopes ||
+ options.pkpPermissionScopes.length < 1
+ ) {
+ options.pkpPermissionScopes = [];
+ for (let i = 0; i < authMethods.length; i++) {
+ options.pkpPermissionScopes.push([
+ ethers.BigNumber.from('1').toNumber(),
+ ]);
+ }
+ }
+
+ const reqBody: MintRequestBody = {
+ keyType: 2,
+ permittedAuthMethodTypes: authMethods.map((value) => {
+ return value.authMethodType;
+ }),
+ permittedAuthMethodScopes: options.pkpPermissionScopes,
+ addPkpEthAddressAsPermittedAddress:
+ options.addPkpEthAddressAsPermittedAddress ?? true,
+ sendPkpToItself: options.sendPkpToitself ?? false,
+ };
+
+ const permittedAuthMethodIds = [];
+ const permittedAuthMethodPubkeys = [];
+ for (const authMethod of authMethods) {
+ const id = await getAuthIdByAuthMethod(authMethod);
+ permittedAuthMethodIds.push(id);
+ if (authMethod.authMethodType === AUTH_METHOD_TYPE.WebAuthn) {
+ permittedAuthMethodPubkeys.push(
+ WebAuthnProvider.getPublicKeyFromRegistration(
+ JSON.parse(authMethod.accessToken)
+ )
+ );
+ } else {
+ // only webauthn has a `authMethodPubkey`
+ permittedAuthMethodPubkeys.push('0x');
+ }
+ }
+
+ reqBody.permittedAuthMethodIds = permittedAuthMethodIds;
+ reqBody.permittedAuthMethodPubkeys = permittedAuthMethodPubkeys;
+
+ const mintRes = await this.mintPKP(JSON.stringify(reqBody));
+ if (!mintRes || !mintRes.requestId) {
+ throw new NetworkError(
+ {
+ info: {
+ mintRes,
+ },
+ },
+ `Missing mint response or request ID from mint response ${mintRes.error}`
+ );
+ }
+
+ const pollerResult = await this.pollRequestUntilTerminalState(
+ mintRes.requestId
+ );
+
+ return {
+ pkpTokenId: pollerResult.pkpTokenId,
+ pkpPublicKey: pollerResult.pkpPublicKey,
+ pkpEthAddress: pollerResult.pkpEthAddress,
+ };
+ }
+
/**
* Poll the relay server for status of minting request
*
diff --git a/packages/lit-auth-client/src/lib/utils.ts b/packages/lit-auth-client/src/lib/utils.ts
index 0f1f8acb35..636986a974 100644
--- a/packages/lit-auth-client/src/lib/utils.ts
+++ b/packages/lit-auth-client/src/lib/utils.ts
@@ -1,7 +1,20 @@
-import { getLoggerbyId } from '@lit-protocol/misc';
-import { LoginUrlParams } from '@lit-protocol/types';
import * as cbor from 'cbor-web';
+import {
+ AUTH_METHOD_TYPE,
+ InvalidArgumentException,
+ UnknownError,
+} from '@lit-protocol/constants';
+import { getLoggerbyId } from '@lit-protocol/misc';
+import { AuthMethod, LoginUrlParams } from '@lit-protocol/types';
+
+import DiscordProvider from './providers/DiscordProvider';
+import EthWalletProvider from './providers/EthWalletProvider';
+import GoogleProvider from './providers/GoogleProvider';
+import StytchAuthFactorOtpProvider from './providers/StytchAuthFactorOtp';
+import { StytchOtpProvider } from './providers/StytchOtpProvider';
+import WebAuthnProvider from './providers/WebAuthnProvider';
+
export const STATE_PARAM_KEY = 'lit-state-param';
export const LIT_LOGIN_GATEWAY = 'https://login.litgateway.com';
@@ -52,7 +65,12 @@ function getLoginRoute(provider: string): string {
case 'discord':
return '/auth/discord';
default:
- throw new Error(
+ throw new InvalidArgumentException(
+ {
+ info: {
+ provider,
+ },
+ },
`No login route available for the given provider "${provider}".`
);
}
@@ -204,9 +222,9 @@ export function parseAuthenticatorData(
): Record {
try {
// deocde the buffer from cbor, will return an object.
- let authDataBufferDecoded: any = cbor.decode(authDataBuffer);
+ const authDataBufferDecoded = cbor.decode(authDataBuffer);
const authenticatorData: any = {};
- let authData: Buffer = authDataBufferDecoded.authData;
+ const authData: Buffer = authDataBufferDecoded.authData;
authenticatorData.rpIdHash = authData.slice(0, 32);
authenticatorData.flags = authData[32];
@@ -219,7 +237,7 @@ export function parseAuthenticatorData(
// Check if the client sent attestedCredentialdata, which is necessary for every new public key scheduled. This is indicated by the 6th bit of the flag byte being 1 (See specification at function start for reference)
if (authenticatorData.flags & 64) {
// Extract the data from the Buffer. Reference of the structure can be found here: https://w3c.github.io/webauthn/#sctn-attested-credential-data
- const attestedCredentialData: { [key: string]: any } = {};
+ const attestedCredentialData: Record = {};
attestedCredentialData['aaguid'] = unparse(authData.slice(37, 53)); ///.toUpperCase()
attestedCredentialData['credentialIdLength'] =
(authData[53] << 8) | authData[54];
@@ -233,7 +251,7 @@ export function parseAuthenticatorData(
authData.length
);
- const publicKey: any = cbor.decode(publicKeyCoseBufferCbor);
+ const publicKey = cbor.decode(publicKeyCoseBufferCbor);
publicKeyCoseBufferCbor = cbor.encode(publicKey);
attestedCredentialData['credentialPublicKey'] = publicKeyCoseBufferCbor;
@@ -270,21 +288,29 @@ export function parseAuthenticatorData(
return authenticatorData;
} catch (e) {
- throw new Error('Authenticator Data could not be parsed');
+ throw new UnknownError(
+ {
+ info: {
+ authDataBuffer,
+ },
+ cause: e,
+ },
+ 'Authenticator Data could not be parsed'
+ );
}
}
// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
export function unparse(buf: any) {
// Maps for number <-> hex string conversion
- var _byteToHex = [];
- var _hexToByte: any = {};
- for (var i = 0; i < 256; i++) {
- _byteToHex[i] = (i + 0x100).toString(16).substr(1);
- _hexToByte[_byteToHex[i]] = i;
+ const _byteToHex = [];
+ const _hexToByte: any = {};
+ for (let it = 0; it < 256; it++) {
+ _byteToHex[it] = (it + 0x100).toString(16).substr(1);
+ _hexToByte[_byteToHex[it]] = it;
}
- var i: number = 0;
- var bth = _byteToHex;
+ let i: number = 0;
+ const bth = _byteToHex;
return (
bth[buf[i++]] +
bth[buf[i++]] +
@@ -313,3 +339,51 @@ export function log(...args: any) {
const logger = getLoggerbyId('auth-client');
logger.debug(...args);
}
+
+/**
+ * Retrieves the authentication ID based on the provided authentication method.
+ *
+ * @param {AuthMethod} authMethod - The authentication method
+ * @returns {Promise} - The authentication ID
+ */
+export async function getAuthIdByAuthMethod(
+ authMethod: AuthMethod
+): Promise {
+ let authId;
+
+ switch (authMethod.authMethodType) {
+ case AUTH_METHOD_TYPE.EthWallet:
+ authId = await EthWalletProvider.authMethodId(authMethod);
+ break;
+ case AUTH_METHOD_TYPE.Discord:
+ authId = await DiscordProvider.authMethodId(authMethod);
+ break;
+ case AUTH_METHOD_TYPE.WebAuthn:
+ authId = await WebAuthnProvider.authMethodId(authMethod);
+ break;
+ case AUTH_METHOD_TYPE.GoogleJwt:
+ authId = await GoogleProvider.authMethodId(authMethod);
+ break;
+ case AUTH_METHOD_TYPE.StytchOtp:
+ authId = await StytchOtpProvider.authMethodId(authMethod);
+ break;
+ case AUTH_METHOD_TYPE.StytchEmailFactorOtp:
+ case AUTH_METHOD_TYPE.StytchSmsFactorOtp:
+ case AUTH_METHOD_TYPE.StytchTotpFactorOtp:
+ case AUTH_METHOD_TYPE.StytchWhatsAppFactorOtp:
+ authId = await StytchAuthFactorOtpProvider.authMethodId(authMethod);
+ break;
+ default:
+ log(`unsupported AuthMethodType: ${authMethod.authMethodType}`);
+ throw new InvalidArgumentException(
+ {
+ info: {
+ authMethod,
+ },
+ },
+ `Unsupported auth method type: ${authMethod.authMethodType}`
+ );
+ }
+
+ return authId;
+}
diff --git a/packages/lit-auth-client/tsconfig.json b/packages/lit-auth-client/tsconfig.json
index d43e5f3e93..d87cb2e661 100644
--- a/packages/lit-auth-client/tsconfig.json
+++ b/packages/lit-auth-client/tsconfig.json
@@ -2,7 +2,6 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
- "moduleResolution": "node16",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
diff --git a/packages/lit-node-client-nodejs/package.json b/packages/lit-node-client-nodejs/package.json
index 2d957e1aaf..c5236a1909 100644
--- a/packages/lit-node-client-nodejs/package.json
+++ b/packages/lit-node-client-nodejs/package.json
@@ -24,7 +24,7 @@
"tags": [
"nodejs"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/lit-node-client-nodejs/src/index.ts b/packages/lit-node-client-nodejs/src/index.ts
index ba66b7aa4a..bbe72272e2 100644
--- a/packages/lit-node-client-nodejs/src/index.ts
+++ b/packages/lit-node-client-nodejs/src/index.ts
@@ -1,38 +1,8 @@
import 'cross-fetch/dist/node-polyfill.js';
-import * as _LitNodeClientNodeJs from './lib/lit-node-client-nodejs';
-// ==================== Environment ====================
-
-declare global {
- // This `declare global` hackery _must_ use var to work.
- // eslint-disable-next-line no-var, @typescript-eslint/no-explicit-any
- var LitNodeClientNodeJs: any;
-}
-
-const LitNodeClientNodeJs = _LitNodeClientNodeJs.LitNodeClientNodeJs;
-if (!globalThis.LitNodeClientNodeJs) {
- globalThis.LitNodeClientNodeJs = LitNodeClientNodeJs;
-}
-
// ==================== Exports ====================
export * from './lib/lit-node-client-nodejs';
-export {
- decryptToFile,
- decryptFromJson,
- decryptToString,
- decryptToZip,
- decryptZipFileWithMetadata,
- encryptFile,
- encryptFileAndZipWithMetadata,
- encryptToJson,
- encryptString,
- encryptZip,
- verifyJwt,
- zipAndEncryptFiles,
- zipAndEncryptString,
-} from '@lit-protocol/encryption';
-
export {
hashResourceIdForSigning,
humanizeAccessControlConditions,
diff --git a/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.test.ts b/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.test.ts
index 71d69adf59..766943f250 100644
--- a/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.test.ts
+++ b/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.test.ts
@@ -1,14 +1,9 @@
-import { initWasmEcdsaSdk } from '@lit-protocol/ecdsa-sdk';
import { SigResponse } from '@lit-protocol/types';
import { getSignatures } from './get-signatures';
describe('getSignatures', () => {
- beforeAll(async () => {
- await initWasmEcdsaSdk();
- });
-
- it('should return signatures object', () => {
+ it('should return signatures object', async () => {
const networkPubKeySet = 'testing';
const minNodeCount = 1;
const signedData = [
@@ -54,7 +49,7 @@ describe('getSignatures', () => {
];
const requestId = '';
- const signatures = getSignatures<{ sig: SigResponse }>({
+ const signatures = await getSignatures<{ sig: SigResponse }>({
networkPubKeySet,
minNodeCount,
signedData,
diff --git a/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.ts b/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.ts
index 0ecab7084e..b222523ae6 100644
--- a/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.ts
+++ b/packages/lit-node-client-nodejs/src/lib/helpers/get-signatures.ts
@@ -1,12 +1,17 @@
import { joinSignature } from 'ethers/lib/utils';
-import { LIT_CURVE, LIT_ERROR } from '@lit-protocol/constants';
+import {
+ LIT_CURVE,
+ NoValidShares,
+ ParamNullError,
+ UnknownSignatureError,
+ UnknownSignatureType,
+} from '@lit-protocol/constants';
import { combineEcdsaShares } from '@lit-protocol/crypto';
import {
logErrorWithRequestId,
logWithRequestId,
mostCommonString,
- throwError,
} from '@lit-protocol/misc';
import { SigResponse, SigShare } from '@lit-protocol/types';
@@ -92,12 +97,12 @@ export const getFlattenShare = (share: any): SigShare => {
* executeJs: getSignatures<{ signature: SigResponse }>
* pkpSign: getSignatures<{ sig: SigResponse }>
*/
-export const getSignatures = (params: {
+export const getSignatures = async (params: {
networkPubKeySet: any;
minNodeCount: number;
signedData: any[];
requestId: string;
-}): T | { signature: SigResponse; sig: SigResponse } => {
+}): Promise => {
const { networkPubKeySet, minNodeCount, signedData, requestId } = params;
const initialKeys = [...new Set(signedData.flatMap((i) => Object.keys(i)))];
@@ -145,22 +150,21 @@ export const getSignatures = (params: {
];
if (allKeys.length !== initialKeys.length) {
- throwError({
- message: `Total number of valid signatures does not match requested. Valid signatures: ${allKeys.length}, Requested signatures: ${initialKeys.length}`,
- errorKind: LIT_ERROR.NO_VALID_SHARES.kind,
- errorCode: LIT_ERROR.NO_VALID_SHARES.code,
- });
+ throw new NoValidShares(
+ {},
+ 'total number of valid signatures does not match requested'
+ );
}
// -- combine
- for (var i = 0; i < allKeys.length; i++) {
+ for (const key of allKeys) {
// here we use a map filter implementation to find common shares in each node response.
// we then filter out undefined object from the key access.
// currently we are unable to know the total signature count requested by the user.
// but this allows for incomplete sets of signature shares to be aggregated
// and then checked against threshold
const shares = validatedSignedData
- .map((r) => r[allKeys[i]])
+ .map((r) => r[key])
.filter((r) => r !== undefined);
shares.sort((a, b) => a.shareIndex - b.shareIndex);
@@ -193,23 +197,32 @@ export const getSignatures = (params: {
`not enough nodes to get the signatures. Expected ${minNodeCount}, got ${shares.length}`
);
- throwError({
- message: `The total number of valid signatures shares ${shares.length} does not meet the threshold of ${minNodeCount}`,
- errorKind: LIT_ERROR.NO_VALID_SHARES.kind,
- errorCode: LIT_ERROR.NO_VALID_SHARES.code,
- requestId,
- });
+ throw new NoValidShares(
+ {
+ info: {
+ requestId,
+ shares: shares.length,
+ minNodeCount,
+ },
+ },
+ 'The total number of valid signatures shares %s does not meet the threshold of %s',
+ shares.length,
+ minNodeCount
+ );
}
const sigType = mostCommonString(shares.map((s) => s.sigType));
// -- validate if this.networkPubKeySet is null
if (networkPubKeySet === null) {
- return throwError({
- message: 'networkPubKeySet cannot be null',
- errorKind: LIT_ERROR.PARAM_NULL_ERROR.kind,
- errorCode: LIT_ERROR.PARAM_NULL_ERROR.name,
- });
+ throw new ParamNullError(
+ {
+ info: {
+ requestId,
+ },
+ },
+ 'networkPubKeySet cannot be null'
+ );
}
// -- validate if signature type is ECDSA
@@ -218,21 +231,29 @@ export const getSignatures = (params: {
sigType !== LIT_CURVE.EcdsaK256 &&
sigType !== LIT_CURVE.EcdsaCAITSITHP256
) {
- return throwError({
- message: `signature type is ${sigType} which is invalid`,
- errorKind: LIT_ERROR.UNKNOWN_SIGNATURE_TYPE.kind,
- errorCode: LIT_ERROR.UNKNOWN_SIGNATURE_TYPE.name,
- });
+ throw new UnknownSignatureType(
+ {
+ info: {
+ requestId,
+ signatureType: sigType,
+ },
+ },
+ 'signature type is %s which is invalid',
+ sigType
+ );
}
- const signature = combineEcdsaShares(shares);
-
+ const signature = await combineEcdsaShares(shares);
if (!signature.r) {
- throwError({
- message: 'siganture could not be combined',
- errorKind: LIT_ERROR.UNKNOWN_SIGNATURE_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_SIGNATURE_ERROR.name,
- });
+ throw new UnknownSignatureError(
+ {
+ info: {
+ requestId,
+ signature,
+ },
+ },
+ 'signature could not be combined'
+ );
}
const encodedSig = joinSignature({
@@ -241,7 +262,7 @@ export const getSignatures = (params: {
v: signature.recid,
});
- signatures[allKeys[i]] = {
+ signatures[key] = {
...signature,
signature: encodedSig,
publicKey: mostCommonString(shares.map((s) => s.publicKey)),
diff --git a/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sig.ts b/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sig.ts
index 3e1e01d858..2b893d2562 100644
--- a/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sig.ts
+++ b/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sig.ts
@@ -1,5 +1,9 @@
+import { log } from '@lit-protocol/misc';
import { AuthSig } from '@lit-protocol/types';
-import { uint8arrayToString } from '@lit-protocol/uint8arrays';
+import {
+ uint8arrayFromString,
+ uint8arrayToString,
+} from '@lit-protocol/uint8arrays';
import { ethers } from 'ethers';
import { SiweError, SiweErrorType, SiweMessage } from 'siwe';
@@ -8,20 +12,23 @@ const LIT_SESSION_SIGNED_MESSAGE_PREFIX = 'lit_session:';
/**
* Verifies a BLS session signature.
*
- * @param {Function} verifier - A wasm function that takes a public key, message, and signature to verify. NOTE: `public_key` is snake cased because it's a wasm parameter
+ * @param {Function} verifier - A wasm function that takes a public key, message, and signature to verify.
* @param {string} networkPubKey - The public key of the network.
* @param {AuthSig} authSig
* @typedef {Object} AuthSig
* @property {string} sig - The signature in string format.
* @property {string} signedMessage - The message that was signed.
*/
-export const blsSessionSigVerify = (
- // TODO: refactor type with merger of PR 'https://github.com/LIT-Protocol/js-sdk/pull/503`
- verifier: (public_key: any, message: any, signature: any) => void,
+export const blsSessionSigVerify = async (
+ verifier: (
+ publicKeyHex: string,
+ message: Uint8Array,
+ signature: Uint8Array
+ ) => Promise,
networkPubKey: string,
authSig: AuthSig,
authSigSiweMessage: SiweMessage
-): void => {
+): Promise => {
let sigJson = JSON.parse(authSig.sig);
// we do not nessesarly need to use ethers here but was a quick way
// to get verification working.
@@ -29,9 +36,7 @@ export const blsSessionSigVerify = (
const prefixedStr =
LIT_SESSION_SIGNED_MESSAGE_PREFIX + eip191Hash.replace('0x', '');
const prefixedEncoded = ethers.utils.toUtf8Bytes(prefixedStr);
- const shaHashed = ethers.utils.base64.encode(
- ethers.utils.sha256(prefixedEncoded)
- );
+ const shaHashed = ethers.utils.sha256(prefixedEncoded).replace('0x', '');
const signatureBytes = Buffer.from(sigJson.ProofOfPossession, `hex`);
/** Check time or now */
@@ -62,9 +67,5 @@ export const blsSessionSigVerify = (
);
}
- verifier(
- networkPubKey,
- shaHashed,
- uint8arrayToString(signatureBytes, `base64`)
- );
+ await verifier(networkPubKey, Buffer.from(shaHashed, 'hex'), signatureBytes);
};
diff --git a/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts b/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts
index f1563339e8..1d4563c954 100644
--- a/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts
+++ b/packages/lit-node-client-nodejs/src/lib/helpers/validate-bls-session-sigs.spec.ts
@@ -1,3 +1,4 @@
+import { SiweMessage } from 'siwe';
import { blsSessionSigVerify } from './validate-bls-session-sig';
describe('BlsSessionSigVerify', () => {
@@ -25,16 +26,37 @@ describe('BlsSessionSigVerify', () => {
let networkPubKey =
'a43499a4b786da2dd28af9f209eb152ff6f646b34b68a02954967271e17fb4c511fd67b81e067f690c6f38acab70585d';
- it(`should verify valid bls signatrue`, () => {
+ it(`should verify valid bls signatrue`, async () => {
expect(
- blsSessionSigVerify(
- (public_key: any, message: any, signature: any) => {
- expect(typeof public_key).toBe('string');
- expect(typeof message).toBe('string');
- expect(typeof signature).toBe('string');
+ await blsSessionSigVerify(
+ async (
+ publicKey: String,
+ message: Uint8Array,
+ signature: Uint8Array
+ ): Promise => {
+ expect(typeof publicKey).toBe('string');
+ expect(typeof message).toBe('object');
+ expect(typeof signature).toBe('object');
},
networkPubKey,
- authSig
+ authSig,
+ new SiweMessage({
+ domain: 'localhost',
+ statement:
+ 'litprotocol.com wants you to sign in with your Ethereum account:\n' +
+ '0xf087a967D9eA9445D9182692C2944DcC0Af57341\n' +
+ '\n' +
+ "Lit Protocol PKP session signature I further authorize the stated URI to perform the following actions on my behalf: I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. I further authorize the stated URI to perform the following actions on my behalf: (1) 'Threshold': 'Execution' for 'lit-litaction://*'. (2) 'Threshold': 'Signing' for 'lit-pkp://*'. (3) 'Auth': 'Auth' for 'lit-resolvedauthcontext://*'.\n",
+ address: authSig.address,
+ uri: 'lit:session:efebafcc9063827a49dffdb11c36b2d64a33330631ac7f5825e2960946bcc8ff',
+ version: '1',
+ nonce:
+ '0x1f623ab8dfe6bbd3b3dc22c7a041deb697c14817bce471b1bd1d86a25d5a319c',
+ expirationTime: new Date(
+ Date.now() + 1000 * 60 * 60 * 24 * 7
+ ).toISOString(),
+ notBefore: new Date(Date.now()).toISOString(),
+ })
)
).toBeUndefined();
});
diff --git a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts
index 74068b2e2a..74f72afd16 100644
--- a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts
+++ b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.spec.ts
@@ -5,6 +5,8 @@
// [Lit-JS-SDK v2.2.39] ✅ [ECDSA SDK NodeJS] wasmECDSA loaded.
global.jestTesting = true;
+import { LIT_NETWORK } from '@lit-protocol/constants';
+
import { LitNodeClientNodeJs } from './lit-node-client-nodejs';
const isClass = (v) => {
@@ -18,23 +20,16 @@ describe('LitNodeClientNodeJs', () => {
expect(isClass(LitNodeClientNodeJs)).toBe(true);
});
- it('should be able to instantiate a new LitNodeClientNodeJs to localhost', async () => {
- const litNodeClient = new LitNodeClientNodeJs({
- litNetwork: 'localhost',
- });
- expect(litNodeClient).toBeDefined();
- });
-
it('should be able to instantiate a new LitNodeClientNodeJs to custom', async () => {
const litNodeClient = new LitNodeClientNodeJs({
- litNetwork: 'custom',
+ litNetwork: LIT_NETWORK.Custom,
});
expect(litNodeClient).toBeDefined();
});
- it('should be able to instantiate a new LitNodeClientNodeJs to cayenne', async () => {
+ it('should be able to instantiate a new LitNodeClientNodeJs to datil dev', async () => {
const litNodeClient = new LitNodeClientNodeJs({
- litNetwork: 'cayenne',
+ litNetwork: LIT_NETWORK.DatilDev,
});
expect(litNodeClient).toBeDefined();
});
@@ -44,7 +39,7 @@ describe('LitNodeClientNodeJs', () => {
Object.defineProperty(globalThis, 'localStorage', { value: undefined });
const ls = require('node-localstorage').LocalStorage;
const litNodeClient = new LitNodeClientNodeJs({
- litNetwork: 'custom',
+ litNetwork: LIT_NETWORK.Custom,
storageProvider: {
provider: new ls('./storage.test.db'),
},
diff --git a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts
index bd087a0691..d07d82b9f0 100644
--- a/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts
+++ b/packages/lit-node-client-nodejs/src/lib/lit-node-client-nodejs.ts
@@ -1,43 +1,47 @@
import { computeAddress } from '@ethersproject/transactions';
import { BigNumber, ethers } from 'ethers';
-import { joinSignature, sha256 } from 'ethers/lib/utils';
+import { sha256 } from 'ethers/lib/utils';
import { SiweMessage } from 'siwe';
import {
- ILitResource,
- ISessionCapabilityObject,
LitAccessControlConditionResource,
LitResourceAbilityRequest,
- decode,
RecapSessionCapabilityObject,
- generateAuthSig,
+ createSiweMessage,
createSiweMessageWithCapacityDelegation,
createSiweMessageWithRecaps,
- createSiweMessage,
+ decode,
+ generateAuthSig,
} from '@lit-protocol/auth-helpers';
-import * as blsSdk from '@lit-protocol/bls-sdk';
import {
- AuthMethodType,
+ AUTH_METHOD_TYPE,
EITHER_TYPE,
FALLBACK_IPFS_GATEWAYS,
GLOBAL_OVERWRITE_IPFS_CODE_BY_NETWORK,
+ InvalidArgumentException,
+ InvalidParamType,
+ InvalidSessionSigs,
+ InvalidSignatureError,
LIT_ACTION_IPFS_HASH,
LIT_CURVE,
LIT_ENDPOINT,
- LIT_ERROR,
LIT_SESSION_KEY_URI,
LOCAL_STORAGE_KEYS,
- LitNetwork,
+ LitNodeClientNotReadyError,
+ ParamNullError,
+ ParamsMissingError,
+ UnknownError,
+ UnsupportedMethodError,
+ WalletSignatureNotFoundError,
} from '@lit-protocol/constants';
import { LitCore, composeLitUrl } from '@lit-protocol/core';
import {
- combineEcdsaShares,
combineSignatureShares,
encrypt,
generateSessionKeyPair,
verifyAndDecryptWithSignatureShares,
+ verifySignature,
} from '@lit-protocol/crypto';
-import { safeParams } from '@lit-protocol/encryption';
import {
defaultMintClaimCallback,
findMostCommonResponse,
@@ -50,7 +54,7 @@ import {
mostCommonString,
normalizeAndStringify,
removeHexPrefix,
- throwError,
+ safeParams,
validateSessionSigs,
} from '@lit-protocol/misc';
import {
@@ -59,6 +63,7 @@ import {
setStorageItem,
} from '@lit-protocol/misc-browser';
import { nacl } from '@lit-protocol/nacl';
+import { ILitResource, ISessionCapabilityObject } from '@lit-protocol/types';
import {
uint8arrayFromString,
uint8arrayToString,
@@ -68,7 +73,7 @@ import { encodeCode } from './helpers/encode-code';
import { getBlsSignatures } from './helpers/get-bls-signatures';
import { getClaims } from './helpers/get-claims';
import { getClaimsList } from './helpers/get-claims-list';
-import { getFlattenShare, getSignatures } from './helpers/get-signatures';
+import { getSignatures } from './helpers/get-signatures';
import { normalizeArray } from './helpers/normalize-array';
import { normalizeJsParams } from './helpers/normalize-params';
import { parseAsJsonOrString } from './helpers/parse-as-json-or-string';
@@ -81,6 +86,9 @@ import type {
AuthCallback,
AuthCallbackParams,
AuthSig,
+ BlsResponseData,
+ CapacityCreditsReq,
+ CapacityCreditsRes,
ClaimKeyResponse,
ClaimProcessor,
ClaimRequest,
@@ -89,13 +97,25 @@ import type {
DecryptResponse,
EncryptRequest,
EncryptResponse,
+ EncryptSdkParams,
+ EncryptionSignRequest,
+ ExecuteJsNoSigningResponse,
ExecuteJsResponse,
FormattedMultipleAccs,
+ GetLitActionSessionSigs,
+ GetPkpSessionSigs,
GetSessionSigsProps,
- GetSignedTokenRequest,
+ GetSignSessionKeySharesProp,
GetWalletSigProps,
+ ILitNodeClient,
JsonExecutionRequest,
+ JsonExecutionRequestTargetNode,
+ JsonExecutionSdkParams,
+ JsonExecutionSdkParamsTargetNode,
+ JsonPKPClaimKeyRequest,
JsonPkpSignRequest,
+ JsonPkpSignSdkParams,
+ JsonSignSessionKeyRequestV1,
LitClientSessionManager,
LitNodeClientConfig,
NodeBlsSigningShare,
@@ -107,30 +127,11 @@ import type {
SessionKeyPair,
SessionSigningTemplate,
SessionSigsMap,
- SigShare,
+ SigResponse,
SignSessionKeyProp,
SignSessionKeyResponse,
Signature,
SuccessNodePromises,
- ILitNodeClient,
- GetPkpSessionSigs,
- CapacityCreditsReq,
- CapacityCreditsRes,
- JsonSignSessionKeyRequestV1,
- BlsResponseData,
- JsonExecutionSdkParamsTargetNode,
- JsonExecutionRequestTargetNode,
- JsonExecutionSdkParams,
- ExecuteJsNoSigningResponse,
- JsonPkpSignSdkParams,
- SigResponse,
- EncryptSdkParams,
- GetLitActionSessionSigs,
- GetSignSessionKeySharesProp,
- EncryptionSignRequest,
- SigningAccessControlConditionRequest,
- JsonPKPClaimKeyRequest,
- IpfsOptions,
} from '@lit-protocol/types';
export class LitNodeClientNodeJs
@@ -142,11 +143,7 @@ export class LitNodeClientNodeJs
// ========== Constructor ==========
constructor(args: LitNodeClientConfig | CustomNetwork) {
if (!args) {
- throwError({
- message: 'must provide LitNodeClient parameters',
- errorKind: LIT_ERROR.PARAMS_MISSING_ERROR.kind,
- errorCode: LIT_ERROR.PARAMS_MISSING_ERROR.name,
- });
+ throw new ParamsMissingError({}, 'must provide LitNodeClient parameters');
}
super(args);
@@ -164,7 +161,14 @@ export class LitNodeClientNodeJs
): Promise => {
// -- validate
if (!params.dAppOwnerWallet) {
- throw new Error('dAppOwnerWallet must exist');
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
+ 'dAppOwnerWallet must exist'
+ );
}
// Useful log for debugging
@@ -239,7 +243,7 @@ export class LitNodeClientNodeJs
storedSessionKeyOrError.result === ''
) {
console.warn(
- `Storage key "${storageKey}" is missing. Not a problem. Contiune...`
+ `Storage key "${storageKey}" is missing. Not a problem. Continue...`
);
// Generate new one
@@ -250,7 +254,7 @@ export class LitNodeClientNodeJs
localStorage.setItem(storageKey, JSON.stringify(newSessionKey));
} catch (e) {
log(
- `[getSessionKey] Localstorage not available.Not a problem. Contiune...`
+ `[getSessionKey] Localstorage not available.Not a problem. Continue...`
);
}
@@ -397,11 +401,10 @@ export class LitNodeClientNodeJs
log('getWalletSig - flow 1.2');
if (!this.defaultAuthCallback) {
log('getWalletSig - flow 1.2.1');
- return throwError({
- message: 'No default auth callback provided',
- errorKind: LIT_ERROR.PARAMS_MISSING_ERROR.kind,
- errorCode: LIT_ERROR.PARAMS_MISSING_ERROR.name,
- });
+ throw new ParamsMissingError(
+ {},
+ 'No authNeededCallback nor default auth callback provided'
+ );
}
log('getWalletSig - flow 1.2.2');
@@ -459,11 +462,10 @@ export class LitNodeClientNodeJs
authSig = await authCallback(authCallbackParams);
} else {
if (!this.defaultAuthCallback) {
- return throwError({
- message: 'No default auth callback provided',
- errorKind: LIT_ERROR.PARAMS_MISSING_ERROR.kind,
- errorCode: LIT_ERROR.PARAMS_MISSING_ERROR.name,
- });
+ throw new ParamsMissingError(
+ {},
+ 'No authCallback nor default auth callback provided'
+ );
}
authSig = await this.defaultAuthCallback(authCallbackParams);
}
@@ -521,13 +523,13 @@ export class LitNodeClientNodeJs
{ suppressExceptions: false }
);
} catch (e) {
- log(`Error while verifying ECDSA signature: `, e);
+ log(`Error while verifying BLS signature: `, e);
return true;
}
} else if (authSig.algo === `LIT_BLS`) {
try {
- blsSessionSigVerify(
- blsSdk.verify_signature,
+ await blsSessionSigVerify(
+ verifySignature,
this.networkPubKey!,
authSig,
authSigSiweMessage
@@ -537,11 +539,17 @@ export class LitNodeClientNodeJs
return true;
}
} else {
- throwError({
- message: `Unsupported signature algo for session signature. Expected ed25519 or LIT_BLS received ${authSig.algo}`,
- errorKind: LIT_ERROR.SIGNATURE_VALIDATION_ERROR.kind,
- errorCode: LIT_ERROR.SIGNATURE_VALIDATION_ERROR.code,
- });
+ throw new InvalidSignatureError(
+ {
+ info: {
+ authSig,
+ resourceAbilityRequests,
+ sessionKeyUri,
+ },
+ },
+ 'Unsupported signature algo for session signature. Expected ed25519 or LIT_BLS received %s',
+ authSig.algo
+ );
}
// make sure the sig is for the correct session key
@@ -596,10 +604,10 @@ export class LitNodeClientNodeJs
* @returns { string } final JWT (convert the sig to base64 and append to the jwt)
*
*/
- combineSharesAndGetJWT = (
+ combineSharesAndGetJWT = async (
signatureShares: NodeBlsSigningShare[],
requestId: string = ''
- ): string => {
+ ): Promise => {
// ========== Shares Validations ==========
// -- sanity check
if (
@@ -617,7 +625,7 @@ export class LitNodeClientNodeJs
signatureShares.sort((a, b) => a.shareIndex - b.shareIndex);
// ========== Combine Shares ==========
- const signature = combineSignatureShares(
+ const signature = await combineSignatureShares(
signatureShares.map((s) => s.signatureShare)
);
@@ -642,7 +650,7 @@ export class LitNodeClientNodeJs
identityParam: Uint8Array,
ciphertext: string,
signatureShares: NodeBlsSigningShare[]
- ): Uint8Array => {
+ ): Promise => {
const sigShares = signatureShares.map((s) => s.signatureShare);
return verifyAndDecryptWithSignatureShares(
@@ -709,11 +717,14 @@ export class LitNodeClientNodeJs
log('running runOnTargetedNodes:', params.targetNodeRange);
if (!params.targetNodeRange) {
- return throwError({
- message: 'targetNodeRange is required',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
+ 'targetNodeRange is required'
+ );
}
// determine which node to run on
@@ -751,7 +762,7 @@ export class LitNodeClientNodeJs
log('Final Selected Indexes:', randomSelectedNodeIndexes);
- const requestId = this.getRequestId();
+ const requestId = this._getNewRequestId();
const nodePromises = [];
for (let i = 0; i < randomSelectedNodeIndexes.length; i++) {
@@ -798,159 +809,6 @@ export class LitNodeClientNodeJs
)) as SuccessNodePromises | RejectedNodePromises;
};
- /**
- *
- * Get signatures from signed data
- *
- * @param { Array } signedData
- *
- * @returns { any }
- *
- */
- getSessionSignatures = (signedData: any[]): any => {
- // -- prepare
- const signatures: any = {};
-
- // TOOD: get keys of signedData
- const keys = Object.keys(signedData[0]);
-
- // removeExtraBackslashesAndQuotes
- const sanitise = (str: string) => {
- // Check if str is a string and remove extra backslashes
- if (typeof str === 'string') {
- // Remove backslashes
- let newStr = str.replace(/\\+/g, '');
- // Remove leading and trailing double quotes
- newStr = newStr.replace(/^"|"$/g, '');
- return newStr;
- }
- return str;
- };
-
- // -- execute
- keys.forEach((key) => {
- log('key:', key);
-
- const shares = signedData.map((r) => r[key]);
-
- log('shares:', shares);
-
- shares.sort((a, b) => a.shareIndex - b.shareIndex);
-
- const sigShares: SigShare[] = shares.map((s, index: number) => {
- log('Original Share Struct:', s);
-
- const share = getFlattenShare(s);
-
- log('share:', share);
-
- if (!share) {
- throw new Error('share is null or undefined');
- }
-
- if (!share.bigr) {
- throw new Error(
- `bigR is missing in share ${index}. share ${JSON.stringify(share)}`
- );
- }
-
- const sanitisedBigR = sanitise(share.bigr);
- const sanitisedSigShare = sanitise(share.publicKey);
-
- log('sanitisedBigR:', sanitisedBigR);
- log('sanitisedSigShare:', sanitisedSigShare);
-
- return {
- sigType: share.sigType,
- signatureShare: sanitise(share.signatureShare),
- shareIndex: share.shareIndex,
- bigR: sanitise(share.bigr),
- publicKey: share.publicKey,
- dataSigned: share.dataSigned,
- siweMessage: share.siweMessage,
- };
- });
-
- log('getSessionSignatures - sigShares', sigShares);
-
- const sigType = mostCommonString(sigShares.map((s) => s.sigType));
-
- // -- validate if this.networkPubKeySet is null
- if (this.networkPubKeySet === null) {
- throwError({
- message: 'networkPubKeySet cannot be null',
- errorKind: LIT_ERROR.PARAM_NULL_ERROR.kind,
- errorCode: LIT_ERROR.PARAM_NULL_ERROR.name,
- });
- return;
- }
-
- // -- validate if signature type is ECDSA
- if (
- sigType !== LIT_CURVE.EcdsaCaitSith &&
- sigType !== LIT_CURVE.EcdsaK256 &&
- sigType !== LIT_CURVE.EcdsaCAITSITHP256
- ) {
- throwError({
- message: `signature type is ${sigType} which is invalid`,
- errorKind: LIT_ERROR.UNKNOWN_SIGNATURE_TYPE.kind,
- errorCode: LIT_ERROR.UNKNOWN_SIGNATURE_TYPE.name,
- });
- return;
- }
-
- const signature = combineEcdsaShares(sigShares);
- if (!signature.r) {
- throwError({
- message: 'siganture could not be combined',
- errorKind: LIT_ERROR.UNKNOWN_SIGNATURE_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_SIGNATURE_ERROR.name,
- });
- }
-
- const encodedSig = joinSignature({
- r: '0x' + signature.r,
- s: '0x' + signature.s,
- v: signature.recid,
- });
-
- signatures[key] = {
- ...signature,
- signature: encodedSig,
- publicKey: mostCommonString(sigShares.map((s) => s.publicKey)),
- dataSigned: mostCommonString(sigShares.map((s) => s.dataSigned)),
- siweMessage: mostCommonString(sigShares.map((s) => s.siweMessage)),
- };
- });
-
- return signatures;
- };
-
- /**
- *
- * Get a single signature
- *
- * @param { Array } shareData from all node promises
- * @param { string } requestId
- *
- * @returns { string } signature
- *
- */
- getSignature = async (shareData: any[], requestId: string): Promise => {
- // R_x & R_y values can come from any node (they will be different per node), and will generate a valid signature
- const R_x = shareData[0].local_x;
- const R_y = shareData[0].local_y;
-
- const valid_shares = shareData.map((s) => s.signature_share);
- const shares = JSON.stringify(valid_shares);
-
- await wasmECDSA.initWasmEcdsaSdk(); // init WASM
- const signature = wasmECDSA.combine_signature(R_x, R_y, shares);
- logWithRequestId(requestId, 'raw ecdsa sig', signature);
-
- return signature;
- };
-
// ========== Scoped Business Logics ==========
/**
@@ -1036,11 +894,7 @@ export class LitNodeClientNodeJs
const message =
'[executeJs] LitNodeClient is not ready. Please call await litNodeClient.connect() first.';
- throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError({}, message);
}
const paramsIsSafe = safeParams({
@@ -1049,22 +903,24 @@ export class LitNodeClientNodeJs
});
if (!paramsIsSafe) {
- return throwError({
- message: 'executeJs params are not valid',
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
+ 'executeJs params are not valid'
+ );
}
// validate session sigs
const checkedSessionSigs = validateSessionSigs(params.sessionSigs);
if (checkedSessionSigs.isValid === false) {
- return throwError({
- message: `Invalid sessionSigs. Errors: ${checkedSessionSigs.errors}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidSessionSigs(
+ {},
+ `Invalid sessionSigs. Errors: ${checkedSessionSigs.errors}`
+ );
}
// Format the params
@@ -1094,7 +950,7 @@ export class LitNodeClientNodeJs
};
}
- const requestId = this.getRequestId();
+ const requestId = this._getNewRequestId();
// ========== Get Node Promises ==========
// Handle promises for commands sent to Lit nodes
const getNodePromises = async () => {
@@ -1119,7 +975,7 @@ export class LitNodeClientNodeJs
// -- case: promises rejected
if (!res.success) {
- this._throwNodeError(res as RejectedNodePromises, requestId);
+ this._throwNodeError(res, requestId);
}
// -- case: promises success (TODO: check the keys of "values")
@@ -1175,7 +1031,7 @@ export class LitNodeClientNodeJs
signedDataList
);
- const signatures = getSignatures({
+ const signatures = await getSignatures({
requestId,
networkPubKeySet: this.networkPubKeySet,
minNodeCount: params.useSingleNode ? 1 : this.config.minNodeCount,
@@ -1243,11 +1099,16 @@ export class LitNodeClientNodeJs
(requiredParamKeys as (keyof JsonPkpSignSdkParams)[]).forEach((key) => {
if (!params[key]) {
- throwError({
- message: `"${key}" cannot be undefined, empty, or null. Please provide a valid value.`,
- errorKind: LIT_ERROR.PARAM_NULL_ERROR.kind,
- errorCode: LIT_ERROR.PARAM_NULL_ERROR.name,
- });
+ throw new ParamNullError(
+ {
+ info: {
+ params,
+ key,
+ },
+ },
+ `"%s" cannot be undefined, empty, or null. Please provide a valid value.`,
+ key
+ );
}
});
@@ -1256,25 +1117,28 @@ export class LitNodeClientNodeJs
!params.sessionSigs &&
(!params.authMethods || params.authMethods.length <= 0)
) {
- throwError({
- message: `Either sessionSigs or authMethods (length > 0) must be present.`,
- errorKind: LIT_ERROR.PARAM_NULL_ERROR.kind,
- errorCode: LIT_ERROR.PARAM_NULL_ERROR.name,
- });
+ throw new ParamNullError(
+ {
+ info: {
+ params,
+ },
+ },
+ 'Either sessionSigs or authMethods (length > 0) must be present.'
+ );
}
+ const requestId = this._getNewRequestId();
+
// validate session sigs
const checkedSessionSigs = validateSessionSigs(params.sessionSigs);
if (checkedSessionSigs.isValid === false) {
- return throwError({
- message: `Invalid sessionSigs. Errors: ${checkedSessionSigs.errors}`,
- errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- });
+ throw new InvalidSessionSigs(
+ {},
+ `Invalid sessionSigs. Errors: ${checkedSessionSigs.errors}`
+ );
}
- const requestId = this.getRequestId();
// ========== Get Node Promises ==========
// Handle promises for commands sent to Lit nodes
@@ -1310,13 +1174,13 @@ export class LitNodeClientNodeJs
const res = await this.handleNodePromises(
nodePromises,
requestId,
- this.connectedNodes.size // ECDSA requires responses from all nodes, but only shares from minNodeCount.
+ this.connectedNodes.size
);
// ========== Handle Response ==========
// -- case: promises rejected
if (!res.success) {
- this._throwNodeError(res as RejectedNodePromises, requestId);
+ this._throwNodeError(res, requestId);
}
// -- case: promises success (TODO: check the keys of "values")
@@ -1332,7 +1196,7 @@ export class LitNodeClientNodeJs
// -- 1. combine signed data as a list, and get the signatures from it
const signedDataList = parsePkpSignResponse(responseData);
- const signatures = getSignatures<{ signature: SigResponse }>({
+ const signatures = await getSignatures<{ signature: SigResponse }>({
requestId,
networkPubKeySet: this.networkPubKeySet,
minNodeCount: this.config.minNodeCount,
@@ -1344,128 +1208,6 @@ export class LitNodeClientNodeJs
return signatures.signature; // only a single signature is ever present, so we just return it.
};
- /**
- *
- * Request a signed JWT from the LIT network. Before calling this function, you must know the access control conditions for the item you wish to gain authorization for.
- *
- * @param { GetSignedTokenRequest } params
- *
- * @returns { Promise } final JWT
- *
- */
- getSignedToken = async (params: GetSignedTokenRequest): Promise => {
- // ========== Prepare Params ==========
- const { chain, authSig, sessionSigs } = params;
-
- // ========== Validation ==========
- // -- validate if it's ready
- if (!this.ready) {
- const message =
- '3 LitNodeClient is not ready. Please call await litNodeClient.connect() first.';
- throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
- }
-
- // -- validate if this.networkPubKeySet is null
- if (this.networkPubKeySet === null) {
- return throwError({
- message: 'networkPubKeySet cannot be null',
- errorKind: LIT_ERROR.PARAM_NULL_ERROR.kind,
- errorCode: LIT_ERROR.PARAM_NULL_ERROR.name,
- });
- }
-
- const paramsIsSafe = safeParams({
- functionName: 'getSignedToken',
- params,
- });
-
- if (!paramsIsSafe) {
- return throwError({
- message: `Parameter validation failed.`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
- }
-
- // ========== Prepare ==========
- // we need to send jwt params iat (issued at) and exp (expiration)
- // because the nodes may have different wall clock times
- // the nodes will verify that these params are withing a grace period
- const { iat, exp } = this.getJWTParams();
-
- // ========== Formatting Access Control Conditions =========
- const {
- error,
- formattedAccessControlConditions,
- formattedEVMContractConditions,
- formattedSolRpcConditions,
- formattedUnifiedAccessControlConditions,
- }: FormattedMultipleAccs = this.getFormattedAccessControlConditions(params);
-
- if (error) {
- return throwError({
- message: `You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
- }
-
- // ========== Get Node Promises ==========
- const requestId = this.getRequestId();
- const nodePromises = this.getNodePromises((url: string) => {
- // -- if session key is available, use it
- const authSigToSend = sessionSigs ? sessionSigs[url] : authSig;
-
- const reqBody: SigningAccessControlConditionRequest = {
- accessControlConditions: formattedAccessControlConditions,
- evmContractConditions: formattedEVMContractConditions,
- solRpcConditions: formattedSolRpcConditions,
- unifiedAccessControlConditions: formattedUnifiedAccessControlConditions,
- chain,
- authSig: authSigToSend,
- iat,
- exp,
- };
-
- const urlWithPath = composeLitUrl({
- url,
- endpoint: LIT_ENDPOINT.SIGN_ACCS,
- });
-
- return this.generatePromise(urlWithPath, reqBody, requestId);
- });
-
- // -- resolve promises
- const res = await this.handleNodePromises(
- nodePromises,
- requestId,
- this.config.minNodeCount
- );
-
- // -- case: promises rejected
- if (!res.success) {
- this._throwNodeError(res as RejectedNodePromises, requestId);
- }
-
- const signatureShares: NodeBlsSigningShare[] = (
- res as SuccessNodePromises
- ).values;
-
- log('signatureShares', signatureShares);
-
- // ========== Result ==========
- const finalJwt: string = this.combineSharesAndGetJWT(
- signatureShares,
- requestId
- );
-
- return finalJwt;
- };
-
/**
*
* Encrypt data using the LIT network public key.
@@ -1486,23 +1228,15 @@ export class LitNodeClientNodeJs
// ========== Validate Params ==========
// -- validate if it's ready
if (!this.ready) {
- const message =
- '6 LitNodeClient is not ready. Please call await litNodeClient.connect() first.';
- throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError(
+ {},
+ '6 LitNodeClient is not ready. Please call await litNodeClient.connect() first.'
+ );
}
// -- validate if this.subnetPubKey is null
if (!this.subnetPubKey) {
- const message = 'subnetPubKey cannot be null';
- return throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError({}, 'subnetPubKey cannot be null');
}
const paramsIsSafe = safeParams({
@@ -1511,11 +1245,14 @@ export class LitNodeClientNodeJs
});
if (!paramsIsSafe) {
- return throwError({
- message: `You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions'
+ );
}
// ========== Validate Access Control Conditions Schema ==========
@@ -1527,11 +1264,14 @@ export class LitNodeClientNodeJs
await this.getHashedAccessControlConditions(params);
if (!hashOfConditions) {
- return throwError({
- message: `You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions'
+ );
}
const hashOfConditionsStr = uint8arrayToString(
@@ -1557,7 +1297,7 @@ export class LitNodeClientNodeJs
);
// ========== Encrypt ==========
- const ciphertext = encrypt(
+ const ciphertext = await encrypt(
this.subnetPubKey,
params.dataToEncrypt,
uint8arrayFromString(identityParam, 'utf8')
@@ -1572,28 +1312,21 @@ export class LitNodeClientNodeJs
*
*/
decrypt = async (params: DecryptRequest): Promise => {
- const { sessionSigs, chain, ciphertext, dataToEncryptHash } = params;
+ const { sessionSigs, authSig, chain, ciphertext, dataToEncryptHash } =
+ params;
// ========== Validate Params ==========
// -- validate if it's ready
if (!this.ready) {
- const message =
- '6 LitNodeClient is not ready. Please call await litNodeClient.connect() first.';
- throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError(
+ {},
+ '6 LitNodeClient is not ready. Please call await litNodeClient.connect() first.'
+ );
}
// -- validate if this.subnetPubKey is null
if (!this.subnetPubKey) {
- const message = 'subnetPubKey cannot be null';
- return throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError({}, 'subnetPubKey cannot be null');
}
const paramsIsSafe = safeParams({
@@ -1602,11 +1335,14 @@ export class LitNodeClientNodeJs
});
if (!paramsIsSafe) {
- return throwError({
- message: `Parameter validation failed.`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'Parameter validation failed.'
+ );
}
// ========== Hashing Access Control Conditions =========
@@ -1615,11 +1351,14 @@ export class LitNodeClientNodeJs
await this.getHashedAccessControlConditions(params);
if (!hashOfConditions) {
- return throwError({
- message: `You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions'
+ );
}
const hashOfConditionsStr = uint8arrayToString(
@@ -1637,11 +1376,14 @@ export class LitNodeClientNodeJs
}: FormattedMultipleAccs = this.getFormattedAccessControlConditions(params);
if (error) {
- throwError({
- message: `You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions'
+ );
}
// ========== Assemble identity parameter ==========
@@ -1653,17 +1395,20 @@ export class LitNodeClientNodeJs
log('identityParam', identityParam);
// ========== Get Network Signature ==========
- const requestId = this.getRequestId();
+ const requestId = this._getNewRequestId();
const nodePromises = this.getNodePromises((url: string) => {
// -- if session key is available, use it
- const authSigToSend = sessionSigs ? sessionSigs[url] : params.authSig;
+ const authSigToSend = sessionSigs ? sessionSigs[url] : authSig;
if (!authSigToSend) {
- return throwError({
- message: `authSig is required`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'authSig is required'
+ );
}
const reqBody: EncryptionSignRequest = {
@@ -1694,7 +1439,7 @@ export class LitNodeClientNodeJs
// -- case: promises rejected
if (!res.success) {
- this._throwNodeError(res as RejectedNodePromises, requestId);
+ this._throwNodeError(res, requestId);
}
const signatureShares: NodeBlsSigningShare[] = (
@@ -1704,7 +1449,7 @@ export class LitNodeClientNodeJs
logWithRequestId(requestId, 'signatureShares', signatureShares);
// ========== Result ==========
- const decryptedData = this._decryptWithSignatureShares(
+ const decryptedData = await this._decryptWithSignatureShares(
this.subnetPubKey,
uint8arrayFromString(identityParam, 'utf8'),
ciphertext,
@@ -1723,11 +1468,14 @@ export class LitNodeClientNodeJs
await this.getHashedAccessControlConditions(params);
if (!hashOfConditions) {
- return throwError({
- message: `You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions`,
- errorKind: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.kind,
- errorCode: LIT_ERROR.INVALID_ARGUMENT_EXCEPTION.name,
- });
+ throw new InvalidArgumentException(
+ {
+ info: {
+ params,
+ },
+ },
+ 'You must provide either accessControlConditions or evmContractConditions or solRpcConditions or unifiedAccessControlConditions'
+ );
}
const hashOfConditionsStr = uint8arrayToString(
@@ -1775,14 +1523,10 @@ export class LitNodeClientNodeJs
// ========== Validate Params ==========
// -- validate: If it's NOT ready
if (!this.ready) {
- const message =
- '[signSessionKey] ]LitNodeClient is not ready. Please call await litNodeClient.connect() first.';
-
- throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError(
+ {},
+ '[signSessionKey] ]LitNodeClient is not ready. Please call await litNodeClient.connect() first.'
+ );
}
// -- construct SIWE message that will be signed by node to generate an authSig.
@@ -1801,7 +1545,12 @@ export class LitNodeClientNodeJs
);
if (!sessionKeyUri) {
- throw new Error(
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
'[signSessionKey] sessionKeyUri is not defined. Please provide a sessionKeyUri or a sessionKey.'
);
}
@@ -1866,7 +1615,7 @@ export class LitNodeClientNodeJs
log(`[signSessionKey] body:`, body);
- const requestId = this.getRequestId();
+ const requestId = this._getNewRequestId();
logWithRequestId(requestId, 'signSessionKey body', body);
const nodePromises = this.getNodePromises((url: string) => {
const reqBody: JsonSignSessionKeyRequestV1 = body;
@@ -1889,7 +1638,15 @@ export class LitNodeClientNodeJs
);
log('signSessionKey node promises:', res);
} catch (e) {
- throw new Error(`Error when handling node promises: ${e}`);
+ throw new UnknownError(
+ {
+ info: {
+ requestId,
+ },
+ cause: e,
+ },
+ 'Error when handling node promises'
+ );
}
logWithRequestId(requestId, 'handleNodePromises res:', res);
@@ -1911,9 +1668,10 @@ export class LitNodeClientNodeJs
// -- 1. combine signed data as a list, and get the signatures from it
let curveType = responseData[0]?.curveType;
- if (!curveType) {
- log(`[signSessionKey] curveType not found. Defaulting to ECDSA.`);
- curveType = 'ECDSA';
+ if (curveType === 'ECDSA') {
+ throw new Error(
+ 'The ECDSA curve type is not supported in this version. Please use version 6.x.x instead.'
+ );
}
log(`[signSessionKey] curveType is "${curveType}"`);
@@ -1923,7 +1681,16 @@ export class LitNodeClientNodeJs
if (signedDataList.length <= 0) {
const err = `[signSessionKey] signedDataList is empty.`;
log(err);
- throw new Error(err);
+ throw new InvalidSignatureError(
+ {
+ info: {
+ requestId,
+ responseData,
+ signedDataList,
+ },
+ },
+ err
+ );
}
logWithRequestId(
@@ -1965,7 +1732,16 @@ export class LitNodeClientNodeJs
if (!data.signatureShare.ProofOfPossession) {
const err = `[signSessionKey] Invalid signed data. "ProofOfPossession" is missing.`;
log(err);
- throw new Error(err);
+ throw new InvalidSignatureError(
+ {
+ info: {
+ requestId,
+ responseData,
+ data,
+ },
+ },
+ err
+ );
}
return data;
@@ -1988,7 +1764,15 @@ export class LitNodeClientNodeJs
this.config.minNodeCount
);
if (validatedSignedDataList.length < this.config.minNodeCount) {
- throw new Error(
+ throw new InvalidSignatureError(
+ {
+ info: {
+ requestId,
+ responseData,
+ validatedSignedDataList,
+ minNodeCount: this.config.minNodeCount,
+ },
+ },
`[signSessionKey] not enough nodes signed the session key. Expected ${this.config.minNodeCount}, got ${validatedSignedDataList.length}`
);
}
@@ -2003,10 +1787,7 @@ export class LitNodeClientNodeJs
log(`[signSessionKey] signatureShares:`, signatureShares);
- // TODO: refactor type with merger of PR 'https://github.com/LIT-Protocol/js-sdk/pull/503`
- const blsCombinedSignature = blsSdk.combine_signature_shares(
- signatureShares.map((s) => JSON.stringify(s))
- );
+ const blsCombinedSignature = await combineSignatureShares(signatureShares);
log(`[signSessionKey] blsCombinedSignature:`, blsCombinedSignature);
@@ -2022,7 +1803,7 @@ export class LitNodeClientNodeJs
log(`[signSessionKey] mostCommonSiweMessage:`, mostCommonSiweMessage);
- const signedMessage = normalizeAndStringify(mostCommonSiweMessage);
+ const signedMessage = normalizeAndStringify(mostCommonSiweMessage!);
log(`[signSessionKey] signedMessage:`, signedMessage);
@@ -2169,13 +1950,14 @@ export class LitNodeClientNodeJs
authSig.sig === '' ||
authSig.signedMessage === ''
) {
- throwError({
- message: 'No wallet signature found',
- errorKind: LIT_ERROR.WALLET_SIGNATURE_NOT_FOUND_ERROR.kind,
- errorCode: LIT_ERROR.WALLET_SIGNATURE_NOT_FOUND_ERROR.name,
- });
- // @ts-ignore - we throw an error above, so below should never be reached
- return;
+ throw new WalletSignatureNotFoundError(
+ {
+ info: {
+ authSig,
+ },
+ },
+ 'No wallet signature found'
+ );
}
// ===== AFTER we have Valid Signed Session Key =====
@@ -2259,24 +2041,46 @@ export class LitNodeClientNodeJs
authNeededCallback: async (props: AuthCallbackParams) => {
// -- validate
if (!props.expiration) {
- throw new Error(
+ throw new ParamsMissingError(
+ {
+ info: {
+ props,
+ },
+ },
'[getPkpSessionSigs/callback] expiration is required'
);
}
if (!props.resources) {
- throw new Error('[getPkpSessionSigs/callback]resources is required');
+ throw new ParamsMissingError(
+ {
+ info: {
+ props,
+ },
+ },
+ '[getPkpSessionSigs/callback]resources is required'
+ );
}
if (!props.resourceAbilityRequests) {
- throw new Error(
+ throw new ParamsMissingError(
+ {
+ info: {
+ props,
+ },
+ },
'[getPkpSessionSigs/callback]resourceAbilityRequests is required'
);
}
// lit action code and ipfs id cannot exist at the same time
if (props.litActionCode && props.litActionIpfsId) {
- throw new Error(
+ throw new UnsupportedMethodError(
+ {
+ info: {
+ props,
+ },
+ },
'[getPkpSessionSigs/callback]litActionCode and litActionIpfsId cannot exist at the same time'
);
}
@@ -2344,14 +2148,26 @@ export class LitNodeClientNodeJs
getLitActionSessionSigs = async (params: GetLitActionSessionSigs) => {
// Check if either litActionCode or litActionIpfsId is provided
if (!params.litActionCode && !params.litActionIpfsId) {
- throw new Error(
- "Either 'litActionCode' or 'litActionIpfsId' must be provided."
+ throw new InvalidParamType(
+ {
+ info: {
+ params,
+ },
+ },
+ 'Either "litActionCode" or "litActionIpfsId" must be provided.'
);
}
// Check if jsParams is provided
if (!params.jsParams) {
- throw new Error("'jsParams' is required.");
+ throw new ParamsMissingError(
+ {
+ info: {
+ params,
+ },
+ },
+ "'jsParams' is required."
+ );
}
return this.getPkpSessionSigs(params);
@@ -2381,27 +2197,28 @@ export class LitNodeClientNodeJs
if (!this.ready) {
const message =
'LitNodeClient is not ready. Please call await litNodeClient.connect() first.';
- throwError({
- message,
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ throw new LitNodeClientNotReadyError({}, message);
}
- if (params.authMethod.authMethodType == AuthMethodType.WebAuthn) {
- throwError({
- message:
- 'Unsupported auth method type. Webauthn, and Lit Actions are not supported for claiming',
- errorKind: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.kind,
- errorCode: LIT_ERROR.LIT_NODE_CLIENT_NOT_READY_ERROR.name,
- });
+ if (params.authMethod.authMethodType == AUTH_METHOD_TYPE.WebAuthn) {
+ throw new LitNodeClientNotReadyError(
+ {},
+ 'Unsupported auth method type. Webauthn, and Lit Actions are not supported for claiming'
+ );
}
- const requestId = this.getRequestId();
+ const requestId = this._getNewRequestId();
const nodePromises = this.getNodePromises((url: string) => {
if (!params.authMethod) {
- throw new Error('authMethod is required');
+ throw new ParamsMissingError(
+ {
+ info: {
+ params,
+ },
+ },
+ 'authMethod is required'
+ );
}
const reqBody: JsonPKPClaimKeyRequest = {
@@ -2423,9 +2240,7 @@ export class LitNodeClientNodeJs
);
if (responseData.success) {
- const nodeSignatures: Signature[] = (
- responseData as SuccessNodePromises
- ).values.map((r) => {
+ const nodeSignatures: Signature[] = responseData.values.map((r) => {
const sig = ethers.utils.splitSignature(`0x${r.signature}`);
return {
r: sig.r,
@@ -2439,10 +2254,9 @@ export class LitNodeClientNodeJs
`responseData: ${JSON.stringify(responseData, null, 2)}`
);
- const derivedKeyId = (responseData as SuccessNodePromises).values[0]
- .derivedKeyId;
+ const derivedKeyId = responseData.values[0].derivedKeyId;
- const pubkey: string = this.computeHDPubKey(derivedKeyId);
+ const pubkey = await this.computeHDPubKey(derivedKeyId);
logWithRequestId(
requestId,
`pubkey ${pubkey} derived from key id ${derivedKeyId}`
@@ -2461,7 +2275,7 @@ export class LitNodeClientNodeJs
signer: (params as ClaimRequest<'client'>).signer,
...relayParams,
},
- this.config.litNetwork as LitNetwork
+ this.config.litNetwork
);
} else {
mintTx = await defaultMintClaimCallback(
@@ -2472,7 +2286,7 @@ export class LitNodeClientNodeJs
pubkey,
...relayParams,
},
- this.config.litNetwork as LitNetwork
+ this.config.litNetwork
);
}
@@ -2483,11 +2297,16 @@ export class LitNodeClientNodeJs
mintTx,
};
} else {
- return throwError({
- message: `Claim request has failed. Request trace id: lit_${requestId} `,
- errorKind: LIT_ERROR.UNKNOWN_ERROR.kind,
- errorCode: LIT_ERROR.UNKNOWN_ERROR.code,
- });
+ throw new UnknownError(
+ {
+ info: {
+ requestId,
+ responseData,
+ },
+ },
+ `Claim request has failed. Request trace id: lit_%s`,
+ requestId
+ );
}
}
}
diff --git a/packages/lit-node-client/README.md b/packages/lit-node-client/README.md
index e20e4656b2..86ee2ff17e 100644
--- a/packages/lit-node-client/README.md
+++ b/packages/lit-node-client/README.md
@@ -7,12 +7,3 @@ This module is the main module of this monorepo. It sets a default authenticatio
```
yarn add @lit-protocol/lit-node-client
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/lit-node-client/package.json b/packages/lit-node-client/package.json
index 26382555d8..e53d71bfa2 100644
--- a/packages/lit-node-client/package.json
+++ b/packages/lit-node-client/package.json
@@ -28,7 +28,7 @@
"crypto": false,
"stream": false
},
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/lit-node-client/src/index.ts b/packages/lit-node-client/src/index.ts
index a1bc1e4bcf..534a93b50a 100644
--- a/packages/lit-node-client/src/index.ts
+++ b/packages/lit-node-client/src/index.ts
@@ -1,12 +1,4 @@
-import * as _LitNodeClient from './lib/lit-node-client';
-
-const LitNodeClient = _LitNodeClient.LitNodeClient;
-if (!globalThis.LitNodeClient) {
- globalThis.LitNodeClient = LitNodeClient;
-}
-
// ==================== Exports ====================
-
export * from './lib/lit-node-client';
export {
diff --git a/packages/lit-node-client/src/lib/lit-node-client.ts b/packages/lit-node-client/src/lib/lit-node-client.ts
index c10caa81f5..716be94e98 100644
--- a/packages/lit-node-client/src/lib/lit-node-client.ts
+++ b/packages/lit-node-client/src/lib/lit-node-client.ts
@@ -11,10 +11,10 @@ import { CustomNetwork, LitNodeClientConfig } from '@lit-protocol/types';
* @example
*
* ```
- * import { LitNetwork } from '@lit-protocol/constants';
- *
+ * import { LIT_NETWORK } from '@lit-protocol/constants';
+ *
* const litNodeClient = new LitNodeClient({
- litNetwork: LitNetwork.Habanero,
+ litNetwork: LIT_NETWORK.DatilTest,
});
* ```
*/
diff --git a/packages/lit-node-client/tsconfig.spec.json b/packages/lit-node-client/tsconfig.spec.json
index 0b95e4a584..df5eec354a 100644
--- a/packages/lit-node-client/tsconfig.spec.json
+++ b/packages/lit-node-client/tsconfig.spec.json
@@ -4,8 +4,7 @@
"outDir": "../../dist/out-tsc",
"module": "ES2022",
"types": ["jest", "node"],
- "allowJs": true,
- "esModuleInterop": true
+ "allowJs": true
},
"include": [
"jest.config.ts",
diff --git a/packages/logger/package.json b/packages/logger/package.json
index 2b58c9994a..e13be93e5b 100644
--- a/packages/logger/package.json
+++ b/packages/logger/package.json
@@ -1,6 +1,6 @@
{
"name": "@lit-protocol/logger",
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"type": "commonjs",
"tags": [
"universal"
diff --git a/packages/logger/src/lib/logger.spec.ts b/packages/logger/src/lib/logger.spec.ts
index cfa72d8d48..2ba2784166 100644
--- a/packages/logger/src/lib/logger.spec.ts
+++ b/packages/logger/src/lib/logger.spec.ts
@@ -1,4 +1,4 @@
-import { Logger, LogLevel, LogManager } from './logger';
+import { LOG_LEVEL, LogManager } from './logger';
describe('logger', () => {
let lm: LogManager;
@@ -34,7 +34,7 @@ describe('logger', () => {
condenseLogs: true,
});
let logger = lm.get('category', 'bar');
- logger.setLevel(LogLevel.INFO);
+ logger.setLevel(LOG_LEVEL.INFO);
expect(logger.Config?.['condenseLogs']).toEqual(true);
logger.info('hello');
logger.info('hello');
@@ -44,7 +44,7 @@ describe('logger', () => {
it('should respect info logging level', () => {
const logger = lm.get('info-logger', 'foo');
- logger.setLevel(LogLevel.INFO);
+ logger.setLevel(LOG_LEVEL.INFO);
logger.info('logging');
logger.debug('shouldnt log');
let logs = lm.getLogsForId('foo');
@@ -53,7 +53,7 @@ describe('logger', () => {
it('should log error at any level', () => {
const logger = lm.get('info-logger', 'foo2');
- logger.setLevel(LogLevel.DEBUG);
+ logger.setLevel(LOG_LEVEL.DEBUG);
logger.debug('logging');
logger.error('error');
let logs = lm.getLogsForId('foo2');
@@ -62,7 +62,7 @@ describe('logger', () => {
it('should safe serialize circular references', () => {
const logger = lm.get('info-logger', 'foo3');
- logger.setLevel(LogLevel.DEBUG);
+ logger.setLevel(LOG_LEVEL.DEBUG);
let circ: any = { foo: 'bar' };
circ.circ = circ;
logger.debug('circular reference to serialize', circ);
@@ -72,9 +72,9 @@ describe('logger', () => {
it('should trace logs through multiple categories', () => {
const logger = lm.get('info-logger', 'foo4');
- logger.setLevel(LogLevel.DEBUG);
+ logger.setLevel(LOG_LEVEL.DEBUG);
const logger2 = lm.get('debug-logger', 'foo4');
- logger2.setLevel(LogLevel.DEBUG);
+ logger2.setLevel(LOG_LEVEL.DEBUG);
logger2.debug('foo');
logger.debug('bar');
expect(lm.getLogsForId('foo4').length).toEqual(2);
@@ -84,7 +84,7 @@ describe('logger', () => {
const count = 1_000;
for (let i = 0; i < count; i++) {
const logger = lm.get('' + i, 'foo5');
- logger.setLevel(LogLevel.OFF);
+ logger.setLevel(LOG_LEVEL.OFF);
logger.debug(i + '');
}
@@ -95,7 +95,7 @@ describe('logger', () => {
const count = 10_000;
for (let i = 0; i < count; i++) {
const logger = lm.get('' + i, 'foo6');
- logger.setLevel(LogLevel.DEBUG);
+ logger.setLevel(LOG_LEVEL.DEBUG);
logger.debug(i + '');
}
diff --git a/packages/logger/src/lib/logger.ts b/packages/logger/src/lib/logger.ts
index 5c2e0a94f7..9ec0dbe3ed 100644
--- a/packages/logger/src/lib/logger.ts
+++ b/packages/logger/src/lib/logger.ts
@@ -1,7 +1,6 @@
+import { version, LOG_LEVEL, LOG_LEVEL_VALUES } from '@lit-protocol/constants';
import { hashMessage } from 'ethers/lib/utils';
-import { version } from '@lit-protocol/constants';
-
export enum LogLevel {
OFF = -1,
ERROR = 0,
@@ -48,42 +47,42 @@ const colours = {
},
};
-function _convertLoggingLevel(level: LogLevel): string {
+function _convertLoggingLevel(level: LOG_LEVEL_VALUES): string {
switch (level) {
- case LogLevel.INFO:
+ case LOG_LEVEL.INFO:
return `${colours.fg.green}[INFO]${colours.reset}`;
- case LogLevel.DEBUG:
+ case LOG_LEVEL.DEBUG:
return `${colours.fg.cyan}[DEBUG]${colours.reset}`;
- case LogLevel.WARN:
+ case LOG_LEVEL.WARN:
return `${colours.fg.yellow}[WARN]${colours.reset}`;
- case LogLevel.ERROR:
+ case LOG_LEVEL.ERROR:
return `${colours.fg.red}[ERROR]${colours.reset}`;
- case LogLevel.FATAL:
+ case LOG_LEVEL.FATAL:
return `${colours.fg.red}[FATAL]${colours.reset}`;
- case LogLevel.TIMING_START:
+ case LOG_LEVEL.TIMING_START:
return `${colours.fg.green}[TIME_START]${colours.reset}`;
- case LogLevel.TIMING_END:
+ case LOG_LEVEL.TIMING_END:
return `${colours.fg.green}[TIME_END]${colours.reset}`;
}
return '[UNKNOWN]';
}
-function _resolveLoggingHandler(level: LogLevel): any {
+function _resolveLoggingHandler(level: LOG_LEVEL_VALUES): any {
switch (level) {
- case LogLevel.DEBUG:
+ case LOG_LEVEL.DEBUG:
return console.debug;
- case LogLevel.INFO:
+ case LOG_LEVEL.INFO:
return console.info;
- case LogLevel.ERROR:
+ case LOG_LEVEL.ERROR:
return console.error;
- case LogLevel.WARN:
+ case LOG_LEVEL.WARN:
return console.warn;
- case LogLevel.FATAL:
+ case LOG_LEVEL.FATAL:
return console.error;
- case LogLevel.TIMING_END:
+ case LOG_LEVEL.TIMING_END:
return console.timeLog;
- case LogLevel.TIMING_START:
+ case LOG_LEVEL.TIMING_START:
return console.time;
}
}
@@ -120,7 +119,7 @@ interface ILog {
args: any[];
id: string;
category: string;
- level: LogLevel;
+ level: LOG_LEVEL_VALUES;
error?: any;
toString(): string;
toJSON(): Record;
@@ -132,7 +131,7 @@ class Log implements ILog {
args: any[];
id: string;
category: string;
- level: LogLevel;
+ level: LOG_LEVEL_VALUES;
error?: any;
constructor(
@@ -141,7 +140,7 @@ class Log implements ILog {
args: any[],
id: string,
category: string,
- level: LogLevel
+ level: LOG_LEVEL_VALUES
) {
this.timestamp = timestamp;
this.message = message;
@@ -198,7 +197,7 @@ export type messageHandler = (log: Log) => void;
export class Logger {
private _category: string;
- private _level: LogLevel;
+ private _level: LOG_LEVEL_VALUES;
private _id: string;
private _handler: messageHandler | undefined;
private _consoleHandler: any;
@@ -211,7 +210,7 @@ export class Logger {
public static createLogger(
category: string,
- level: LogLevel,
+ level: LOG_LEVEL_VALUES,
id: string,
isParent: boolean,
config?: Record
@@ -221,7 +220,7 @@ export class Logger {
private constructor(
category: string,
- level: LogLevel,
+ level: LOG_LEVEL_VALUES,
id: string,
isParent: boolean,
config?: Record
@@ -264,7 +263,7 @@ export class Logger {
return this._children;
}
- public setLevel(level: LogLevel): void {
+ public setLevel(level: LOG_LEVEL_VALUES): void {
this._level = level;
}
@@ -273,39 +272,43 @@ export class Logger {
}
public info(message: string = '', ...args: any[]): void {
- this._log(LogLevel.INFO, message, ...args);
+ this._log(LOG_LEVEL.INFO, message, ...args);
}
public debug(message: string = '', ...args: any[]): void {
- this._log(LogLevel.DEBUG, message, ...args);
+ this._log(LOG_LEVEL.DEBUG, message, ...args);
}
public warn(message: string = '', ...args: any[]): void {
- this._log(LogLevel.WARN, message, args);
+ this._log(LOG_LEVEL.WARN, message, args);
}
public error(message: string = '', ...args: any[]): void {
- this._log(LogLevel.ERROR, message, ...args);
+ this._log(LOG_LEVEL.ERROR, message, ...args);
}
public fatal(message: string = '', ...args: any[]): void {
- this._log(LogLevel.FATAL, message, ...args);
+ this._log(LOG_LEVEL.FATAL, message, ...args);
}
public trace(message: string = '', ...args: any[]): void {
- this._log(LogLevel.FATAL, message, ...args);
+ this._log(LOG_LEVEL.FATAL, message, ...args);
}
public timeStart(message: string = '', ...args: any[]): void {
- this._log(LogLevel.TIMING_START, message, ...args);
+ this._log(LOG_LEVEL.TIMING_START, message, ...args);
}
public timeEnd(message: string = '', ...args: any[]): void {
- this._level < LogLevel.OFF &&
- this._log(LogLevel.TIMING_END, message, ...args);
+ this._level < LOG_LEVEL.OFF &&
+ this._log(LOG_LEVEL.TIMING_END, message, ...args);
}
- private _log(level: LogLevel, message: string = '', ...args: any[]): void {
+ private _log(
+ level: LOG_LEVEL_VALUES,
+ message: string = '',
+ ...args: any[]
+ ): void {
const log = new Log(
new Date().toISOString(),
message,
@@ -320,7 +323,7 @@ export class Logger {
(this._level >= level || level === LogLevel.ERROR) &&
this._consoleHandler &&
this._consoleHandler(...arrayLog);
- (this._level >= level || level === LogLevel.ERROR) &&
+ (this._level >= level || level === LOG_LEVEL.ERROR) &&
this._handler &&
this._handler(log);
@@ -329,10 +332,10 @@ export class Logger {
(this._level >= level || level === LogLevel.ERROR) &&
this._consoleHandler &&
this._consoleHandler(...arrayLog);
- (this._level >= level || level === LogLevel.ERROR) &&
+ (this._level >= level || level === LOG_LEVEL.ERROR) &&
this._handler &&
this._handler(log);
- (this._level >= level || level === LogLevel.ERROR) && this._addLog(log);
+ (this._level >= level || level === LOG_LEVEL.ERROR) && this._addLog(log);
}
}
@@ -396,7 +399,7 @@ export class Logger {
export class LogManager {
private static _instance: LogManager;
private _loggers: Map;
- private _level: LogLevel | undefined = LogLevel.DEBUG;
+ private _level: LOG_LEVEL_VALUES | undefined = LOG_LEVEL.DEBUG;
private _config: Record | undefined;
static get Instance(): LogManager {
@@ -421,7 +424,7 @@ export class LogManager {
}
}
- public setLevel(level: LogLevel) {
+ public setLevel(level: LOG_LEVEL_VALUES) {
this._level = level;
for (const logger of this._loggers) {
logger[1].setLevel(level);
@@ -457,7 +460,7 @@ export class LogManager {
if (!instance && !id) {
this._loggers.set(
category,
- Logger.createLogger(category, this._level ?? LogLevel.INFO, '', true)
+ Logger.createLogger(category, this._level ?? LOG_LEVEL.INFO, '', true)
);
instance = this._loggers.get(category) as Logger;
@@ -469,7 +472,7 @@ export class LogManager {
if (!instance) {
this._loggers.set(
category,
- Logger.createLogger(category, this._level ?? LogLevel.INFO, '', true)
+ Logger.createLogger(category, this._level ?? LOG_LEVEL.INFO, '', true)
);
instance = this._loggers.get(category) as Logger;
@@ -484,7 +487,7 @@ export class LogManager {
id,
Logger.createLogger(
category,
- this._level ?? LogLevel.INFO,
+ this._level ?? LOG_LEVEL.INFO,
id ?? '',
true
)
@@ -498,7 +501,7 @@ export class LogManager {
} else if (!instance) {
this._loggers.set(
category,
- Logger.createLogger(category, this._level ?? LogLevel.INFO, '', true)
+ Logger.createLogger(category, this._level ?? LOG_LEVEL.INFO, '', true)
);
instance = this._loggers.get(category) as Logger;
diff --git a/packages/misc-browser/README.md b/packages/misc-browser/README.md
index 22c3454e4a..dd282b9528 100644
--- a/packages/misc-browser/README.md
+++ b/packages/misc-browser/README.md
@@ -7,12 +7,3 @@ This submodule includes functions for interaction with local storage (get, set,
```
yarn add @lit-protocol/misc-browser
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/misc-browser/package.json b/packages/misc-browser/package.json
index bd2f574b36..5a68fac775 100644
--- a/packages/misc-browser/package.json
+++ b/packages/misc-browser/package.json
@@ -21,7 +21,7 @@
"tags": [
"browser"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/misc-browser/src/lib/misc-browser.ts b/packages/misc-browser/src/lib/misc-browser.ts
index ffdab198ca..9c2b0d96a5 100644
--- a/packages/misc-browser/src/lib/misc-browser.ts
+++ b/packages/misc-browser/src/lib/misc-browser.ts
@@ -1,4 +1,12 @@
-import { ELeft, ERight, IEither, LIT_ERROR } from '@lit-protocol/constants';
+import {
+ ELeft,
+ ERight,
+ IEither,
+ InvalidArgumentException,
+ LocalStorageItemNotFoundException,
+ LocalStorageItemNotRemovedException,
+ LocalStorageItemNotSetException,
+} from '@lit-protocol/constants';
import {
uint8arrayFromString,
uint8arrayToString,
@@ -19,11 +27,17 @@ export const getStorageItem = (key: string): IEither => {
}
if (!item) {
- return ELeft({
- message: `Failed to get ${key} from local storage`,
- errorKind: LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION.kind,
- errorCode: LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION.name,
- });
+ return ELeft(
+ new LocalStorageItemNotFoundException(
+ {
+ info: {
+ storageKey: key,
+ },
+ },
+ `Failed to get %s from local storage`,
+ key
+ )
+ );
}
return ERight(item);
@@ -41,10 +55,17 @@ export const setStorageItem = (key: string, value: string): IEither => {
localStorage.setItem(key, value);
return ERight(value);
} catch (e) {
- return ELeft({
- message: `Failed to set ${key} in local storage`,
- error: LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_SET_EXCEPTION,
- });
+ return ELeft(
+ new LocalStorageItemNotSetException(
+ {
+ info: {
+ storageKey: key,
+ },
+ },
+ `Failed to set %s in local storage`,
+ key
+ )
+ );
}
};
@@ -60,10 +81,17 @@ export const removeStorageItem = (key: string): IEither => {
localStorage.removeItem(key);
return ERight(key);
} catch (e) {
- return ELeft({
- message: `Failed to remove ${key} from local storage`,
- error: LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_REMOVED_EXCEPTION,
- });
+ return ELeft(
+ new LocalStorageItemNotRemovedException(
+ {
+ info: {
+ storageKey: key,
+ },
+ },
+ `Failed to remove %s from local storage`,
+ key
+ )
+ );
}
};
@@ -106,7 +134,7 @@ export const base64StringToBlob = (base64String: string): Blob => {
export const fileToDataUrl = (
file: File
): Promise => {
- return new Promise((resolve: any) => {
+ return new Promise((resolve) => {
const reader = new FileReader();
reader.onloadend = () => {
resolve(reader.result);
@@ -181,15 +209,25 @@ export const injectViewerIFrame = ({
}): void => {
if (fileUrl.includes('data:')) {
// data urls are not safe, refuse to do this
- throw new Error(
- 'You can not inject an iFrame with a data url. Try a regular https URL.'
+ throw new InvalidArgumentException(
+ {
+ info: {
+ fileUrl,
+ },
+ },
+ 'You can not inject an iFrame with a data url. Try a regular https URL.'
);
}
const url = new URL(fileUrl);
if (url.host.toLowerCase() === window.location.host.toLowerCase()) {
- throw new Error(
- 'You cannot host a LIT on the same domain as the parent webpage. This is because iFrames with the same origin have access to localstorage and cookies in the parent webpage which is unsafe'
+ throw new InvalidArgumentException(
+ {
+ info: {
+ fileUrl,
+ },
+ },
+ 'You cannot host a LIT on the same domain as the parent webpage. This is because iFrames with the same origin have access to localstorage and cookies in the parent webpage which is unsafe'
);
}
diff --git a/packages/misc/README.md b/packages/misc/README.md
index 88853a1112..381773dbee 100644
--- a/packages/misc/README.md
+++ b/packages/misc/README.md
@@ -7,12 +7,3 @@ This submodule contains various utility functions for error handling, logging, t
```
yarn add @lit-protocol/misc
```
-
-### Vanilla JS (UMD)
-
-```js
-
-
-```
diff --git a/packages/misc/package.json b/packages/misc/package.json
index c2be44aff8..14570eb6d9 100644
--- a/packages/misc/package.json
+++ b/packages/misc/package.json
@@ -13,9 +13,6 @@
"url": "https://github.com/LIT-Protocol/js-sdk/issues"
},
"type": "commonjs",
- "dependencies": {
- "ethers": "^5.7.1"
- },
"publishConfig": {
"access": "public",
"directory": "../../dist/packages/misc"
@@ -24,7 +21,7 @@
"tags": [
"universal"
],
- "version": "6.11.0",
+ "version": "7.0.0-alpha.9",
"main": "./dist/src/index.js",
"typings": "./dist/src/index.d.ts"
}
diff --git a/packages/misc/src/index.ts b/packages/misc/src/index.ts
index 88be5e3cc5..c2ec7a0691 100644
--- a/packages/misc/src/index.ts
+++ b/packages/misc/src/index.ts
@@ -1,4 +1,7 @@
+export * from './lib/addresses';
export * from './lib/misc';
+export * from './lib/params-validators';
+export * from './lib/utils';
export {
validateSessionSig,
validateSessionSigs,
diff --git a/packages/misc/src/lib/addresses.spec.ts b/packages/misc/src/lib/addresses.spec.ts
new file mode 100644
index 0000000000..3fff59c663
--- /dev/null
+++ b/packages/misc/src/lib/addresses.spec.ts
@@ -0,0 +1,21 @@
+import { derivedAddresses } from './addresses';
+
+const COMPRESSED_PUBLIC_KEY =
+ '02e5896d70c1bc4b4844458748fe0f936c7919d7968341e391fb6d82c258192e64';
+
+describe('adddresses', () => {
+ it('should return the derived address from a compressed eth public key', async () => {
+ const derivedAddress = await derivedAddresses({
+ publicKey: COMPRESSED_PUBLIC_KEY,
+ });
+ expect(derivedAddress).toEqual({
+ tokenId: undefined,
+ publicKey: `0x${COMPRESSED_PUBLIC_KEY}`,
+ publicKeyBuffer: Buffer.from(COMPRESSED_PUBLIC_KEY, 'hex'),
+ ethAddress: '0x7206cB69380ee83c4Ef13f05713e814F3e4dee0f',
+ btcAddress: '1HD3rsQMzn5iJJJMeiZSgzbUkai2UhphbY',
+ cosmosAddress: 'cosmos1k8ykgtjwxzvzmwzdpenjp56g9cf77jvhu7p703',
+ isNewPKP: false,
+ });
+ });
+});
diff --git a/packages/misc/src/lib/addresses.ts b/packages/misc/src/lib/addresses.ts
new file mode 100644
index 0000000000..6da0f8666a
--- /dev/null
+++ b/packages/misc/src/lib/addresses.ts
@@ -0,0 +1,358 @@
+import {
+ MultiError,
+ NoWalletException,
+ ParamsMissingError,
+} from '@lit-protocol/constants';
+import { TokenInfo } from '@lit-protocol/types';
+import { bech32 } from 'bech32';
+import { createHash } from 'crypto';
+import { Contract, ethers } from 'ethers';
+import { computeAddress } from 'ethers/lib/utils';
+
+/**
+ * Converts a public key between compressed and uncompressed formats.
+ *
+ * @param publicKey - Public key as a Buffer (33 bytes compressed or 65 bytes uncompressed)
+ * @param compressed - Boolean flag indicating whether the output should be compressed
+ * @returns Converted public key as a Buffer
+ */
+export function publicKeyConvert(
+ publicKey: Buffer,
+ compressed: boolean = true
+): Buffer {
+ if (compressed) {
+ // Compress the public key (if it's not already compressed)
+ if (publicKey.length === 65 && publicKey[0] === 0x04) {
+ const x = publicKey.subarray(1, 33);
+ const y = publicKey.subarray(33, 65);
+ const prefix = y[y.length - 1] % 2 === 0 ? 0x02 : 0x03;
+ return Buffer.concat([Buffer.from([prefix]), x]);
+ }
+ } else {
+ // Decompress the public key
+ if (
+ publicKey.length === 33 &&
+ (publicKey[0] === 0x02 || publicKey[0] === 0x03)
+ ) {
+ const x = publicKey.subarray(1);
+ const y = decompressY(publicKey[0], x);
+ return Buffer.concat([Buffer.from([0x04]), x, y]);
+ }
+ }
+ // Return the original if no conversion is needed
+ return publicKey;
+}
+
+/**
+ * Decompresses the y-coordinate of a compressed public key.
+ *
+ * @param prefix - The first byte of the compressed public key (0x02 or 0x03)
+ * @param x - The x-coordinate of the public key
+ * @returns The decompressed y-coordinate as a Buffer
+ */
+function decompressY(prefix: number, x: Buffer): Buffer {
+ const p = BigInt(
+ '0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'
+ );
+ const a = BigInt('0');
+ const b = BigInt('7');
+
+ const xBigInt = BigInt('0x' + x.toString('hex'));
+ const rhs = (xBigInt ** 3n + a * xBigInt + b) % p;
+ const yBigInt = modSqrt(rhs, p);
+
+ const isEven = yBigInt % 2n === 0n;
+ const y = isEven === (prefix === 0x02) ? yBigInt : p - yBigInt;
+
+ return Buffer.from(y.toString(16).padStart(64, '0'), 'hex');
+}
+
+/**
+ * Computes the modular square root of a number.
+ *
+ * @param a - The number to find the square root of
+ * @param p - The modulus
+ * @returns The square root modulo p
+ */
+function modSqrt(a: bigint, p: bigint): bigint {
+ return a ** ((p + 1n) / 4n) % p;
+}
+
+/**
+ * Derives a Bitcoin address (P2PKH) from a public key.
+ *
+ * @param ethPubKey - Public key as a hex string (uncompressed or compressed)
+ * @returns Bitcoin address as a Base58Check string
+ */
+function deriveBitcoinAddress(ethPubKey: string): string {
+ // Remove the "0x" prefix if it exists and convert to a Buffer
+ if (ethPubKey.startsWith('0x')) {
+ ethPubKey = ethPubKey.slice(2);
+ }
+
+ const pubkeyBuffer = Buffer.from(ethPubKey, 'hex');
+
+ // Perform SHA-256 hashing on the public key
+ const sha256Hash = createHash('sha256').update(pubkeyBuffer).digest();
+
+ // Perform RIPEMD-160 hashing on the result of SHA-256
+ const ripemd160Hash = createHash('ripemd160').update(sha256Hash).digest();
+
+ // Add version byte in front of RIPEMD-160 hash (0x00 for mainnet)
+ const versionedPayload = Buffer.concat([Buffer.from([0x00]), ripemd160Hash]);
+
+ // Create a checksum by hashing the versioned payload twice with SHA-256
+ const checksum = createHash('sha256')
+ .update(createHash('sha256').update(versionedPayload).digest())
+ .digest()
+ .subarray(0, 4);
+
+ // Concatenate the versioned payload and the checksum
+ const binaryBitcoinAddress = Buffer.concat([versionedPayload, checksum]);
+
+ // Encode the result with Base58 to get the final Bitcoin address and return it
+ return ethers.utils.base58.encode(binaryBitcoinAddress);
+}
+
+/**
+ * Derives a Cosmos address from an Ethereum public key.
+ *
+ * @param ethPubKey - Ethereum public key as a hex string (uncompressed, 130 characters long, or compressed, 66 characters long)
+ * @param prefix - Cosmos address prefix (e.g., "cosmos")
+ * @returns Cosmos address as a Bech32 string
+ */
+function deriveCosmosAddress(
+ ethPubKey: string,
+ prefix: string = 'cosmos'
+): string {
+ let pubKeyBuffer = Buffer.from(ethPubKey, 'hex');
+
+ // If the Ethereum public key is uncompressed (130 characters), compress it
+ if (pubKeyBuffer.length === 65 && pubKeyBuffer[0] === 0x04) {
+ pubKeyBuffer = Buffer.from(publicKeyConvert(pubKeyBuffer, true));
+ }
+
+ // Hash the compressed public key with SHA-256
+ const sha256Hash = createHash('sha256').update(pubKeyBuffer).digest();
+
+ // Hash the SHA-256 hash with RIPEMD-160
+ const ripemd160Hash = createHash('ripemd160').update(sha256Hash).digest();
+
+ // Encode the RIPEMD-160 hash with Bech32 and return it
+ return bech32.encode(prefix, bech32.toWords(ripemd160Hash));
+}
+
+type DerivedAddressesParams =
+ | {
+ publicKey: string;
+ pkpTokenId?: never;
+ pkpContractAddress?: never;
+ defaultRPCUrl?: never;
+ options?: never;
+ }
+ | {
+ publicKey?: never;
+ pkpTokenId: string;
+ pkpContractAddress: string;
+ defaultRPCUrl: string;
+ options?: {
+ cacheContractCall?: boolean;
+ };
+ };
+
+/**
+ * Derives multiple blockchain addresses (Ethereum, Bitcoin, and Cosmos) from a given uncompressed eth public key
+ * or PKP token ID. If a PKP token ID is provided, it retrieves the public key from the PKP contract.
+ *
+ * @param params - The parameters for deriving addresses.
+ * @param params.publicKey - The Ethereum public key as a hex string (optional). If not provided, pkpTokenId must be provided.
+ * @param params.pkpTokenId - The PKP token ID (optional). If not provided, publicKey must be provided.
+ * @param params.pkpContractAddress - The PKP contract address (optional). If not provided, a default address is used.
+ * @param params.defaultRPCUrl - The default RPC URL for connecting to the Ethereum network.
+ * @param params.options - Additional options (optional).
+ * @param params.options.cacheContractCall - Whether to cache the contract call result in local storage (default: false).
+ *
+ * @returns A Promise that resolves to an object containing token information:
+ * @property {string} tokenId - The PKP token ID.
+ * @property {string} publicKey - The Ethereum public key as a hex string.
+ * @property {Buffer} publicKeyBuffer - The buffer representation of the public key.
+ * @property {string} ethAddress - The derived Ethereum address.
+ * @property {string} btcAddress - The derived Bitcoin address.
+ * @property {string} cosmosAddress - The derived Cosmos address.
+ * @property {boolean} isNewPKP - Whether a new PKP was created.
+ *
+ * @throws {InvalidArgumentException} If the defaultRPCUrl is not provided.
+ * @throws {ParamsMissingError} If neither publicKey nor pkpTokenId is provided.
+ * @throws {MultiError} If any of the derived addresses (btcAddress, ethAddress, cosmosAddress) are undefined.
+ */
+export const derivedAddresses = async ({
+ publicKey,
+ pkpTokenId,
+ pkpContractAddress,
+ defaultRPCUrl,
+ options = {
+ cacheContractCall: false,
+ },
+}: DerivedAddressesParams): Promise => {
+ // one of the two must be provided
+ if (!publicKey && !pkpTokenId) {
+ throw new ParamsMissingError(
+ {
+ info: {
+ publicKey,
+ pkpTokenId,
+ },
+ },
+ 'publicKey or pkpTokenId must be provided'
+ );
+ }
+
+ // if pkpTokenId is provided, we must get the public key from it (in cache or from the contract)
+ let isNewPKP = false;
+ if (pkpTokenId) {
+ // try to get the public key from 'lit-cached-pkps' local storage
+ const CACHE_KEY = 'lit-cached-pkps';
+ let cachedPkpJSON;
+ try {
+ const cachedPkp = localStorage.getItem(CACHE_KEY);
+ if (cachedPkp) {
+ cachedPkpJSON = JSON.parse(cachedPkp);
+ publicKey = cachedPkpJSON[pkpTokenId];
+ }
+ } catch (e) {
+ console.error(e);
+ }
+
+ if (!publicKey) {
+ // Could not get the public key from the cache, so we need to get it from the contract
+ if (!defaultRPCUrl || !pkpContractAddress) {
+ throw new NoWalletException(
+ {
+ info: {
+ publicKey,
+ pkpTokenId,
+ pkpContractAddress,
+ defaultRPCUrl,
+ },
+ },
+ 'defaultRPCUrl or pkpContractAddress was not provided'
+ );
+ }
+
+ const provider = new ethers.providers.StaticJsonRpcProvider(
+ defaultRPCUrl
+ );
+
+ const contract = new Contract(
+ pkpContractAddress,
+ ['function getPubkey(uint256 tokenId) view returns (bytes memory)'],
+ provider
+ );
+
+ publicKey = await contract['getPubkey'](pkpTokenId);
+ isNewPKP = true;
+ }
+
+ if (options.cacheContractCall) {
+ // trying to store key value pair in local storage
+ try {
+ const cachedPkp = localStorage.getItem(CACHE_KEY);
+ if (cachedPkp) {
+ const cachedPkpJSON = JSON.parse(cachedPkp);
+ cachedPkpJSON[pkpTokenId] = publicKey;
+ localStorage.setItem(CACHE_KEY, JSON.stringify(cachedPkpJSON));
+ } else {
+ const cachedPkpJSON: Record = {};
+ cachedPkpJSON[pkpTokenId] = publicKey;
+ localStorage.setItem(CACHE_KEY, JSON.stringify(cachedPkpJSON));
+ }
+ } catch (e) {
+ console.error(e);
+ }
+ }
+ }
+
+ if (!publicKey) {
+ throw new NoWalletException(
+ {
+ info: {
+ publicKey,
+ pkpTokenId,
+ pkpContractAddress,
+ defaultRPCUrl,
+ },
+ },
+ 'publicKey was not provided or could not be obtained from the pkpTokenId'
+ );
+ }
+
+ if (publicKey.startsWith('0x')) {
+ publicKey = publicKey.slice(2);
+ }
+ const pubkeyBuffer = Buffer.from(publicKey, 'hex');
+
+ // get the address from the public key
+ const ethAddress = computeAddress(pubkeyBuffer);
+
+ // get the btc address from the public key
+ const btcAddress = deriveBitcoinAddress(publicKey);
+
+ // get cosmos address from the public key
+ const cosmosAddress = deriveCosmosAddress(publicKey);
+
+ if (!btcAddress || !ethAddress || !cosmosAddress) {
+ // push to error reporting service
+ const errors = [];
+
+ if (!btcAddress) {
+ errors.push(
+ new NoWalletException(
+ {
+ info: {
+ publicKey,
+ },
+ },
+ 'btcAddress is undefined'
+ )
+ );
+ }
+
+ if (!ethAddress) {
+ errors.push(
+ new NoWalletException(
+ {
+ info: {
+ publicKey,
+ },
+ },
+ 'ethAddress is undefined'
+ )
+ );
+ }
+
+ if (!cosmosAddress) {
+ errors.push(
+ new NoWalletException(
+ {
+ info: {
+ publicKey,
+ },
+ },
+ 'cosmosAddress is undefined'
+ )
+ );
+ }
+
+ throw new MultiError(errors);
+ }
+
+ return {
+ tokenId: pkpTokenId,
+ publicKey: `0x${publicKey}`,
+ publicKeyBuffer: pubkeyBuffer,
+ ethAddress,
+ btcAddress,
+ cosmosAddress,
+ isNewPKP,
+ };
+};
diff --git a/packages/misc/src/lib/misc.spec.ts b/packages/misc/src/lib/misc.spec.ts
index 12cfb8c0d1..f20dc60508 100644
--- a/packages/misc/src/lib/misc.spec.ts
+++ b/packages/misc/src/lib/misc.spec.ts
@@ -4,7 +4,6 @@ global.TextEncoder = TextEncoder;
// @ts-ignore
global.TextDecoder = TextDecoder;
-import { LitErrorKind, LIT_ERROR, CAYENNE_URL } from '@lit-protocol/constants';
import * as utilsModule from './misc';
describe('utils', () => {
@@ -45,60 +44,12 @@ describe('utils', () => {
expect(mostOccured).toBe(0);
});
- it('should throwError in the Lit standardized way', () => {
- let err: Error;
-
- try {
- err = utilsModule.throwError({
- message: 'Message!',
- errorKind: 'hello',
- errorCode: 'world',
- });
- } catch (e) {
- err = e as Error;
- }
-
- const keys = Object.keys(err);
- const values = Object.values(err);
-
- expect(keys).toContain('message');
- expect(keys).toContain('errorKind');
- expect(keys).toContain('errorCode');
- expect(values).toContain('Message!');
- expect(values).toContain('hello');
- expect(values).toContain('world');
- });
-
- // it('should able to use the error type from constants', () => {
- // let err: Error;
-
- // try {
- // err = utilsModule.throwError({
- // message: 'custom message',
- // errorKind: LIT_ERROR.INVALID_PARAM_TYPE.kind,
- // errorCode: LIT_ERROR.INVALID_PARAM_TYPE.name,
- // });
- // } catch (e) {
- // err = e as Error;
- // }
-
- // const keys = Object.keys(err);
- // const values = Object.values(err);
-
- // expect(keys).toContain('message');
- // expect(keys).toContain('errorKind');
- // expect(keys).toContain('errorCode');
- // expect(values).toContain('custom message');
- // expect(values).toContain(LitErrorKind.Validation);
- // expect(values).toContain(LIT_ERROR.INVALID_PARAM_TYPE.name);
- // });
-
it('should get value type by a given value', () => {
const fooString = 'fooString';
const fooBool = true;
const fooNumber = 6;
const fooList: number[] = [1, 2, 3];
- const fooArray: Array = ['a', 'b', 'c'];
+ const fooArray: string[] = ['a', 'b', 'c'];
const fooTuple: [string, number] = ['hello', 10];
const fooUint8Arr = new Uint8Array([1, 2, 3, 4, 5]);
const fooUint16Arr = new Uint16Array([1, 2, 3, 4, 5]);
diff --git a/packages/misc/src/lib/misc.ts b/packages/misc/src/lib/misc.ts
index e91d0b5f5b..e2fa8a36b1 100644
--- a/packages/misc/src/lib/misc.ts
+++ b/packages/misc/src/lib/misc.ts
@@ -1,40 +1,44 @@
+import { LitNodeClientConfig } from '@lit-protocol/types';
+import { Contract } from '@ethersproject/contracts';
+import { JsonRpcProvider } from '@ethersproject/providers';
+import Ajv, { JSONSchemaType } from 'ajv';
+
import {
ABI_ERC20,
- ILitError,
+ InvalidArgumentException,
+ InvalidParamType,
LIT_AUTH_SIG_CHAIN_KEYS,
LIT_CHAINS,
- LIT_ERROR,
LIT_NETWORK,
LIT_NETWORK_VALUES,
+ LOG_LEVEL,
+ LOG_LEVEL_VALUES,
+ NetworkError,
RELAYER_URL_BY_NETWORK,
+ RemovedFunctionError,
+ UnknownError,
+ WrongNetworkException,
} from '@lit-protocol/constants';
-
+import { LogManager } from '@lit-protocol/logger';
import {
Chain,
AuthSig,
- KV,
- NodeClientErrorV0,
- NodeClientErrorV1,
- NodeErrorV1,
NodeErrorV3,
- ClaimRequest,
- ClaimKeyResponse,
ClaimResult,
- ClaimProcessor,
MintCallback,
RelayClaimProcessor,
- SuccessNodePromises,
- RejectedNodePromises,
} from '@lit-protocol/types';
-import { JsonRpcProvider } from '@ethersproject/providers';
-import { Contract } from '@ethersproject/contracts';
-import { LogLevel, LogManager } from '@lit-protocol/logger';
-import { version } from '@lit-protocol/constants';
-import Ajv, { JSONSchemaType } from 'ajv';
-const logBuffer: Array> = [];
+const logBuffer: any[][] = [];
const ajv = new Ajv();
+// Module scoped variable to store the LitNodeClientConfig passed to LitCore
+let litConfig: LitNodeClientConfig | undefined;
+
+export const setMiscLitConfig = (config: LitNodeClientConfig | undefined) => {
+ litConfig = config;
+};
+
/**
*
* Print error message based on Error interface
@@ -55,25 +59,25 @@ export const printError = (e: Error): void => {
* @param { Array } arr
* @returns { any } the element that appeared the most
*/
-export const mostCommonString = (arr: Array): any => {
+export const mostCommonString = (arr: T[]): T | undefined => {
return arr
.sort(
- (a: any, b: any) =>
- arr.filter((v: any) => v === a).length -
- arr.filter((v: any) => v === b).length
+ (a: T, b: T) =>
+ arr.filter((v: T) => v === a).length -
+ arr.filter((v: T) => v === b).length
)
.pop();
};
-export const findMostCommonResponse = (responses: Array