diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..0cd2388
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,10 @@
+{
+ "env": {
+ "test": {
+ "plugins": [
+ "transform-es2015-modules-commonjs",
+ "syntax-dynamic-import"
+ ]
+ }
+ }
+}
diff --git a/.browserslistrc b/.browserslistrc
new file mode 100644
index 0000000..d6471a3
--- /dev/null
+++ b/.browserslistrc
@@ -0,0 +1,2 @@
+> 1%
+last 2 versions
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..e89e2d6
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,2 @@
+back_node_modules/
+dist/
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..0d55ef1
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,29 @@
+module.exports = {
+ root: true,
+ env: {
+ node: true,
+ },
+ extends: [
+ 'eslint:recommended',
+ 'plugin:@typescript-eslint/recommended',
+ 'plugin:vue/recommended',
+ '@vue/typescript',
+ 'prettier/vue',
+ 'prettier/@typescript-eslint',
+ 'plugin:prettier/recommended',
+ ],
+ plugins: ['vue', '@typescript-eslint'],
+ rules: {
+ '@typescript-eslint/ban-ts-ignore': 'off',
+ '@typescript-eslint/explicit-function-return-type': 'off',
+ '@typescript-eslint/camelcase': 'off',
+ '@typescript-eslint/interface-name-prefix': 'off',
+ '@typescript-eslint/no-explicit-any': 'off',
+ '@typescript-eslint/no-inferrable-types': 'off',
+ curly: 2,
+ 'no-extra-boolean-cast': 0,
+ // @TODO: remove v-html
+ 'vue/no-v-html': 'off',
+ 'no-useless-escape': 'off',
+ },
+}
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..77a079b
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+github: UsingBlockchain
+patreon: usingblockchainltd
+custom: ["https://www.paypal.me/usingblockchainltd"]
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6ee3fce
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,25 @@
+.quokka
+.DS_Store
+node_modules
+/dist
+/release
+/tests
+.git
+.idea
+.vscode
+.run
+*.iml
+*.js.map
+/www
+src/**/*.map
+src/**/*.js
+coverage
+build
+__tests__/**/*.map
+__tests__/**/*.js
+__mocks__/**/*.map
+__mocks__/**/*.js
+/.templates
+template.config.js
+.env
+keys-whitelist.json
diff --git a/.prettierrc.js b/.prettierrc.js
new file mode 100644
index 0000000..2e20a7d
--- /dev/null
+++ b/.prettierrc.js
@@ -0,0 +1,8 @@
+module.exports = {
+ semi: true,
+ trailingComma: 'all',
+ singleQuote: true,
+ printWidth: 140,
+ tabWidth: 4,
+ endOfLine: 'auto',
+};
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..caa29c4
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,54 @@
+language: node_js
+services:
+ - docker
+node_js:
+ - 12
+os:
+ - linux
+# - osx
+#osx_image: xcode11.3
+env:
+ global:
+ - ELECTRON_CACHE=$HOME/.cache/electron
+ - ELECTRON_BUILDER_CACHE=$HOME/.cache/electron-builder
+cache:
+ directories:
+ - node_modules
+ - $HOME/.cache/electron
+ - $HOME/.cache/electron-builder
+before_cache:
+ - rm -rf $HOME/.cache/electron-builder/wine
+script:
+ - npm run build:web
+jobs:
+ include:
+ - stage: test
+ name: lint tests
+ script: npm run lint
+ os: linux
+
+ - name: unit tests
+ script: npm run test
+ os: linux
+
+ # - stage: alpha
+ # name: publish alpha docker
+ # script: /bin/sh travis/docker.sh
+ # if: branch = env(DEV_BRANCH) AND type = push
+ # os: linux
+
+ - script: npm run release:all
+ name: build desktop artifacts
+ if: branch = env(DEV_BRANCH) AND type = push
+ os: linux
+
+ # - stage: release
+ # name: release docker
+ # script: /bin/sh travis/docker.sh
+ # if: branch = env(RELEASE_BRANCH) AND type = api AND commit_message = env(RELEASE_MESSAGE)
+ # os: linux
+
+ # - name: release desktop artifacts, tag and update version
+ # script: /bin/sh travis/release.sh
+ # if: branch = env(RELEASE_BRANCH) AND type = api AND commit_message = env(RELEASE_MESSAGE)
+ # os: linux
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..10ec146
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,17 @@
+# CHANGELOG
+All notable changes to this project will be documented in this file.
+
+The changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+
+## [1.0.0][1.0.0] - 03-May-2021
+
+#### Changed
+
+- Changed default testnet network to dHealth Test Network
+- Changed default mainnet network to dHealth Public Network
+
+#### Known Issues
+
+- Some missing re-branding items for dHealth logos.
+
+[1.0.0]: https://github.com/dhealthproject/dhealth-wallet/releases/tag/v1.0.0
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..25408f2
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at support@nem.group. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..6fee63e
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,76 @@
+# Contributing to dhealth-wallet
+
+First off, thank you for considering contributing to dhealth-wallet.
+
+The dhealth-wallet is an open source project and we love to receive contributions from our community — you!
+
+Following these guidelines helps to communicate that you respect the time of
+the developers managing and developing this open source project. In return,
+they should reciprocate that respect in addressing your issue, assessing changes,
+and help you finalize your pull requests.
+
+## Error reports
+
+If you think you have found an error in the dhealth-wallet, first make sure that you
+are testing against the latest version of dhealth-wallet - your issue may already
+have been fixed. If not, search our issues list on GitHub in case a similar
+issue has already been opened.
+
+It is very helpful if you can prepare a reproduction of the error. It makes it easier to
+find the problem and to fix it.
+
+Please, take into consideration the next template to report your issue:
+
+ **Describe the error**
+ A clear and concise description of what the error is.
+
+ **To Reproduce**
+ Steps to reproduce the behavior:
+ 1. Go to '...'
+ 2. Click on '....'
+ 3. Scroll down to '....'
+ 4. See error
+
+ **Expected behavior**
+ A clear and concise description of what you expected to happen.
+
+ **Screenshots**
+ If applicable, add screenshots to help explain your problem.
+
+Open a new issue [here][github-issues].
+
+## Contributing code and documentation changes
+
+To expand and improve the dhealth-wallet, please find or open an issue about it first.
+
+Talk about what you would like to do. It may be that somebody is already working on it,
+or that there are particular issues that you should know about before implementing the change.
+
+We enjoy working with contributors to get their pull-requests accepted.
+
+### Contributing License Notice
+
+When you contribute code, you affirm that the contribution is your original work and that you license the work to the project under the project's open source license.
+
+Whether or not you state this explicitly, by submitting any copyrighted material via pull request, email, or other means you agree to license the material under the project's open source license and warrant that you have the legal authority to do so.
+
+### Submitting your changes
+
+Once your changes and tests are ready to submit for review:
+
+1. Test your changes.
+
+ ``npm run dev``
+
+ Make sure that nothing is broken.
+
+2. Submit a pull request.
+
+ Push your local changes to your forked copy of the repository and [submit a pull request](https://help.github.com/articles/about-pull-requests/) targeting the **master branch**. In the pull request, choose a title which sums up the changes that you have made, and in the body provide more details about what your changes do. Also mention the number of the issue where discussion has taken place, eg "Closes #123".
+
+Then sit back and wait. There will probably be a discussion about the pull request and, if any changes are needed, we would love to work with you to get your pull request merged into dhealth-wallet.
+
+*CONTRIBUTING.md is based on [CONTRIBUTING-template.md](https://github.com/nayafia/contributing-template/blob/master/CONTRIBUTING-template.md)* , [elasticsearch/CONTRIBUTING](https://github.com/elastic/elasticsearch/blob/master/CONTRIBUTING.md) and [spark/CONTRIBUTING](https://github.com/apache/spark/blob/master/CONTRIBUTING.md)
+
+[pull-request]: https://help.github.com/articles/about-pull-requests/
+[github-issues]: https://github.com/dhealthproject/dhealt-walleth/issues
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..2db82b3
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,21 @@
+FROM node:lts-alpine AS builder
+
+# Python and Make
+#ENV PYTHONUNBUFFERED=1
+#RUN apk add --update --no-cache python3 && ln -sf python3 /usr/bin/python
+#RUN python3 -m ensurepip
+#RUN pip3 install --no-cache --upgrade pip setuptools
+#RUN apk add g++ make python
+#RUN node --version
+#RUN apk add --update pkgconfig
+
+WORKDIR /app
+COPY . .
+RUN export WEB=true && npm install && npm run build
+
+FROM nginx:1.17-alpine AS runner
+COPY --from=builder /app/dist /usr/share/nginx/html
+COPY ./docker/default.conf /etc/nginx/conf.d/default.conf
+WORKDIR /usr/share/nginx/html
+EXPOSE 80
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/LICENCE b/LICENCE
new file mode 100644
index 0000000..b70e765
--- /dev/null
+++ b/LICENCE
@@ -0,0 +1,202 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright 2019-2020 NEM
+ Copyright 2021-present Using Blockchain Ltd, All rights reserved.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d290723
--- /dev/null
+++ b/README.md
@@ -0,0 +1,101 @@
+
+
+
+# dHealth Wallet
+
+[![npm-badge][npm-badge]][npm-url]
+[![dl-badge][dl-badge]][npm-url]
+[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
+
+Cross-platform software for dHealth Public Blockchain Network to manage profiles, assets, registered names, and transact with others on the network.
+
+This software lets you connect to [dHealth Public Network](https://dhealth.network) - as well as test networks for dHealth.
+
+- [Installation](#installation)
+- [Developers](#developers)
+- [Sponsor Us](#sponsor-us)
+- [Disclaimer](#disclaimer)
+- [Licensing](#license)
+
+## Installation
+
+dHealth Wallet is available for Mac, Windows, and as a web application.
+
+1. Download dHealth Wallet from the [releases section](https://github.com/dhealthproject/dhealth-wallet/releases).
+
+2. Launch the executable file and follow the installation instructions.
+
+3. Create a profile. Remember to save the mnemonic somewhere safe (offline).
+
+## Developers
+
+### Requirements
+
+- [Node 10+](https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-20-04)
+
+Validate your environment by running:
+
+```bash
+node -v
+```
+
+### Building
+
+Developers can use this software and build awesome new features. Pull requests are very much appreciated.
+
+This software requires **Node.js 10 or 12 LTS** to build and execute in development environment.
+
+1. Clone the project.
+
+```
+git clone https://github.com/dhealthproject/dhealth-wallet.git
+```
+
+2. Install the dependencies.
+```
+cd dhealth-wallet
+npm install
+```
+
+3. Start the development server.
+
+```
+npm run dev
+```
+
+4. Visit http://localhost:8080/#/ in your browser.
+
+## Donations / Pot de vin
+
+Donations can also be made with cryptocurrencies and will be used for running the project!
+
+ NEM (XEM): NB72EM6TTSX72O47T3GQFL345AB5WYKIDODKPPYW
+ Symbol (XYM): NDQALDK4XWLOUYKPE7RDEWUI25YNRQ7VCGXMPCI
+ Ethereum (ETH): 0x7a846fd5Daa4b904caF7C59f866bb906153305D2
+ Bitcoin (BTC): 3EVqgUqYFRYbf9RjhyjBgKXcEwAQxhaf6o
+
+## Sponsor us
+
+| Platform | Sponsor Link |
+| --- | --- |
+| Paypal | [https://paypal.me/usingblockchainltd](https://paypal.me/usingblockchainltd) |
+| Patreon | [https://patreon.com/usingblockchainltd](https://patreon.com/usingblockchainltd) |
+| Github | [https://github.com/sponsors/UsingBlockchain](https://github.com/sponsors/UsingBlockchain) |
+
+## Disclaimer
+
+ *The author of this package cannot be held responsible for any loss of money or any malintentioned usage forms of this package. Please use this package with caution.*
+
+ *Our software contains links to the websites of third parties (“external links”). As the content of these websites is not under our control, we cannot assume any liability for such external content. In all cases, the provider of information of the linked websites is liable for the content and accuracy of the information provided. At the point in time when the links were placed, no infringements of the law were recognisable to us..*
+
+## License
+
+Copyright 2020 NEM.
+Copyright 2021-present [Using Blockchain Ltd][ref-ltd], All rights reserved.
+
+Licensed under the [Apache License 2.0](LICENSE)
+
+[ref-ltd]: https://using-blockchain.org
+[npm-url]: https://www.npmjs.com/package/dhealth-wallet
+[npm-badge]: https://img.shields.io/npm/v/dhealth-wallet
+[dl-badge]: https://img.shields.io/npm/dt/dhealth-wallet
diff --git a/Vue.config-back.js b/Vue.config-back.js
new file mode 100644
index 0000000..a1c7c98
--- /dev/null
+++ b/Vue.config-back.js
@@ -0,0 +1,21 @@
+const webpack = require('webpack');
+
+const packageVersion = JSON.stringify(require('./package.json').version);
+const web = process.env.WEB || false;
+
+console.log(`Building package ${packageVersion} for Web: ${web}`);
+
+module.exports = {
+ configureWebpack: () => {
+ return {
+ plugins: [
+ new webpack.DefinePlugin({
+ 'process.env': {
+ PACKAGE_VERSION: packageVersion,
+ WEB: web,
+ },
+ }),
+ ],
+ };
+ },
+};
diff --git a/__mocks__/Accounts.ts b/__mocks__/Accounts.ts
new file mode 100644
index 0000000..bafc0d7
--- /dev/null
+++ b/__mocks__/Accounts.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { SimpleWallet, Account, NetworkType, Password } from 'symbol-sdk';
+
+// internal dependencies
+import { AccountModel, AccountType } from '@/core/database/entities/AccountModel';
+
+export const account1Params = {
+ accountName: 'account_name',
+ privateKey: '145160ba92878447cb45d6cb147d2ade035b0b47cab1b9e1551aa5679d92b314',
+ networkType: NetworkType.MIJIN_TEST,
+ password: new Password('password1'),
+};
+
+export const account1 = Account.createFromPrivateKey(account1Params.privateKey, account1Params.networkType);
+
+export const simpleWallet1 = SimpleWallet.createFromPrivateKey(
+ account1Params.accountName,
+ account1Params.password,
+ account1Params.privateKey,
+ account1Params.networkType,
+);
+
+export const WalletsModel1: AccountModel = {
+ id: 'someId',
+ node: '',
+ profileName: 'profile_name',
+ name: account1Params.accountName,
+ type: AccountType.PRIVATE_KEY,
+ address: simpleWallet1.address.plain(),
+ publicKey: account1.publicKey,
+ encryptedPrivateKey: simpleWallet1.encryptedPrivateKey,
+ path: '',
+ isMultisig: false,
+};
+
+export const WalletsModel2: AccountModel = {
+ id: 'someId2',
+ node: '',
+ profileName: 'profile1',
+ name: account1Params.accountName,
+ type: AccountType.SEED,
+ address: simpleWallet1.address.plain(),
+ publicKey: account1.publicKey,
+ encryptedPrivateKey: simpleWallet1.encryptedPrivateKey,
+ path: "m/44'/1'/1'/0'/0'",
+ isMultisig: false,
+};
+
+const TEST_ACCOUNTS = {
+ cosigner1: {
+ networkType: NetworkType.MIJIN_TEST,
+ privateKey: '27002B109810E4C25E8E6AE964FAF129CC3BFD1A95CB99062E0205060041D0C9',
+ },
+ remoteTestnet: {
+ networkType: NetworkType.TEST_NET,
+ privateKey: '803040D4A33983C4B233C6C2054A24B9C655E8CAC6C06AECCED56B8FE424FF2B',
+ },
+ remoteMijin: {
+ networkType: NetworkType.MIJIN_TEST,
+ privateKey: '803040D4A33983C4B233C6C2054A24B9C655E8CAC6C06AECCED56B8FE424FF2B',
+ },
+ cosigner2: {
+ networkType: NetworkType.MIJIN_TEST,
+ privateKey: '8472FA74A64A97C85F0A285299D9FD2D44D71CB5698FE9C7E88C33001F9DD83F',
+ },
+ multisig1: {
+ networkType: NetworkType.MIJIN_TEST,
+ privateKey: 'CAD57FEC0C7F2106AD8A6203DA67EE675A1A3C232C676945306448DF5B4124F8',
+ },
+ multisig2: {
+ networkType: NetworkType.MIJIN_TEST,
+ privateKey: '72B08ACF80558B285EADA206BB1226A44038C65AC4649108B2284591641657B5',
+ },
+};
+
+export const getTestAccount = (name: string): Account => {
+ if (!(name in TEST_ACCOUNTS)) {
+ throw new Error('Test account with name: ' + name + ' could not be found in __mocks__/accounts.ts');
+ }
+
+ const spec = TEST_ACCOUNTS[name];
+ return Account.createFromPrivateKey(spec.privateKey, spec.networkType);
+};
diff --git a/__mocks__/Components.ts b/__mocks__/Components.ts
new file mode 100644
index 0000000..4cb336a
--- /dev/null
+++ b/__mocks__/Components.ts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import { createStore } from '@MOCKS/Store';
+import i18n from '@/language/index';
+
+/// region globals
+const localVue = createLocalVue();
+localVue.use(Vuex);
+/// end-region globals
+
+/// region helpers
+/**
+ * Create and *shallow* mount a component injecting
+ * store \a modules and \a state (namespaced).
+ * @param component
+ * @param modules
+ * @param state
+ */
+export const getComponent = (
+ component,
+ storeModules: { [name: string]: any },
+ stateChanges?: { [field: string]: any },
+ propsData?: { [field: string]: any },
+ stubsData?: { [field: string]: any },
+) => {
+ // - format store module overwrites
+ const modules = Object.keys(storeModules)
+ .map((k) => ({
+ [k]: Object.assign({}, storeModules[k], {
+ // - map state overwrites to store module
+ state: Object.assign({}, storeModules[k].state, stateChanges),
+ // - map unmodified getters
+ getters: storeModules[k].getters,
+ }),
+ }))
+ .reduce((obj, item) => {
+ // - reducer to get {profile: x, account: y} format
+ const key = Object.keys(item).shift();
+ obj[key] = item[key];
+ return obj;
+ }, {});
+
+ // - create fake store
+ const store = createStore({ modules });
+ const params = {
+ store,
+ i18n,
+ localVue,
+ };
+
+ if (propsData && Object.keys(propsData).length) {
+ params['propsData'] = propsData;
+ }
+
+ if (stubsData && Object.keys(stubsData).length) {
+ params['stubs'] = stubsData;
+ }
+
+ // - mount component
+ const wrapper = shallowMount(component, params);
+ return wrapper;
+};
+/// end-region helpers
diff --git a/__mocks__/MosaicConfigurations.ts b/__mocks__/MosaicConfigurations.ts
new file mode 100644
index 0000000..837809f
--- /dev/null
+++ b/__mocks__/MosaicConfigurations.ts
@@ -0,0 +1,26 @@
+export const mosaicConfigurations = {
+ B147F63C31CE2347: {
+ '05D6A80DE3C9ADCA': {
+ hidden: false,
+ },
+ '31774AAAC74F9A86': {
+ hidden: false,
+ },
+ '63B8C5F8A30F8F89': {
+ hidden: false,
+ },
+ '3B18F8E49D1536D6': {
+ hidden: false,
+ },
+ },
+ D0413A4634C85190: {
+ '05D6A80DE3C9ADCA': {
+ hidden: false,
+ },
+ },
+ '14113BE4FDA661C3': {
+ '5C981B3D74C23BD3': {
+ hidden: false,
+ },
+ },
+};
diff --git a/__mocks__/Store.ts b/__mocks__/Store.ts
new file mode 100644
index 0000000..4125f1b
--- /dev/null
+++ b/__mocks__/Store.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+/**
+ * Create a fake store
+ * @internal
+ * @param {any} storeOptions
+ */
+export const createStore = (storeOptions?: any) => {
+ const store = new Vuex.Store(storeOptions);
+ store.dispatch = jest.fn();
+ store.commit = jest.fn();
+ return store;
+};
diff --git a/__mocks__/mosaics.ts b/__mocks__/mosaics.ts
new file mode 100644
index 0000000..acea6f9
--- /dev/null
+++ b/__mocks__/mosaics.ts
@@ -0,0 +1,292 @@
+export const mosaicsMock = [
+ {
+ addressRawPlain: 'TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ name: 'symbol.xym',
+ isCurrencyMosaic: true,
+ balance: 15000000,
+ mosaicIdHex: '519FC24B9223E0B4',
+ divisibility: 6,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 0,
+ height: 1,
+ supply: 7841148552567058,
+ },
+ {
+ addressRawPlain: 'TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '2C56C7D764F17B09',
+ divisibility: 0,
+ transferable: true,
+ supplyMutable: true,
+ restrictable: true,
+ duration: 0,
+ height: 66506,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ name: 'root-name-space',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '534CD11F6D984B4B',
+ divisibility: 5,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 82104,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '119C8A107ACADD5F',
+ divisibility: 3,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 94672,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TDARSPFSZVLYGBOHGOVWIKAZ4FGGDPGZ3DSS7CQ',
+ ownerRawPlain: 'TCEPWMC37ZGXOGOXQOAGDYPI7YH65HLXIMLKNOQ',
+ name: 'symbol.xym',
+ isCurrencyMosaic: true,
+ balance: 958700624,
+ mosaicIdHex: '519FC24B9223E0B4',
+ divisibility: 6,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 0,
+ height: 1,
+ supply: 7841148552567058,
+ },
+ {
+ addressRawPlain: 'TDARSPFSZVLYGBOHGOVWIKAZ4FGGDPGZ3DSS7CQ',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '2C56C7D764F17B09',
+ divisibility: 0,
+ transferable: true,
+ supplyMutable: true,
+ restrictable: true,
+ duration: 0,
+ height: 66506,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TDARSPFSZVLYGBOHGOVWIKAZ4FGGDPGZ3DSS7CQ',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ name: 'root-name-space',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '534CD11F6D984B4B',
+ divisibility: 5,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 82104,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TDARSPFSZVLYGBOHGOVWIKAZ4FGGDPGZ3DSS7CQ',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '119C8A107ACADD5F',
+ divisibility: 3,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 94672,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ ownerRawPlain: 'TCEPWMC37ZGXOGOXQOAGDYPI7YH65HLXIMLKNOQ',
+ name: 'symbol.xym',
+ isCurrencyMosaic: true,
+ balance: 1819951406,
+ mosaicIdHex: '519FC24B9223E0B4',
+ divisibility: 6,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 0,
+ height: 1,
+ supply: 7841148552567058,
+ },
+ {
+ addressRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 500000000,
+ mosaicIdHex: '2C56C7D764F17B09',
+ divisibility: 0,
+ transferable: true,
+ supplyMutable: true,
+ restrictable: true,
+ duration: 0,
+ height: 66506,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ name: 'root-name-space',
+ isCurrencyMosaic: false,
+ balance: 500000000,
+ mosaicIdHex: '534CD11F6D984B4B',
+ divisibility: 5,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 82104,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 500000000,
+ mosaicIdHex: '119C8A107ACADD5F',
+ divisibility: 3,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 94672,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TCEPWMC37ZGXOGOXQOAGDYPI7YH65HLXIMLKNOQ',
+ name: 'symbol.xym',
+ isCurrencyMosaic: true,
+ balance: 979900272,
+ mosaicIdHex: '519FC24B9223E0B4',
+ divisibility: 6,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 0,
+ height: 1,
+ supply: 7841148552567058,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '2C56C7D764F17B09',
+ divisibility: 0,
+ transferable: true,
+ supplyMutable: true,
+ restrictable: true,
+ duration: 0,
+ height: 66506,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ name: 'root-name-space',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '534CD11F6D984B4B',
+ divisibility: 5,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 82104,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '119C8A107ACADD5F',
+ divisibility: 3,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 94672,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TCEPWMC37ZGXOGOXQOAGDYPI7YH65HLXIMLKNOQ',
+ name: 'symbol.xym',
+ isCurrencyMosaic: true,
+ balance: 998000304,
+ mosaicIdHex: '519FC24B9223E0B4',
+ divisibility: 6,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 0,
+ height: 1,
+ supply: 7841148552567058,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '2C56C7D764F17B09',
+ divisibility: 0,
+ transferable: true,
+ supplyMutable: true,
+ restrictable: true,
+ duration: 0,
+ height: 66506,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ name: 'root-name-space',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '534CD11F6D984B4B',
+ divisibility: 5,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 82104,
+ supply: 500000000,
+ },
+ {
+ addressRawPlain: 'TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY',
+ ownerRawPlain: 'TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ',
+ isCurrencyMosaic: false,
+ balance: 0,
+ mosaicIdHex: '119C8A107ACADD5F',
+ divisibility: 3,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ duration: 10000,
+ height: 94672,
+ supply: 500000000,
+ },
+];
diff --git a/__mocks__/multisigGraphInfo.ts b/__mocks__/multisigGraphInfo.ts
new file mode 100644
index 0000000..a0413ea
--- /dev/null
+++ b/__mocks__/multisigGraphInfo.ts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { MultisigAccountGraphInfo, MultisigAccountInfo, NetworkType, PublicAccount } from 'symbol-sdk';
+
+export const multisigGraphInfoPublicAccount1 = PublicAccount.createFromPublicKey(
+ 'B694186EE4AB0558CA4AFCFDD43B42114AE71094F5A1FC4A913FE9971CACD21D',
+ NetworkType.MIJIN_TEST,
+);
+export const multisigGraphInfoPublicAccount2 = PublicAccount.createFromPublicKey(
+ 'CF893FFCC47C33E7F68AB1DB56365C156B0736824A0C1E273F9E00B8DF8F01EB',
+ NetworkType.MIJIN_TEST,
+);
+export const multisigGraphInfoPublicAccount3 = PublicAccount.createFromPublicKey(
+ '68B3FBB18729C1FDE225C57F8CE080FA828F0067E451A3FD81FA628842B0B763',
+ NetworkType.MIJIN_TEST,
+);
+export const multisigGraphInfoPublicAccount4 = PublicAccount.createFromPublicKey(
+ 'DAB1C38C3E1642494FCCB33138B95E81867B5FB59FC4277A1D53761C8B9F6D14',
+ NetworkType.MIJIN_TEST,
+);
+export const multisigGraphInfoPublicAccount5 = PublicAccount.createFromPublicKey(
+ '1674016C27FE2C2EB5DFA73996FA54A183B38AED0AA64F756A3918BAF08E061B',
+ NetworkType.MIJIN_TEST,
+);
+
+export const multisigGraphInfoPublicAccounts = [
+ multisigGraphInfoPublicAccount1,
+ multisigGraphInfoPublicAccount2,
+ multisigGraphInfoPublicAccount3,
+ multisigGraphInfoPublicAccount4,
+ multisigGraphInfoPublicAccount5,
+];
+
+const multisigAccountGraphInfoDTO = {
+ level: -1,
+ multisigEntries: [
+ {
+ multisig: {
+ version: 1,
+ accountAddress: multisigGraphInfoPublicAccount1.address,
+ cosignatoryAddresses: [
+ multisigGraphInfoPublicAccount2.address,
+ multisigGraphInfoPublicAccount3.address,
+ multisigGraphInfoPublicAccount4.address,
+ ],
+ minApproval: 3,
+ minRemoval: 3,
+ multisigAddresses: [multisigGraphInfoPublicAccount5.address],
+ },
+ },
+ ],
+};
+
+export const multisigEntries1 = multisigAccountGraphInfoDTO.multisigEntries.map(
+ (multisigAccountInfoDTO) =>
+ new MultisigAccountInfo(
+ 1,
+ multisigAccountInfoDTO.multisig.accountAddress,
+ multisigAccountInfoDTO.multisig.minApproval,
+ multisigAccountInfoDTO.multisig.minRemoval,
+ multisigAccountInfoDTO.multisig.cosignatoryAddresses,
+ multisigAccountInfoDTO.multisig.multisigAddresses,
+ ),
+);
+
+const multisigAccountGraphInfoDTO2 = {
+ level: -2,
+ multisigEntries: [
+ {
+ multisig: {
+ version: 1,
+ accountAddress: multisigGraphInfoPublicAccount5.address,
+ cosignatoryAddresses: [multisigGraphInfoPublicAccount1.address],
+ minApproval: 1,
+ minRemoval: 1,
+ multisigAddresses: [],
+ },
+ },
+ ],
+};
+
+export const multisigEntries2 = multisigAccountGraphInfoDTO2.multisigEntries.map(
+ (multisigAccountInfoDTO) =>
+ new MultisigAccountInfo(
+ 1,
+ multisigAccountInfoDTO.multisig.accountAddress,
+ multisigAccountInfoDTO.multisig.minApproval,
+ multisigAccountInfoDTO.multisig.minRemoval,
+ multisigAccountInfoDTO.multisig.cosignatoryAddresses,
+ multisigAccountInfoDTO.multisig.multisigAddresses,
+ ),
+);
+
+const multisigAccounts = new Map();
+multisigAccounts.set(multisigAccountGraphInfoDTO.level, multisigEntries1);
+
+multisigAccounts.set(multisigAccountGraphInfoDTO2.level, multisigEntries2);
+
+export const multisigGraphInfo1 = new MultisigAccountGraphInfo(multisigAccounts);
diff --git a/__mocks__/profiles.ts b/__mocks__/profiles.ts
new file mode 100644
index 0000000..5d64eae
--- /dev/null
+++ b/__mocks__/profiles.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkType } from 'symbol-sdk';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+
+const TEST_PROFILES = {
+ profile1: {
+ generationHash: 'ACECD90E7B248E012803228ADB4424F0D966D24149B72E58987D2BF2F2AF03C4',
+ profileName: 'profile1',
+ hint: 'password is password',
+ networkType: NetworkType.MIJIN_TEST,
+ password: '0b831096cf25adbd7324ad2dbb3d99a829b40b53c6f76dd50fb2ef56fceded2f2kixTXdr/q/ci5PPwWVCiA==',
+ accounts: "['WalletsModel2']",
+ seed:
+ '4fcd1e1b896551f68c3d5314be1f8d2fad48d7b492e65ecf4ac1ac2dfc9749a08CyBF9Q5APg07qXEMWQzQIcN+/KBekkw0T2hBPfdAd5VxXkdzWikv46dIaYxyHCn9hdr839ITfgIWYnAiE54jRWfFKkDvyEZL4pchX6mAqCcc0Ew9VGFfHjKStHWFeBezrhp/MlNeSw/EbxiCFo5C2pmeSuGz5NABUXT+BoDi62gB8r6gyF9hjB8J7Lz6D4SBf6J4cvj9krCXzkkWX1jqg==',
+ },
+};
+
+export const getTestProfile = (name: string): ProfileModel => {
+ if (!(name in TEST_PROFILES)) {
+ throw new Error('Test account with name: ' + name + ' could not be found in __mocks__/accounts.ts');
+ }
+
+ return TEST_PROFILES[name];
+};
diff --git a/__tests__/components/AccountSelectorField.spec.ts b/__tests__/components/AccountSelectorField.spec.ts
new file mode 100644
index 0000000..e688930
--- /dev/null
+++ b/__tests__/components/AccountSelectorField.spec.ts
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { getComponent } from '@MOCKS/Components';
+import AccountStore from '@/store/Account';
+// @ts-ignore
+import AccountSelectorField from '@/components/AccountSelectorField/AccountSelectorField.vue';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+
+describe('components/AccountSelectorField', () => {
+ describe('getter for property "currentAccountIdentifier" should', () => {
+ test('return empty string given no currentAccount and no value', () => {
+ // prepare
+ const wrapper = getComponent(
+ AccountSelectorField,
+ { account: AccountStore },
+ {
+ currentAccount: null,
+ },
+ );
+ const component = wrapper.vm as AccountSelectorField;
+
+ // act
+ const actual = component.currentAccountIdentifier;
+
+ // assert
+ expect(actual).toBeDefined();
+ expect(actual.length).toBe(0);
+ });
+
+ test('return account identifier given value', () => {
+ // prepare
+ const account = { id: '5678' } as AccountModel;
+ const wrapper = getComponent(
+ AccountSelectorField,
+ { account: AccountStore },
+ {},
+ {
+ value: account.id,
+ },
+ );
+ const component = wrapper.vm as AccountSelectorField;
+
+ // act
+ const actual = component.currentAccountIdentifier;
+
+ // assert
+ expect(actual).toBeDefined();
+ expect(actual.length).toBe(4);
+ expect(actual).toBe('5678');
+ });
+ });
+
+ describe('setter for property "currentAccountIdentifier" should', () => {
+ test('do nothing given empty identifier', () => {
+ // prepare
+ const wrapper = getComponent(AccountSelectorField, { account: AccountStore }, {});
+ const component = wrapper.vm as AccountSelectorField;
+
+ // act
+ component.currentAccountIdentifier = '';
+ expect(wrapper.vm.$store.dispatch).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('getter for property "currentAccounts" should', () => {
+ test('return empty array given no knownAccounts', () => {
+ // prepare
+ const wrapper = getComponent(
+ AccountSelectorField,
+ { account: AccountStore },
+ {
+ knownAccounts: [],
+ },
+ );
+ const component = wrapper.vm as AccountSelectorField;
+
+ // act
+ const actual = component.currentAccounts;
+
+ // assert
+ expect(actual).toBeDefined();
+ expect(actual.length).toBe(0);
+ });
+ });
+});
diff --git a/__tests__/components/AmountDisplay.spec.ts b/__tests__/components/AmountDisplay.spec.ts
new file mode 100644
index 0000000..0788bbf
--- /dev/null
+++ b/__tests__/components/AmountDisplay.spec.ts
@@ -0,0 +1,53 @@
+import { AmountDisplayTs } from '@/components/AmountDisplay/AmountDisplayTs';
+//@ts-ignore
+import AmountDisplay from '@/components/AmountDisplay/AmountDisplay.vue';
+import { appConfig } from '@/config';
+import { createLocalVue, shallowMount, Wrapper } from '@vue/test-utils';
+import Vuex from 'vuex';
+import flushPromises from 'flush-promises';
+
+appConfig.constants.DECIMAL_SEPARATOR = '.';
+const localVue = createLocalVue();
+localVue.use(Vuex);
+const networkStore = {
+ namespaced: true,
+ getters: {
+ networkConfiguration: () => ({ maxMosaicDivisibility: 6 }),
+ },
+};
+const componentOptions = {
+ localVue,
+ store: new Vuex.Store({
+ modules: {
+ network: networkStore,
+ },
+ }),
+};
+
+describe('AmountDisplay', () => {
+ let amountDisplay: Wrapper;
+ let amountDisplayTs: AmountDisplayTs;
+
+ beforeEach(() => {
+ amountDisplay = shallowMount(AmountDisplay, componentOptions);
+ amountDisplayTs = amountDisplay.vm as AmountDisplayTs;
+ });
+
+ [
+ { input: 0, integerPart: '0', fractionalPart: '' },
+ { input: 1, integerPart: '1', fractionalPart: '' },
+ { input: 1.234, integerPart: '1', fractionalPart: '.234' },
+ { input: 0.234, integerPart: '0', fractionalPart: '.234' },
+ { input: -1, integerPart: '-1', fractionalPart: '' },
+ { input: -1.234, integerPart: '-1', fractionalPart: '.234' },
+ { input: -0.234, integerPart: '-0', fractionalPart: '.234' },
+ ].forEach((testCase) =>
+ test(`${testCase.input} should be displayed correctly`, async () => {
+ amountDisplay.setProps({ value: testCase.input });
+ await flushPromises();
+
+ expect(amountDisplayTs.integerPart).toEqual(testCase.integerPart);
+ expect(amountDisplayTs.fractionalPart).toEqual(testCase.fractionalPart);
+ }),
+ );
+});
diff --git a/__tests__/components/AmountInput.spec.ts b/__tests__/components/AmountInput.spec.ts
new file mode 100644
index 0000000..cf5d102
--- /dev/null
+++ b/__tests__/components/AmountInput.spec.ts
@@ -0,0 +1,109 @@
+//@ts-ignore
+import AmountInput from '@/components/AmountInput/AmountInput.vue';
+import { ValidationProvider, extend, validate } from 'vee-validate';
+
+import { mosaicsMock } from '@MOCKS/mosaics';
+import Vuex from 'vuex';
+import { mount, createLocalVue } from '@vue/test-utils';
+import flushPromises from 'flush-promises';
+import VueI18n, { Values } from 'vue-i18n';
+import i18n from '@/language/index';
+import { StandardValidationRules } from '@/core/validation/StandardValidationRules';
+import { MaxDecimalsValidator } from '@/core/validation/validators';
+import { appConfig } from '@/config';
+import { PositiveDecimalNumberValidator } from '@/core/validation/validators/PositiveDecimalNumberValidator';
+
+StandardValidationRules.register();
+appConfig.constants.DECIMAL_SEPARATOR = '.';
+extend('maxDecimals', {
+ validate: (value, args: any) => {
+ const { maxDecimalNumber } = args;
+ return MaxDecimalsValidator.validate(value, maxDecimalNumber);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('max_decimal_number_error', values)}`,
+ params: ['maxDecimalNumber'],
+});
+extend('positiveDecimal', {
+ validate: (value) => PositiveDecimalNumberValidator.validate(value),
+ message: () => i18n.t('positive_decimal_error', { decimalSeparator: appConfig.constants.DECIMAL_SEPARATOR }).toString(),
+});
+const localVue = createLocalVue();
+localVue.component('ValidationProvider', ValidationProvider);
+localVue.use(Vuex);
+localVue.use(VueI18n);
+const mosaicModule = {
+ namespaced: true,
+ getters: {
+ mosaics: () => {
+ return mosaicsMock;
+ },
+ },
+};
+const store = new Vuex.Store({
+ modules: {
+ mosaic: mosaicModule,
+ },
+});
+const options = {
+ localVue,
+ i18n,
+ store,
+ propsData: {
+ mosaicHex: '519FC24B9223E0B4',
+ },
+ stubs: ['Tooltip'],
+ sync: false,
+};
+const options2 = {
+ localVue,
+ i18n,
+ store,
+ propsData: {
+ mosaicHex: '534CD11F6D984B4B',
+ },
+ stubs: ['Tooltip'],
+ sync: false,
+};
+let wrapper;
+let wrapper2;
+
+describe('AmountInput', () => {
+ beforeEach(() => {
+ wrapper = mount(AmountInput, options);
+ wrapper2 = mount(AmountInput, options2);
+ });
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper2 = mount(AmountInput, options2);
+ });
+ test.skip('input correctly', async () => {
+ wrapper.setProps({
+ value: '10.12345678',
+ });
+ await flushPromises();
+ expect((wrapper.vm as AmountInput).relativeValue).toBe('10.12345678');
+ });
+ test.skip('output correctly', async () => {
+ wrapper.find('.input-style').setValue('10.1234567');
+ await flushPromises();
+ expect(wrapper.emitted().input[0]).toEqual(['10.1234567']);
+ });
+ test("divisibility of the mosaic '519FC24B9223E0B4' is 6", async () => {
+ const rule = wrapper.vm.validationRules.amount;
+ const falseResult = await validate('10.1234567', rule);
+ expect(falseResult.valid).toBeFalsy();
+ const rightResult = await validate('10.123456', rule);
+ expect(rightResult.valid).toBeTruthy();
+ });
+ test("divisibility of the mosaic '534CD11F6D984B4B' is 5", async () => {
+ wrapper2.setProps({
+ mosaicHex: '534CD11F6D984B4B',
+ });
+ await flushPromises();
+ const rule = wrapper2.vm.validationRules.amount;
+ const falseResult = await validate('10.123456', rule);
+ expect(falseResult.valid).toBeFalsy();
+ const rightResult = await validate('10.12345', rule);
+ expect(rightResult.valid).toBeTruthy();
+ });
+});
diff --git a/__tests__/components/ButtonCopyToClipboard.spec.ts b/__tests__/components/ButtonCopyToClipboard.spec.ts
new file mode 100644
index 0000000..017d4e8
--- /dev/null
+++ b/__tests__/components/ButtonCopyToClipboard.spec.ts
@@ -0,0 +1,40 @@
+import i18n from '@/language/index';
+import Vuex from 'vuex';
+//@ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { UIHelpers } from '@/core/utils/UIHelpers';
+const localVue = createLocalVue();
+
+const options = {
+ localVue,
+ Vuex,
+ i18n,
+ propsData: {
+ value: '123',
+ },
+ mocks: {
+ $store: {
+ dispatch: jest.fn(),
+ },
+ },
+};
+const wrapper = shallowMount(ButtonCopyToClipboard, options);
+
+const vm = wrapper.vm as ButtonCopyToClipboard;
+describe('ButtonCopyToClipboard', () => {
+ test('receive a property "value" correctly', () => {
+ expect(vm.value).toBe('123');
+ });
+ test('Click on Button should call method "copyToClipboard" when prop "value" exists', () => {
+ UIHelpers.copyToClipboard = jest.fn();
+ wrapper.find('Button').trigger('click');
+ expect(UIHelpers.copyToClipboard).toBeCalledWith('123');
+ });
+ test('Click on Button should call method "copyToClipboard" when prop "value" does not exists', () => {
+ UIHelpers.copyToClipboard = jest.fn();
+ wrapper.setProps({ value: null });
+ wrapper.find('Button').trigger('click');
+ expect(UIHelpers.copyToClipboard).not.toBeCalled();
+ });
+});
diff --git a/__tests__/components/FormLabel.spec.ts b/__tests__/components/FormLabel.spec.ts
new file mode 100644
index 0000000..4cc2cc2
--- /dev/null
+++ b/__tests__/components/FormLabel.spec.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { shallowMount } from '@vue/test-utils';
+// @ts-ignore
+import FormLabel from '@/components/FormLabel/FormLabel';
+
+describe('FormLabel', () => {
+ test('default slot should be load', () => {
+ const defaultSlot = 'this is a test slot
';
+ const wrapper = shallowMount(FormLabel, {
+ slots: {
+ default: defaultSlot,
+ },
+ });
+ expect(wrapper.vm.$el.textContent).toMatch('this is a test slot');
+ wrapper.destroy();
+ });
+});
diff --git a/__tests__/components/FormRow.spec.ts b/__tests__/components/FormRow.spec.ts
new file mode 100644
index 0000000..8684679
--- /dev/null
+++ b/__tests__/components/FormRow.spec.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { shallowMount } from '@vue/test-utils';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow';
+
+describe('FormRow', () => {
+ test('default slot should be load', () => {
+ const defaultSlot = 'this is a test label
';
+ const wrapper = shallowMount(FormRow, {
+ slots: {
+ label: defaultSlot,
+ },
+ });
+ expect(wrapper.vm.$el.textContent).toMatch('this is a test label');
+ wrapper.destroy();
+ });
+
+ test('inputs slot should be laod', () => {
+ const inputs = ' ';
+ const wrapper = shallowMount(FormRow, {
+ propsData: {
+ whitelisted: true,
+ },
+ slots: {
+ inputs: inputs,
+ },
+ });
+ expect(wrapper.vm.$el.querySelector('input').value).toBe('1');
+ wrapper.destroy();
+ });
+});
diff --git a/__tests__/components/FormWrapper.spec.ts b/__tests__/components/FormWrapper.spec.ts
new file mode 100644
index 0000000..76ca98b
--- /dev/null
+++ b/__tests__/components/FormWrapper.spec.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import i18n from 'vue-i18n';
+// @ts-ignore
+import FormWrapper from '@/components/FormWrapper/FormWrapper';
+// @ts-ignore
+import DisabledFormOverlay from '@/components/DisabledFormOverlay/DisabledFormOverlay';
+const localVue = createLocalVue();
+localVue.use(i18n);
+
+describe('FormWrapper', () => {
+ test('default slot should be load', () => {
+ const defaultSlot = 'this is a test slot
';
+ const wrapper = shallowMount(FormWrapper, {
+ slots: {
+ default: defaultSlot,
+ },
+ });
+ expect(wrapper.vm.$el.textContent).toMatch('this is a test slot');
+ wrapper.destroy();
+ });
+
+ test('DisabledFormOverlay should be laod when whitelisted is true', () => {
+ const wrapper = shallowMount(FormWrapper, {
+ localVue,
+ propsData: {
+ whitelisted: true,
+ },
+ slots: {
+ DisabledFormOverlay,
+ },
+ });
+ expect(wrapper.find('whitelisted').selector).toBe('whitelisted');
+ wrapper.destroy();
+ });
+});
diff --git a/__tests__/components/MosaicInputManager.spec.ts b/__tests__/components/MosaicInputManager.spec.ts
new file mode 100644
index 0000000..61113d7
--- /dev/null
+++ b/__tests__/components/MosaicInputManager.spec.ts
@@ -0,0 +1,88 @@
+import { MosaicInputsManager } from '@/views/forms/FormTransferTransaction/MosaicInputsManager.ts';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+
+export const mockMosaic1: MosaicModel = {
+ mosaicIdHex: '619CE7E50DB644DE',
+ balance: 1,
+} as MosaicModel;
+
+export const mockMosaic2: MosaicModel = {
+ mosaicIdHex: '28A59CC8B0C9E4DD',
+ balance: 1,
+} as MosaicModel;
+
+export const mockMosaic3: MosaicModel = {
+ mosaicIdHex: '2D58F9BF5F8C014D',
+ balance: 1,
+} as MosaicModel;
+
+const mockMosaics = [mockMosaic1, mockMosaic2, mockMosaic3];
+const mockMosaicHexIds = mockMosaics.map(({ mosaicIdHex }) => mosaicIdHex);
+
+describe('components/MosaicInputManager', () => {
+ describe('initialize() should', () => {
+ test('return an instantiated object', () => {
+ expect(MosaicInputsManager.initialize(mockMosaics)).toBeInstanceOf(MosaicInputsManager);
+ });
+ });
+
+ describe('hasFreeSlots() should', () => {
+ test('return true after initialization with mosaics provided', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize(mockMosaics);
+ expect(mosaicInputsManager.hasFreeSlots()).toBeTruthy();
+ });
+
+ test('return false after initialization with empty array', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize([]);
+ expect(mosaicInputsManager.hasFreeSlots()).toBeFalsy();
+ });
+ });
+
+ describe('setSlot() should', () => {
+ test('throw if a an unknown id is provided', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize([]);
+ expect(() => mosaicInputsManager.setSlot('wrongHexId', 1)).toThrowError();
+ });
+
+ test('throw if a mosaic is already affected to the slot', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize(mockMosaics);
+ mosaicInputsManager.setSlot(mockMosaicHexIds[1], 2);
+ expect(() => mosaicInputsManager.setSlot(mockMosaicHexIds[1], 1)).toThrowError();
+ });
+ });
+
+ describe('getMosaicsBySlot() should', () => {
+ test('return all mosaics after initialization with mosaics provided, for any slot', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize(mockMosaics);
+ expect(mosaicInputsManager.getMosaicsBySlot(0)).toStrictEqual(mockMosaicHexIds);
+ expect(mosaicInputsManager.getMosaicsBySlot(1)).toStrictEqual(mockMosaicHexIds);
+ expect(mosaicInputsManager.getMosaicsBySlot(2)).toStrictEqual(mockMosaicHexIds);
+ });
+
+ test('return an empty array after after initialization with empty array, for any slot', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize([]);
+ expect(mosaicInputsManager.getMosaicsBySlot(0)).toStrictEqual([]);
+ expect(mosaicInputsManager.getMosaicsBySlot(1)).toStrictEqual([]);
+ expect(mosaicInputsManager.getMosaicsBySlot(2)).toStrictEqual([]);
+ });
+
+ describe('contain expected mosaics after affectations', () => {
+ const mosaicInputsManager = MosaicInputsManager.initialize(mockMosaics);
+ mosaicInputsManager.setSlot(mockMosaicHexIds[1], 2);
+
+ const slot1Mosaics = mosaicInputsManager.getMosaicsBySlot(1);
+ const slot2Mosaics = mosaicInputsManager.getMosaicsBySlot(2);
+
+ expect(slot1Mosaics).toStrictEqual([mockMosaicHexIds[0], mockMosaicHexIds[2]]);
+ expect(slot2Mosaics).toStrictEqual([mockMosaicHexIds[1], mockMosaicHexIds[0], mockMosaicHexIds[2]]);
+
+ mosaicInputsManager.unsetSlot(2);
+ mosaicInputsManager.setSlot(mockMosaicHexIds[1], 1);
+ const slot1Mosaics2 = mosaicInputsManager.getMosaicsBySlot(1);
+ const slot2Mosaics2 = mosaicInputsManager.getMosaicsBySlot(2);
+
+ expect(slot1Mosaics2).toStrictEqual([mockMosaicHexIds[1], mockMosaicHexIds[0], mockMosaicHexIds[2]]);
+ expect(slot2Mosaics2).toStrictEqual([mockMosaicHexIds[0], mockMosaicHexIds[2]]);
+ });
+ });
+});
diff --git a/__tests__/components/MultisigCosignatoriesDisplay.spec.ts b/__tests__/components/MultisigCosignatoriesDisplay.spec.ts
new file mode 100644
index 0000000..0fbe8af
--- /dev/null
+++ b/__tests__/components/MultisigCosignatoriesDisplay.spec.ts
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+// @ts-ignore
+import MultisigCosignatoriesDisplay from '@/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplay';
+import { MultisigAccountInfo, NetworkType, PublicAccount } from 'symbol-sdk';
+import i18n from '@/language/index';
+
+const networkType = NetworkType.MAIN_NET;
+const account1 = PublicAccount.createFromPublicKey('B694186EE4AB0558CA4AFCFDD43B42114AE71094F5A1FC4A913FE9971CACD21D', networkType);
+const account2 = PublicAccount.createFromPublicKey('CF893FFCC47C33E7F68AB1DB56365C156B0736824A0C1E273F9E00B8DF8F01EB', networkType);
+const account3 = PublicAccount.createFromPublicKey('DAB1C38C3E1642494FCCB33138B95E81867B5FB59FC4277A1D53761C8B9F6D14', networkType);
+const account4 = PublicAccount.createFromPublicKey('1674016C27FE2C2EB5DFA73996FA54A183B38AED0AA64F756A3918BAF08E061B', networkType);
+const multisigInfo = new MultisigAccountInfo(1, account1.address, 1, 1, [account2.address, account3.address], []);
+
+describe('MultisigCosignatoriesDisplay', () => {
+ test('Getters should return correct values when no modifications', () => {
+ const wrapper = shallowMount(MultisigCosignatoriesDisplay, {
+ i18n,
+ propsData: {
+ multisig: multisigInfo,
+ modifiable: true,
+ cosignatoryModifications: {},
+ },
+ });
+
+ const component = wrapper.vm as MultisigCosignatoriesDisplay;
+
+ expect(component.addModifications).toEqual([]);
+ expect(component.removeModifications).toEqual([]);
+ expect(component.cosignatories).toEqual([{ address: account2.address }, { address: account3.address }]);
+
+ wrapper.destroy();
+ });
+
+ test('Getters should return correct values when there are modifications', () => {
+ const wrapper = shallowMount(MultisigCosignatoriesDisplay, {
+ i18n,
+ propsData: {
+ multisig: multisigInfo,
+ modifiable: true,
+ cosignatoryModifications: {
+ [account4.address.plain()]: { cosignatory: account4.address, addOrRemove: 'add' },
+ [account3.address.plain()]: { cosignatory: account3.address, addOrRemove: 'remove' },
+ },
+ },
+ });
+
+ const component = wrapper.vm as MultisigCosignatoriesDisplay;
+
+ expect(component.addModifications).toEqual([{ address: account4.address }]);
+ expect(component.removeModifications).toEqual([{ address: account3.address }]);
+ expect(component.cosignatories).toEqual([{ address: account2.address }]);
+
+ wrapper.destroy();
+ });
+
+ test('Should dispatch an error when adding a cosigner that is already one', () => {
+ const mockStoreDispatch = jest.fn();
+
+ const wrapper = shallowMount(MultisigCosignatoriesDisplay, {
+ i18n,
+ propsData: {
+ multisig: multisigInfo,
+ modifiable: true,
+ cosignatoryModifications: {},
+ },
+ mocks: {
+ $store: {
+ dispatch: mockStoreDispatch,
+ },
+ },
+ });
+
+ const component = wrapper.vm as MultisigCosignatoriesDisplay;
+
+ component.onAddCosignatory(account2.address);
+
+ expect(mockStoreDispatch).toHaveBeenCalledWith('notification/ADD_WARNING', 'warning_already_a_cosignatory');
+ wrapper.destroy();
+ });
+
+ test('Should dispatch an error when adding a cosigner has already been added', () => {
+ const mockStoreDispatch = jest.fn();
+
+ const wrapper = shallowMount(MultisigCosignatoriesDisplay, {
+ i18n,
+ propsData: {
+ multisig: multisigInfo,
+ modifiable: true,
+ cosignatoryModifications: {
+ [account4.address.plain()]: { cosignatory: account4.address, addOrRemove: 'add' },
+ },
+ },
+ mocks: {
+ $store: {
+ dispatch: mockStoreDispatch,
+ },
+ },
+ });
+
+ const component = wrapper.vm as MultisigCosignatoriesDisplay;
+
+ component.onAddCosignatory(account4.address);
+
+ expect(mockStoreDispatch).toHaveBeenCalledWith('notification/ADD_WARNING', 'warning_already_a_cosignatory');
+ wrapper.destroy();
+ });
+
+ test('Should emit when adding a cosigner', async () => {
+ const vue = createLocalVue();
+ vue.use(Vuex);
+
+ const wrapper = shallowMount(MultisigCosignatoriesDisplay, {
+ i18n,
+ propsData: {
+ multisig: multisigInfo,
+ modifiable: true,
+ cosignatoryModifications: {},
+ },
+ mocks: {
+ $store: {
+ dispatch: jest.fn(() => true),
+ },
+ },
+ });
+
+ const component = wrapper.vm as MultisigCosignatoriesDisplay;
+
+ component.onAddCosignatory(account4.address);
+
+ await wrapper.vm.$nextTick();
+
+ expect(wrapper.emitted('add')).toBeTruthy();
+ expect(wrapper.emitted().add[0]).toEqual([account4.address]);
+ wrapper.destroy();
+ });
+
+ test('Should emit when removing a cosigner', () => {
+ const wrapper = shallowMount(MultisigCosignatoriesDisplay, {
+ i18n,
+ propsData: {
+ multisig: multisigInfo,
+ modifiable: true,
+ cosignatoryModifications: {},
+ },
+ });
+
+ const component = wrapper.vm as MultisigCosignatoriesDisplay;
+
+ component.onRemoveCosignatory(account2.address);
+ expect(wrapper.emitted('remove')).toBeTruthy();
+ expect(wrapper.emitted().remove[0]).toEqual([account2.address]);
+ wrapper.destroy();
+ });
+});
diff --git a/__tests__/components/NavigationLinks/NavigationLinks.spec.ts b/__tests__/components/NavigationLinks/NavigationLinks.spec.ts
new file mode 100644
index 0000000..608d8a0
--- /dev/null
+++ b/__tests__/components/NavigationLinks/NavigationLinks.spec.ts
@@ -0,0 +1,28 @@
+//@ts-ignore
+import NavigationLinks from '@/components/NavigationLinks/NavigationLinks.vue';
+import { shallowMount, createLocalVue, ThisTypedShallowMountOptions } from '@vue/test-utils';
+import { Vue } from 'vue-property-decorator';
+const localVue = createLocalVue();
+const options: ThisTypedShallowMountOptions = {
+ localVue,
+ propsData: {
+ direction: 'horizontal',
+ },
+};
+let wrapper;
+beforeEach(() => {
+ wrapper = shallowMount(NavigationLinks, options);
+});
+afterEach(() => {
+ wrapper.destroy();
+});
+describe('NavigationLinks should be rendered correctly with', () => {
+ it("prop 'horizontal'", () => {
+ expect(wrapper.find('.symbol-tab-container').classes()).toEqual(['symbol-tab-container', 'horizontal']);
+ });
+ it("with prop 'vertical'", async () => {
+ wrapper.setProps({ direction: 'vertical' });
+ await Vue.nextTick();
+ expect(wrapper.find('.symbol-tab-container').classes()).toEqual(['symbol-tab-container', 'vertical']);
+ });
+});
diff --git a/__tests__/components/PeerSelector.spec.ts b/__tests__/components/PeerSelector.spec.ts
new file mode 100644
index 0000000..28cb6f2
--- /dev/null
+++ b/__tests__/components/PeerSelector.spec.ts
@@ -0,0 +1,108 @@
+//@ts-ignore
+import PeerSelector from '@/components/PeerSelector/PeerSelector.vue';
+import { createLocalVue, ThisTypedShallowMountOptions, mount } from '@vue/test-utils';
+import Vuex from 'vuex';
+import i18n from '@/language';
+import VueI18n from 'vue-i18n';
+import { NetworkService } from '@/services/NetworkService';
+import { NetworkType } from 'symbol-sdk';
+// configuration
+let wrapper;
+let vm;
+let options: ThisTypedShallowMountOptions;
+const localVue = createLocalVue();
+localVue.use(Vuex);
+localVue.use(VueI18n);
+localVue.directive('auto-scroll', {
+ componentUpdated: function (el, { value }) {
+ if (value && value.length) {
+ const className = value.charAt(0) === '.' ? value : '.' + value;
+ if (el.querySelector(className)) {
+ const offsetTop = (el.querySelector(className) as HTMLElement).offsetTop;
+ el.scrollTo(0, offsetTop);
+ }
+ }
+ },
+});
+beforeEach(() => {
+ const networkModule = {
+ namespaced: true,
+ getters: {
+ currentPeerInfo: () => {
+ return { url: 'www.google.com', friendlyName: 'google' };
+ },
+ isConnected: () => true,
+ networkType: () => null,
+ repositoryFactory: () => NetworkService.createRepositoryFactory(''),
+ generationHash: () => 123,
+ knowNodes: () => [
+ { url: 'http://api-01.us-west-1.0941-v1.symboldev.network:3000', friendlyName: '614084b4', isDefault: true },
+ {
+ url: 'http://api-01.ap-southeast-1.0941-v1.symboldev.network:3000',
+ friendlyName: '08b0274c',
+ isDefault: true,
+ networkType: NetworkType.TEST_NET,
+ },
+ {
+ url: 'http://api-01.eu-west-1.0941-v1.symboldev.network:3000',
+ friendlyName: 'c44a95bd',
+ isDefault: true,
+ networkType: NetworkType.TEST_NET,
+ },
+ {
+ url: 'http://api-02.eu-central-1.0941-v1.symboldev.network:3000',
+ friendlyName: '7a26944a',
+ isDefault: true,
+ networkType: NetworkType.TEST_NET,
+ },
+ {
+ url: 'http://api-02.ap-northeast-1.0941-v1.symboldev.network:3000',
+ friendlyName: '4d08a4d9',
+ isDefault: true,
+ networkType: NetworkType.TEST_NET,
+ },
+ {
+ url: 'http://api-01.eu-central-1.0941-v1.symboldev.network:3000',
+ friendlyName: 'a08950e0',
+ isDefault: true,
+ networkType: NetworkType.TEST_NET,
+ },
+ {
+ url: 'http://api-01.ap-northeast-1.0941-v1.symboldev.network:3000',
+ friendlyName: 'API AP North-East 1',
+ isDefault: true,
+ networkType: NetworkType.TEST_NET,
+ },
+ {
+ url: 'http://api.experimental.symboldev.network:3000',
+ friendlyName: 'Main Net Opt In Experimental',
+ isDefault: true,
+ networkType: NetworkType.MAIN_NET,
+ },
+ ],
+ },
+ };
+ const store = new Vuex.Store({
+ modules: {
+ network: networkModule,
+ },
+ });
+ options = {
+ localVue,
+ i18n,
+ store,
+ stubs: ['Poptip', 'i-col', 'Row', 'Icon'],
+ };
+ wrapper = mount(PeerSelector, options);
+ vm = wrapper.vm;
+});
+describe('PeerSelector should', () => {
+ it("correctly get value of 'networkTypeText' ", () => {
+ expect(vm.isConnected).toBeTruthy();
+ expect(vm.networkType).toBeFalsy();
+ expect(vm.networkTypeText).toBe('Loading...');
+ });
+ it("correctly get value of 'peersList'", () => {
+ expect(vm.peersList.length).toBe(8);
+ });
+});
diff --git a/__tests__/components/Settings.spec.ts b/__tests__/components/Settings.spec.ts
new file mode 100644
index 0000000..bcfc0a7
--- /dev/null
+++ b/__tests__/components/Settings.spec.ts
@@ -0,0 +1,38 @@
+import { createLocalVue, shallowMount, ThisTypedShallowMountOptions } from '@vue/test-utils';
+import Vuex from 'vuex';
+import i18n from '@/language';
+import VueI18n from 'vue-i18n';
+import { Icon } from 'view-design';
+//@ts-ignore
+import Settings from '@/components/Settings/Settings.vue';
+const localVue = createLocalVue();
+localVue.use(Vuex);
+localVue.use(VueI18n);
+/* fake module */
+const profileModule = {
+ namespaced: true,
+ getters: {
+ isSettingsVisible: () => true,
+ },
+};
+const store = new Vuex.Store({
+ modules: {
+ profile: profileModule,
+ },
+});
+store.commit = jest.fn();
+const options: ThisTypedShallowMountOptions = {
+ localVue,
+ store,
+ stubs: { Icon },
+ i18n,
+};
+
+describe('Settings', () => {
+ test('trigger commit', () => {
+ const wrapper = shallowMount(Settings, options);
+ wrapper.find('.setting-menu-icon').trigger('click');
+ expect(wrapper.vm.$store.commit).toBeCalledWith('profile/toggleSettings');
+ wrapper.destroy();
+ });
+});
diff --git a/__tests__/components/TransactionList/TransactionListFilters/TransactionListFilter.spec.ts b/__tests__/components/TransactionList/TransactionListFilters/TransactionListFilter.spec.ts
new file mode 100644
index 0000000..8ac6331
--- /dev/null
+++ b/__tests__/components/TransactionList/TransactionListFilters/TransactionListFilter.spec.ts
@@ -0,0 +1,32 @@
+import { Address } from 'symbol-sdk';
+//@ts-ignore
+import TransactionListFilters from '@/components/TransactionList/TransactionListFilters/TransactionListFilters.vue';
+import { getComponent } from '@MOCKS/Components';
+import AccountStore from '@/store/Account';
+import TransactionStore from '@/store/Transaction';
+let wrapper;
+let vm;
+beforeEach(() => {
+ wrapper = getComponent(
+ TransactionListFilters,
+ { account: AccountStore, transaction: TransactionStore },
+ { currentAccount: null, signers: [] },
+ {},
+ {},
+ );
+ vm = wrapper.vm as TransactionListFilters;
+});
+afterEach(() => {
+ wrapper.destroy();
+});
+const addr = Address.createFromRawAddress('TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY');
+describe('TransactionListFilters', () => {
+ test("should call the 'account/SET_CURRENT_SIGNER' with address", () => {
+ vm.onSignerSelectorChange('TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY');
+ expect(vm.$store.dispatch).toBeCalledWith('account/SET_CURRENT_SIGNER', { address: addr, reset: true, unsubscribeWS: false });
+ });
+ test("should not call the 'account/SET_CURRENT_SIGNER' without address", () => {
+ vm.onSignerSelectorChange();
+ expect(vm.$store.dispatch).not.toBeCalled();
+ });
+});
diff --git a/__tests__/components/TransactionList/TransactuionStatusFilter/TransactionStatusFilter.spec.ts b/__tests__/components/TransactionList/TransactuionStatusFilter/TransactionStatusFilter.spec.ts
new file mode 100644
index 0000000..f4f592c
--- /dev/null
+++ b/__tests__/components/TransactionList/TransactuionStatusFilter/TransactionStatusFilter.spec.ts
@@ -0,0 +1,51 @@
+//@ts-ignore
+import TransactionStatusFilter from '@/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.vue';
+import { getComponent } from '@MOCKS/Components';
+import AccountStore from '@/store/Account';
+import TransactionStore from '@/store/Transaction';
+import { Vue } from 'vue-property-decorator';
+let wrapper;
+/* eslint-disable @typescript-eslint/no-unused-vars */
+let vm;
+beforeEach(() => {
+ wrapper = getComponent(
+ TransactionStatusFilter,
+ { account: AccountStore, transaction: TransactionStore },
+ { currentAccount: null, signers: [] },
+ {},
+ {},
+ );
+ vm = wrapper.vm as TransactionStatusFilter;
+});
+afterEach(() => {
+ wrapper.destroy();
+});
+describe('TransactionStatusFilter', () => {
+ let wrapper: any;
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ let vm: any;
+ beforeEach(() => {
+ wrapper = getComponent(
+ TransactionStatusFilter,
+ { account: AccountStore, transaction: TransactionStore },
+ { currentAccount: null, signers: [] },
+ {},
+ {},
+ );
+ vm = wrapper.vm as TransactionStatusFilter;
+ });
+ afterEach(() => {
+ wrapper.destroy();
+ });
+ describe('TransactionStatusFilter', () => {
+ test('renders correctly', async (): Promise => {
+ expect(wrapper).toMatchSnapshot();
+
+ wrapper.find('.filter-button').trigger('click');
+
+ await Vue.nextTick();
+
+ expect(wrapper).toMatchSnapshot();
+ });
+ });
+});
diff --git a/__tests__/components/TransactionList/TransactuionStatusFilter/__snapshots__/TransactionStatusFilter.spec.ts.snap b/__tests__/components/TransactionList/TransactuionStatusFilter/__snapshots__/TransactionStatusFilter.spec.ts.snap
new file mode 100644
index 0000000..4f3dde2
--- /dev/null
+++ b/__tests__/components/TransactionList/TransactuionStatusFilter/__snapshots__/TransactionStatusFilter.spec.ts.snap
@@ -0,0 +1,53 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TransactionStatusFilter TransactionStatusFilter renders correctly 1`] = `
+
+
+
+
+ Confirmed
+
+
+ Unconfirmed
+
+
+ Partial
+
+
+
+ Sent
+
+
+ Received
+
+
+
+`;
+
+exports[`TransactionStatusFilter TransactionStatusFilter renders correctly 2`] = `
+
+
+
+
+ Confirmed
+
+
+ Unconfirmed
+
+
+ Partial
+
+
+
+ Sent
+
+
+ Received
+
+
+
+`;
diff --git a/__tests__/core/validation/validators/PositiveDecimalNumberValidator.spec.ts b/__tests__/core/validation/validators/PositiveDecimalNumberValidator.spec.ts
new file mode 100644
index 0000000..bd3aab3
--- /dev/null
+++ b/__tests__/core/validation/validators/PositiveDecimalNumberValidator.spec.ts
@@ -0,0 +1,22 @@
+import { appConfig } from '@/config';
+import { PositiveDecimalNumberValidator } from '@/core/validation/validators/PositiveDecimalNumberValidator';
+
+fdescribe('PositiveDecimalNumberValidator', () => {
+ beforeAll(() => {
+ appConfig.constants.DECIMAL_SEPARATOR = '.';
+ });
+
+ ['1', ' 1 ', '1.1', ' 123.456 ', '123.'].forEach((validValue) => {
+ test(`'${validValue}' is valid`, () => {
+ const isValid = PositiveDecimalNumberValidator.validate(validValue);
+ expect(isValid).toBe(true);
+ });
+ });
+
+ ['-1', ' -1 ', '1,1', ' 123,456 ', '-123,456', 'hallo', '123.456.789', 'hallo 123'].forEach((invalidValue) => {
+ test(`'${invalidValue}' is invalid`, () => {
+ const isValid = PositiveDecimalNumberValidator.validate(invalidValue);
+ expect(isValid).toBe(false);
+ });
+ });
+});
diff --git a/__tests__/core/validation/validators/UrlValidator.spec.ts b/__tests__/core/validation/validators/UrlValidator.spec.ts
new file mode 100644
index 0000000..479a371
--- /dev/null
+++ b/__tests__/core/validation/validators/UrlValidator.spec.ts
@@ -0,0 +1,59 @@
+import { UrlValidator } from '@/core/validation/validators';
+
+describe('UrlValidator.validate should', () => {
+ describe('return false when passing in', () => {
+ test('http://', () => {
+ expect(UrlValidator.validate('http')).toBeFalsy();
+ });
+ test('https://', () => {
+ expect(UrlValidator.validate('http://')).toBeFalsy();
+ });
+ test('https://foo', () => {
+ expect(UrlValidator.validate('https://q')).toBeFalsy();
+ });
+ test('https://foo..', () => {
+ expect(UrlValidator.validate('https://foo..')).toBeFalsy();
+ });
+ test('https://foo.-', () => {
+ expect(UrlValidator.validate('https://foo.-')).toBeFalsy();
+ });
+ test('https://foo--', () => {
+ expect(UrlValidator.validate('https://foo--')).toBeFalsy();
+ });
+ test('https://192.0.0', () => {
+ expect(UrlValidator.validate('https://192.0.0')).toBeFalsy();
+ });
+ test('https://goo_gle.com', () => {
+ expect(UrlValidator.validate('https://goo_gle.com')).toBeFalsy();
+ });
+ test('localhost', () => {
+ expect(UrlValidator.validate('localhost')).toBeFalsy();
+ });
+ });
+ describe('return true when passing in', () => {
+ test('google.com', () => {
+ expect(UrlValidator.validate('google.com')).toBeTruthy();
+ });
+ test('http://google.com', () => {
+ expect(UrlValidator.validate('http://google.com')).toBeTruthy();
+ });
+ test('https://google.com', () => {
+ expect(UrlValidator.validate('https://google.com')).toBeTruthy();
+ });
+ test('https://goo-gle.com', () => {
+ expect(UrlValidator.validate('https://goo-gle.com')).toBeTruthy();
+ });
+ test('https://goo.gle.com', () => {
+ expect(UrlValidator.validate('https://goo.gle.com')).toBeTruthy();
+ });
+ test('192.0.0.1:8080', () => {
+ expect(UrlValidator.validate('192.0.0.1:8080')).toBeTruthy();
+ });
+ test('localhost:8080', () => {
+ expect(UrlValidator.validate('localhost:8080')).toBeTruthy();
+ });
+ test('http://api-01.eu-west-1.0941-v1.symboldev.network:3000', () => {
+ expect(UrlValidator.validate('http://api-01.eu-west-1.0941-v1.symboldev.network:3000')).toBeTruthy();
+ });
+ });
+});
diff --git a/__tests__/database/backends/NetworkBasedObjectStorage.spec.ts b/__tests__/database/backends/NetworkBasedObjectStorage.spec.ts
new file mode 100644
index 0000000..efc179b
--- /dev/null
+++ b/__tests__/database/backends/NetworkBasedObjectStorage.spec.ts
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkBasedObjectStorage } from '@/core/database/backends/NetworkBasedObjectStorage';
+import { SimpleObjectStorage } from '@/core/database/backends/SimpleObjectStorage';
+
+const getStorage = () => new NetworkBasedObjectStorage(new SimpleObjectStorage('SomeStorageKey'));
+
+describe('database/NetworkBasedObjectStorage.spec ==>', () => {
+ describe('constructor() should', () => {
+ test('create instance given no data', () => {
+ const storage = getStorage();
+ expect(storage).toBeDefined();
+ });
+
+ test('Get/Set/Delete same generation hash', () => {
+ const storage = getStorage();
+ const generationHash = 'abc';
+ expect(storage.get(generationHash)).toBeUndefined();
+ storage.set(generationHash, 123);
+ expect(storage.get(generationHash)).toBe(123);
+ storage.set(generationHash, 456);
+ expect(storage.get(generationHash)).toBe(456);
+ storage.remove(generationHash);
+ storage.remove(generationHash);
+ storage.remove(generationHash);
+ expect(storage.get(generationHash)).toBeUndefined();
+ });
+ });
+
+ function delay(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+ }
+
+ test('Get/Set/Delete same generation hash different generation hash', async () => {
+ const storage = getStorage();
+ const generationHash1 = 'abc1';
+ const generationHash2 = 'abc2';
+ expect(storage.get(generationHash1)).toBeUndefined();
+ expect(storage.get(generationHash2)).toBeUndefined();
+ storage.set(generationHash1, 123);
+ await delay(1);
+ expect(storage.getLatest()).toBe(123);
+ expect(storage.get(generationHash1)).toBe(123);
+ storage.set(generationHash2, 345);
+
+ await delay(1);
+ expect(storage.getLatest()).toBe(345);
+
+ expect(storage.get(generationHash2)).toBe(345);
+ expect(storage.get(generationHash1)).toBe(123);
+ storage.set(generationHash1, 456);
+ await delay(1);
+ expect(storage.getLatest()).toBe(456);
+ expect(storage.get(generationHash1)).toBe(456);
+ storage.remove(generationHash1);
+ storage.remove(generationHash1);
+ storage.remove(generationHash1);
+ expect(storage.get(generationHash1)).toBeUndefined();
+
+ storage.set(generationHash2, 456);
+ await delay(1);
+ expect(storage.get(generationHash2)).toBe(456);
+ storage.remove(generationHash2);
+ storage.remove(generationHash2);
+ storage.remove(generationHash2);
+ expect(storage.get(generationHash2)).toBeUndefined();
+ });
+});
diff --git a/__tests__/database/backends/SimpleObjectStorage.spec.ts b/__tests__/database/backends/SimpleObjectStorage.spec.ts
new file mode 100644
index 0000000..e91fa3d
--- /dev/null
+++ b/__tests__/database/backends/SimpleObjectStorage.spec.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { SimpleObjectStorage } from '@/core/database/backends/SimpleObjectStorage';
+
+const getStorage = () => new SimpleObjectStorage('SomeStorageKey');
+
+describe('database/SimpleObjectStorage.spec ==>', () => {
+ describe('constructor() should', () => {
+ test('create instance given no data', () => {
+ const storage = getStorage();
+ expect(storage).toBeDefined();
+ });
+
+ test('Get/Set/Delete', () => {
+ const storage = getStorage();
+ expect(storage.get()).toBeUndefined();
+ storage.set(123);
+ expect(storage.get()).toBe(123);
+ storage.set(456);
+ expect(storage.get()).toBe(456);
+ storage.remove();
+ expect(storage.get()).toBeUndefined();
+ });
+ });
+});
diff --git a/__tests__/database/backends/VersionedObjectStorage.spec.ts b/__tests__/database/backends/VersionedObjectStorage.spec.ts
new file mode 100644
index 0000000..f957bfd
--- /dev/null
+++ b/__tests__/database/backends/VersionedObjectStorage.spec.ts
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { Migration, VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+
+describe('database/SimpleObjectStorage.spec ==>', () => {
+ describe('constructor() should', () => {
+ test('Get/Set/Delete', () => {
+ const storageKey = 'someTable';
+ const storage1 = new VersionedObjectStorage({ storageKey: storageKey });
+ expect(storage1.get()).toBeUndefined();
+ expect(storage1.getVersion()).toBeUndefined();
+ storage1.set(123);
+ expect(storage1.get()).toBe(123);
+ storage1.set(456);
+ expect(storage1.getVersion()).toBe(1);
+ expect(storage1.get()).toBe(456);
+ storage1.remove();
+ expect(storage1.get()).toBeUndefined();
+ expect(storage1.getVersion()).toBeUndefined();
+ });
+
+ test('Get/Set/Delete Migration', () => {
+ const storageKey = 'someTable';
+ const storage1 = new VersionedObjectStorage({ storageKey: storageKey });
+ storage1.set(123);
+ expect(storage1.getVersion()).toBe(1);
+ expect(storage1.get()).toBe(123);
+
+ const migration1: Migration = {
+ description: 'toString',
+ migrate(from: any): any {
+ return from.toString();
+ },
+ };
+
+ const migration2: Migration = {
+ description: 'add A',
+ migrate(from: any): any {
+ return from + 'A';
+ },
+ };
+
+ const migration3: Migration = {
+ description: 'add Z',
+ migrate(from: any): any {
+ return from + 'Z';
+ },
+ };
+ // Migrate to string
+ const storage2 = new VersionedObjectStorage({
+ storageKey: storageKey,
+ migrations: [migration1],
+ });
+ expect(storage2.get()).toBe('123');
+ expect(storage2.getVersion()).toBe(2);
+
+ // No Migration
+ const storage3 = new VersionedObjectStorage({
+ storageKey: storageKey,
+ migrations: [migration1],
+ });
+ expect(storage3.get()).toBe('123');
+ expect(storage3.getVersion()).toBe(2);
+
+ // Double Migration (append A and append Z)
+ const storage4 = new VersionedObjectStorage({
+ storageKey: storageKey,
+ migrations: [migration1, migration2, migration3],
+ });
+ expect(storage4.get()).toBe('123AZ');
+ expect(storage4.getVersion()).toBe(4);
+ });
+ });
+});
diff --git a/__tests__/e2e/MosaicServiceIntegrationTest.spec.ts b/__tests__/e2e/MosaicServiceIntegrationTest.spec.ts
new file mode 100644
index 0000000..0825a1b
--- /dev/null
+++ b/__tests__/e2e/MosaicServiceIntegrationTest.spec.ts
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import {
+ AccountInfo,
+ AccountRepository,
+ Address,
+ MosaicFlags,
+ MosaicId,
+ MosaicInfo,
+ MosaicRepository,
+ NetworkCurrencies,
+ NetworkType,
+ Page,
+ RepositoryFactory,
+ UInt64,
+} from 'symbol-sdk';
+import { MosaicService } from '@/services/MosaicService';
+import { of } from 'rxjs';
+import { anything, deepEqual, instance, mock, when } from 'ts-mockito';
+
+const fakeMosaicInfo = new MosaicInfo(
+ 1,
+ '59FDA0733F17CF0001772CBC',
+ new MosaicId([3646934825, 3576016193]),
+ new UInt64([3403414400, 2095475]),
+ new UInt64([1, 0]),
+ Address.createFromRawAddress('TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY'),
+ 1,
+ new MosaicFlags(7),
+ 3,
+ UInt64.fromNumericString('1000'),
+);
+
+const address1 = Address.createFromRawAddress('TAD5BAHLOIXCRRB6GU2H72HPXMBBVAEUQRYPHBY');
+const accountInfo1 = { address: address1, mosaics: [{ id: fakeMosaicInfo.id, amount: UInt64.fromUint(10) }] } as AccountInfo;
+
+const address2 = Address.createFromRawAddress('TAWJ2M7BGKWGBPOUGD5NDKHYDDQ7OQD26HJMMQQ');
+const accountInfo2 = { address: address2, mosaics: [{ id: fakeMosaicInfo.id, amount: UInt64.fromUint(20) }] } as AccountInfo;
+
+const address3 = Address.createFromRawAddress('TDARSPFSZVLYGBOHGOVWIKAZ4FGGDPGZ3DSS7CQ');
+const accountInfo3 = { address: address3, mosaics: [{ id: fakeMosaicInfo.id, amount: UInt64.fromUint(30) }] } as AccountInfo;
+
+const address4 = Address.createFromRawAddress('TCEPWMC37ZGXOGOXQOAGDYPI7YH65HLXIMLKNOQ');
+const accountInfo4 = { address: address4, mosaics: [{ id: fakeMosaicInfo.id, amount: UInt64.fromUint(40) }] } as AccountInfo;
+
+const address5 = Address.createFromRawAddress('TAUDGSA7IEFH6MRGXO26SUU3W5ICF7OLLI3O7CY');
+const accountInfo5 = { address: address5, mosaics: [{ id: fakeMosaicInfo.id, amount: UInt64.fromUint(50) }] } as AccountInfo;
+
+const mosaicService = new MosaicService();
+
+const mockRepoFactory = mock();
+
+const mockMosaicRepository = mock();
+when(mockMosaicRepository.getMosaic(anything())).thenReturn(of(fakeMosaicInfo));
+when(mockMosaicRepository.getMosaics(anything())).thenReturn(of([fakeMosaicInfo]));
+when(mockMosaicRepository.search(anything())).thenReturn(of(new Page([fakeMosaicInfo], 1, 1)));
+
+const mosaicRepository = instance(mockMosaicRepository);
+const mockAccountRepository = mock();
+
+when(mockAccountRepository.getAccountsInfo(deepEqual([address1, address2, address3, address4, address5]))).thenReturn(
+ of([accountInfo1, accountInfo2, accountInfo3, accountInfo4, accountInfo5]),
+);
+
+when(mockAccountRepository.getAccountsInfo(deepEqual([address1]))).thenReturn(of([accountInfo1]));
+when(mockAccountRepository.getAccountsInfo(deepEqual([address3]))).thenReturn(of([accountInfo3]));
+
+const accountRepository = instance(mockAccountRepository);
+when(mockRepoFactory.createAccountRepository()).thenReturn(accountRepository);
+when(mockRepoFactory.createMosaicRepository()).thenReturn(mosaicRepository);
+
+when(mockRepoFactory.getEpochAdjustment()).thenReturn(of(1573430400));
+when(mockRepoFactory.getGenerationHash()).thenReturn(of('Some Gen Hash'));
+when(mockRepoFactory.getNetworkType()).thenReturn(of(NetworkType.MIJIN_TEST));
+when(mockRepoFactory.getCurrencies()).thenReturn(of(NetworkCurrencies.PUBLIC));
+const repositoryFactory = instance(mockRepoFactory);
+
+describe('services/MosaicService', () => {
+ test('getMosaics all addresses', async () => {
+ const generationHash = await repositoryFactory.getGenerationHash().toPromise();
+ const { networkCurrency } = await mosaicService.getNetworkCurrencies(repositoryFactory, generationHash).toPromise();
+ const addresses: Address[] = [address1, address2, address3, address4, address5];
+ const accountInfos = await repositoryFactory.createAccountRepository().getAccountsInfo(addresses).toPromise();
+ const result = await mosaicService
+ .getMosaics(repositoryFactory, generationHash, networkCurrency, accountInfos, address1)
+ .toPromise();
+ console.log(JSON.stringify(result, null, 2));
+ });
+
+ test('getMosaics account 1 addresses', async () => {
+ const generationHash = await repositoryFactory.getGenerationHash().toPromise();
+ const { networkCurrency } = await mosaicService.getNetworkCurrencies(repositoryFactory, generationHash).toPromise();
+ const addresses: Address[] = [address1];
+ const accountInfos = await repositoryFactory.createAccountRepository().getAccountsInfo(addresses).toPromise();
+ const result = await mosaicService
+ .getMosaics(repositoryFactory, generationHash, networkCurrency, accountInfos, address1)
+ .toPromise();
+ console.log(JSON.stringify(result, null, 2));
+ });
+
+ test('getMosaics account 3 addresses', async () => {
+ const generationHash = await repositoryFactory.getGenerationHash().toPromise();
+ const { networkCurrency } = await mosaicService.getNetworkCurrencies(repositoryFactory, generationHash).toPromise();
+ const addresses: Address[] = [address3];
+ const accountInfos = await repositoryFactory.createAccountRepository().getAccountsInfo(addresses).toPromise();
+ const result = await mosaicService
+ .getMosaics(repositoryFactory, generationHash, networkCurrency, accountInfos, address1)
+ .toPromise();
+ console.log(JSON.stringify(result, null, 2));
+ });
+});
diff --git a/__tests__/e2e/NetworkServiceIntegrationTest.spec.ts b/__tests__/e2e/NetworkServiceIntegrationTest.spec.ts
new file mode 100644
index 0000000..e5f0d8c
--- /dev/null
+++ b/__tests__/e2e/NetworkServiceIntegrationTest.spec.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkService } from '@/services/NetworkService';
+
+const networkService = new NetworkService();
+describe.skip('services/NetworkService', () => {
+ test('getNetworkModel when custom', async () => {
+ const candidate = 'http://api-01.eu-central-1.symboldev.network:3000';
+ const data = await networkService.getNetworkModel(candidate).toPromise();
+ expect(data.networkModel.url).toBe(candidate);
+ });
+});
diff --git a/__tests__/e2e/NodeServiceIntegrationTest.spec.ts b/__tests__/e2e/NodeServiceIntegrationTest.spec.ts
new file mode 100644
index 0000000..9bf457b
--- /dev/null
+++ b/__tests__/e2e/NodeServiceIntegrationTest.spec.ts
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkType, NodeInfo, NodeRepository, RepositoryFactory, RoleType } from 'symbol-sdk';
+import { NodeService } from '@/services/NodeService';
+import { toArray } from 'rxjs/operators';
+import { of } from 'rxjs';
+import { instance, mock, when } from 'ts-mockito';
+
+const nodeService = new NodeService();
+const realUrl = 'http://api-01.us-west-1.symboldev.network:3000';
+const fakeNodeInfo = new NodeInfo(
+ 'Some Public Key',
+ 'Some Gen Hash',
+ 1234,
+ NetworkType.TEST_NET,
+ 4567,
+ [RoleType.ApiNode],
+ 'Some Host',
+ 'Some Friendly Name',
+);
+
+const mockRepoFactory = mock();
+
+const mockNodeRepository = mock();
+when(mockNodeRepository.getNodePeers()).thenReturn(of([fakeNodeInfo]));
+when(mockNodeRepository.getNodeInfo()).thenReturn(of(fakeNodeInfo));
+
+const nodeRepository = instance(mockNodeRepository);
+
+when(mockRepoFactory.createNodeRepository()).thenReturn(nodeRepository);
+when(mockRepoFactory.getEpochAdjustment()).thenReturn(of(1573430400));
+when(mockRepoFactory.getNetworkType()).thenReturn(of(NetworkType.MIJIN_TEST));
+const repositoryFactory = instance(mockRepoFactory);
+
+describe('services/NodeService', () => {
+ test('getNodes', async () => {
+ const peers = await nodeService.getNodes(repositoryFactory, realUrl, NetworkType.TEST_NET).pipe(toArray()).toPromise();
+ console.log(JSON.stringify(peers, null, 2));
+ });
+});
diff --git a/__tests__/services/AccountService.spec.ts b/__tests__/services/AccountService.spec.ts
new file mode 100644
index 0000000..2477747
--- /dev/null
+++ b/__tests__/services/AccountService.spec.ts
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkType, Account, Password, Crypto } from 'symbol-sdk';
+import { AccountService } from '@/services/AccountService';
+import { MnemonicPassPhrase } from 'symbol-hd-wallets';
+import { account1Params, WalletsModel1 } from '@MOCKS/Accounts';
+
+// Sample mnemonic passphrase
+const mnemonic = new MnemonicPassPhrase(
+ 'limit sing post cross matrix pizza topple rack cigar skirt girl hurt outer humble fancy elegant bunker pipe ensure grain regret bulk renew trim',
+);
+
+// Standard account paths
+const standardPaths_Main = {
+ 1: "m/44'/4343'/0'/0'/0'",
+ 2: "m/44'/4343'/1'/0'/0'",
+ 3: "m/44'/4343'/2'/0'/0'",
+};
+
+const standardPaths_Test = {
+ 1: "m/44'/1'/0'/0'/0'",
+ 2: "m/44'/1'/1'/0'/0'",
+ 3: "m/44'/1'/2'/0'/0'",
+};
+
+// Expected private keys from derivation of mnemonic with standard account paths
+const expectedPrivateKeys_Main = {
+ 1: '197AD5021C055EB9107CCBCD51B57B341448BC1EFF2094DD470EA164CE78364A',
+ 2: '882620B87AEA2D3D02BDDFFA81A3BBD1F5E940A9C8FF56C1D1453E92332A56DE',
+ 3: '347DF965A3A77150C8F45CDAEB79FBDD97318D89F69B12DFFFAADD74716DAF66',
+};
+
+const expectedPrivateKeys_Test = {
+ 1: 'EF35256CAB4125452061413DA4BDB455325EDD4FFCD7D0333D9CD06BAB1C6D6D',
+ 2: 'C2B331F35F0CAD716CD187901D856173448FA52A9B350F1DDDC0240DE9E156AE',
+ 3: 'F22F9EFCCC9DA6F7C56DEB3853100847AAF07B12BC6ACF909511A8B389AD648A',
+};
+
+// Accounts from private keys
+const expectedAccounts_Main = Object.values(expectedPrivateKeys_Main).map((key) => Account.createFromPrivateKey(key, NetworkType.MAIN_NET));
+const expectedAccounts_Test = Object.values(expectedPrivateKeys_Test).map((key) => Account.createFromPrivateKey(key, NetworkType.TEST_NET));
+// max 2+2 generations
+const generatedAccounts = new AccountService().generateAccountsFromMnemonic(mnemonic, NetworkType.MAIN_NET, 2);
+const generatedAddresses = new AccountService().getAddressesFromMnemonic(mnemonic, NetworkType.MAIN_NET, 2);
+
+const generatedAccounts_test = new AccountService().generateAccountsFromMnemonic(mnemonic, NetworkType.TEST_NET, 2);
+const generatedAddresses_test = new AccountService().getAddressesFromMnemonic(mnemonic, NetworkType.TEST_NET, 2);
+
+describe('services/AccountService_Main', () => {
+ describe('generateAccountsFromMnemonic() should', () => {
+ test('generate correct child account given mnemonic', () => {
+ expect(generatedAccounts).toBeDefined();
+ expect(generatedAccounts.length).toBe(2);
+ expect(generatedAccounts[0].privateKey).toBe(expectedAccounts_Main[0].privateKey);
+ expect(generatedAccounts[0].publicKey).toBe(expectedAccounts_Main[0].publicKey);
+ expect(generatedAccounts[0].address.plain()).toBe(expectedAccounts_Main[0].address.plain());
+ });
+
+ test('generate multiple correct children accounts given mnemonic and count', () => {
+ expect(generatedAccounts).toBeDefined();
+ expect(generatedAccounts.length).toBe(2);
+ expect(generatedAccounts[0].privateKey).toBe(expectedAccounts_Main[0].privateKey);
+ expect(generatedAccounts[1].privateKey).toBe(expectedAccounts_Main[1].privateKey);
+ });
+ });
+
+ describe('generateAccountsFromPaths() should', () => {
+ test('generate correct account given mnemonic and paths', () => {
+ const accounts = new AccountService().generateAccountsFromPaths(
+ mnemonic,
+ NetworkType.MAIN_NET,
+ Object.values(standardPaths_Main).slice(0, 1),
+ );
+
+ expect(accounts).toBeDefined();
+ expect(accounts.length).toBe(1);
+ expect(accounts[0].privateKey).toBe(expectedAccounts_Main[0].privateKey);
+ expect(accounts[0].publicKey).toBe(expectedAccounts_Main[0].publicKey);
+ expect(accounts[0].address.plain()).toBe(expectedAccounts_Main[0].address.plain());
+ });
+ });
+
+ describe('getAddressesFromMnemonic() should', () => {
+ test('generate correct address given mnemonic', () => {
+ expect(generatedAddresses).toBeDefined();
+ expect(generatedAddresses.length).toBe(2);
+ expect(generatedAddresses[0].plain()).toBe(expectedAccounts_Main[0].address.plain());
+ });
+
+ test('generate multiple correct addresses given mnemonic and count', () => {
+ expect(generatedAddresses).toBeDefined();
+ expect(generatedAddresses.length).toBe(2);
+ expect(generatedAddresses[0].plain()).toBe(expectedAccounts_Main[0].address.plain());
+ expect(generatedAddresses[1].plain()).toBe(expectedAccounts_Main[1].address.plain());
+ });
+ });
+
+ describe('getAccountByPath() should', () => {
+ test('generate correct account given mnemonic and path', () => {
+ const account_3 = new AccountService().getAccountByPath(mnemonic, NetworkType.MAIN_NET, standardPaths_Main[3]);
+
+ expect(account_3.privateKey).toBe(expectedAccounts_Main[2].privateKey);
+ });
+ });
+
+ describe('updateWalletPassword', () => {
+ test('should update an account password', () => {
+ // initialize account service
+ const service = new AccountService();
+
+ // get initial encrypted private key values
+ const initialEncPrivate = WalletsModel1.encryptedPrivateKey;
+
+ // update the model
+ const updatedWallet = service.updateWalletPassword(WalletsModel1, account1Params.password, new Password('password2'));
+
+ // decrypt the new model's private key
+ const newEncPrivate = updatedWallet.encryptedPrivateKey;
+ const privateKey = Crypto.decrypt(newEncPrivate, 'password2');
+
+ // assert the encrypted private key changed
+ expect(newEncPrivate).not.toBe(initialEncPrivate);
+
+ // assert the plain private key did not change
+ expect(privateKey).toBe(account1Params.privateKey);
+ });
+
+ test('should throw if provided with an incorrect password', () => {
+ const service = new AccountService();
+ expect(() => {
+ service.updateWalletPassword(WalletsModel1, new Password('wrong_password'), new Password('password2'));
+ }).toThrow();
+ });
+ });
+});
+
+describe('services/AccountService_Test', () => {
+ describe('generateAccountsFromMnemonic() should', () => {
+ test('generate correct child account given mnemonic', () => {
+ expect(generatedAccounts_test).toBeDefined();
+ expect(generatedAccounts_test.length).toBe(2);
+ expect(generatedAccounts_test[0].privateKey).toBe(expectedAccounts_Test[0].privateKey);
+ expect(generatedAccounts_test[0].publicKey).toBe(expectedAccounts_Test[0].publicKey);
+ expect(generatedAccounts_test[0].address.plain()).toBe(expectedAccounts_Test[0].address.plain());
+ });
+
+ test('generate multiple correct children accounts given mnemonic and count', () => {
+ expect(generatedAccounts_test).toBeDefined();
+ expect(generatedAccounts_test.length).toBe(2);
+ expect(generatedAccounts_test[0].privateKey).toBe(expectedAccounts_Test[0].privateKey);
+ expect(generatedAccounts_test[1].privateKey).toBe(expectedAccounts_Test[1].privateKey);
+ });
+ });
+
+ describe('generateAccountsFromPaths() should', () => {
+ test('generate correct account given mnemonic and paths', () => {
+ const accounts = new AccountService().generateAccountsFromPaths(
+ mnemonic,
+ NetworkType.TEST_NET,
+ Object.values(standardPaths_Test).slice(0, 1),
+ );
+
+ expect(accounts).toBeDefined();
+ expect(accounts.length).toBe(1);
+ expect(accounts[0].privateKey).toBe(expectedAccounts_Test[0].privateKey);
+ expect(accounts[0].publicKey).toBe(expectedAccounts_Test[0].publicKey);
+ expect(accounts[0].address.plain()).toBe(expectedAccounts_Test[0].address.plain());
+ });
+ });
+
+ describe('getAddressesFromMnemonic() should', () => {
+ test('generate correct address given mnemonic', () => {
+ expect(generatedAddresses_test).toBeDefined();
+ expect(generatedAddresses_test.length).toBe(2);
+ expect(generatedAddresses_test[0].plain()).toBe(expectedAccounts_Test[0].address.plain());
+ });
+
+ test('generate multiple correct addresses given mnemonic and count', () => {
+ expect(generatedAddresses_test).toBeDefined();
+ expect(generatedAddresses_test.length).toBe(2);
+ expect(generatedAddresses_test[0].plain()).toBe(expectedAccounts_Test[0].address.plain());
+ expect(generatedAddresses_test[1].plain()).toBe(expectedAccounts_Test[1].address.plain());
+ });
+ });
+
+ describe('getAccountByPath() should', () => {
+ test('generate correct account given mnemonic and path', () => {
+ const account_3 = new AccountService().getAccountByPath(mnemonic, NetworkType.TEST_NET, standardPaths_Test[3]);
+
+ expect(account_3.privateKey).toBe(expectedAccounts_Test[2].privateKey);
+ });
+ });
+
+ describe('updateWalletPassword', () => {
+ test('should update an account password', () => {
+ // initialize account service
+ const service = new AccountService();
+
+ // get initial encrypted private key values
+ const initialEncPrivate = WalletsModel1.encryptedPrivateKey;
+
+ // update the model
+ const updatedWallet = service.updateWalletPassword(WalletsModel1, account1Params.password, new Password('password2'));
+
+ // decrypt the new model's private key
+ const newEncPrivate = updatedWallet.encryptedPrivateKey;
+ const privateKey = Crypto.decrypt(newEncPrivate, 'password2');
+
+ // assert the encrypted private key changed
+ expect(newEncPrivate).not.toBe(initialEncPrivate);
+
+ // assert the plain private key did not change
+ expect(privateKey).toBe(account1Params.privateKey);
+ });
+
+ test('should throw if provided with an incorrect password', () => {
+ const service = new AccountService();
+ expect(() => {
+ service.updateWalletPassword(WalletsModel1, new Password('wrong_password'), new Password('password2'));
+ }).toThrow();
+ });
+ });
+});
diff --git a/__tests__/services/DerivationService.spec.ts b/__tests__/services/DerivationService.spec.ts
new file mode 100644
index 0000000..3469594
--- /dev/null
+++ b/__tests__/services/DerivationService.spec.ts
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { DerivationPathLevels, DerivationService } from '@/services/DerivationService';
+import { AccountService } from '@/services/AccountService';
+import { NetworkType } from 'symbol-sdk';
+
+const networkType = NetworkType.MAIN_NET;
+const DEFAULT_ACCOUNT_PATH = AccountService.getAccountPathByNetworkType(networkType);
+
+// Standard profile paths
+const standardPaths = {
+ // the path number one is the DEFAULT_ACCOUNT_PATH
+ 2: "m/44'/4343'/1'/0'/0'",
+ 3: "m/44'/4343'/2'/0'/0'",
+ 4: "m/44'/4343'/3'/0'/0'",
+ 5: "m/44'/4343'/4'/0'/0'",
+ 6: "m/44'/4343'/5'/0'/0'",
+ 7: "m/44'/4343'/6'/0'/0'",
+ 8: "m/44'/4343'/7'/0'/0'",
+ 9: "m/44'/4343'/8'/0'/0'",
+ 10: "m/44'/4343'/9'/0'/0'",
+};
+
+describe('services/DerivationService ==>', () => {
+ describe('incrementPathLevel() should', () => {
+ test('increase standard paths as expected', () => {
+ expect(
+ [...Array(9).keys()].map((index) =>
+ new DerivationService(networkType).incrementPathLevel(DEFAULT_ACCOUNT_PATH, DerivationPathLevels.Profile, index + 1),
+ ),
+ ).toEqual(Object.values(standardPaths));
+ });
+ });
+
+ describe('decrementPathLevel() should', () => {
+ test('decrease standard paths as expected', () => {
+ expect(
+ [...Array(9).keys()].map((index) =>
+ new DerivationService(networkType).decrementPathLevel(standardPaths[10], DerivationPathLevels.Profile, index + 1),
+ ),
+ ).toEqual([DEFAULT_ACCOUNT_PATH, ...Object.values(standardPaths).slice(0, 8)].reverse());
+ });
+ });
+
+ describe('getNextAccountPath() should', () => {
+ test('return default path when provided an empty array', () => {
+ expect(new DerivationService(networkType).getNextAccountPath([])).toBe(DEFAULT_ACCOUNT_PATH);
+ });
+
+ test('return the first missing consecutive path when it is the default one', () => {
+ const paths = [standardPaths[2], standardPaths[3]];
+ expect(new DerivationService(networkType).getNextAccountPath(paths)).toBe(DEFAULT_ACCOUNT_PATH);
+ });
+
+ test('return the first missing consecutive path when it is the second one', () => {
+ const paths = [standardPaths[3], standardPaths[5], DEFAULT_ACCOUNT_PATH];
+ expect(new DerivationService(networkType).getNextAccountPath(paths)).toBe(standardPaths[2]);
+ });
+
+ test('return the first missing consecutive path when it is in the middle', () => {
+ const paths = [standardPaths[2], DEFAULT_ACCOUNT_PATH, standardPaths[4]];
+ expect(new DerivationService(networkType).getNextAccountPath(paths)).toBe(standardPaths[3]);
+ });
+
+ test('return the next path when all paths are consecutive', () => {
+ const paths = [standardPaths[2], standardPaths[3], DEFAULT_ACCOUNT_PATH];
+ expect(new DerivationService(networkType).getNextAccountPath(paths)).toBe(standardPaths[4]);
+ });
+ });
+});
diff --git a/__tests__/services/MosaicModel.spec.ts b/__tests__/services/MosaicModel.spec.ts
new file mode 100644
index 0000000..4454f70
--- /dev/null
+++ b/__tests__/services/MosaicModel.spec.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address, MosaicFlags, MosaicId, MosaicInfo, NetworkType, PublicAccount, UInt64 } from 'symbol-sdk';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+
+describe('services/MosaicData', () => {
+ describe('serialization', () => {
+ test('canSerializeDeserialize', () => {
+ // act
+ const address = Address.createFromEncoded('917E7E29A01014C2F3000000000000000000000000000000');
+
+ const id = new MosaicId('85BBEA6CC462B244');
+ const mosaicInfo = new MosaicInfo(
+ 1,
+ '85BBEA6CC462B244',
+ id, // mosaicId
+ new UInt64([3403414400, 2095475]), // supply
+ new UInt64([1, 0]), // height
+ PublicAccount.createFromPublicKey(
+ 'B4F12E7C9F6946091E2CB8B6D3A12B50D17CCBBF646386EA27CE2946A7423DCF',
+ NetworkType.MIJIN_TEST,
+ ).address,
+ 1, // revision
+ MosaicFlags.create(true, true, true),
+ 3,
+ UInt64.fromUint(1000),
+ );
+ const expected = new MosaicModel(address.plain(), address.plain(), 'someName', true, 1234, mosaicInfo);
+
+ // assert
+ expect(expected).not.toBeNull();
+ expect(expected.mosaicIdHex).toBe('85BBEA6CC462B244');
+ expect(expected.addressRawPlain).toBe(address.plain());
+
+ const deserialized: MosaicModel = JSON.parse(JSON.stringify(expected));
+ expect(deserialized).not.toBeNull();
+ expect(deserialized.mosaicIdHex).toBe('85BBEA6CC462B244');
+ expect(deserialized.addressRawPlain).toBe(address.plain());
+ expect(JSON.stringify(expected)).toBe(JSON.stringify(deserialized));
+
+ const deserializedMosaicInfo: MosaicInfo = JSON.parse(JSON.stringify(mosaicInfo));
+ // NOTE I lose the methods!
+ expect(deserializedMosaicInfo).not.toBeNull();
+ expect(deserializedMosaicInfo.id.toHex).toBe(undefined);
+ expect(deserializedMosaicInfo.duration.compact).toBe(undefined);
+ });
+ });
+});
diff --git a/__tests__/services/MosaicService.spec.ts b/__tests__/services/MosaicService.spec.ts
new file mode 100644
index 0000000..5bf7861
--- /dev/null
+++ b/__tests__/services/MosaicService.spec.ts
@@ -0,0 +1,55 @@
+import { MosaicId } from 'symbol-sdk';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { MosaicService } from '@/services/MosaicService';
+import { mosaicConfigurations } from '@MOCKS/MosaicConfigurations';
+
+const mosaicId = new MosaicId('05D6A80DE3C9ADCA');
+const account1: AccountModel = {
+ address: 'TD2UU6EY4G4WSV5NJMVLVVNRKZOKEZIBYXBFZ4U2',
+ encryptedPrivateKey:
+ '5730f8e71484dc0cc8ff8a206552080dcbcfc244e1294bf1cc303198561c916ciDHHCOVVjNm3qx5xY6wLXpDjqV8iTiR7,+FlJdiMZYUKIX79aBeyqmJcUsEHW011ZGKSg7WJXobtua6y5VutCq8qm1yBBcRlVdTEFBSjHjGg=',
+ id: 'B147F63C31CE2347',
+ isMultisig: false,
+ name: 'Seed Account 6',
+ node: '',
+ path: "m/44'/4343'/5'/0'/0'",
+ profileName: 'test',
+ publicKey: '82D539A540E89EC5848BBE6CF95F2001CDE8A6DEB904D0ADA86D613A4FD0CACB',
+ type: 1,
+};
+const account2: AccountModel = {
+ address: 'TD2UU6EY4G4WSV5NJMVLVVNRKZOKEZIBYXBFZ4U2',
+ encryptedPrivateKey:
+ '5730f8e71484dc0cc8ff8a206552080dcbcfc244e1294bf1cc303198561c916ciDHHCOVVjNm3qx5xY6wLXpDjqV8iTiR7,+FlJdiMZYUKIX79aBeyqmJcUsEHW011ZGKSg7WJXobtua6y5VutCq8qm1yBBcRlVdTEFBSjHjGg=',
+ id: 'D27115119E1DD723',
+ isMultisig: false,
+ name: 'Seed Account 6',
+ node: '',
+ path: "m/44'/4343'/5'/0'/0'",
+ profileName: 'test',
+ publicKey: '82D539A540E89EC5848BBE6CF95F2001CDE8A6DEB904D0ADA86D613A4FD0CACB',
+ type: 1,
+};
+
+const mosaicService = new MosaicService();
+mosaicService.getMosaicConfigurations = jest.fn().mockImplementation(() => {
+ return mosaicConfigurations;
+});
+describe('MosaicService', () => {
+ describe('configurations of different account should be separated', () => {
+ test('account1 which exist in the data', () => {
+ const newConfigs = {
+ hidden: false,
+ };
+ const mosaicConfigurations = mosaicService.changeMosaicConfiguration(mosaicId, account1, newConfigs);
+ expect(mosaicConfigurations['05D6A80DE3C9ADCA'].hidden).toBe(false);
+ });
+ test("account2 which doesn't exist in the data", () => {
+ const newConfigs = {
+ hidden: true,
+ };
+ const mosaicConfigurations = mosaicService.changeMosaicConfiguration(mosaicId, account2, newConfigs);
+ expect(mosaicConfigurations['05D6A80DE3C9ADCA'].hidden).toBe(true);
+ });
+ });
+});
diff --git a/__tests__/services/MultisigService.spec.ts b/__tests__/services/MultisigService.spec.ts
new file mode 100644
index 0000000..93be26a
--- /dev/null
+++ b/__tests__/services/MultisigService.spec.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { multisigEntries1, multisigEntries2, multisigGraphInfo1 } from '@MOCKS/multisigGraphInfo';
+import { MultisigService } from '@/services/MultisigService';
+
+describe('services/MultisigService', () => {
+ describe('getMultisigInfoFromMultisigGraphInfo() should', () => {
+ test('return multisig info contained in a multisig graph', () => {
+ const multisigsInfo = MultisigService.getMultisigInfoFromMultisigGraphInfo(multisigGraphInfo1);
+ expect(multisigsInfo).toStrictEqual([...multisigEntries1, ...multisigEntries2]);
+ });
+ });
+});
diff --git a/__tests__/services/ProfileService.spec.ts b/__tests__/services/ProfileService.spec.ts
new file mode 100644
index 0000000..8547111
--- /dev/null
+++ b/__tests__/services/ProfileService.spec.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { ProfileService } from '@/services/ProfileService';
+import { Password } from 'symbol-sdk';
+
+// prepare all
+
+describe('services/ProfileService', () => {
+ describe('getPasswordHash() should', () => {
+ test('create 64 bytes hash of password', () => {
+ // act
+ const hash = ProfileService.getPasswordHash(new Password('1234567a'));
+
+ // assert
+ expect(hash).toBeDefined();
+ expect(hash.length).toBe(128);
+ });
+ });
+});
diff --git a/__tests__/services/RemoteAccountService.spec.ts b/__tests__/services/RemoteAccountService.spec.ts
new file mode 100644
index 0000000..11b9fd1
--- /dev/null
+++ b/__tests__/services/RemoteAccountService.spec.ts
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import {
+ NetworkType,
+ Password,
+ Address,
+ AccountInfo,
+ AccountRepository,
+ PublicAccount,
+ Page,
+ AccountType as sdkAccountType,
+ RepositoryFactory,
+ NetworkCurrencies,
+} from 'symbol-sdk';
+import { RemoteAccountService } from '@/services/RemoteAccountService';
+import { WalletsModel2 } from '@MOCKS/Accounts';
+import { getTestProfile } from '@MOCKS/profiles';
+import { of } from 'rxjs';
+import { anything, instance, mock, when } from 'ts-mockito';
+
+const accountInfo = { address: Address.createFromRawAddress(WalletsModel2.address) } as AccountInfo;
+
+const accountInfos = [
+ {
+ address: Address.createFromRawAddress(WalletsModel2.address),
+ accountType: sdkAccountType.Main,
+ } as AccountInfo,
+ {
+ address: PublicAccount.createFromPublicKey('FA0939C5F11FC89A8EB997329C64AC785CDD23AE9D73C3E060D3B5FF0BABC2A4', NetworkType.TEST_NET)
+ .address,
+ accountType: sdkAccountType.Remote_Unlinked,
+ } as AccountInfo,
+];
+
+const mockRepoFactory = mock();
+
+const mockAccountRepository = mock();
+
+when(mockAccountRepository.getAccountInfo(anything())).thenReturn(of(accountInfo));
+when(mockAccountRepository.getAccountsInfo(anything())).thenReturn(of(accountInfos));
+when(mockAccountRepository.search(anything())).thenReturn(of(new Page(accountInfos, 1, 2)));
+
+const accountRepository = instance(mockAccountRepository);
+when(mockRepoFactory.createAccountRepository()).thenReturn(accountRepository);
+
+when(mockRepoFactory.getEpochAdjustment()).thenReturn(of(1573430400));
+when(mockRepoFactory.getGenerationHash()).thenReturn(of('Some Gen Hash'));
+when(mockRepoFactory.getNetworkType()).thenReturn(of(NetworkType.MIJIN_TEST));
+when(mockRepoFactory.getCurrencies()).thenReturn(of(NetworkCurrencies.PUBLIC));
+const repositoryFactory = instance(mockRepoFactory);
+
+describe('services/RemoteAccountService', () => {
+ describe('getAvailableRemotePublicKey()', () => {
+ test('should return the first linkable public key', async (done) => {
+ // prepare
+
+ // act
+ const remoteAccount = await new RemoteAccountService(
+ WalletsModel2,
+ getTestProfile('profile1'),
+ repositoryFactory.createAccountRepository(),
+ ).getAvailableRemoteAccount(new Password('password'));
+
+ expect(remoteAccount.publicKey).toBe('82F7AFB6655B85563DCF6E7722B556722992B432ED0F51A22A4587E0E18B797C');
+ done();
+ });
+ });
+});
diff --git a/__tests__/services/TransactionFilterService.spec.ts b/__tests__/services/TransactionFilterService.spec.ts
new file mode 100644
index 0000000..202c056
--- /dev/null
+++ b/__tests__/services/TransactionFilterService.spec.ts
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { TransactionFilterOptionsState, TransactionState } from '@/store/Transaction';
+import { TransactionFilterService } from '@/services/TransactionFilterService';
+import { getTestAccount } from '@MOCKS/Accounts';
+import { TransferTransaction } from 'symbol-sdk';
+
+const currentSigner = getTestAccount('remoteTestnet');
+const recepient = getTestAccount('remoteMijin');
+const sentTransaction = {
+ signer: currentSigner,
+ recipientAddress: {
+ address: currentSigner.address.plain(),
+ },
+};
+const receivedTransaction = {
+ signer: recepient,
+ recipientAddress: {
+ address: currentSigner.address.plain(),
+ },
+};
+
+const transactionState: TransactionState = {
+ initialized: false,
+ isFetchingTransactions: false,
+ transactions: [(sentTransaction as unknown) as TransferTransaction, (receivedTransaction as unknown) as TransferTransaction],
+ filteredTransactions: [],
+ confirmedTransactions: [(sentTransaction as unknown) as TransferTransaction],
+ unconfirmedTransactions: [(receivedTransaction as unknown) as TransferTransaction],
+ partialTransactions: [],
+ filterOptions: new TransactionFilterOptionsState(),
+ currentConfirmedPage: { pageNumber: 1, isLastPage: false },
+};
+
+describe('services/TransactionFilterService', () => {
+ describe('filter()', () => {
+ test('should return all with all selected/unselected', async (done) => {
+ const result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ transactionState.filterOptions.isSentSelected = true;
+ transactionState.filterOptions.isUnconfirmedSelected = true;
+ transactionState.filterOptions.isPartialSelected = true;
+
+ expect(result.length).toBe(2);
+ done();
+ });
+
+ test('should return correct confirmed transactions', async (done) => {
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isConfirmedSelected = true;
+ const result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(1);
+ expect(result[0]).toBe(sentTransaction);
+ done();
+ });
+
+ test('should return correct unconfirmed and confirmed transactions', async (done) => {
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isUnconfirmedSelected = true;
+ const result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(1);
+ expect(result[0]).toBe(receivedTransaction);
+ done();
+ });
+
+ test('should return correct partial transactions', async (done) => {
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isPartialSelected = true;
+ const result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(0);
+ done();
+ });
+
+ test('should return correct sent transactions', async (done) => {
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isSentSelected = true;
+ const result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(1);
+ expect(result[0]).toBe(sentTransaction);
+
+ done();
+ });
+
+ test('should return correct received transactions', async (done) => {
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isReceivedSelected = true;
+ const result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(2);
+ done();
+ });
+
+ test('should return correct transactions on multiple criterias', async (done) => {
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isConfirmedSelected = true;
+ transactionState.filterOptions.isUnconfirmedSelected = true;
+ let result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(2);
+
+ transactionState.filterOptions = new TransactionFilterOptionsState();
+ transactionState.filterOptions.isSentSelected = true;
+ transactionState.filterOptions.isReceivedSelected = true;
+
+ result = TransactionFilterService.filter(transactionState, currentSigner.address.plain());
+
+ expect(result.length).toBe(2);
+ done();
+ });
+ });
+});
diff --git a/__tests__/store/Diagnostic.spec.ts b/__tests__/store/Diagnostic.spec.ts
new file mode 100644
index 0000000..d2573b9
--- /dev/null
+++ b/__tests__/store/Diagnostic.spec.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { LogLevels } from '@/core/utils/LogLevels';
+import DiagnosticStore from '@/store/Diagnostic';
+
+describe('store/Diagnostic', () => {
+ describe('action "ADD_LOG" should', () => {
+ test('mutate logs given debug level and message', () => {
+ // prepare
+ const commit = jest.fn();
+
+ // act
+ DiagnosticStore.actions.ADD_LOG(
+ { commit },
+ {
+ level: LogLevels.DEBUG,
+ message: 'debug message',
+ },
+ );
+
+ // assert
+ expect(commit).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('specialized actions should', () => {
+ test('mutate logs with correct log level given message', () => {
+ // prepare
+ const commit = jest.fn();
+
+ // act
+ const message = 'info message';
+ const time1 = DiagnosticStore.actions.ADD_INFO({ commit }, message);
+ const time2 = DiagnosticStore.actions.ADD_DEBUG({ commit }, message);
+ const time3 = DiagnosticStore.actions.ADD_WARNING({ commit }, message);
+ const time4 = DiagnosticStore.actions.ADD_ERROR({ commit }, message);
+
+ // assert
+ expect(commit).toHaveBeenCalledTimes(4);
+ expect(commit).toHaveBeenNthCalledWith(1, 'addLog', {
+ level: LogLevels.INFO,
+ message,
+ time: time1,
+ });
+ expect(commit).toHaveBeenNthCalledWith(2, 'addLog', {
+ level: LogLevels.DEBUG,
+ message,
+ time: time2,
+ });
+ expect(commit).toHaveBeenNthCalledWith(3, 'addLog', {
+ level: LogLevels.WARNING,
+ message,
+ time: time3,
+ });
+ expect(commit).toHaveBeenNthCalledWith(4, 'addLog', {
+ level: LogLevels.ERROR,
+ message,
+ time: time4,
+ });
+ });
+ });
+});
diff --git a/__tests__/store/Profile.spec.ts b/__tests__/store/Profile.spec.ts
new file mode 100644
index 0000000..7701e56
--- /dev/null
+++ b/__tests__/store/Profile.spec.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import ProfileStore from '@/store/Profile';
+import flushPromises from 'flush-promises';
+import { NetworkType } from 'symbol-sdk';
+
+describe('store/Profile', () => {
+ describe('action "RESET_STATE" should', () => {
+ test('mutate currentProfile and isAuthenticated', () => {
+ // prepare
+ const commit = jest.fn();
+
+ // act
+ ProfileStore.actions.RESET_STATE({ commit });
+
+ // assert
+ expect(commit).toHaveBeenCalledTimes(2);
+ expect(commit).toHaveBeenNthCalledWith(1, 'currentProfile', null);
+ expect(commit).toHaveBeenNthCalledWith(2, 'setAuthenticated', false);
+ });
+ });
+
+ describe('action "LOG_OUT" should', () => {
+ test('dispatch "RESET_STATE"', async (done) => {
+ // prepare
+ const dispatch = jest.fn();
+ const rootGetters = { 'account/currentAccount': {} };
+
+ // act
+ ProfileStore.actions.LOG_OUT({ dispatch, rootGetters });
+ await flushPromises();
+
+ // assert
+ expect(dispatch).toHaveBeenCalled();
+ expect(dispatch).toHaveBeenCalledWith('account/uninitialize', { address: undefined }, { root: true });
+ expect(dispatch).toHaveBeenCalledWith('account/SET_KNOWN_ACCOUNTS', [], { root: true });
+ expect(dispatch).toHaveBeenCalledWith('account/RESET_CURRENT_ACCOUNT', undefined, { root: true });
+ expect(dispatch).toHaveBeenCalledWith('RESET_STATE');
+ done();
+ });
+ });
+
+ describe('action "SET_CURRENT_PROFILE" should', () => {
+ test('mutate currentProfile and isAuthenticated', async () => {
+ // prepare
+ const commit = jest.fn();
+ const dispatch = jest.fn();
+ const model = { networkType: NetworkType.TEST_NET } as ProfileModel;
+ // act
+ await ProfileStore.actions.SET_CURRENT_PROFILE({ commit, dispatch }, model);
+
+ // assert
+ expect(commit).toHaveBeenCalledTimes(2);
+ expect(commit).toHaveBeenNthCalledWith(1, 'currentProfile', model);
+ expect(commit).toHaveBeenNthCalledWith(2, 'setAuthenticated', true);
+ });
+ });
+});
diff --git a/__tests__/store/Temporary.spec.ts b/__tests__/store/Temporary.spec.ts
new file mode 100644
index 0000000..dde1991
--- /dev/null
+++ b/__tests__/store/Temporary.spec.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import TemporaryStore from '@/store/Temporary';
+import { Password } from 'symbol-sdk';
+
+describe('store/Profile', () => {
+ describe('action "RESET_STATE" should', () => {
+ test('mutate password and mnemonic', () => {
+ // prepare
+ const commit = jest.fn();
+
+ // act
+ TemporaryStore.actions.RESET_STATE({ commit });
+
+ // assert
+ expect(commit).toHaveBeenCalledTimes(2);
+ expect(commit).toHaveBeenNthCalledWith(1, 'setPassword', null);
+ expect(commit).toHaveBeenNthCalledWith(2, 'setMnemonic', null);
+ });
+ });
+
+ describe('action "SET_PASSWORD" should', () => {
+ test('mutate password', () => {
+ // prepare
+ const commit = jest.fn();
+
+ // act
+ TemporaryStore.actions.SET_PASSWORD({ commit }, '1234567a');
+
+ // assert
+ expect(commit).toHaveBeenCalledTimes(1);
+ expect(commit).toHaveBeenNthCalledWith(1, 'setPassword', new Password('1234567a'));
+ });
+
+ test('throw password error if less than 8 characters', () => {
+ // prepare
+ const commit = jest.fn();
+
+ // act + assert
+ expect(() => TemporaryStore.actions.SET_PASSWORD({ commit }, '1234567')).toThrowError();
+ });
+ });
+});
diff --git a/__tests__/transactions/TransactionView.spec.ts b/__tests__/transactions/TransactionView.spec.ts
new file mode 100644
index 0000000..1d085c5
--- /dev/null
+++ b/__tests__/transactions/TransactionView.spec.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Deadline, NamespaceId, NetworkType, PlainMessage, TransferTransaction } from 'symbol-sdk';
+import { createStore } from '@MOCKS/Store';
+import { ViewUnknownTransaction } from '@/core/transactions/ViewUnknownTransaction';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+const store = createStore({});
+const transfer = TransferTransaction.create(
+ Deadline.create(1573430400),
+ new NamespaceId('alias'),
+ [],
+ PlainMessage.create('test-message'),
+ NetworkType.MIJIN_TEST,
+);
+const networkConfig = new NetworkConfigurationModel();
+Object.assign(networkConfig, { epochAdjustment: 1573430400 });
+store.getters['network/networkConfiguration'] = networkConfig;
+describe('transactions/TransactionView', () => {
+ describe('use() should', () => {
+ test('set transaction property', () => {
+ // prepare
+ const view = new ViewUnknownTransaction(store, transfer);
+
+ // assert
+ expect(view).toBeDefined();
+ expect(view.transaction).toBeDefined();
+ });
+ });
+
+ describe('initialize() should', () => {
+ test('set common transaction fields', () => {
+ // prepare + act
+ const view = new ViewUnknownTransaction(store, transfer);
+
+ // assert
+ expect(view).toBeDefined();
+ expect(view.detailItems.length).toBe(0);
+ expect(view.headerItems.length).toBe(4);
+ });
+ });
+});
diff --git a/__tests__/transactions/ViewAliasTransaction.spec.ts b/__tests__/transactions/ViewAliasTransaction.spec.ts
new file mode 100644
index 0000000..2ac7f92
--- /dev/null
+++ b/__tests__/transactions/ViewAliasTransaction.spec.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { AliasAction, Deadline, MosaicAliasTransaction, MosaicId, NamespaceId, NetworkType } from 'symbol-sdk';
+import { createStore } from '@MOCKS/Store';
+import { ViewAliasTransaction } from '@/core/transactions/ViewAliasTransaction';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+const store = createStore({});
+const epochAdjustment = 1573430400;
+describe('transactions/ViewAliasTransaction', () => {
+ describe('use() should', () => {
+ test('populate mosaic alias transaction fields', () => {
+ const namespaceId = new NamespaceId('alias');
+ const mosaicId = new MosaicId('747B276C30626442');
+ const alias = MosaicAliasTransaction.create(
+ Deadline.create(epochAdjustment),
+ AliasAction.Link,
+ namespaceId,
+ mosaicId,
+ NetworkType.MIJIN_TEST,
+ );
+ const networkConfig = new NetworkConfigurationModel();
+ Object.assign(networkConfig, { epochAdjustment: 1573430400 });
+ store.getters['network/networkConfiguration'] = networkConfig;
+ const view = new ViewAliasTransaction(store, alias);
+
+ // assert
+ expect(view).toBeDefined();
+ expect(view.transaction).toBeDefined();
+ expect(view.detailItems.length).toBe(3);
+ });
+
+ // XXX test recognition of Namespace vs Address for recipient
+ // XXX test recognition of Namespace vs MosaicId for mosaics
+ });
+});
diff --git a/__tests__/transactions/ViewHashLockTransaction.spec.ts b/__tests__/transactions/ViewHashLockTransaction.spec.ts
new file mode 100644
index 0000000..10806b4
--- /dev/null
+++ b/__tests__/transactions/ViewHashLockTransaction.spec.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { AggregateTransaction, Deadline, LockFundsTransaction, NetworkCurrencies, NetworkType, UInt64 } from 'symbol-sdk';
+import { createStore } from '@MOCKS/Store';
+import { getTestAccount } from '@MOCKS/Accounts';
+import { ViewHashLockTransaction } from '@/core/transactions/ViewHashLockTransaction';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+const store = createStore({});
+const epochAdjustment = 1573430400;
+describe('transactions/ViewHashLockTransaction', () => {
+ describe('use() should', () => {
+ test('populate hash lock transaction fields', () => {
+ const generationHash = '57F7DA205008026C776CB6AED843393F04CD458E0AA2D9F1D5F31A402072B2D6';
+ const aggregateTransaction = AggregateTransaction.createBonded(
+ Deadline.create(epochAdjustment, 48),
+ [],
+ NetworkType.MIJIN_TEST,
+ [],
+ );
+ const signedTransaction = getTestAccount('cosigner1').sign(aggregateTransaction, generationHash);
+ const hashLock = LockFundsTransaction.create(
+ Deadline.create(epochAdjustment, 6),
+ NetworkCurrencies.PUBLIC.currency.createRelative(10),
+ UInt64.fromUint(5760),
+ signedTransaction,
+ NetworkType.MIJIN_TEST,
+ );
+ const networkConfig = new NetworkConfigurationModel();
+ Object.assign(networkConfig, { epochAdjustment: 1573430400 });
+ store.getters['network/networkConfiguration'] = networkConfig;
+ // act
+ const view = new ViewHashLockTransaction(store, hashLock);
+
+ // assert
+ expect(view).toBeDefined();
+ expect(view.transaction).toBeDefined();
+ expect(view.detailItems.length).toBe(3);
+ });
+ });
+});
diff --git a/__tests__/transactions/ViewTransferTransaction.spec.ts b/__tests__/transactions/ViewTransferTransaction.spec.ts
new file mode 100644
index 0000000..c41a3e5
--- /dev/null
+++ b/__tests__/transactions/ViewTransferTransaction.spec.ts
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Account, Deadline, NamespaceId, NetworkType, PlainMessage, TransferTransaction } from 'symbol-sdk';
+import { createStore } from '@MOCKS/Store';
+import { ViewTransferTransaction } from '@/core/transactions/ViewTransferTransaction';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+const store = createStore({});
+const epochAdjustment = 1573430400;
+describe('transactions/ViewTransferTransaction', () => {
+ describe('use() should', () => {
+ test('populate transfer transaction fields', () => {
+ // prepare
+ const alias = new NamespaceId('test');
+
+ const transferTransaction = TransferTransaction.create(
+ Deadline.create(epochAdjustment),
+ alias,
+ [],
+ PlainMessage.create('test-message'),
+ NetworkType.MIJIN_TEST,
+ );
+
+ store.getters['account/currentSignerAddress'] = Account.generateNewAccount(NetworkType.MAIN_NET).address;
+ const networkConfig = new NetworkConfigurationModel();
+ Object.assign(networkConfig, { epochAdjustment: 1573430400 });
+ store.getters['network/networkConfiguration'] = networkConfig;
+
+ // act
+ const view = new ViewTransferTransaction(store, transferTransaction);
+
+ // assert
+ expect(view).toBeDefined();
+ expect(view.transaction).toBeDefined();
+
+ expect(view.detailItems.length).toBe(3);
+ });
+ });
+});
diff --git a/__tests__/utils/FilterHelpers.spec.ts b/__tests__/utils/FilterHelpers.spec.ts
new file mode 100644
index 0000000..d78c590
--- /dev/null
+++ b/__tests__/utils/FilterHelpers.spec.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { FilterHelpers } from '@/core/utils/FilterHelpers';
+
+describe('stripFilter', () => {
+ // should return a string without tags
+ test.each([
+ ['no tags', 'no tags'],
+ ['no tags;\'"#!?%&/8{}', 'no tags;\'"#!?%&/8{}'],
+ ['', 'alert("abc");'],
+ ['/>', '/>alert("abc");'],
+ ['This is a normal text ', 'This is a normal text '],
+ ])('FilterHelpers.stripFilter(%s)', (a, expected) => {
+ expect(FilterHelpers.stripFilter(a)).toBe(expected);
+ });
+});
diff --git a/__tests__/utils/Formatters.spec.ts b/__tests__/utils/Formatters.spec.ts
new file mode 100644
index 0000000..2e6692e
--- /dev/null
+++ b/__tests__/utils/Formatters.spec.ts
@@ -0,0 +1,16 @@
+import { Formatters } from '@/core/utils/Formatters';
+
+describe('splitArrayByDelimiter', () => {
+ test('should throw a error when pass in Array, one of its element is not an string ', () => {
+ const testArr = ['1', {}];
+ expect(() => Formatters.splitArrayByDelimiter(testArr as Array)).toThrow();
+ });
+ test('should return a string when pass in Array without delimiter', () => {
+ const testArr = ['1', '2'];
+ expect(Formatters.splitArrayByDelimiter(testArr)).toBe(testArr.join(' '));
+ });
+ test('should return a string which is joined the delimiter when pass in Array with a delimiter', () => {
+ const testArr = ['1', '2'];
+ expect(Formatters.splitArrayByDelimiter(testArr, '?')).toBe(testArr.join('?'));
+ });
+});
diff --git a/__tests__/utils/TimeHelpers.spec.ts b/__tests__/utils/TimeHelpers.spec.ts
new file mode 100644
index 0000000..d9cb2c4
--- /dev/null
+++ b/__tests__/utils/TimeHelpers.spec.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+
+describe('utils/TimeHelpers', () => {
+ describe('durationStringToSeconds', () => {
+ test('returns how many seconds there is in a duration string', () => {
+ // assert
+ expect(TimeHelpers.durationStringToSeconds('1m')).toBe(60);
+ expect(TimeHelpers.durationStringToSeconds('2m')).toBe(60 * 2);
+ expect(TimeHelpers.durationStringToSeconds('1s')).toBe(1);
+ expect(TimeHelpers.durationStringToSeconds('50s')).toBe(50);
+ expect(TimeHelpers.durationStringToSeconds('1h')).toBe(60 * 60);
+ expect(TimeHelpers.durationStringToSeconds('2h')).toBe(60 * 60 * 2);
+ expect(TimeHelpers.durationStringToSeconds('1d')).toBe(24 * 60 * 60);
+ expect(TimeHelpers.durationStringToSeconds('2d')).toBe(24 * 60 * 60 * 2);
+ expect(TimeHelpers.durationStringToSeconds('20ms')).toBe(0);
+ expect(TimeHelpers.durationStringToSeconds('2010ms')).toBe(2);
+ expect(TimeHelpers.durationStringToSeconds('2d 2h 10m 50s 20ms')).toBe(24 * 60 * 60 * 2 + 60 * 60 * 2 + 60 * 10 + 50);
+ });
+ });
+
+ describe('durationStringToMilliseconds', () => {
+ test('returns how many milliseconds there is in a duration string', () => {
+ // assert
+ expect(TimeHelpers.durationStringToMilliseconds('1m')).toBe(1000 * 60);
+ expect(TimeHelpers.durationStringToMilliseconds('2m')).toBe(1000 * 60 * 2);
+ expect(TimeHelpers.durationStringToMilliseconds('1s')).toBe(1000);
+ expect(TimeHelpers.durationStringToMilliseconds('50s')).toBe(1000 * 50);
+ expect(TimeHelpers.durationStringToMilliseconds('1h')).toBe(1000 * 60 * 60);
+ expect(TimeHelpers.durationStringToMilliseconds('2h')).toBe(1000 * 60 * 60 * 2);
+ expect(TimeHelpers.durationStringToMilliseconds('1d')).toBe(1000 * 24 * 60 * 60);
+ expect(TimeHelpers.durationStringToMilliseconds('2d')).toBe(1000 * 24 * 60 * 60 * 2);
+ expect(TimeHelpers.durationStringToMilliseconds('20ms')).toBe(20);
+ expect(TimeHelpers.durationStringToMilliseconds('2010ms')).toBe(2010);
+ expect(TimeHelpers.durationStringToMilliseconds('2d 2h 10m 50s 20ms')).toBe(
+ 1000 * (24 * 60 * 60 * 2 + 60 * 60 * 2 + 60 * 10 + 50) + 20,
+ );
+ });
+ });
+});
diff --git a/__tests__/utils/URLHelpers.spec.ts b/__tests__/utils/URLHelpers.spec.ts
new file mode 100644
index 0000000..0ebc222
--- /dev/null
+++ b/__tests__/utils/URLHelpers.spec.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { URLHelpers } from '@/core/utils/URLHelpers';
+
+describe('utils/URLHelpers', () => {
+ describe('formatUrl() should', () => {
+ test('return correctly shaped object', () => {
+ // act
+ const payload = URLHelpers.formatUrl('http://localhost:3000');
+
+ // assert
+ expect(payload).toBeDefined();
+ expect(payload.protocol).toBeDefined();
+ expect(payload.hostname).toBeDefined();
+ expect(payload.port).toBeDefined();
+ expect(payload.url).toBeDefined();
+ });
+ });
+
+ describe('httpToWsUrl() should', () => {
+ test('should replace http by ws protocol', () => {
+ // act
+ const wsEndpoint = URLHelpers.httpToWsUrl('http://localhost:3000');
+ const wssEndpoint = URLHelpers.httpToWsUrl('https://localhost:3000');
+
+ // assert
+ expect(wsEndpoint).toBeDefined();
+ expect(wssEndpoint).toBeDefined();
+ expect(wsEndpoint).toBe('ws://localhost:3000');
+ expect(wssEndpoint).toBe('wss://localhost:3000');
+ });
+ });
+
+ describe('completeUrlWithHostAndProtocol() should', () => {
+ test('add protocol and port given hostname only', () => {
+ // act
+ const url = URLHelpers.getNodeUrl('localhost');
+
+ // assert
+ expect(url).toBeDefined();
+ expect(url).toBe('http://localhost:3000');
+ });
+
+ test('add port given protocol and hostname', () => {
+ // act
+ const url = URLHelpers.getNodeUrl('http://localhost');
+
+ // assert
+ expect(url).toBeDefined();
+ expect(url).toBe('http://localhost:3000');
+ });
+
+ test('add protocol given hostname and port', () => {
+ // act
+ const url = URLHelpers.getNodeUrl('localhost:3000');
+
+ // assert
+ expect(url).toBeDefined();
+ expect(url).toBe('http://localhost:3000');
+ });
+ });
+});
diff --git a/__tests__/views/forms/FormNodeEdit.spec.ts b/__tests__/views/forms/FormNodeEdit.spec.ts
new file mode 100644
index 0000000..001d18c
--- /dev/null
+++ b/__tests__/views/forms/FormNodeEdit.spec.ts
@@ -0,0 +1,121 @@
+import { createLocalVue, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
+import i18n from '@/language';
+import VueI18n, { Values } from 'vue-i18n';
+import { Vue } from 'vue-property-decorator';
+import { NotificationType } from '@/core/utils/NotificationType';
+import flushPromises from 'flush-promises';
+//@ts-ignore
+import FormNodeEdit from '@/views/forms/FormNodeEdit/FormNodeEdit.vue';
+import { NetworkType } from 'symbol-sdk';
+import { StandardValidationRules } from '@/core/validation/StandardValidationRules';
+import { extend } from 'vee-validate';
+import { UrlValidator } from '@/core/validation/validators';
+StandardValidationRules.register();
+extend('url', {
+ validate: (value) => {
+ return UrlValidator.validate(value);
+ },
+ message: (fieldName: string, values: Values) => `${i18n.t('error_incorrect_url', values)}`,
+});
+const localVue = createLocalVue();
+localVue.use(Vuex);
+localVue.use(VueI18n);
+
+/* fake store */
+const networkModule = {
+ namespaced: true,
+ getters: {
+ knowNodes: () => [
+ { url: 'http://api-01.us-west-1.0941-v1.symboldev.network:3000', friendlyName: '614084b4', isDefault: true },
+ {
+ url: 'http://api-01.ap-southeast-1.0941-v1.symboldev.network:3000',
+ friendlyName: '08b0274c',
+ isDefault: true,
+ },
+ { url: 'http://api-01.eu-west-1.0941-v1.symboldev.network:3000', friendlyName: 'c44a95bd', isDefault: true },
+ { url: 'http://api-02.eu-central-1.0941-v1.symboldev.network:3000', friendlyName: '7a26944a', isDefault: true },
+ {
+ url: 'http://api-02.ap-northeast-1.0941-v1.symboldev.network:3000',
+ friendlyName: '4d08a4d9',
+ isDefault: true,
+ },
+ { url: 'http://api-01.eu-central-1.0941-v1.symboldev.network:3000', friendlyName: 'a08950e0', isDefault: true },
+ {
+ url: 'http://api-01.ap-northeast-1.0941-v1.symboldev.network:3000',
+ friendlyName: 'API AP North-East 1',
+ isDefault: true,
+ },
+ ],
+ currentProfile: () => {
+ return {
+ netWorkType: NetworkType,
+ };
+ },
+ },
+};
+const store = new Vuex.Store({
+ modules: {
+ network: networkModule,
+ },
+});
+store.commit = jest.fn();
+store.dispatch = jest.fn();
+
+const options = {
+ localVue,
+ i18n,
+ store,
+};
+let wrapper;
+let vm;
+beforeEach(() => {
+ wrapper = shallowMount(FormNodeEdit, options);
+ vm = wrapper.vm;
+});
+afterEach(() => {
+ wrapper.destroy();
+ vm = undefined;
+});
+describe('FormNodeEdit', () => {
+ it('successfully submitted', async () => {
+ wrapper.setData({
+ formItems: {
+ nodeUrl: '',
+ networkType: '',
+ networkHash: '',
+ },
+ });
+ wrapper.setMethods({
+ addPeer: jest.fn(),
+ });
+ await Vue.nextTick();
+ vm.onSubmit();
+ expect(vm.addPeer).toBeCalled();
+ });
+ it('successfully add custom node', async () => {
+ wrapper.setData({
+ formItems: {
+ nodeUrl: 'http://api-01.us-west-1.0941-v1.symboldev.network:3000',
+ networkType: 'TEST_NET',
+ networkHash: 'ACECD90E7B248E012803228ADB4424F0D966D24149B72E58987D2BF2F2AF03C4',
+ },
+ });
+ vm.addPeer();
+ expect(vm.$store.dispatch).toBeCalledWith('notification/ADD_ERROR', NotificationType.NODE_EXISTS_ERROR);
+ wrapper.setData({
+ formItems: {
+ nodeUrl: 'http://dual-001.symbol.ninja:3000',
+ networkType: 'TEST_NET',
+ networkHash: 'ACECD90E7B248E012803228ADB4424F0D966D24149B72E58987D2BF2F2AF03C4',
+ },
+ });
+ await flushPromises();
+ vm.addPeer();
+ expect(vm.$store.dispatch).toBeCalledWith('notification/ADD_SUCCESS', NotificationType.OPERATION_SUCCESS);
+ });
+ it('provide the right choices', async () => {
+ await vm.handleInput('http://api-01.us-west-1.0941-v1.symboldev.network:8000');
+ expect(vm.customNodeData).toContain('http://api-01.us-west-1.0941-v1.symboldev.network:8000');
+ });
+});
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 0000000..274804c
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,3 @@
+module.exports = {
+ presets: [["@vue/app", {useBuiltIns: "entry"}]]
+};
diff --git a/docker/default.conf b/docker/default.conf
new file mode 100644
index 0000000..07e6377
--- /dev/null
+++ b/docker/default.conf
@@ -0,0 +1,13 @@
+server {
+ listen 80;
+ server_name localhost;
+ location / {
+ root /usr/share/nginx/html;
+ index index.html index.htm;
+ try_files $uri $uri/ /index.html;
+ }
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root /usr/share/nginx/html;
+ }
+}
diff --git a/electron/entitlements.mac.plist b/electron/entitlements.mac.plist
new file mode 100644
index 0000000..7eb28ed
--- /dev/null
+++ b/electron/entitlements.mac.plist
@@ -0,0 +1,11 @@
+
+
+
+
+ com.apple.security.cs.allow-jit
+ com.apple.security.cs.allow-unsigned-executable-memory
+ com.apple.security.cs.allow-dyld-environment-variables
+ com.apple.security.device.audio-input
+ com.apple.security.device.camera
+
+
\ No newline at end of file
diff --git a/jest.config.js b/jest.config.js
new file mode 100644
index 0000000..48878d1
--- /dev/null
+++ b/jest.config.js
@@ -0,0 +1,52 @@
+const path = require('path')
+module.exports = {
+ rootDir: path.join(__dirname),
+ moduleFileExtensions: [
+ 'js',
+ 'jsx',
+ 'json',
+ 'vue',
+ 'ts',
+ 'tsx',
+ 'node'
+ ],
+ moduleDirectories: ['node_modules', 'src'],
+ modulePaths: ['/src', '/node_modules'],
+ transform: {
+ "^.+\\.js$": "babel-jest",
+ '^.+\\.vue$': 'vue-jest',
+ '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2|ogg)$': 'jest-transform-stub',
+ "^.+\\.ts$": "ts-jest",
+ },
+ transformIgnorePatterns: [
+ '/node_modules/?!(vee-validate/dist/rules)',
+ ],
+ moduleNameMapper: {
+ "^@/(.*)$": "/src/$1",
+ "^@MOCKS/(.*)$": "/__mocks__/$1",
+ "\\.(css|less)$": "identity-obj-proxy"
+ },
+ snapshotSerializers: [
+ 'jest-serializer-vue'
+ ],
+ testMatch: [
+ '**/__tests__/**/**/*.spec.ts',
+ ],
+ testURL: 'http://localhost/',
+ globals: {
+ 'ts-jest': {
+ babelConfig: true,
+ },
+ },
+ coverageDirectory: "coverage",
+ collectCoverageFrom: [
+ "**/*.ts",
+ "**/*.vue",
+ "!**/node_modules/**",
+ "!**/__mocks__/**",
+ "!**/*.png",
+ "!**/*.ogg",
+ "!**/*.d.ts",
+ "!**/*.less",
+ ],
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..d69d48e
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,22717 @@
+{
+ "name": "dhealth-wallet",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "7zip-bin": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.0.3.tgz",
+ "integrity": "sha512-GLyWIFBbGvpKPGo55JyRZAo4lVbnBiD52cKlw/0Vt+wnmKvWJkpZvsjVoaIolyBXDeAQKSicRtqFNPem9w0WYA==",
+ "dev": true
+ },
+ "@babel/code-frame": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz",
+ "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==",
+ "requires": {
+ "@babel/highlight": "^7.10.4"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz",
+ "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz",
+ "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==",
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/generator": "^7.12.10",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helpers": "^7.12.5",
+ "@babel/parser": "^7.12.10",
+ "@babel/template": "^7.12.7",
+ "@babel/traverse": "^7.12.10",
+ "@babel/types": "^7.12.10",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/generator": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz",
+ "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==",
+ "requires": {
+ "@babel/types": "^7.12.11",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-annotate-as-pure": {
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz",
+ "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.10"
+ }
+ },
+ "@babel/helper-builder-binary-assignment-operator-visitor": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz",
+ "integrity": "sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-explode-assignable-expression": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz",
+ "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.12.5",
+ "@babel/helper-validator-option": "^7.12.1",
+ "browserslist": "^4.14.5",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/helper-create-class-features-plugin": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz",
+ "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-member-expression-to-functions": "^7.12.1",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.10.4"
+ }
+ },
+ "@babel/helper-create-regexp-features-plugin": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz",
+ "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "regexpu-core": "^4.7.1"
+ }
+ },
+ "@babel/helper-define-map": {
+ "version": "7.10.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz",
+ "integrity": "sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/types": "^7.10.5",
+ "lodash": "^4.17.19"
+ }
+ },
+ "@babel/helper-explode-assignable-expression": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz",
+ "integrity": "sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz",
+ "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==",
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.12.10",
+ "@babel/template": "^7.12.7",
+ "@babel/types": "^7.12.11"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz",
+ "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==",
+ "requires": {
+ "@babel/types": "^7.12.10"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz",
+ "integrity": "sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz",
+ "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==",
+ "requires": {
+ "@babel/types": "^7.12.7"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz",
+ "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==",
+ "requires": {
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz",
+ "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-simple-access": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.11.0",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.1",
+ "@babel/types": "^7.12.1",
+ "lodash": "^4.17.19"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz",
+ "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==",
+ "requires": {
+ "@babel/types": "^7.12.10"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz",
+ "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==",
+ "dev": true
+ },
+ "@babel/helper-remap-async-to-generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz",
+ "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-wrap-function": "^7.10.4",
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz",
+ "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==",
+ "requires": {
+ "@babel/helper-member-expression-to-functions": "^7.12.7",
+ "@babel/helper-optimise-call-expression": "^7.12.10",
+ "@babel/traverse": "^7.12.10",
+ "@babel/types": "^7.12.11"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz",
+ "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==",
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz",
+ "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.12.1"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz",
+ "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==",
+ "requires": {
+ "@babel/types": "^7.12.11"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+ "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz",
+ "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==",
+ "dev": true
+ },
+ "@babel/helper-wrap-function": {
+ "version": "7.12.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz",
+ "integrity": "sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.10.4",
+ "@babel/types": "^7.10.4"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz",
+ "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==",
+ "requires": {
+ "@babel/template": "^7.10.4",
+ "@babel/traverse": "^7.12.5",
+ "@babel/types": "^7.12.5"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz",
+ "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz",
+ "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg=="
+ },
+ "@babel/plugin-proposal-async-generator-functions": {
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz",
+ "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.12.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-class-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz",
+ "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-decorators": {
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.12.12.tgz",
+ "integrity": "sha512-fhkE9lJYpw2mjHelBpM2zCbaA11aov2GJs7q4cFaXNrWx0H3bW58H9Esy2rdtYOghFBEYUDRIpvlgi+ZD+AvvQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-decorators": "^7.12.1"
+ }
+ },
+ "@babel/plugin-proposal-dynamic-import": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz",
+ "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-export-namespace-from": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz",
+ "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3"
+ }
+ },
+ "@babel/plugin-proposal-json-strings": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz",
+ "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-logical-assignment-operators": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz",
+ "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-nullish-coalescing-operator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz",
+ "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-numeric-separator": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz",
+ "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-object-rest-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz",
+ "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-transform-parameters": "^7.12.1"
+ }
+ },
+ "@babel/plugin-proposal-optional-catch-binding": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz",
+ "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-optional-chaining": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz",
+ "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0"
+ }
+ },
+ "@babel/plugin-proposal-private-methods": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz",
+ "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-class-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-proposal-unicode-property-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz",
+ "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz",
+ "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-decorators": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.12.1.tgz",
+ "integrity": "sha512-ir9YW5daRrTYiy9UJ2TzdNIJEZu8KclVzDcfSt4iEmOtwQ4llPtWInNKJyKnVXp1vE4bbVd5S31M/im3mYMO1w==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-export-namespace-from": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz",
+ "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.3"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz",
+ "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz",
+ "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-arrow-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz",
+ "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-async-to-generator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz",
+ "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-remap-async-to-generator": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-block-scoped-functions": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz",
+ "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-block-scoping": {
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz",
+ "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-classes": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz",
+ "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.10.4",
+ "@babel/helper-define-map": "^7.10.4",
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-optimise-call-expression": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1",
+ "@babel/helper-split-export-declaration": "^7.10.4",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/plugin-transform-computed-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz",
+ "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-destructuring": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz",
+ "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-dotall-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz",
+ "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-duplicate-keys": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz",
+ "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-exponentiation-operator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz",
+ "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-for-of": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz",
+ "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-function-name": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz",
+ "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-function-name": "^7.10.4",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz",
+ "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-member-expression-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz",
+ "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-modules-amd": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz",
+ "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz",
+ "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-simple-access": "^7.12.1",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-systemjs": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz",
+ "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-hoist-variables": "^7.10.4",
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-validator-identifier": "^7.10.4",
+ "babel-plugin-dynamic-import-node": "^2.3.3"
+ }
+ },
+ "@babel/plugin-transform-modules-umd": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz",
+ "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-named-capturing-groups-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz",
+ "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-new-target": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz",
+ "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-object-super": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz",
+ "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-replace-supers": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-parameters": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz",
+ "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-property-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz",
+ "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-regenerator": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz",
+ "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "^0.14.2"
+ }
+ },
+ "@babel/plugin-transform-reserved-words": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz",
+ "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-runtime": {
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz",
+ "integrity": "sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.12.5",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "semver": "^5.5.1"
+ }
+ },
+ "@babel/plugin-transform-shorthand-properties": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz",
+ "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-spread": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz",
+ "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1"
+ }
+ },
+ "@babel/plugin-transform-sticky-regex": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz",
+ "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-template-literals": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz",
+ "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-typeof-symbol": {
+ "version": "7.12.10",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz",
+ "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-unicode-escapes": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz",
+ "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-transform-unicode-regex": {
+ "version": "7.12.1",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz",
+ "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-create-regexp-features-plugin": "^7.12.1",
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/preset-env": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz",
+ "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.12.7",
+ "@babel/helper-compilation-targets": "^7.12.5",
+ "@babel/helper-module-imports": "^7.12.5",
+ "@babel/helper-plugin-utils": "^7.10.4",
+ "@babel/helper-validator-option": "^7.12.11",
+ "@babel/plugin-proposal-async-generator-functions": "^7.12.1",
+ "@babel/plugin-proposal-class-properties": "^7.12.1",
+ "@babel/plugin-proposal-dynamic-import": "^7.12.1",
+ "@babel/plugin-proposal-export-namespace-from": "^7.12.1",
+ "@babel/plugin-proposal-json-strings": "^7.12.1",
+ "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
+ "@babel/plugin-proposal-numeric-separator": "^7.12.7",
+ "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.12.1",
+ "@babel/plugin-proposal-optional-chaining": "^7.12.7",
+ "@babel/plugin-proposal-private-methods": "^7.12.1",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.12.1",
+ "@babel/plugin-syntax-async-generators": "^7.8.0",
+ "@babel/plugin-syntax-class-properties": "^7.12.1",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.0",
+ "@babel/plugin-syntax-export-namespace-from": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.0",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.0",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.0",
+ "@babel/plugin-syntax-top-level-await": "^7.12.1",
+ "@babel/plugin-transform-arrow-functions": "^7.12.1",
+ "@babel/plugin-transform-async-to-generator": "^7.12.1",
+ "@babel/plugin-transform-block-scoped-functions": "^7.12.1",
+ "@babel/plugin-transform-block-scoping": "^7.12.11",
+ "@babel/plugin-transform-classes": "^7.12.1",
+ "@babel/plugin-transform-computed-properties": "^7.12.1",
+ "@babel/plugin-transform-destructuring": "^7.12.1",
+ "@babel/plugin-transform-dotall-regex": "^7.12.1",
+ "@babel/plugin-transform-duplicate-keys": "^7.12.1",
+ "@babel/plugin-transform-exponentiation-operator": "^7.12.1",
+ "@babel/plugin-transform-for-of": "^7.12.1",
+ "@babel/plugin-transform-function-name": "^7.12.1",
+ "@babel/plugin-transform-literals": "^7.12.1",
+ "@babel/plugin-transform-member-expression-literals": "^7.12.1",
+ "@babel/plugin-transform-modules-amd": "^7.12.1",
+ "@babel/plugin-transform-modules-commonjs": "^7.12.1",
+ "@babel/plugin-transform-modules-systemjs": "^7.12.1",
+ "@babel/plugin-transform-modules-umd": "^7.12.1",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1",
+ "@babel/plugin-transform-new-target": "^7.12.1",
+ "@babel/plugin-transform-object-super": "^7.12.1",
+ "@babel/plugin-transform-parameters": "^7.12.1",
+ "@babel/plugin-transform-property-literals": "^7.12.1",
+ "@babel/plugin-transform-regenerator": "^7.12.1",
+ "@babel/plugin-transform-reserved-words": "^7.12.1",
+ "@babel/plugin-transform-shorthand-properties": "^7.12.1",
+ "@babel/plugin-transform-spread": "^7.12.1",
+ "@babel/plugin-transform-sticky-regex": "^7.12.7",
+ "@babel/plugin-transform-template-literals": "^7.12.1",
+ "@babel/plugin-transform-typeof-symbol": "^7.12.10",
+ "@babel/plugin-transform-unicode-escapes": "^7.12.1",
+ "@babel/plugin-transform-unicode-regex": "^7.12.1",
+ "@babel/preset-modules": "^0.1.3",
+ "@babel/types": "^7.12.11",
+ "core-js-compat": "^3.8.0",
+ "semver": "^5.5.0"
+ }
+ },
+ "@babel/preset-modules": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz",
+ "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@babel/plugin-proposal-unicode-property-regex": "^7.4.4",
+ "@babel/plugin-transform-dotall-regex": "^7.4.4",
+ "@babel/types": "^7.4.4",
+ "esutils": "^2.0.2"
+ }
+ },
+ "@babel/runtime": {
+ "version": "7.12.5",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz",
+ "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@babel/template": {
+ "version": "7.12.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz",
+ "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==",
+ "requires": {
+ "@babel/code-frame": "^7.10.4",
+ "@babel/parser": "^7.12.7",
+ "@babel/types": "^7.12.7"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz",
+ "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==",
+ "requires": {
+ "@babel/code-frame": "^7.12.11",
+ "@babel/generator": "^7.12.11",
+ "@babel/helper-function-name": "^7.12.11",
+ "@babel/helper-split-export-declaration": "^7.12.11",
+ "@babel/parser": "^7.12.11",
+ "@babel/types": "^7.12.12",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.19"
+ }
+ },
+ "@babel/types": {
+ "version": "7.12.12",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz",
+ "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "@cnakazawa/watch": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz",
+ "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==",
+ "dev": true,
+ "requires": {
+ "exec-sh": "^0.3.2",
+ "minimist": "^1.2.0"
+ }
+ },
+ "@develar/schema-utils": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
+ "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.12.0",
+ "ajv-keywords": "^3.4.1"
+ }
+ },
+ "@electron/get": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.12.2.tgz",
+ "integrity": "sha512-vAuHUbfvBQpYTJ5wB7uVIDq5c/Ry0fiTBMs7lnEYAo/qXXppIVcWdfBr57u6eRnKdVso7KSiH6p/LbQAG6Izrg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "env-paths": "^2.2.0",
+ "fs-extra": "^8.1.0",
+ "global-agent": "^2.0.2",
+ "global-tunnel-ng": "^2.7.1",
+ "got": "^9.6.0",
+ "progress": "^2.0.3",
+ "sanitize-filename": "^1.6.2",
+ "sumchecker": "^3.0.1"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ }
+ }
+ },
+ "@fortawesome/fontawesome-common-types": {
+ "version": "0.2.34",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.34.tgz",
+ "integrity": "sha512-XcIn3iYbTEzGIxD0/dY5+4f019jIcEIWBiHc3KrmK/ROahwxmZ/s+tdj97p/5K0klz4zZUiMfUlYP0ajhSJjmA=="
+ },
+ "@fortawesome/fontawesome-svg-core": {
+ "version": "1.2.34",
+ "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.34.tgz",
+ "integrity": "sha512-0KNN0nc5eIzaJxlv43QcDmTkDY1CqeN6J7OCGSs+fwGPdtv0yOQqRjieopBCmw+yd7uD3N2HeNL3Zm5isDleLg==",
+ "requires": {
+ "@fortawesome/fontawesome-common-types": "^0.2.34"
+ }
+ },
+ "@fortawesome/free-solid-svg-icons": {
+ "version": "5.15.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.2.tgz",
+ "integrity": "sha512-ZfCU+QjaFsdNZmOGmfqEWhzI3JOe37x5dF4kz9GeXvKn/sTxhqMtZ7mh3lBf76SvcYY5/GKFuyG7p1r4iWMQqw==",
+ "requires": {
+ "@fortawesome/fontawesome-common-types": "^0.2.34"
+ }
+ },
+ "@fortawesome/vue-fontawesome": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.2.tgz",
+ "integrity": "sha512-ecpKSBUWXsxRJVi/dbOds4tkKwEcBQ1JSDZFzE2jTFpF8xIh3OgTX8POIor6bOltjibr3cdEyvnDjecMwUmxhQ=="
+ },
+ "@hapi/address": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
+ "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==",
+ "dev": true
+ },
+ "@hapi/bourne": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz",
+ "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==",
+ "dev": true
+ },
+ "@hapi/hoek": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
+ "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==",
+ "dev": true
+ },
+ "@hapi/joi": {
+ "version": "15.1.1",
+ "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz",
+ "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==",
+ "dev": true,
+ "requires": {
+ "@hapi/address": "2.x.x",
+ "@hapi/bourne": "1.x.x",
+ "@hapi/hoek": "8.x.x",
+ "@hapi/topo": "3.x.x"
+ }
+ },
+ "@hapi/topo": {
+ "version": "3.1.6",
+ "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz",
+ "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==",
+ "dev": true,
+ "requires": {
+ "@hapi/hoek": "^8.3.0"
+ }
+ },
+ "@intervolga/optimize-cssnano-plugin": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz",
+ "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==",
+ "dev": true,
+ "requires": {
+ "cssnano": "^4.0.0",
+ "cssnano-preset-default": "^4.0.0",
+ "postcss": "^7.0.0"
+ }
+ },
+ "@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ }
+ }
+ },
+ "@istanbuljs/schema": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
+ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
+ "dev": true
+ },
+ "@jest/console": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz",
+ "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==",
+ "dev": true,
+ "requires": {
+ "@jest/source-map": "^24.9.0",
+ "chalk": "^2.0.1",
+ "slash": "^2.0.0"
+ }
+ },
+ "@jest/core": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz",
+ "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.7.1",
+ "@jest/reporters": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/transform": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "ansi-escapes": "^3.0.0",
+ "chalk": "^2.0.1",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.1.15",
+ "jest-changed-files": "^24.9.0",
+ "jest-config": "^24.9.0",
+ "jest-haste-map": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-regex-util": "^24.3.0",
+ "jest-resolve": "^24.9.0",
+ "jest-resolve-dependencies": "^24.9.0",
+ "jest-runner": "^24.9.0",
+ "jest-runtime": "^24.9.0",
+ "jest-snapshot": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-validate": "^24.9.0",
+ "jest-watcher": "^24.9.0",
+ "micromatch": "^3.1.10",
+ "p-each-series": "^1.0.0",
+ "realpath-native": "^1.1.0",
+ "rimraf": "^2.5.4",
+ "slash": "^2.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "@jest/environment": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz",
+ "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^24.9.0",
+ "@jest/transform": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "jest-mock": "^24.9.0"
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz",
+ "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-mock": "^24.9.0"
+ }
+ },
+ "@jest/globals": {
+ "version": "25.5.2",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz",
+ "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "expect": "^25.5.0"
+ },
+ "dependencies": {
+ "@jest/environment": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz",
+ "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "jest-mock": "^25.5.0"
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz",
+ "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-mock": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "lolex": "^5.0.0"
+ }
+ },
+ "@jest/types": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+ "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^3.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "15.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz",
+ "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz",
+ "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==",
+ "dev": true
+ },
+ "expect": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz",
+ "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "ansi-styles": "^4.0.0",
+ "jest-get-type": "^25.2.6",
+ "jest-matcher-utils": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-regex-util": "^25.2.6"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz",
+ "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==",
+ "dev": true,
+ "requires": {
+ "chalk": "^3.0.0",
+ "diff-sequences": "^25.2.6",
+ "jest-get-type": "^25.2.6",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-get-type": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz",
+ "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==",
+ "dev": true
+ },
+ "jest-matcher-utils": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz",
+ "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^3.0.0",
+ "jest-diff": "^25.5.0",
+ "jest-get-type": "^25.2.6",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-message-util": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz",
+ "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@jest/types": "^25.5.0",
+ "@types/stack-utils": "^1.0.1",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "micromatch": "^4.0.2",
+ "slash": "^3.0.0",
+ "stack-utils": "^1.0.1"
+ }
+ },
+ "jest-mock": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz",
+ "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0"
+ }
+ },
+ "jest-regex-util": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz",
+ "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==",
+ "dev": true
+ },
+ "jest-util": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz",
+ "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^2.0.0",
+ "make-dir": "^3.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "pretty-format": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
+ "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^16.12.0"
+ }
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "@jest/reporters": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz",
+ "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/transform": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "chalk": "^2.0.1",
+ "exit": "^0.1.2",
+ "glob": "^7.1.2",
+ "istanbul-lib-coverage": "^2.0.2",
+ "istanbul-lib-instrument": "^3.0.1",
+ "istanbul-lib-report": "^2.0.4",
+ "istanbul-lib-source-maps": "^3.0.1",
+ "istanbul-reports": "^2.2.6",
+ "jest-haste-map": "^24.9.0",
+ "jest-resolve": "^24.9.0",
+ "jest-runtime": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-worker": "^24.6.0",
+ "node-notifier": "^5.4.2",
+ "slash": "^2.0.0",
+ "source-map": "^0.6.0",
+ "string-length": "^2.0.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/source-map": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz",
+ "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.1.15",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/test-result": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz",
+ "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/istanbul-lib-coverage": "^2.0.0"
+ }
+ },
+ "@jest/test-sequencer": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz",
+ "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^24.9.0",
+ "jest-haste-map": "^24.9.0",
+ "jest-runner": "^24.9.0",
+ "jest-runtime": "^24.9.0"
+ }
+ },
+ "@jest/transform": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz",
+ "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/types": "^24.9.0",
+ "babel-plugin-istanbul": "^5.1.0",
+ "chalk": "^2.0.1",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.1.15",
+ "jest-haste-map": "^24.9.0",
+ "jest-regex-util": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "micromatch": "^3.1.10",
+ "pirates": "^4.0.1",
+ "realpath-native": "^1.1.0",
+ "slash": "^2.0.0",
+ "source-map": "^0.6.1",
+ "write-file-atomic": "2.4.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/types": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz",
+ "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
+ "@types/yargs": "^13.0.0"
+ }
+ },
+ "@js-joda/core": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-3.2.0.tgz",
+ "integrity": "sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg=="
+ },
+ "@ledgerhq/devices": {
+ "version": "5.41.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-5.41.0.tgz",
+ "integrity": "sha512-3rZzjJ8JEX2dBU+Nq8+FygxFoMZJ/XucjwNBXRaZQfqIFfYGywUH2RueQTY8d0JpzeSS5XYALAXzwLCRZmYrAg==",
+ "requires": {
+ "@ledgerhq/errors": "^5.41.0",
+ "@ledgerhq/logs": "^5.41.0",
+ "rxjs": "^6.6.3",
+ "semver": "^7.3.4"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "@ledgerhq/errors": {
+ "version": "5.41.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-5.41.0.tgz",
+ "integrity": "sha512-Di6Uq9l9c/W9V1jZAQjsVPbvSOSRipF+zXd/Z6SVKB1QxIHwXZu7KYSUnDLV6jqKZ9fxXoLjTYWq2Gl/EW87Kw=="
+ },
+ "@ledgerhq/hw-transport": {
+ "version": "5.41.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-5.41.0.tgz",
+ "integrity": "sha512-4zmTW1XwxvO5Ei+LoV11qXPd97UI8XxwuCeb794g/r6dkqlAL8bh35aVCHpbiHRXnoCt51a74ZciQ1yYteR/8Q==",
+ "requires": {
+ "@ledgerhq/devices": "^5.41.0",
+ "@ledgerhq/errors": "^5.41.0",
+ "events": "^3.2.0"
+ }
+ },
+ "@ledgerhq/hw-transport-node-hid-noevents": {
+ "version": "5.41.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-node-hid-noevents/-/hw-transport-node-hid-noevents-5.41.0.tgz",
+ "integrity": "sha512-XMFM10KAPLQMkNYqawcxy9uXGw6B/SRxNILx/gKXhsBvl20yYCMz6zIwgdlOTPTcgckS7IkAaghwoEN8U0Fk8A==",
+ "requires": {
+ "@ledgerhq/devices": "^5.41.0",
+ "@ledgerhq/errors": "^5.41.0",
+ "@ledgerhq/hw-transport": "^5.41.0",
+ "@ledgerhq/logs": "^5.41.0",
+ "node-hid": "2.1.1"
+ }
+ },
+ "@ledgerhq/hw-transport-webusb": {
+ "version": "5.41.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-5.41.0.tgz",
+ "integrity": "sha512-B8j86wHR5+o1a9X0oT0JLK9cXEDZ6Uf2Ok0uyPkFBX1HUpFtjAkQ7Qje2MUo+JdPMi9+fS0qgumL/ZWJNhRMLQ==",
+ "requires": {
+ "@ledgerhq/devices": "^5.41.0",
+ "@ledgerhq/errors": "^5.41.0",
+ "@ledgerhq/hw-transport": "^5.41.0",
+ "@ledgerhq/logs": "^5.41.0"
+ }
+ },
+ "@ledgerhq/logs": {
+ "version": "5.41.0",
+ "resolved": "https://registry.npmjs.org/@ledgerhq/logs/-/logs-5.41.0.tgz",
+ "integrity": "sha512-pY3nIxOWISAreVTiKRDdKgjQvKWkzz3lov9LsJLyaTn0Q1PISHPjcuMpchueLI50BMA6v1M8ENzXgpqqw+KQDw=="
+ },
+ "@malept/cross-spawn-promise": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz",
+ "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.1"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "@mrmlnc/readdir-enhanced": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+ "dev": true,
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "glob-to-regexp": "^0.3.0"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+ "dev": true
+ },
+ "@pdf-lib/fontkit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/fontkit/-/fontkit-1.0.0.tgz",
+ "integrity": "sha512-C1Hn6wqRMAXZMW5vTa/oCvcTPq0FQsqKKP2mzzzMxUcx0BWZuJKeH4ZRS320y0LKvRBEs1ntFG2txstSsMGr2g==",
+ "dev": true,
+ "requires": {
+ "pako": "^1.0.6"
+ }
+ },
+ "@pdf-lib/standard-fonts": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-0.0.4.tgz",
+ "integrity": "sha512-2pg8hXnChVAF6aSFraXtwB0cx/AgE15FvuLJbdPJSq9LYp1xMp0lapH4+t1HsdD9cA05rnWYLqlEBwS4YK1jLg==",
+ "dev": true,
+ "requires": {
+ "base64-arraybuffer": "^0.1.5",
+ "pako": "^1.0.6"
+ }
+ },
+ "@pdf-lib/upng": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
+ "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
+ "dev": true,
+ "requires": {
+ "pako": "^1.0.10"
+ }
+ },
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz",
+ "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@soda/friendly-errors-webpack-plugin": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz",
+ "integrity": "sha512-RLotfx6k1+nfLacwNCenj7VnTMPxVwYKoGOcffMFoJDKM8tXzBiCN0hMHFJNnoAojduYAsxuiMm0EOMixgiRow==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "error-stack-parser": "^2.0.2",
+ "string-width": "^2.0.0",
+ "strip-ansi": "^5"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "@soda/get-current-script": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.2.tgz",
+ "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==",
+ "dev": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "@types/anymatch": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
+ "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==",
+ "dev": true
+ },
+ "@types/babel__core": {
+ "version": "7.1.12",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz",
+ "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "@types/babel__generator": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz",
+ "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__template": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz",
+ "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__traverse": {
+ "version": "7.11.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz",
+ "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "@types/body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==",
+ "dev": true,
+ "requires": {
+ "@types/connect": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/cacheable-request": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.1.tgz",
+ "integrity": "sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==",
+ "dev": true,
+ "requires": {
+ "@types/http-cache-semantics": "*",
+ "@types/keyv": "*",
+ "@types/node": "*",
+ "@types/responselike": "*"
+ }
+ },
+ "@types/caseless": {
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
+ "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
+ "dev": true
+ },
+ "@types/connect": {
+ "version": "3.4.34",
+ "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz",
+ "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/connect-history-api-fallback": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.3.tgz",
+ "integrity": "sha512-7SxFCd+FLlxCfwVwbyPxbR4khL9aNikJhrorw8nUIOqeuooc9gifBuDQOJw5kzN7i6i3vLn9G8Wde/4QDihpYw==",
+ "dev": true,
+ "requires": {
+ "@types/express-serve-static-core": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/debug": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz",
+ "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==",
+ "dev": true
+ },
+ "@types/eslint-visitor-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
+ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==",
+ "dev": true
+ },
+ "@types/express": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz",
+ "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==",
+ "dev": true,
+ "requires": {
+ "@types/body-parser": "*",
+ "@types/express-serve-static-core": "^4.17.18",
+ "@types/qs": "*",
+ "@types/serve-static": "*"
+ }
+ },
+ "@types/express-serve-static-core": {
+ "version": "4.17.18",
+ "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.18.tgz",
+ "integrity": "sha512-m4JTwx5RUBNZvky/JJ8swEJPKFd8si08pPF2PfizYjGZOKr/svUWPcoUmLow6MmPzhasphB7gSTINY67xn3JNA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/qs": "*",
+ "@types/range-parser": "*"
+ }
+ },
+ "@types/file-saver": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.1.tgz",
+ "integrity": "sha512-g1QUuhYVVAamfCifK7oB7G3aIl4BbOyzDOqVyUfEr4tfBKrXfeH+M+Tg7HKCXSrbzxYdhyCP7z9WbKo0R2hBCw==",
+ "dev": true
+ },
+ "@types/fs-extra": {
+ "version": "9.0.6",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.6.tgz",
+ "integrity": "sha512-ecNRHw4clCkowNOBJH1e77nvbPxHYnWIXMv1IAoG/9+MYGkgoyr3Ppxr7XYFNL41V422EDhyV4/4SSK8L2mlig==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/graceful-fs": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz",
+ "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/http-cache-semantics": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz",
+ "integrity": "sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==",
+ "dev": true
+ },
+ "@types/http-proxy": {
+ "version": "1.17.4",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.4.tgz",
+ "integrity": "sha512-IrSHl2u6AWXduUaDLqYpt45tLVCtYv7o4Z0s1KghBCDgIIS9oW5K1H8mZG/A2CfeLdEa7rTd1ACOiHBc1EMT2Q==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/http-proxy-middleware": {
+ "version": "0.19.3",
+ "resolved": "https://registry.npmjs.org/@types/http-proxy-middleware/-/http-proxy-middleware-0.19.3.tgz",
+ "integrity": "sha512-lnBTx6HCOUeIJMLbI/LaL5EmdKLhczJY5oeXZpX/cXE4rRqb3RmV7VcMpiEfYkmTjipv3h7IAyIINe4plEv7cA==",
+ "dev": true,
+ "requires": {
+ "@types/connect": "*",
+ "@types/http-proxy": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/istanbul-lib-coverage": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
+ "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==",
+ "dev": true
+ },
+ "@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
+ "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*",
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "@types/jest": {
+ "version": "23.3.14",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-23.3.14.tgz",
+ "integrity": "sha512-Q5hTcfdudEL2yOmluA1zaSyPbzWPmJ3XfSWeP3RyoYvS9hnje1ZyagrZOuQ6+1nQC1Gw+7gap3pLNL3xL6UBug==",
+ "dev": true
+ },
+ "@types/json-schema": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
+ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw=="
+ },
+ "@types/json2csv": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@types/json2csv/-/json2csv-5.0.1.tgz",
+ "integrity": "sha512-1r5GCTyFtdQ53CRSIctzWZCmtDXvxtzM77SzOqPB4woMeGcc3rhUMzPqEQH3rokG1k/QLzlC5Qe5Ih8NuFN70Q==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/keyv": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.1.tgz",
+ "integrity": "sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/lodash": {
+ "version": "4.14.168",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz",
+ "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==",
+ "dev": true
+ },
+ "@types/mime": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.3.tgz",
+ "integrity": "sha512-Jus9s4CDbqwocc5pOAnh8ShfrnMcPHuJYzVcSUU7lrh8Ni5HuIqX3oilL86p3dlTrk0LzHRCgA/GQ7uNCw6l2Q==",
+ "dev": true
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "@types/minimist": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz",
+ "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "9.6.61",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.61.tgz",
+ "integrity": "sha512-/aKAdg5c8n468cYLy2eQrcR5k6chlbNwZNGUj3TboyPa2hcO2QAJcfymlqPzMiRj8B6nYKXjzQz36minFE0RwQ==",
+ "dev": true
+ },
+ "@types/normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+ "dev": true
+ },
+ "@types/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
+ "dev": true,
+ "optional": true
+ },
+ "@types/prettier": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==",
+ "dev": true
+ },
+ "@types/q": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
+ "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==",
+ "dev": true
+ },
+ "@types/qs": {
+ "version": "6.9.5",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
+ "integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ==",
+ "dev": true
+ },
+ "@types/range-parser": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz",
+ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==",
+ "dev": true
+ },
+ "@types/request": {
+ "version": "2.48.5",
+ "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz",
+ "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==",
+ "dev": true,
+ "requires": {
+ "@types/caseless": "*",
+ "@types/node": "*",
+ "@types/tough-cookie": "*",
+ "form-data": "^2.5.0"
+ },
+ "dependencies": {
+ "form-data": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
+ "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ }
+ }
+ },
+ "@types/responselike": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
+ "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==",
+ "dev": true
+ },
+ "@types/serve-static": {
+ "version": "1.13.8",
+ "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.8.tgz",
+ "integrity": "sha512-MoJhSQreaVoL+/hurAZzIm8wafFR6ajiTM1m4A0kv6AGeVBl4r4pOV8bGFrjjq1sGxDTnCoF8i22o0/aE5XCyA==",
+ "dev": true,
+ "requires": {
+ "@types/mime": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/source-list-map": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
+ "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==",
+ "dev": true
+ },
+ "@types/stack-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
+ "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
+ "dev": true
+ },
+ "@types/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=",
+ "dev": true
+ },
+ "@types/strip-json-comments": {
+ "version": "0.0.30",
+ "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz",
+ "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==",
+ "dev": true
+ },
+ "@types/tapable": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz",
+ "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==",
+ "dev": true
+ },
+ "@types/tough-cookie": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz",
+ "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==",
+ "dev": true
+ },
+ "@types/uglify-js": {
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.1.tgz",
+ "integrity": "sha512-7npvPKV+jINLu1SpSYVWG8KvyJBhBa8tmzMMdDoVc2pWUYHN8KIXlPJhjJ4LT97c4dXJA2SHL/q6ADbDriZN+Q==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@types/vue-moment": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/vue-moment/-/vue-moment-4.0.2.tgz",
+ "integrity": "sha512-QMPYZ6GYNNgPJd8fjbF+exqza6WGma2bPOY5WgvX9hhQ6xPJdUn+lBpqzwSteVab11jwnGCqaSrQOEBPBL0Uew==",
+ "dev": true,
+ "requires": {
+ "moment": ">=2.24.0",
+ "vue": "^2.6.10"
+ }
+ },
+ "@types/webpack": {
+ "version": "4.41.26",
+ "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz",
+ "integrity": "sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA==",
+ "dev": true,
+ "requires": {
+ "@types/anymatch": "*",
+ "@types/node": "*",
+ "@types/tapable": "*",
+ "@types/uglify-js": "*",
+ "@types/webpack-sources": "*",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "@types/webpack-dev-server": {
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.1.tgz",
+ "integrity": "sha512-rIb+LtUkKnh7+oIJm3WiMJONd71Q0lZuqGLcSqhZ5qjN9gV/CNmZe7Bai+brnBPZ/KVYOsr+4bFLiNZwjBicLw==",
+ "dev": true,
+ "requires": {
+ "@types/connect-history-api-fallback": "*",
+ "@types/express": "*",
+ "@types/http-proxy-middleware": "*",
+ "@types/serve-static": "*",
+ "@types/webpack": "*"
+ }
+ },
+ "@types/webpack-env": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.0.tgz",
+ "integrity": "sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==",
+ "dev": true
+ },
+ "@types/webpack-sources": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz",
+ "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/source-list-map": "*",
+ "source-map": "^0.7.3"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ }
+ }
+ },
+ "@types/yargs": {
+ "version": "13.0.11",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.11.tgz",
+ "integrity": "sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "@types/yargs-parser": {
+ "version": "20.2.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz",
+ "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==",
+ "dev": true
+ },
+ "@types/yauzl": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
+ "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@typescript-eslint/eslint-plugin": {
+ "version": "2.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz",
+ "integrity": "sha512-4zY3Z88rEE99+CNvTbXSyovv2z9PNOVffTWD2W8QF5s2prBQtwN2zadqERcrHpcR7O/+KMI3fcTAmUUhK/iQcQ==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/experimental-utils": "2.34.0",
+ "functional-red-black-tree": "^1.0.1",
+ "regexpp": "^3.0.0",
+ "tsutils": "^3.17.1"
+ }
+ },
+ "@typescript-eslint/experimental-utils": {
+ "version": "2.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz",
+ "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.3",
+ "@typescript-eslint/typescript-estree": "2.34.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^2.0.0"
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "2.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.34.0.tgz",
+ "integrity": "sha512-03ilO0ucSD0EPTw2X4PntSIRFtDPWjrVq7C3/Z3VQHRC7+13YB55rcJI3Jt+YgeHbjUdJPcPa7b23rXCBokuyA==",
+ "dev": true,
+ "requires": {
+ "@types/eslint-visitor-keys": "^1.0.0",
+ "@typescript-eslint/experimental-utils": "2.34.0",
+ "@typescript-eslint/typescript-estree": "2.34.0",
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "@typescript-eslint/typescript-estree": {
+ "version": "2.34.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz",
+ "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "eslint-visitor-keys": "^1.1.0",
+ "glob": "^7.1.6",
+ "is-glob": "^4.0.1",
+ "lodash": "^4.17.15",
+ "semver": "^7.3.2",
+ "tsutils": "^3.17.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "@vue/babel-helper-vue-jsx-merge-props": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.2.1.tgz",
+ "integrity": "sha512-QOi5OW45e2R20VygMSNhyQHvpdUwQZqGPc748JLGCYEy+yp8fNFNdbNIGAgZmi9e+2JHPd6i6idRuqivyicIkA==",
+ "dev": true
+ },
+ "@vue/babel-helper-vue-transform-on": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.0.0.tgz",
+ "integrity": "sha512-svFuKPoXP92TJ76ztENOglOsLjcMGUXkdeQhYDxl6KBnZCpqFjqx6RodUPWFg1bj4zsUVsfoIh1RibLO86fUUQ==",
+ "dev": true
+ },
+ "@vue/babel-plugin-jsx": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.0.1.tgz",
+ "integrity": "sha512-pE1YlINZBzqaLeSNfrvo0nNvYjtWTBU+sXUrx65sLW7DL+nDCZcAVeVkMFDcpT1jIahx4hI3EzOcGZE6oLPLoA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/plugin-syntax-jsx": "^7.0.0",
+ "@babel/template": "^7.0.0",
+ "@babel/traverse": "^7.0.0",
+ "@babel/types": "^7.0.0",
+ "@vue/babel-helper-vue-transform-on": "^1.0.0",
+ "camelcase": "^6.0.0",
+ "html-tags": "^3.1.0",
+ "svg-tags": "^1.0.0"
+ }
+ },
+ "@vue/babel-plugin-transform-vue-jsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@vue/babel-plugin-transform-vue-jsx/-/babel-plugin-transform-vue-jsx-1.2.1.tgz",
+ "integrity": "sha512-HJuqwACYehQwh1fNT8f4kyzqlNMpBuUK4rSiSES5D4QsYncv5fxFsLyrxFPG2ksO7t5WP+Vgix6tt6yKClwPzA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/plugin-syntax-jsx": "^7.2.0",
+ "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
+ "html-tags": "^2.0.0",
+ "lodash.kebabcase": "^4.1.1",
+ "svg-tags": "^1.0.0"
+ },
+ "dependencies": {
+ "html-tags": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
+ "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
+ "dev": true
+ }
+ }
+ },
+ "@vue/babel-preset-app": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/babel-preset-app/-/babel-preset-app-4.5.10.tgz",
+ "integrity": "sha512-IHOyfWqgNNM863NjGmX6s2MIF+ILkJZardHcr7bGrxu5mNBT+p0GOGRQU4sN/adDkEQ9cyAxokm/GIeeoRrnOg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.0",
+ "@babel/helper-compilation-targets": "^7.9.6",
+ "@babel/helper-module-imports": "^7.8.3",
+ "@babel/plugin-proposal-class-properties": "^7.8.3",
+ "@babel/plugin-proposal-decorators": "^7.8.3",
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
+ "@babel/plugin-syntax-jsx": "^7.8.3",
+ "@babel/plugin-transform-runtime": "^7.11.0",
+ "@babel/preset-env": "^7.11.0",
+ "@babel/runtime": "^7.11.0",
+ "@vue/babel-plugin-jsx": "^1.0.0-0",
+ "@vue/babel-preset-jsx": "^1.1.2",
+ "babel-plugin-dynamic-import-node": "^2.3.3",
+ "core-js": "^3.6.5",
+ "core-js-compat": "^3.6.5",
+ "semver": "^6.1.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "@vue/babel-preset-jsx": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@vue/babel-preset-jsx/-/babel-preset-jsx-1.2.4.tgz",
+ "integrity": "sha512-oRVnmN2a77bYDJzeGSt92AuHXbkIxbf/XXSE3klINnh9AXBmVS1DGa1f0d+dDYpLfsAKElMnqKTQfKn7obcL4w==",
+ "dev": true,
+ "requires": {
+ "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
+ "@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
+ "@vue/babel-sugar-composition-api-inject-h": "^1.2.1",
+ "@vue/babel-sugar-composition-api-render-instance": "^1.2.4",
+ "@vue/babel-sugar-functional-vue": "^1.2.2",
+ "@vue/babel-sugar-inject-h": "^1.2.2",
+ "@vue/babel-sugar-v-model": "^1.2.3",
+ "@vue/babel-sugar-v-on": "^1.2.3"
+ }
+ },
+ "@vue/babel-sugar-composition-api-inject-h": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-inject-h/-/babel-sugar-composition-api-inject-h-1.2.1.tgz",
+ "integrity": "sha512-4B3L5Z2G+7s+9Bwbf+zPIifkFNcKth7fQwekVbnOA3cr3Pq71q71goWr97sk4/yyzH8phfe5ODVzEjX7HU7ItQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ }
+ },
+ "@vue/babel-sugar-composition-api-render-instance": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-composition-api-render-instance/-/babel-sugar-composition-api-render-instance-1.2.4.tgz",
+ "integrity": "sha512-joha4PZznQMsxQYXtR3MnTgCASC9u3zt9KfBxIeuI5g2gscpTsSKRDzWQt4aqNIpx6cv8On7/m6zmmovlNsG7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ }
+ },
+ "@vue/babel-sugar-functional-vue": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-functional-vue/-/babel-sugar-functional-vue-1.2.2.tgz",
+ "integrity": "sha512-JvbgGn1bjCLByIAU1VOoepHQ1vFsroSA/QkzdiSs657V79q6OwEWLCQtQnEXD/rLTA8rRit4rMOhFpbjRFm82w==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ }
+ },
+ "@vue/babel-sugar-inject-h": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-inject-h/-/babel-sugar-inject-h-1.2.2.tgz",
+ "integrity": "sha512-y8vTo00oRkzQTgufeotjCLPAvlhnpSkcHFEp60+LJUwygGcd5Chrpn5480AQp/thrxVm8m2ifAk0LyFel9oCnw==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-jsx": "^7.2.0"
+ }
+ },
+ "@vue/babel-sugar-v-model": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-model/-/babel-sugar-v-model-1.2.3.tgz",
+ "integrity": "sha512-A2jxx87mySr/ulAsSSyYE8un6SIH0NWHiLaCWpodPCVOlQVODCaSpiR4+IMsmBr73haG+oeCuSvMOM+ttWUqRQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-jsx": "^7.2.0",
+ "@vue/babel-helper-vue-jsx-merge-props": "^1.2.1",
+ "@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
+ "camelcase": "^5.0.0",
+ "html-tags": "^2.0.0",
+ "svg-tags": "^1.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "html-tags": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz",
+ "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=",
+ "dev": true
+ }
+ }
+ },
+ "@vue/babel-sugar-v-on": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@vue/babel-sugar-v-on/-/babel-sugar-v-on-1.2.3.tgz",
+ "integrity": "sha512-kt12VJdz/37D3N3eglBywV8GStKNUhNrsxChXIV+o0MwVXORYuhDTHJRKPgLJRb/EY3vM2aRFQdxJBp9CLikjw==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-jsx": "^7.2.0",
+ "@vue/babel-plugin-transform-vue-jsx": "^1.2.1",
+ "camelcase": "^5.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ }
+ }
+ },
+ "@vue/cli-overlay": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.5.10.tgz",
+ "integrity": "sha512-BydPsWJTXHTzH8wBcN1rinwLe5QRee52sf/Tceixpn4VVZCio2k8VkNG/o6hRTA+MeGuetXOhmAz0UQfIxfX8w==",
+ "dev": true
+ },
+ "@vue/cli-plugin-babel": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-babel/-/cli-plugin-babel-4.5.10.tgz",
+ "integrity": "sha512-vWEGj3w9mbV27WBJslCmQP1l+hmdOiCHn0hmmHOrCdELm/WK/2/iXQEsPSXujtVd7TQgiaFgvvHmHurBlC/+3w==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.0",
+ "@vue/babel-preset-app": "^4.5.10",
+ "@vue/cli-shared-utils": "^4.5.10",
+ "babel-loader": "^8.1.0",
+ "cache-loader": "^4.1.0",
+ "thread-loader": "^2.1.3",
+ "webpack": "^4.0.0"
+ }
+ },
+ "@vue/cli-plugin-router": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.10.tgz",
+ "integrity": "sha512-roiZTx2W59kTRaqNzHEnjnakP89MS+pVf3zWBlwsNXZpQuvqwFvoNfH/nBSJjqGRgZTRtCUe6vGgVPUEFYi/cg==",
+ "dev": true,
+ "requires": {
+ "@vue/cli-shared-utils": "^4.5.10"
+ }
+ },
+ "@vue/cli-plugin-typescript": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-4.5.10.tgz",
+ "integrity": "sha512-Eo1D+ejv/gFHFwhM6bwYwcU4ZU12vhOnlTkGPWDpjV0EpB9gNOUJTWoYH3b72q/xcP/jyfvPxuezGQBtEPanZg==",
+ "dev": true,
+ "requires": {
+ "@types/webpack-env": "^1.15.2",
+ "@vue/cli-shared-utils": "^4.5.10",
+ "cache-loader": "^4.1.0",
+ "fork-ts-checker-webpack-plugin": "^3.1.1",
+ "fork-ts-checker-webpack-plugin-v5": "npm:fork-ts-checker-webpack-plugin@^5.0.11",
+ "globby": "^9.2.0",
+ "thread-loader": "^2.1.3",
+ "ts-loader": "^6.2.2",
+ "tslint": "^5.20.1",
+ "webpack": "^4.0.0",
+ "yorkie": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "optional": true
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true,
+ "optional": true
+ },
+ "fork-ts-checker-webpack-plugin-v5": {
+ "version": "npm:fork-ts-checker-webpack-plugin@5.2.1",
+ "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz",
+ "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@types/json-schema": "^7.0.5",
+ "chalk": "^4.1.0",
+ "cosmiconfig": "^6.0.0",
+ "deepmerge": "^4.2.2",
+ "fs-extra": "^9.0.0",
+ "memfs": "^3.1.2",
+ "minimatch": "^3.0.4",
+ "schema-utils": "2.7.0",
+ "semver": "^7.3.2",
+ "tapable": "^1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "optional": true
+ },
+ "schema-utils": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz",
+ "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/json-schema": "^7.0.4",
+ "ajv": "^6.12.2",
+ "ajv-keywords": "^3.4.1"
+ }
+ },
+ "semver": {
+ "version": "7.3.5",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
+ "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "@vue/cli-plugin-unit-jest": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-unit-jest/-/cli-plugin-unit-jest-4.5.10.tgz",
+ "integrity": "sha512-x4IPonIpzFmJWD4RvUInSYFDy9W8Ck0h5oxG/3vKQlDR3y2E3Zgh/p0DvcFn6krCXzCJDxGQ+YmxKE0AsUVgYw==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.9.6",
+ "@types/jest": "^24.0.19",
+ "@vue/cli-shared-utils": "^4.5.10",
+ "babel-core": "^7.0.0-bridge.0",
+ "babel-jest": "^24.9.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
+ "deepmerge": "^4.2.2",
+ "jest": "^24.9.0",
+ "jest-environment-jsdom-fifteen": "^1.0.2",
+ "jest-serializer-vue": "^2.0.2",
+ "jest-transform-stub": "^2.0.0",
+ "jest-watch-typeahead": "^0.4.2",
+ "ts-jest": "^24.2.0",
+ "vue-jest": "^3.0.5"
+ },
+ "dependencies": {
+ "@types/jest": {
+ "version": "24.9.1",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.9.1.tgz",
+ "integrity": "sha512-Fb38HkXSVA4L8fGKEZ6le5bB8r6MRWlOCZbVuWZcmOMSCd2wCYOwN1ibj8daIoV9naq7aaOZjrLCoCMptKU/4Q==",
+ "dev": true,
+ "requires": {
+ "jest-diff": "^24.3.0"
+ }
+ },
+ "babel-jest": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz",
+ "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/babel__core": "^7.1.0",
+ "babel-plugin-istanbul": "^5.1.0",
+ "babel-preset-jest": "^24.9.0",
+ "chalk": "^2.4.2",
+ "slash": "^2.0.0"
+ }
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "jest": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz",
+ "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==",
+ "dev": true,
+ "requires": {
+ "import-local": "^2.0.0",
+ "jest-cli": "^24.9.0"
+ },
+ "dependencies": {
+ "jest-cli": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz",
+ "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "chalk": "^2.0.1",
+ "exit": "^0.1.2",
+ "import-local": "^2.0.0",
+ "is-ci": "^2.0.0",
+ "jest-config": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-validate": "^24.9.0",
+ "prompts": "^2.0.1",
+ "realpath-native": "^1.1.0",
+ "yargs": "^13.3.0"
+ }
+ }
+ }
+ },
+ "ts-jest": {
+ "version": "24.3.0",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.3.0.tgz",
+ "integrity": "sha512-Hb94C/+QRIgjVZlJyiWwouYUF+siNJHJHknyspaOcZ+OQAIdFG/UrdQVXw/0B8Z3No34xkUXZJpOTy9alOWdVQ==",
+ "dev": true,
+ "requires": {
+ "bs-logger": "0.x",
+ "buffer-from": "1.x",
+ "fast-json-stable-stringify": "2.x",
+ "json5": "2.x",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "mkdirp": "0.x",
+ "resolve": "1.x",
+ "semver": "^5.5",
+ "yargs-parser": "10.x"
+ }
+ },
+ "yargs-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "@vue/cli-plugin-vuex": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.10.tgz",
+ "integrity": "sha512-Z5pnL3Eg2uwkKqP09NoM46/rwQCJ1j/1cZMgO4JF817O9n5AsFgV456UE6lK2cVCvIfvt7+S3HLrSPZUsYNQjQ==",
+ "dev": true
+ },
+ "@vue/cli-service": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.10.tgz",
+ "integrity": "sha512-HnVkbc+Zb6J1lu0ojuKC6aQ4PjCW2fqlJE0G9Zqg+7VsUZ2e15UVRoIXj2hcIWtQiFF6n2FDxEkvZLslht9rkg==",
+ "dev": true,
+ "requires": {
+ "@intervolga/optimize-cssnano-plugin": "^1.0.5",
+ "@soda/friendly-errors-webpack-plugin": "^1.7.1",
+ "@soda/get-current-script": "^1.0.0",
+ "@types/minimist": "^1.2.0",
+ "@types/webpack": "^4.0.0",
+ "@types/webpack-dev-server": "^3.11.0",
+ "@vue/cli-overlay": "^4.5.10",
+ "@vue/cli-plugin-router": "^4.5.10",
+ "@vue/cli-plugin-vuex": "^4.5.10",
+ "@vue/cli-shared-utils": "^4.5.10",
+ "@vue/component-compiler-utils": "^3.1.2",
+ "@vue/preload-webpack-plugin": "^1.1.0",
+ "@vue/web-component-wrapper": "^1.2.0",
+ "acorn": "^7.4.0",
+ "acorn-walk": "^7.1.1",
+ "address": "^1.1.2",
+ "autoprefixer": "^9.8.6",
+ "browserslist": "^4.12.0",
+ "cache-loader": "^4.1.0",
+ "case-sensitive-paths-webpack-plugin": "^2.3.0",
+ "cli-highlight": "^2.1.4",
+ "clipboardy": "^2.3.0",
+ "cliui": "^6.0.0",
+ "copy-webpack-plugin": "^5.1.1",
+ "css-loader": "^3.5.3",
+ "cssnano": "^4.1.10",
+ "debug": "^4.1.1",
+ "default-gateway": "^5.0.5",
+ "dotenv": "^8.2.0",
+ "dotenv-expand": "^5.1.0",
+ "file-loader": "^4.2.0",
+ "fs-extra": "^7.0.1",
+ "globby": "^9.2.0",
+ "hash-sum": "^2.0.0",
+ "html-webpack-plugin": "^3.2.0",
+ "launch-editor-middleware": "^2.2.1",
+ "lodash.defaultsdeep": "^4.6.1",
+ "lodash.mapvalues": "^4.6.0",
+ "lodash.transform": "^4.6.0",
+ "mini-css-extract-plugin": "^0.9.0",
+ "minimist": "^1.2.5",
+ "pnp-webpack-plugin": "^1.6.4",
+ "portfinder": "^1.0.26",
+ "postcss-loader": "^3.0.0",
+ "ssri": "^7.1.0",
+ "terser-webpack-plugin": "^2.3.6",
+ "thread-loader": "^2.1.3",
+ "url-loader": "^2.2.0",
+ "vue-loader": "^15.9.2",
+ "vue-loader-v16": "npm:vue-loader@^16.1.0",
+ "vue-style-loader": "^4.1.2",
+ "webpack": "^4.0.0",
+ "webpack-bundle-analyzer": "^3.8.0",
+ "webpack-chain": "^6.4.0",
+ "webpack-dev-server": "^3.11.0",
+ "webpack-merge": "^4.2.2"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "cacache": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
+ "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==",
+ "dev": true,
+ "requires": {
+ "chownr": "^1.1.2",
+ "figgy-pudding": "^3.5.1",
+ "fs-minipass": "^2.0.0",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.2",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^5.1.1",
+ "minipass": "^3.0.0",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.2",
+ "mkdirp": "^0.5.1",
+ "move-concurrently": "^1.0.1",
+ "p-map": "^3.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^2.7.1",
+ "ssri": "^7.0.0",
+ "unique-filename": "^1.1.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz",
+ "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "fs-extra": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "jest-worker": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
+ "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "ssri": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz",
+ "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==",
+ "dev": true,
+ "requires": {
+ "figgy-pudding": "^3.5.1",
+ "minipass": "^3.1.1"
+ }
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "terser-webpack-plugin": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz",
+ "integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==",
+ "dev": true,
+ "requires": {
+ "cacache": "^13.0.1",
+ "find-cache-dir": "^3.3.1",
+ "jest-worker": "^25.4.0",
+ "p-limit": "^2.3.0",
+ "schema-utils": "^2.6.6",
+ "serialize-javascript": "^4.0.0",
+ "source-map": "^0.6.1",
+ "terser": "^4.6.12",
+ "webpack-sources": "^1.4.3"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ },
+ "vue-loader-v16": {
+ "version": "npm:vue-loader@16.2.0",
+ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz",
+ "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chalk": "^4.1.0",
+ "hash-sum": "^2.0.0",
+ "loader-utils": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "@vue/cli-shared-utils": {
+ "version": "4.5.10",
+ "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.10.tgz",
+ "integrity": "sha512-Lid6FflDqcvo/JBIBjUriAQ1RkQaKbBpzXSLEK/JmoKkQRHW/rRhDLGI1dEVyOLYnDEiL1m8o1xPJaplUUiXpA==",
+ "dev": true,
+ "requires": {
+ "@hapi/joi": "^15.0.1",
+ "chalk": "^2.4.2",
+ "execa": "^1.0.0",
+ "launch-editor": "^2.2.1",
+ "lru-cache": "^5.1.1",
+ "node-ipc": "^9.1.1",
+ "open": "^6.3.0",
+ "ora": "^3.4.0",
+ "read-pkg": "^5.1.1",
+ "request": "^2.88.2",
+ "semver": "^6.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "@vue/component-compiler-utils": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz",
+ "integrity": "sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==",
+ "dev": true,
+ "requires": {
+ "consolidate": "^0.15.1",
+ "hash-sum": "^1.0.2",
+ "lru-cache": "^4.1.2",
+ "merge-source-map": "^1.1.0",
+ "postcss": "^7.0.14",
+ "postcss-selector-parser": "^6.0.2",
+ "prettier": "^1.18.2",
+ "source-map": "~0.6.1",
+ "vue-template-es2015-compiler": "^1.9.0"
+ },
+ "dependencies": {
+ "hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "prettier": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz",
+ "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==",
+ "dev": true,
+ "optional": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ }
+ }
+ },
+ "@vue/eslint-config-typescript": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-5.1.0.tgz",
+ "integrity": "sha512-wFAdPMWegKZOdbQBEWV4/KbOKuX/6Q5db3304kiWNBK+6P7+CoMrsbaKzJFjuAZF7fQR2fJtZT9ciGWVVT//vw==",
+ "dev": true,
+ "requires": {
+ "vue-eslint-parser": "^7.0.0"
+ }
+ },
+ "@vue/preload-webpack-plugin": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz",
+ "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==",
+ "dev": true
+ },
+ "@vue/test-utils": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@vue/test-utils/-/test-utils-1.1.2.tgz",
+ "integrity": "sha512-utbIL7zn9c+SjhybPwh48lpWCiluFCbP1yyRNAy1fQsw/6hiNFioaWy05FoVAFIZXC5WwBf+5r4ypfM1j/nI4A==",
+ "dev": true,
+ "requires": {
+ "dom-event-types": "^1.0.0",
+ "lodash": "^4.17.15",
+ "pretty": "^2.0.0"
+ }
+ },
+ "@vue/web-component-wrapper": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.2.0.tgz",
+ "integrity": "sha512-Xn/+vdm9CjuC9p3Ae+lTClNutrVhsXpzxvoTXXtoys6kVRX9FkueSUAqSWAyZntmVLlR4DosBV4pH8y5Z/HbUw==",
+ "dev": true
+ },
+ "@webassemblyjs/ast": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz",
+ "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/helper-module-context": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/wast-parser": "1.9.0"
+ }
+ },
+ "@webassemblyjs/floating-point-hex-parser": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz",
+ "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-api-error": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz",
+ "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-buffer": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz",
+ "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-code-frame": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz",
+ "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/wast-printer": "1.9.0"
+ }
+ },
+ "@webassemblyjs/helper-fsm": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz",
+ "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-module-context": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz",
+ "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0"
+ }
+ },
+ "@webassemblyjs/helper-wasm-bytecode": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz",
+ "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==",
+ "dev": true
+ },
+ "@webassemblyjs/helper-wasm-section": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz",
+ "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-buffer": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/wasm-gen": "1.9.0"
+ }
+ },
+ "@webassemblyjs/ieee754": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz",
+ "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==",
+ "dev": true,
+ "requires": {
+ "@xtuc/ieee754": "^1.2.0"
+ }
+ },
+ "@webassemblyjs/leb128": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz",
+ "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==",
+ "dev": true,
+ "requires": {
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/utf8": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz",
+ "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==",
+ "dev": true
+ },
+ "@webassemblyjs/wasm-edit": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz",
+ "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-buffer": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/helper-wasm-section": "1.9.0",
+ "@webassemblyjs/wasm-gen": "1.9.0",
+ "@webassemblyjs/wasm-opt": "1.9.0",
+ "@webassemblyjs/wasm-parser": "1.9.0",
+ "@webassemblyjs/wast-printer": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wasm-gen": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz",
+ "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/ieee754": "1.9.0",
+ "@webassemblyjs/leb128": "1.9.0",
+ "@webassemblyjs/utf8": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wasm-opt": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz",
+ "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-buffer": "1.9.0",
+ "@webassemblyjs/wasm-gen": "1.9.0",
+ "@webassemblyjs/wasm-parser": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wasm-parser": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz",
+ "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-api-error": "1.9.0",
+ "@webassemblyjs/helper-wasm-bytecode": "1.9.0",
+ "@webassemblyjs/ieee754": "1.9.0",
+ "@webassemblyjs/leb128": "1.9.0",
+ "@webassemblyjs/utf8": "1.9.0"
+ }
+ },
+ "@webassemblyjs/wast-parser": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz",
+ "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/floating-point-hex-parser": "1.9.0",
+ "@webassemblyjs/helper-api-error": "1.9.0",
+ "@webassemblyjs/helper-code-frame": "1.9.0",
+ "@webassemblyjs/helper-fsm": "1.9.0",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@webassemblyjs/wast-printer": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz",
+ "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/wast-parser": "1.9.0",
+ "@xtuc/long": "4.2.2"
+ }
+ },
+ "@xtuc/ieee754": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
+ "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
+ "dev": true
+ },
+ "@xtuc/long": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
+ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
+ "dev": true
+ },
+ "@zxing/library": {
+ "version": "0.18.4",
+ "resolved": "https://registry.npmjs.org/@zxing/library/-/library-0.18.4.tgz",
+ "integrity": "sha512-FZ6n3R3QzCPYcKjfHenl6JqKf5XHBo5S1sD7Cv85PFc9F8Emr/hqFgPA3k+ebI88leXmT7ZM42F/vn1dP91z2Q==",
+ "requires": {
+ "@zxing/text-encoding": "~0.9.0",
+ "ts-custom-error": "^3.0.0"
+ }
+ },
+ "@zxing/text-encoding": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@zxing/text-encoding/-/text-encoding-0.9.0.tgz",
+ "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==",
+ "optional": true
+ },
+ "abab": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "dev": true,
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "acorn": {
+ "version": "6.4.2",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
+ "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
+ "dev": true
+ },
+ "acorn-globals": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
+ "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.1",
+ "acorn-walk": "^6.0.1"
+ }
+ },
+ "acorn-jsx": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz",
+ "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
+ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
+ "dev": true
+ },
+ "address": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz",
+ "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==",
+ "dev": true
+ },
+ "aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-errors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz",
+ "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==",
+ "dev": true
+ },
+ "ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="
+ },
+ "alphanum-sort": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+ "dev": true
+ },
+ "animate.css": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/animate.css/-/animate.css-3.7.2.tgz",
+ "integrity": "sha512-0bE8zYo7C0KvgOYrSVfrzkbYk6IOTVPNqkiHg2cbyF4Pq/PXzilz4BRWA3hwEUBoMp5VBgrC29lQIZyhRWdBTw=="
+ },
+ "ansi-align": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+ "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.0.0"
+ }
+ },
+ "ansi-colors": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz",
+ "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-html": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz",
+ "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "app-builder-bin": {
+ "version": "3.5.10",
+ "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-3.5.10.tgz",
+ "integrity": "sha512-Jd+GW68lR0NeetgZDo47PdWBEPdnD+p0jEa7XaxjRC8u6Oo/wgJsfKUkORRgr2NpkD19IFKN50P6JYy04XHFLQ==",
+ "dev": true
+ },
+ "app-builder-lib": {
+ "version": "22.9.1",
+ "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-22.9.1.tgz",
+ "integrity": "sha512-KfXim/fiNwFW2SKffsjEMdAU7RbbEXn62x5YyXle1b4j9X/wEHW9iwox8De6y0hJdR+/kCC/49lI+VgNwLhV7A==",
+ "dev": true,
+ "requires": {
+ "7zip-bin": "~5.0.3",
+ "@develar/schema-utils": "~2.6.5",
+ "async-exit-hook": "^2.0.1",
+ "bluebird-lst": "^1.0.9",
+ "builder-util": "22.9.1",
+ "builder-util-runtime": "8.7.2",
+ "chromium-pickle-js": "^0.2.0",
+ "debug": "^4.3.0",
+ "ejs": "^3.1.5",
+ "electron-publish": "22.9.1",
+ "fs-extra": "^9.0.1",
+ "hosted-git-info": "^3.0.5",
+ "is-ci": "^2.0.0",
+ "isbinaryfile": "^4.0.6",
+ "js-yaml": "^3.14.0",
+ "lazy-val": "^1.0.4",
+ "minimatch": "^3.0.4",
+ "normalize-package-data": "^2.5.0",
+ "read-config-file": "6.0.0",
+ "sanitize-filename": "^1.6.3",
+ "semver": "^7.3.2",
+ "temp-file": "^3.3.7"
+ },
+ "dependencies": {
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "ejs": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.5.tgz",
+ "integrity": "sha512-dldq3ZfFtgVTJMLjOe+/3sROTzALlL9E34V4/sDtUd/KlBSS0s6U1/+WPE1B4sj9CXHJpL1M6rhNJnc9Wbal9w==",
+ "dev": true,
+ "requires": {
+ "jake": "^10.6.1"
+ }
+ },
+ "hosted-git-info": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.7.tgz",
+ "integrity": "sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+ },
+ "arch": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz",
+ "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==",
+ "dev": true
+ },
+ "archiver": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
+ "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
+ "dev": true,
+ "requires": {
+ "archiver-utils": "^1.3.0",
+ "async": "^2.0.0",
+ "buffer-crc32": "^0.2.1",
+ "glob": "^7.0.0",
+ "lodash": "^4.8.0",
+ "readable-stream": "^2.0.0",
+ "tar-stream": "^1.5.0",
+ "walkdir": "^0.0.11",
+ "zip-stream": "^1.1.0"
+ }
+ },
+ "archiver-promise": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archiver-promise/-/archiver-promise-1.0.0.tgz",
+ "integrity": "sha1-p8TlLmB/2XbFSjAlBFQXM2g09lI=",
+ "dev": true,
+ "requires": {
+ "archiver": "^1.2.0"
+ }
+ },
+ "archiver-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
+ "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.0",
+ "graceful-fs": "^4.1.0",
+ "lazystream": "^1.0.0",
+ "lodash": "^4.8.0",
+ "normalize-path": "^2.0.0",
+ "readable-stream": "^2.0.0"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+ "dev": true
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "asar": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/asar/-/asar-3.0.3.tgz",
+ "integrity": "sha512-k7zd+KoR+n8pl71PvgElcoKHrVNiSXtw7odKbyNpmgKe7EGRF9Pnu3uLOukD37EvavKwVFxOUpqXTIZC5B5Pmw==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "chromium-pickle-js": "^0.2.0",
+ "commander": "^5.0.0",
+ "glob": "^7.1.6",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+ "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+ "dev": true
+ }
+ }
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "asn1.js": {
+ "version": "5.4.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz",
+ "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "safer-buffer": "^2.1.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "assert": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz",
+ "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.1",
+ "util": "0.10.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ }
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "async": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
+ "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+ "dev": true
+ },
+ "async-exit-hook": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
+ "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
+ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
+ "dev": true
+ },
+ "async-validator": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.1.tgz",
+ "integrity": "sha512-DDmKA7sdSAJtTVeNZHrnr2yojfFaoeW8MfQN8CeuXg8DDQHTqKk9Fdv38dSvnesHoO8MUwMI2HphOeSyIF+wmQ=="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "at-least-node": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
+ "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "author-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz",
+ "integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "9.8.6",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz",
+ "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.12.0",
+ "caniuse-lite": "^1.0.30001109",
+ "colorette": "^1.2.1",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "postcss": "^7.0.32",
+ "postcss-value-parser": "^4.1.0"
+ }
+ },
+ "await-lock": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/await-lock/-/await-lock-2.1.0.tgz",
+ "integrity": "sha512-t7Zm5YGgEEc/3eYAicF32m/TNvL+XOeYZy9CvBUeJY/szM7frLolFylhrlZNWV/ohWhcUXygrBGjYmoQdxF4CQ=="
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
+ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
+ },
+ "axios": {
+ "version": "0.21.1",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+ "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+ "requires": {
+ "follow-redirects": "^1.10.0"
+ }
+ },
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "babel-core": {
+ "version": "7.0.0-bridge.0",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
+ "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
+ "dev": true
+ },
+ "babel-helper-builder-binary-assignment-operator-visitor": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz",
+ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
+ "dev": true,
+ "requires": {
+ "babel-helper-explode-assignable-expression": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-call-delegate": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz",
+ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-define-map": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz",
+ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-helper-explode-assignable-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz",
+ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz",
+ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
+ "dev": true,
+ "requires": {
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-get-function-arity": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz",
+ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-hoist-variables": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz",
+ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-optimise-call-expression": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz",
+ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-regex": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz",
+ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-helper-remap-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-helper-replace-supers": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz",
+ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
+ "dev": true,
+ "requires": {
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-jest": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz",
+ "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^25.5.1",
+ "@jest/types": "^25.5.0",
+ "@types/babel__core": "^7.1.7",
+ "babel-plugin-istanbul": "^6.0.0",
+ "babel-preset-jest": "^25.5.0",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "@jest/transform": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz",
+ "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/types": "^25.5.0",
+ "babel-plugin-istanbul": "^6.0.0",
+ "chalk": "^3.0.0",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^25.5.1",
+ "jest-regex-util": "^25.2.6",
+ "jest-util": "^25.5.0",
+ "micromatch": "^4.0.2",
+ "pirates": "^4.0.1",
+ "realpath-native": "^2.0.0",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.1",
+ "write-file-atomic": "^3.0.0"
+ }
+ },
+ "@jest/types": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+ "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^3.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "15.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz",
+ "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
+ "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^4.0.0",
+ "test-exclude": "^6.0.0"
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz",
+ "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__traverse": "^7.0.6"
+ }
+ },
+ "babel-preset-jest": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz",
+ "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-jest-hoist": "^25.5.0",
+ "babel-preset-current-node-syntax": "^0.1.2"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "istanbul-lib-coverage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+ "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.7.5",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.0.0",
+ "semver": "^6.3.0"
+ }
+ },
+ "jest-haste-map": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz",
+ "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "@types/graceful-fs": "^4.1.2",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^2.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-serializer": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "jest-worker": "^25.5.0",
+ "micromatch": "^4.0.2",
+ "sane": "^4.0.3",
+ "walker": "^1.0.7",
+ "which": "^2.0.2"
+ }
+ },
+ "jest-regex-util": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz",
+ "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==",
+ "dev": true
+ },
+ "jest-serializer": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz",
+ "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.4"
+ }
+ },
+ "jest-util": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz",
+ "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^2.0.0",
+ "make-dir": "^3.0.0"
+ }
+ },
+ "jest-worker": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
+ "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "realpath-native": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz",
+ "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ }
+ }
+ },
+ "babel-loader": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz",
+ "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==",
+ "dev": true,
+ "requires": {
+ "find-cache-dir": "^3.3.1",
+ "loader-utils": "^1.4.0",
+ "make-dir": "^3.1.0",
+ "schema-utils": "^2.6.5"
+ }
+ },
+ "babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-check-es2015-constants": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz",
+ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz",
+ "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==",
+ "dev": true,
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
+ "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "find-up": "^3.0.0",
+ "istanbul-lib-instrument": "^3.3.0",
+ "test-exclude": "^5.2.3"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz",
+ "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==",
+ "dev": true,
+ "requires": {
+ "@types/babel__traverse": "^7.0.6"
+ }
+ },
+ "babel-plugin-syntax-async-functions": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz",
+ "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=",
+ "dev": true
+ },
+ "babel-plugin-syntax-dynamic-import": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz",
+ "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo="
+ },
+ "babel-plugin-syntax-exponentiation-operator": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz",
+ "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=",
+ "dev": true
+ },
+ "babel-plugin-syntax-trailing-function-commas": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz",
+ "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=",
+ "dev": true
+ },
+ "babel-plugin-transform-async-to-generator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz",
+ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
+ "dev": true,
+ "requires": {
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-functions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-arrow-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz",
+ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoped-functions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz",
+ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-block-scoping": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz",
+ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-plugin-transform-es2015-classes": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz",
+ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
+ "dev": true,
+ "requires": {
+ "babel-helper-define-map": "^6.24.1",
+ "babel-helper-function-name": "^6.24.1",
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-computed-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz",
+ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-destructuring": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz",
+ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-duplicate-keys": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz",
+ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-for-of": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz",
+ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-function-name": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz",
+ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
+ "dev": true,
+ "requires": {
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz",
+ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-amd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz",
+ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-commonjs": {
+ "version": "6.26.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-strict-mode": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-types": "^6.26.0"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-systemjs": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz",
+ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
+ "dev": true,
+ "requires": {
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-modules-umd": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz",
+ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-object-super": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz",
+ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
+ "dev": true,
+ "requires": {
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-parameters": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz",
+ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
+ "dev": true,
+ "requires": {
+ "babel-helper-call-delegate": "^6.24.1",
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-shorthand-properties": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz",
+ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-spread": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz",
+ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-sticky-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz",
+ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-plugin-transform-es2015-template-literals": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz",
+ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-typeof-symbol": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz",
+ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-es2015-unicode-regex": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz",
+ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
+ "dev": true,
+ "requires": {
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "regexpu-core": "^2.0.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true
+ },
+ "regexpu-core": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz",
+ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ },
+ "regjsgen": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+ "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ }
+ }
+ }
+ },
+ "babel-plugin-transform-exponentiation-operator": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz",
+ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
+ "dev": true,
+ "requires": {
+ "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-transform-regenerator": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz",
+ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
+ "dev": true,
+ "requires": {
+ "regenerator-transform": "^0.10.0"
+ },
+ "dependencies": {
+ "regenerator-transform": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz",
+ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.18.0",
+ "babel-types": "^6.19.0",
+ "private": "^0.1.6"
+ }
+ }
+ }
+ },
+ "babel-plugin-transform-strict-mode": {
+ "version": "6.24.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz",
+ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
+ }
+ },
+ "babel-preset-current-node-syntax": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz",
+ "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3"
+ }
+ },
+ "babel-preset-env": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
+ "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-check-es2015-constants": "^6.22.0",
+ "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+ "babel-plugin-transform-async-to-generator": "^6.22.0",
+ "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+ "babel-plugin-transform-es2015-classes": "^6.23.0",
+ "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+ "babel-plugin-transform-es2015-for-of": "^6.23.0",
+ "babel-plugin-transform-es2015-function-name": "^6.22.0",
+ "babel-plugin-transform-es2015-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+ "babel-plugin-transform-es2015-object-super": "^6.22.0",
+ "babel-plugin-transform-es2015-parameters": "^6.23.0",
+ "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-spread": "^6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+ "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+ "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+ "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+ "babel-plugin-transform-regenerator": "^6.22.0",
+ "browserslist": "^3.2.6",
+ "invariant": "^2.2.2",
+ "semver": "^5.3.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "3.2.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30000844",
+ "electron-to-chromium": "^1.3.47"
+ }
+ }
+ }
+ },
+ "babel-preset-jest": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz",
+ "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-object-rest-spread": "^7.0.0",
+ "babel-plugin-jest-hoist": "^24.9.0"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
+ "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
+ "dev": true
+ },
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ }
+ }
+ },
+ "babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ },
+ "dependencies": {
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+ "dev": true
+ }
+ }
+ },
+ "babylon": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+ "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "barcode-detector": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/barcode-detector/-/barcode-detector-0.5.0.tgz",
+ "integrity": "sha512-CL0ETCnLjaklGbFJeU1f5SU3CHVK1Tm+SjPbLKlt8iJ6Fqgc9yseNmWEpXSPmcGW3ET3rUwkWk2fXG+kcSbwBw==",
+ "requires": {
+ "@zxing/library": "^0.18.4",
+ "jsqr": "^1.3.1"
+ }
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "base-x": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz",
+ "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "base64-arraybuffer": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=",
+ "dev": true
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
+ "dev": true
+ },
+ "batch-processor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/batch-processor/-/batch-processor-1.0.0.tgz",
+ "integrity": "sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bfj": {
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz",
+ "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.5",
+ "check-types": "^8.0.3",
+ "hoopy": "^0.1.4",
+ "tryer": "^1.0.1"
+ }
+ },
+ "big.js": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
+ "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ=="
+ },
+ "binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "dev": true
+ },
+ "bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "requires": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "bip32": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bip32/-/bip32-1.0.4.tgz",
+ "integrity": "sha512-8T21eLWylZETolyqCPgia+MNp+kY37zFr7PTFDTPObHeNi9JlfG4qGIh8WzerIJidtwoK+NsWq2I5i66YfHoIw==",
+ "dev": true,
+ "requires": {
+ "bs58check": "^2.1.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "tiny-secp256k1": "^1.0.0",
+ "typeforce": "^1.11.5",
+ "wif": "^2.0.6"
+ }
+ },
+ "bip32-path": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/bip32-path/-/bip32-path-0.4.2.tgz",
+ "integrity": "sha1-XbBBataCJxLwd4NuJVe4aXwMfJk="
+ },
+ "bip39": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.3.tgz",
+ "integrity": "sha512-P0dKrz4g0V0BjXfx7d9QNkJ/Txcz/k+hM9TnjqjUaXtuOfAvxXSw2rJw8DX0e3ZPwnK/IgDxoRqf0bvoVCqbMg==",
+ "dev": true,
+ "requires": {
+ "@types/node": "11.11.6",
+ "create-hash": "^1.1.0",
+ "pbkdf2": "^3.0.9",
+ "randombytes": "^2.0.1"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "11.11.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz",
+ "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==",
+ "dev": true
+ }
+ }
+ },
+ "bip44-constants": {
+ "version": "8.0.103",
+ "resolved": "https://registry.npmjs.org/bip44-constants/-/bip44-constants-8.0.103.tgz",
+ "integrity": "sha512-wuGsY9IKUS9GC5Sf/Acb5jLJZI3Z8qsMoQHWldnQyoVUlij4y8e5srh28Iqul1HwK+elPsAYGNYKtYhovjvNxA==",
+ "dev": true
+ },
+ "bl": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+ "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "bluebird-lst": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz",
+ "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.5"
+ }
+ },
+ "bn.js": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz",
+ "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==",
+ "dev": true
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "@jest/transform": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz",
+ "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==",
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "pirates": "^4.0.1"
+ }
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
+ }
+ }
+ },
+ "bonjour": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz",
+ "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
+ "dev": true,
+ "requires": {
+ "array-flatten": "^2.1.0",
+ "deep-equal": "^1.0.1",
+ "dns-equal": "^1.0.0",
+ "dns-txt": "^2.0.2",
+ "multicast-dns": "^6.0.1",
+ "multicast-dns-service-types": "^1.1.0"
+ },
+ "dependencies": {
+ "array-flatten": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
+ "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
+ "dev": true
+ }
+ }
+ },
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+ "dev": true
+ },
+ "boolean": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.0.2.tgz",
+ "integrity": "sha512-RwywHlpCRc3/Wh81MiCKun4ydaIFyW5Ea6JbL6sRCVx5q5irDw7pMXBUFYF/jArQ6YrG36q0kpovc9P/Kd3I4g==",
+ "dev": true,
+ "optional": true
+ },
+ "boxen": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-4.2.0.tgz",
+ "integrity": "sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==",
+ "dev": true,
+ "requires": {
+ "ansi-align": "^3.0.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "cli-boxes": "^2.2.0",
+ "string-width": "^4.1.0",
+ "term-size": "^2.1.0",
+ "type-fest": "^0.8.1",
+ "widest-line": "^3.1.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
+ },
+ "browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==",
+ "dev": true
+ },
+ "browser-resolve": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz",
+ "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==",
+ "dev": true,
+ "requires": {
+ "resolve": "1.1.7"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "browserify-aes": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
+ "requires": {
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+ "dev": true,
+ "requires": {
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+ "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz",
+ "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^5.0.0",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz",
+ "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^5.1.1",
+ "browserify-rsa": "^4.0.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.5.3",
+ "inherits": "^2.0.4",
+ "parse-asn1": "^5.1.5",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
+ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
+ "dev": true,
+ "requires": {
+ "pako": "~1.0.5"
+ }
+ },
+ "browserslist": {
+ "version": "4.16.1",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.1.tgz",
+ "integrity": "sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001173",
+ "colorette": "^1.2.1",
+ "electron-to-chromium": "^1.3.634",
+ "escalade": "^3.1.1",
+ "node-releases": "^1.1.69"
+ }
+ },
+ "bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "requires": {
+ "fast-json-stable-stringify": "2.x"
+ }
+ },
+ "bs58": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+ "dev": true,
+ "requires": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "bs58check": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+ "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+ "dev": true,
+ "requires": {
+ "bs58": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "requires": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "buffer": {
+ "version": "4.9.2",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+ "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ },
+ "buffer-alloc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+ "dev": true,
+ "requires": {
+ "buffer-alloc-unsafe": "^1.1.0",
+ "buffer-fill": "^1.0.0"
+ }
+ },
+ "buffer-alloc-unsafe": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+ "dev": true
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "dev": true
+ },
+ "buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "buffer-indexof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
+ "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==",
+ "dev": true
+ },
+ "buffer-json": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz",
+ "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==",
+ "dev": true
+ },
+ "buffer-reverse": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz",
+ "integrity": "sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A=",
+ "dev": true
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+ "dev": true
+ },
+ "bufferutil": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-4.0.3.tgz",
+ "integrity": "sha512-yEYTwGndELGvfXsImMBLop58eaGW+YdONi1fNjTINSY98tmMmFijBG6WXgdkfuLNt4imzQNtIE+eBp1PVpMCSw==",
+ "dev": true,
+ "requires": {
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "builder-util": {
+ "version": "22.9.1",
+ "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-22.9.1.tgz",
+ "integrity": "sha512-5hN/XOaYu4ZQUS6F+5CXE6jTo+NAnVqAxDuKGSaHWb9bejfv/rluChTLoY3/nJh7RFjkoyVjvFJv7zQDB1QmHw==",
+ "dev": true,
+ "requires": {
+ "7zip-bin": "~5.0.3",
+ "@types/debug": "^4.1.5",
+ "@types/fs-extra": "^9.0.1",
+ "app-builder-bin": "3.5.10",
+ "bluebird-lst": "^1.0.9",
+ "builder-util-runtime": "8.7.2",
+ "chalk": "^4.1.0",
+ "debug": "^4.3.0",
+ "fs-extra": "^9.0.1",
+ "is-ci": "^2.0.0",
+ "js-yaml": "^3.14.0",
+ "source-map-support": "^0.5.19",
+ "stat-mode": "^1.0.0",
+ "temp-file": "^3.3.7"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "builder-util-runtime": {
+ "version": "8.7.2",
+ "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.7.2.tgz",
+ "integrity": "sha512-xBqv+8bg6cfnzAQK1k3OGpfaHg+QkPgIgpEkXNhouZ0WiUkyZCftuRc2LYzQrLucFywpa14Xbc6+hTbpq83yRA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "sax": "^1.2.4"
+ }
+ },
+ "builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true
+ },
+ "builtin-status-codes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
+ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=",
+ "dev": true
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
+ "dev": true
+ },
+ "cacache": {
+ "version": "12.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz",
+ "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.5",
+ "chownr": "^1.1.1",
+ "figgy-pudding": "^3.5.1",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.1.15",
+ "infer-owner": "^1.0.3",
+ "lru-cache": "^5.1.1",
+ "mississippi": "^3.0.0",
+ "mkdirp": "^0.5.1",
+ "move-concurrently": "^1.0.1",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^2.6.3",
+ "ssri": "^6.0.1",
+ "unique-filename": "^1.1.1",
+ "y18n": "^4.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "cache-loader": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz",
+ "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==",
+ "dev": true,
+ "requires": {
+ "buffer-json": "^2.0.0",
+ "find-cache-dir": "^3.0.0",
+ "loader-utils": "^1.2.3",
+ "mkdirp": "^0.5.1",
+ "neo-async": "^2.6.1",
+ "schema-utils": "^2.0.0"
+ }
+ },
+ "cacheable-lookup": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
+ "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
+ "dev": true
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+ "dev": true
+ }
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+ "dev": true
+ },
+ "caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+ "dev": true,
+ "requires": {
+ "callsites": "^2.0.0"
+ },
+ "dependencies": {
+ "callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+ "dev": true
+ }
+ }
+ },
+ "caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+ "dev": true,
+ "requires": {
+ "caller-callsite": "^2.0.0"
+ }
+ },
+ "callforth": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/callforth/-/callforth-0.3.1.tgz",
+ "integrity": "sha512-Q2zPfqnwoKsb1DTVCr4lmhe49wKNBsMmNlbudjleu3/co+Nw1pOqFHYJHrW3VZ253ou9AAr+xauQR0C55NPdzA=="
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camel-case": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
+ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
+ "dev": true,
+ "requires": {
+ "no-case": "^2.2.0",
+ "upper-case": "^1.1.1"
+ }
+ },
+ "camelcase": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
+ "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
+ "dev": true
+ },
+ "caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001177",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001177.tgz",
+ "integrity": "sha512-6Ld7t3ifCL02jTj3MxPMM5wAYjbo4h/TAQGFTgv1inihP1tWnWp8mxxT4ut4JBEHLbpFXEXJJQ119JCJTBkYDw==",
+ "dev": true
+ },
+ "canvas": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.6.1.tgz",
+ "integrity": "sha512-S98rKsPcuhfTcYbtF53UIJhcbgIAK533d1kJKMwsMwAIFgfd58MOyxRud3kktlzWiEkFliaJtvyZCBtud/XVEA==",
+ "dev": true,
+ "requires": {
+ "nan": "^2.14.0",
+ "node-pre-gyp": "^0.11.0",
+ "simple-get": "^3.0.3"
+ },
+ "dependencies": {
+ "node-pre-gyp": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
+ "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
+ "dev": true,
+ "requires": {
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.1",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.2.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4"
+ }
+ },
+ "nopt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
+ "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "capture-exit": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz",
+ "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==",
+ "dev": true,
+ "requires": {
+ "rsvp": "^4.8.4"
+ }
+ },
+ "case-sensitive-paths-webpack-plugin": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz",
+ "integrity": "sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ==",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "catbuffer-typescript": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/catbuffer-typescript/-/catbuffer-typescript-0.1.1.tgz",
+ "integrity": "sha512-r/z3UKG3YCCdsTEHRXGe3IQxA8OaBRBE31e9du2LOaLStGxYCmxUjfRtJ/DyKfgpS55fJPl3w/VFMnsfwIHmkA==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "check-types": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz",
+ "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.0.tgz",
+ "integrity": "sha512-JgQM9JS92ZbFR4P90EvmzNpSGhpPBGBSj10PILeDyYFwp4h2/D9OM03wsJ4zW1fEp4ka2DGrnUeD7FuvQ2aZ2Q==",
+ "dev": true,
+ "requires": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "fsevents": "~2.3.1",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.5.0"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "chownr": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
+ },
+ "chrome-trace-event": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz",
+ "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "chromium-pickle-js": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
+ "integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU=",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
+ "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
+ "dev": true
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "clean-css": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
+ "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
+ "dev": true,
+ "requires": {
+ "source-map": "~0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "cli-boxes": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz",
+ "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-highlight": {
+ "version": "2.1.10",
+ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.10.tgz",
+ "integrity": "sha512-CcPFD3JwdQ2oSzy+AMG6j3LRTkNjM82kzcSKzoVw6cLanDCJNlsLjeqVTOTfOfucnWv5F0rmBemVf1m9JiIasw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "highlight.js": "^10.0.0",
+ "mz": "^2.4.0",
+ "parse5": "^5.1.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.0",
+ "yargs": "^16.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "parse5": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
+ "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true
+ }
+ }
+ },
+ "cli-spinners": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.5.0.tgz",
+ "integrity": "sha512-PC+AmIuK04E6aeSs/pUccSujsTzBhu4HzC2dL+CfJB/Jcc2qTRbEwZQDfIUpt2Xl8BodYBEq8w4fc0kU2I9DjQ==",
+ "dev": true
+ },
+ "cli-truncate": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz",
+ "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
+ "requires": {
+ "slice-ansi": "^3.0.0",
+ "string-width": "^4.2.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "astral-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+ "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
+ },
+ "slice-ansi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz",
+ "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "astral-regex": "^2.0.0",
+ "is-fullwidth-code-point": "^3.0.0"
+ }
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ }
+ }
+ },
+ "cli-width": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
+ "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
+ "dev": true
+ },
+ "clipboardy": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz",
+ "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==",
+ "dev": true,
+ "requires": {
+ "arch": "^2.1.1",
+ "execa": "^1.0.0",
+ "is-wsl": "^2.1.1"
+ },
+ "dependencies": {
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ }
+ }
+ },
+ "cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+ "dev": true
+ },
+ "clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
+ "dev": true
+ },
+ "coa": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+ "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+ "dev": true,
+ "requires": {
+ "@types/q": "^1.5.1",
+ "chalk": "^2.4.1",
+ "q": "^1.1.2"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz",
+ "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.1",
+ "color-string": "^1.5.4"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
+ },
+ "color-string": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.4.tgz",
+ "integrity": "sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw==",
+ "dev": true,
+ "requires": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "colorette": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz",
+ "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "commander": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
+ "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "compare-version": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz",
+ "integrity": "sha1-AWLsLZNR9d3VmpICy6k1NmpyUIA=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
+ "dev": true
+ },
+ "compress-commons": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
+ "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
+ "dev": true,
+ "requires": {
+ "buffer-crc32": "^0.2.1",
+ "crc32-stream": "^2.0.0",
+ "normalize-path": "^2.0.0",
+ "readable-stream": "^2.0.0"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "compressible": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
+ "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==",
+ "dev": true,
+ "requires": {
+ "mime-db": ">= 1.43.0 < 2"
+ }
+ },
+ "compression": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
+ "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.5",
+ "bytes": "3.0.0",
+ "compressible": "~2.0.16",
+ "debug": "2.6.9",
+ "on-headers": "~1.0.2",
+ "safe-buffer": "5.1.2",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "bytes": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "condense-newlines": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
+ "integrity": "sha1-PemFVTE5R10yUCyDsC9gaE0kxV8=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-whitespace": "^0.3.0",
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "config-chain": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz",
+ "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "configstore": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
+ "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^5.2.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^3.0.0",
+ "unique-string": "^2.0.0",
+ "write-file-atomic": "^3.0.0",
+ "xdg-basedir": "^4.0.0"
+ },
+ "dependencies": {
+ "write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ }
+ }
+ },
+ "connect-history-api-fallback": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz",
+ "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==",
+ "dev": true
+ },
+ "console-browserify": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
+ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==",
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+ },
+ "consolidate": {
+ "version": "0.15.1",
+ "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz",
+ "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.1.1"
+ }
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=",
+ "dev": true
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "5.1.2"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
+ }
+ },
+ "content-type": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
+ }
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
+ "dev": true
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+ "dev": true
+ },
+ "copy-anything": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.1.tgz",
+ "integrity": "sha512-lA57e7viQHOdPQcrytv5jFeudZZOXuyk47lZym279FiDQ8jeZomXiGuVf6ffMKkJ+3TIai3J1J3yi6M+/4U35g==",
+ "dev": true,
+ "requires": {
+ "is-what": "^3.7.1"
+ }
+ },
+ "copy-concurrently": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
+ "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.1.1",
+ "fs-write-stream-atomic": "^1.0.8",
+ "iferr": "^0.1.5",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.4",
+ "run-queue": "^1.0.0"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "copy-webpack-plugin": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz",
+ "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==",
+ "dev": true,
+ "requires": {
+ "cacache": "^12.0.3",
+ "find-cache-dir": "^2.1.0",
+ "glob-parent": "^3.1.0",
+ "globby": "^7.1.1",
+ "is-glob": "^4.0.1",
+ "loader-utils": "^1.2.3",
+ "minimatch": "^3.0.4",
+ "normalize-path": "^3.0.0",
+ "p-limit": "^2.2.1",
+ "schema-utils": "^1.0.0",
+ "serialize-javascript": "^4.0.0",
+ "webpack-log": "^2.0.0"
+ },
+ "dependencies": {
+ "find-cache-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+ "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^2.0.0",
+ "pkg-dir": "^3.0.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "globby": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
+ "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=",
+ "dev": true,
+ "requires": {
+ "array-union": "^1.0.1",
+ "dir-glob": "^2.0.0",
+ "glob": "^7.1.2",
+ "ignore": "^3.3.5",
+ "pify": "^3.0.0",
+ "slash": "^1.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
+ "dev": true
+ }
+ }
+ },
+ "core-js": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz",
+ "integrity": "sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A=="
+ },
+ "core-js-compat": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.2.tgz",
+ "integrity": "sha512-LO8uL9lOIyRRrQmZxHZFl1RV+ZbcsAkFWTktn5SmH40WgLtSNYN4m4W2v9ONT147PxBY/XrRhrWq8TlvObyUjQ==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.16.0",
+ "semver": "7.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz",
+ "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==",
+ "dev": true
+ }
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cosmiconfig": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz",
+ "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.1.0",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.7.2"
+ }
+ },
+ "crc": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
+ "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.1.0"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ }
+ }
+ },
+ "crc32-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
+ "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
+ "dev": true,
+ "requires": {
+ "crc": "^3.4.4",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "create-ecdh": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz",
+ "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.5.3"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "requires": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "cross-env": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz",
+ "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.5"
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+ "dev": true,
+ "requires": {
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
+ }
+ },
+ "crypto-js": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.0.0.tgz",
+ "integrity": "sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg==",
+ "dev": true
+ },
+ "crypto-random-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
+ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
+ "dev": true
+ },
+ "css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
+ "urix": "^0.1.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-color-names": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+ "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+ "dev": true
+ },
+ "css-declaration-sorter": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
+ "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.1",
+ "timsort": "^0.3.0"
+ }
+ },
+ "css-loader": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz",
+ "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "cssesc": "^3.0.0",
+ "icss-utils": "^4.1.1",
+ "loader-utils": "^1.2.3",
+ "normalize-path": "^3.0.0",
+ "postcss": "^7.0.32",
+ "postcss-modules-extract-imports": "^2.0.0",
+ "postcss-modules-local-by-default": "^3.0.2",
+ "postcss-modules-scope": "^2.2.0",
+ "postcss-modules-values": "^3.0.0",
+ "postcss-value-parser": "^4.1.0",
+ "schema-utils": "^2.7.0",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "css-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
+ "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
+ "dev": true,
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^3.2.1",
+ "domutils": "^1.7.0",
+ "nth-check": "^1.0.2"
+ }
+ },
+ "css-select-base-adapter": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
+ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
+ "dev": true
+ },
+ "css-tree": {
+ "version": "1.0.0-alpha.37",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
+ "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==",
+ "dev": true,
+ "requires": {
+ "mdn-data": "2.0.4",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "css-what": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
+ "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==",
+ "dev": true
+ },
+ "cssesc": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
+ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
+ "dev": true
+ },
+ "cssnano": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
+ "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^5.0.0",
+ "cssnano-preset-default": "^4.0.7",
+ "is-resolvable": "^1.0.0",
+ "postcss": "^7.0.0"
+ },
+ "dependencies": {
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ }
+ },
+ "import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "cssnano-preset-default": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
+ "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+ "dev": true,
+ "requires": {
+ "css-declaration-sorter": "^4.0.1",
+ "cssnano-util-raw-cache": "^4.0.1",
+ "postcss": "^7.0.0",
+ "postcss-calc": "^7.0.1",
+ "postcss-colormin": "^4.0.3",
+ "postcss-convert-values": "^4.0.1",
+ "postcss-discard-comments": "^4.0.2",
+ "postcss-discard-duplicates": "^4.0.2",
+ "postcss-discard-empty": "^4.0.1",
+ "postcss-discard-overridden": "^4.0.1",
+ "postcss-merge-longhand": "^4.0.11",
+ "postcss-merge-rules": "^4.0.3",
+ "postcss-minify-font-values": "^4.0.2",
+ "postcss-minify-gradients": "^4.0.2",
+ "postcss-minify-params": "^4.0.2",
+ "postcss-minify-selectors": "^4.0.2",
+ "postcss-normalize-charset": "^4.0.1",
+ "postcss-normalize-display-values": "^4.0.2",
+ "postcss-normalize-positions": "^4.0.2",
+ "postcss-normalize-repeat-style": "^4.0.2",
+ "postcss-normalize-string": "^4.0.2",
+ "postcss-normalize-timing-functions": "^4.0.2",
+ "postcss-normalize-unicode": "^4.0.1",
+ "postcss-normalize-url": "^4.0.1",
+ "postcss-normalize-whitespace": "^4.0.2",
+ "postcss-ordered-values": "^4.1.2",
+ "postcss-reduce-initial": "^4.0.3",
+ "postcss-reduce-transforms": "^4.0.2",
+ "postcss-svgo": "^4.0.2",
+ "postcss-unique-selectors": "^4.0.1"
+ }
+ },
+ "cssnano-util-get-arguments": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
+ "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
+ "dev": true
+ },
+ "cssnano-util-get-match": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
+ "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
+ "dev": true
+ },
+ "cssnano-util-raw-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
+ "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "cssnano-util-same-parent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
+ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
+ "dev": true
+ },
+ "csso": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz",
+ "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==",
+ "dev": true,
+ "requires": {
+ "css-tree": "^1.1.2"
+ },
+ "dependencies": {
+ "css-tree": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz",
+ "integrity": "sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==",
+ "dev": true,
+ "requires": {
+ "mdn-data": "2.0.14",
+ "source-map": "^0.6.1"
+ }
+ },
+ "mdn-data": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz",
+ "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
+ "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
+ "dev": true,
+ "requires": {
+ "cssom": "0.3.x"
+ }
+ },
+ "cyclist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
+ "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=",
+ "dev": true
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "data-urls": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+ "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "whatwg-mimetype": "^2.2.0",
+ "whatwg-url": "^7.0.0"
+ },
+ "dependencies": {
+ "whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ }
+ }
+ },
+ "de-indent": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+ "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=",
+ "dev": true
+ },
+ "deasync": {
+ "version": "0.1.21",
+ "resolved": "https://registry.npmjs.org/deasync/-/deasync-0.1.21.tgz",
+ "integrity": "sha512-kUmM8Y+PZpMpQ+B4AuOW9k2Pfx/mSupJtxOsLzmnHY2WqZUYRFccFn2RhzPAqt3Xb+sorK/badW2D4zNzqZz5w==",
+ "dev": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "node-addon-api": "^1.7.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decamelize": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.0.tgz",
+ "integrity": "sha512-U75DcT5hrio3KNtvdULAWnLiAPbFUC4191ldxMmj4FA/mRuBnmDwU0boNfPyFRhnan+Jm+haLeSn3P0afcBn4w=="
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "deep-equal": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
+ "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
+ "dev": true,
+ "requires": {
+ "is-arguments": "^1.0.4",
+ "is-date-object": "^1.0.1",
+ "is-regex": "^1.0.4",
+ "object-is": "^1.0.1",
+ "object-keys": "^1.1.1",
+ "regexp.prototype.flags": "^1.2.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz",
+ "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA=="
+ },
+ "default-gateway": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-5.0.5.tgz",
+ "integrity": "sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==",
+ "dev": true,
+ "requires": {
+ "execa": "^3.3.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "execa": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
+ "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "p-finally": "^2.0.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "p-finally": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+ "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "defaults": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz",
+ "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
+ "dev": true,
+ "requires": {
+ "clone": "^1.0.2"
+ }
+ },
+ "defer-to-connect": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz",
+ "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==",
+ "dev": true
+ },
+ "define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "requires": {
+ "object-keys": "^1.0.12"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "del": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
+ "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "globby": "^6.1.0",
+ "is-path-cwd": "^2.0.0",
+ "is-path-in-cwd": "^2.0.0",
+ "p-map": "^2.0.0",
+ "pify": "^4.0.1",
+ "rimraf": "^2.6.3"
+ },
+ "dependencies": {
+ "globby": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
+ "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
+ "dev": true,
+ "requires": {
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "p-map": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
+ "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
+ },
+ "des.js": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+ "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+ "dev": true
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
+ },
+ "detect-newline": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+ "dev": true
+ },
+ "detect-node": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz",
+ "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==",
+ "dev": true
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz",
+ "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==",
+ "dev": true
+ },
+ "diffie-hellman": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "dijkstrajs": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.1.tgz",
+ "integrity": "sha1-082BIh4+pAdCz83lVtTpnpjdxxs=",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dev": true,
+ "requires": {
+ "path-type": "^3.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "dmg-builder": {
+ "version": "22.9.1",
+ "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-22.9.1.tgz",
+ "integrity": "sha512-jc+DAirqmQrNT6KbDHdfEp8D1kD0DBTnsLhwUR3MX+hMBun5bT134LQzpdK0GKvd22GqF8L1Cz/NOgaVjscAXQ==",
+ "dev": true,
+ "requires": {
+ "app-builder-lib": "22.9.1",
+ "builder-util": "22.9.1",
+ "fs-extra": "^9.0.1",
+ "iconv-lite": "^0.6.2",
+ "js-yaml": "^3.14.0",
+ "sanitize-filename": "^1.6.3"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+ "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
+ "dns-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz",
+ "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=",
+ "dev": true
+ },
+ "dns-packet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
+ "dev": true,
+ "requires": {
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "dns-txt": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz",
+ "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
+ "dev": true,
+ "requires": {
+ "buffer-indexof": "^1.0.0"
+ }
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dom-converter": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
+ "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==",
+ "dev": true,
+ "requires": {
+ "utila": "~0.4"
+ }
+ },
+ "dom-event-types": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dom-event-types/-/dom-event-types-1.0.0.tgz",
+ "integrity": "sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ==",
+ "dev": true
+ },
+ "dom-serializer": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
+ "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.1.0.tgz",
+ "integrity": "sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w==",
+ "dev": true
+ }
+ }
+ },
+ "domain-browser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
+ "dev": true
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domexception": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "requires": {
+ "is-obj": "^2.0.0"
+ }
+ },
+ "dotenv": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
+ "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
+ "dev": true
+ },
+ "dotenv-expand": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
+ "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==",
+ "dev": true
+ },
+ "duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "easy-stack": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
+ "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==",
+ "dev": true
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "editorconfig": {
+ "version": "0.15.3",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
+ "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.19.0",
+ "lru-cache": "^4.1.5",
+ "semver": "^5.6.0",
+ "sigmund": "^1.0.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ }
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
+ },
+ "ejs": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz",
+ "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==",
+ "dev": true
+ },
+ "electron": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-11.1.0.tgz",
+ "integrity": "sha512-RFAhR/852VMaRd9NSe7jprwSoG9dLc6u1GwnqRWg+/3cy/8Zrwt1Betw1lXiZH7hGuB9K2cqju83Xv5Pq5ZSGA==",
+ "dev": true,
+ "requires": {
+ "@electron/get": "^1.0.1",
+ "@types/node": "^12.0.12",
+ "extract-zip": "^1.0.3"
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "12.19.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.13.tgz",
+ "integrity": "sha512-qdixo2f0U7z6m0UJUugTJqVF94GNDkdgQhfBtMs8t5898JE7G/D2kJYw4rc1nzjIPLVAsDkY2MdABnLAP5lM1w==",
+ "dev": true
+ }
+ }
+ },
+ "electron-builder": {
+ "version": "22.9.1",
+ "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-22.9.1.tgz",
+ "integrity": "sha512-GXPt8l5Mxwm1QKYopUM6/Tdh9W3695G6Ax+IFyj5pQ51G4SD5L1uq4/RkPSsOgs3rP7jNSV6g6OfDzdtVufPdA==",
+ "dev": true,
+ "requires": {
+ "@types/yargs": "^15.0.5",
+ "app-builder-lib": "22.9.1",
+ "bluebird-lst": "^1.0.9",
+ "builder-util": "22.9.1",
+ "builder-util-runtime": "8.7.2",
+ "chalk": "^4.1.0",
+ "dmg-builder": "22.9.1",
+ "fs-extra": "^9.0.1",
+ "is-ci": "^2.0.0",
+ "lazy-val": "^1.0.4",
+ "read-config-file": "6.0.0",
+ "sanitize-filename": "^1.6.3",
+ "update-notifier": "^4.1.1",
+ "yargs": "^16.0.3"
+ },
+ "dependencies": {
+ "@types/yargs": {
+ "version": "15.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz",
+ "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
+ "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true
+ }
+ }
+ },
+ "electron-context-menu": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/electron-context-menu/-/electron-context-menu-2.4.0.tgz",
+ "integrity": "sha512-6HRAEeFoMoBZyQ69FBGNQIVVDRBw8nYmvMPaV+CfRDa/spreHsjMD+XesJ/2/lMSAAMDTCgFCC24167Uer2cZw==",
+ "requires": {
+ "cli-truncate": "^2.0.0",
+ "electron-dl": "^3.0.0",
+ "electron-is-dev": "^1.0.1"
+ }
+ },
+ "electron-dl": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/electron-dl/-/electron-dl-3.0.2.tgz",
+ "integrity": "sha512-pRgE9Jbhoo5z6Vk3qi+vIrfpMDlCp2oB1UeR96SMnsfz073jj0AZGQwp69EdIcEvlUlwBSGyJK8Jt6OB6JLn+g==",
+ "requires": {
+ "ext-name": "^5.0.0",
+ "pupa": "^2.0.1",
+ "unused-filename": "^2.1.0"
+ }
+ },
+ "electron-is-accelerator": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz",
+ "integrity": "sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns="
+ },
+ "electron-is-dev": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz",
+ "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw=="
+ },
+ "electron-localshortcut": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz",
+ "integrity": "sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==",
+ "requires": {
+ "debug": "^4.0.1",
+ "electron-is-accelerator": "^0.1.0",
+ "keyboardevent-from-electron-accelerator": "^2.0.0",
+ "keyboardevents-areequal": "^0.2.1"
+ }
+ },
+ "electron-notarize": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz",
+ "integrity": "sha512-dsib1IAquMn0onCrNMJ6gtEIZn/azG8hZMCYOuZIMVMUeRMgBYHK1s5TK9P8xAcrAjh/2aN5WYHzgVSWX314og==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "fs-extra": "^9.0.1"
+ }
+ },
+ "electron-osx-sign": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz",
+ "integrity": "sha512-icoRLHzFz/qxzDh/N4Pi2z4yVHurlsCAYQvsCSG7fCedJ4UJXBS6PoQyGH71IfcqKupcKeK7HX/NkyfG+v6vlQ==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.0",
+ "compare-version": "^0.1.2",
+ "debug": "^2.6.8",
+ "isbinaryfile": "^3.0.2",
+ "minimist": "^1.2.0",
+ "plist": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "isbinaryfile": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.3.tgz",
+ "integrity": "sha512-8cJBL5tTd2OS0dM4jz07wQd5g0dCCqIhUxPIGtZfa5L6hWlvV5MHTITy/DBAsF+Oe2LS1X3krBUhNwaGUWpWxw==",
+ "dev": true,
+ "requires": {
+ "buffer-alloc": "^1.2.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "electron-packager": {
+ "version": "15.2.0",
+ "resolved": "https://registry.npmjs.org/electron-packager/-/electron-packager-15.2.0.tgz",
+ "integrity": "sha512-BaklTBRQy1JTijR3hi8XxHf/uo76rHbDCNM/eQHSblzE9C0NoNfOe86nPxB7y1u2jwlqoEJ4zFiHpTFioKGGRA==",
+ "dev": true,
+ "requires": {
+ "@electron/get": "^1.6.0",
+ "asar": "^3.0.0",
+ "debug": "^4.0.1",
+ "electron-notarize": "^1.0.0",
+ "electron-osx-sign": "^0.5.0",
+ "extract-zip": "^2.0.0",
+ "filenamify": "^4.1.0",
+ "fs-extra": "^9.0.0",
+ "galactus": "^0.2.1",
+ "get-package-info": "^1.0.0",
+ "junk": "^3.1.0",
+ "parse-author": "^2.0.0",
+ "plist": "^3.0.0",
+ "rcedit": "^2.0.0",
+ "resolve": "^1.1.6",
+ "semver": "^7.1.3",
+ "yargs-parser": "^20.0.0"
+ },
+ "dependencies": {
+ "extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "dev": true,
+ "requires": {
+ "@types/yauzl": "^2.9.1",
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true
+ }
+ }
+ },
+ "electron-publish": {
+ "version": "22.9.1",
+ "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz",
+ "integrity": "sha512-ducLjRJLEeU87FaTCWaUyDjCoLXHkawkltP2zqS/n2PyGke54ZIql0tBuUheht4EpR8AhFbVJ11spSn1gy8r6w==",
+ "dev": true,
+ "requires": {
+ "@types/fs-extra": "^9.0.1",
+ "bluebird-lst": "^1.0.9",
+ "builder-util": "22.9.1",
+ "builder-util-runtime": "8.7.2",
+ "chalk": "^4.1.0",
+ "fs-extra": "^9.0.1",
+ "lazy-val": "^1.0.4",
+ "mime": "^2.4.6"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "electron-rebuild": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/electron-rebuild/-/electron-rebuild-2.3.4.tgz",
+ "integrity": "sha512-EHr1bkqXTN/jQJuh2/IunF9QGa9yOgpE9KdQ9A7VHshd7ycWvoXjWzaXaimfa1nu1l7vKqLLu7N2COe3Jn9NuA==",
+ "dev": true,
+ "requires": {
+ "@malept/cross-spawn-promise": "^1.1.0",
+ "colors": "^1.3.3",
+ "debug": "^4.1.1",
+ "detect-libc": "^1.0.3",
+ "fs-extra": "^9.0.1",
+ "got": "^11.7.0",
+ "lzma-native": "^6.0.1",
+ "node-abi": "^2.19.2",
+ "node-gyp": "^7.1.0",
+ "ora": "^5.1.0",
+ "tar": "^6.0.5",
+ "yargs": "^16.0.0"
+ },
+ "dependencies": {
+ "@sindresorhus/is": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.0.tgz",
+ "integrity": "sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ==",
+ "dev": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.5.tgz",
+ "integrity": "sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==",
+ "dev": true,
+ "requires": {
+ "defer-to-connect": "^2.0.0"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "bl": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
+ "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "cacheable-request": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.1.tgz",
+ "integrity": "sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^4.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^2.0.0"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "decompress-response": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
+ "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^3.1.0"
+ }
+ },
+ "defer-to-connect": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.0.tgz",
+ "integrity": "sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "got": {
+ "version": "11.8.1",
+ "resolved": "https://registry.npmjs.org/got/-/got-11.8.1.tgz",
+ "integrity": "sha512-9aYdZL+6nHmvJwHALLwKSUZ0hMwGaJGYv3hoPLPgnT8BoBXm1SjnZeky+91tfwJaDzun2s4RsBRy48IEYv2q2Q==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^4.0.0",
+ "@szmarczak/http-timer": "^4.0.5",
+ "@types/cacheable-request": "^6.0.1",
+ "@types/responselike": "^1.0.0",
+ "cacheable-lookup": "^5.0.3",
+ "cacheable-request": "^7.0.1",
+ "decompress-response": "^6.0.0",
+ "http2-wrapper": "^1.0.0-beta.5.2",
+ "lowercase-keys": "^2.0.0",
+ "p-cancelable": "^2.0.0",
+ "responselike": "^2.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true
+ },
+ "keyv": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz",
+ "integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "log-symbols": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
+ "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
+ "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
+ "dev": true
+ },
+ "minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz",
+ "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==",
+ "dev": true
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "ora": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz",
+ "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==",
+ "dev": true,
+ "requires": {
+ "bl": "^4.0.3",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-spinners": "^2.5.0",
+ "is-interactive": "^1.0.0",
+ "log-symbols": "^4.0.0",
+ "strip-ansi": "^6.0.0",
+ "wcwidth": "^1.0.1"
+ }
+ },
+ "p-cancelable": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.0.0.tgz",
+ "integrity": "sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "responselike": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
+ "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^2.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "tar": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
+ "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz",
+ "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+ "dev": true
+ }
+ }
+ },
+ "electron-to-chromium": {
+ "version": "1.3.637",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.637.tgz",
+ "integrity": "sha512-924WXYMYquYybc+7pNApGlhY2RWg3MY3he4BrZ5BUmM2n1MGBsrS+PZxrlo6UAsWuNl4NE66fqFdwsWkBUGgkA==",
+ "dev": true
+ },
+ "electron-updater": {
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.3.5.tgz",
+ "integrity": "sha512-5jjN7ebvfj1cLI0VZMdCnJk6aC4bP+dy7ryBf21vArR0JzpRVk0OZHA2QBD+H5rm6ZSeDYHOY6+8PrMEqJ4wlQ==",
+ "dev": true,
+ "requires": {
+ "@types/semver": "^7.3.1",
+ "builder-util-runtime": "8.7.2",
+ "fs-extra": "^9.0.1",
+ "js-yaml": "^3.14.0",
+ "lazy-val": "^1.0.4",
+ "lodash.isequal": "^4.5.0",
+ "semver": "^7.3.2"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "element-resize-detector": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/element-resize-detector/-/element-resize-detector-1.2.1.tgz",
+ "integrity": "sha512-BdFsPepnQr9fznNPF9nF4vQ457U/ZJXQDSNF1zBe7yaga8v9AdZf3/NElYxFdUh7SitSGt040QygiTo6dtatIw==",
+ "requires": {
+ "batch-processor": "1.0.0"
+ }
+ },
+ "elliptic": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz",
+ "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
+ "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
+ },
+ "encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "^0.6.2"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz",
+ "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enhanced-resolve": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz",
+ "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "memory-fs": "^0.5.0",
+ "tapable": "^1.0.0"
+ },
+ "dependencies": {
+ "memory-fs": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
+ "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==",
+ "dev": true,
+ "requires": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ }
+ }
+ }
+ },
+ "entities": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
+ "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
+ },
+ "env-paths": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.0.tgz",
+ "integrity": "sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA==",
+ "dev": true
+ },
+ "errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "dev": true,
+ "requires": {
+ "prr": "~1.0.1"
+ }
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "error-stack-parser": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz",
+ "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==",
+ "dev": true,
+ "requires": {
+ "stackframe": "^1.1.1"
+ }
+ },
+ "es-abstract": {
+ "version": "1.18.0-next.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz",
+ "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-negative-zero": "^2.0.0",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true,
+ "optional": true
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-goat": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz",
+ "integrity": "sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q=="
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+ },
+ "escodegen": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
+ "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
+ "dev": true,
+ "requires": {
+ "esprima": "^4.0.1",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "eslint": {
+ "version": "6.8.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
+ "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.10.0",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^5.0.0",
+ "eslint-utils": "^1.4.3",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.2",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob-parent": "^5.0.0",
+ "globals": "^12.1.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^7.0.0",
+ "is-glob": "^4.0.0",
+ "js-yaml": "^3.13.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.14",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.3",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^6.1.2",
+ "strip-ansi": "^5.2.0",
+ "strip-json-comments": "^3.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0",
+ "v8-compile-cache": "^2.0.3"
+ },
+ "dependencies": {
+ "eslint-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
+ "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "globals": {
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
+ "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.8.1"
+ }
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-config-prettier": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz",
+ "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^6.0.0"
+ }
+ },
+ "eslint-plugin-prettier": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.1.tgz",
+ "integrity": "sha512-Rq3jkcFY8RYeQLgk2cCwuc0P7SEFwDravPhsJZOQ5N4YI4DSg50NyqJ/9gdZHzQlHf8MvafSesbNJCcP/FF6pQ==",
+ "dev": true,
+ "requires": {
+ "prettier-linter-helpers": "^1.0.0"
+ }
+ },
+ "eslint-plugin-vue": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.2.tgz",
+ "integrity": "sha512-Nhc+oVAHm0uz/PkJAWscwIT4ijTrK5fqNqz9QB1D35SbbuMG1uB6Yr5AJpvPSWg+WOw7nYNswerYh0kOk64gqQ==",
+ "dev": true,
+ "requires": {
+ "natural-compare": "^1.4.0",
+ "semver": "^5.6.0",
+ "vue-eslint-parser": "^7.0.0"
+ }
+ },
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
+ "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0"
+ }
+ },
+ "eslint-visitor-keys": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
+ "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
+ "dev": true
+ },
+ "espree": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
+ "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-jsx": "^5.2.0",
+ "eslint-visitor-keys": "^1.1.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ }
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
+ "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.1.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^5.2.0"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
+ "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
+ "dev": true
+ }
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "dev": true
+ },
+ "event-pubsub": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
+ "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==",
+ "dev": true
+ },
+ "eventemitter3": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
+ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
+ "dev": true
+ },
+ "events": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
+ "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg=="
+ },
+ "eventsource": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
+ "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
+ "dev": true,
+ "requires": {
+ "original": "^1.0.0"
+ }
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "dev": true,
+ "requires": {
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "exec-sh": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
+ "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
+ "dev": true
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "expand-template": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
+ "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
+ },
+ "expect": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz",
+ "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "ansi-styles": "^3.2.0",
+ "jest-get-type": "^24.9.0",
+ "jest-matcher-utils": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-regex-util": "^24.9.0"
+ }
+ },
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ }
+ }
+ },
+ "ext-list": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
+ "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
+ "requires": {
+ "mime-db": "^1.28.0"
+ }
+ },
+ "ext-name": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
+ "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
+ "requires": {
+ "ext-list": "^2.0.0",
+ "sort-keys-length": "^1.0.0"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "external-editor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
+ "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "20.2.4",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+ "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA=="
+ }
+ }
+ },
+ "extract-from-css": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/extract-from-css/-/extract-from-css-0.4.4.tgz",
+ "integrity": "sha1-HqffLnx8brmSL6COitrqSG9vj5I=",
+ "dev": true,
+ "requires": {
+ "css": "^2.1.0"
+ }
+ },
+ "extract-zip": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
+ "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.6.2",
+ "debug": "^2.6.9",
+ "mkdirp": "^0.5.4",
+ "yauzl": "^2.10.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "dev": true,
+ "requires": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ }
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "faye-websocket": {
+ "version": "0.11.3",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
+ "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
+ "dev": true,
+ "requires": {
+ "websocket-driver": ">=0.5.1"
+ }
+ },
+ "fb-watchman": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz",
+ "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==",
+ "dev": true,
+ "requires": {
+ "bser": "2.1.1"
+ }
+ },
+ "fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
+ "dev": true,
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "figgy-pudding": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
+ "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
+ "dev": true
+ },
+ "figures": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
+ "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "file-loader": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz",
+ "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.2.3",
+ "schema-utils": "^2.5.0"
+ }
+ },
+ "file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
+ },
+ "file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
+ },
+ "filelist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.1.tgz",
+ "integrity": "sha512-8zSK6Nu0DQIC08mUC46sWGXi+q3GGpKydAG36k+JDba6VRpkevvOWUW5a/PhShij4+vHT9M+ghgG7eM+a9JDUQ==",
+ "dev": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "filename-reserved-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+ "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=",
+ "dev": true
+ },
+ "filenamify": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.2.0.tgz",
+ "integrity": "sha512-pkgE+4p7N1n7QieOopmn3TqJaefjdWXwEkj2XLZJLKfOgcQKkn11ahvGNgTD8mLggexLiDFQxeTs14xVU22XPA==",
+ "dev": true,
+ "requires": {
+ "filename-reserved-regex": "^2.0.0",
+ "strip-outer": "^1.0.1",
+ "trim-repeated": "^1.0.0"
+ }
+ },
+ "filesize": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz",
+ "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "find-babel-config": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
+ "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
+ "dev": true,
+ "requires": {
+ "json5": "^0.5.1",
+ "path-exists": "^3.0.0"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
+ }
+ },
+ "find-cache-dir": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+ "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "flatted": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
+ "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+ "dev": true
+ },
+ "flora-colossus": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-1.0.1.tgz",
+ "integrity": "sha512-d+9na7t9FyH8gBJoNDSi28mE4NgQVGGvxQ4aHtFRetjyh5SXjuus+V5EZaxFmFdXVemSOrx0lsgEl/ZMjnOWJA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "fs-extra": "^7.0.0"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ }
+ }
+ },
+ "flush-promises": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flush-promises/-/flush-promises-1.0.2.tgz",
+ "integrity": "sha512-G0sYfLQERwKz4+4iOZYQEZVpOt9zQrlItIxQAAYAWpfby3gbHrx0osCHz5RLl/XoXevXk0xoN4hDFky/VV9TrA==",
+ "dev": true
+ },
+ "flush-write-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.3.6"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz",
+ "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg=="
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "fork-ts-checker-webpack-plugin": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz",
+ "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.22.0",
+ "chalk": "^2.4.1",
+ "chokidar": "^3.3.0",
+ "micromatch": "^3.1.10",
+ "minimatch": "^3.0.4",
+ "semver": "^5.6.0",
+ "tapable": "^1.0.0",
+ "worker-rpc": "^0.1.0"
+ }
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "dev": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
+ "from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
+ "fs-extra": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
+ "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^1.0.0"
+ }
+ },
+ "fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "fs-monkey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz",
+ "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==",
+ "dev": true,
+ "optional": true
+ },
+ "fs-write-stream-atomic": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "iferr": "^0.1.5",
+ "imurmurhash": "^0.1.4",
+ "readable-stream": "1 || 2"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz",
+ "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "futoin-hkdf": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/futoin-hkdf/-/futoin-hkdf-1.3.3.tgz",
+ "integrity": "sha512-oR75fYk3B3X9/B02Y6vusrBKucrpC6VjxhRL+C6B7FwUpuSRHbhBNG3AZbcE/xPyJmEQWsyqUFp3VeNNbA3S7A==",
+ "dev": true
+ },
+ "galactus": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/galactus/-/galactus-0.2.1.tgz",
+ "integrity": "sha1-y+0tIKQMH1Z5o1kI4rlBVzPnjbk=",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0",
+ "flora-colossus": "^1.0.0",
+ "fs-extra": "^4.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "fs-extra": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ }
+ }
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz",
+ "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "get-package-info": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz",
+ "integrity": "sha1-ZDJ5ZWPigRPNlHTbvQAFKYWkmZw=",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.1.1",
+ "debug": "^2.2.0",
+ "lodash.get": "^4.0.0",
+ "read-pkg-up": "^2.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+ "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.0.0"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+ "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
+ }
+ }
+ }
+ },
+ "get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "github-from-package": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
+ "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4="
+ },
+ "glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
+ "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "glob-to-regexp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+ "dev": true
+ },
+ "global-agent": {
+ "version": "2.1.12",
+ "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-2.1.12.tgz",
+ "integrity": "sha512-caAljRMS/qcDo69X9BfkgrihGUgGx44Fb4QQToNQjsiWh+YlQ66uqYVAdA8Olqit+5Ng0nkz09je3ZzANMZcjg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "boolean": "^3.0.1",
+ "core-js": "^3.6.5",
+ "es6-error": "^4.1.1",
+ "matcher": "^3.0.0",
+ "roarr": "^2.15.3",
+ "semver": "^7.3.2",
+ "serialize-error": "^7.0.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "global-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
+ "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==",
+ "dev": true,
+ "requires": {
+ "ini": "1.3.7"
+ },
+ "dependencies": {
+ "ini": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
+ "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==",
+ "dev": true
+ }
+ }
+ },
+ "global-tunnel-ng": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz",
+ "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "encodeurl": "^1.0.2",
+ "lodash": "^4.17.10",
+ "npm-conf": "^1.1.3",
+ "tunnel": "^0.0.6"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+ },
+ "globalthis": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.1.tgz",
+ "integrity": "sha512-mJPRTc/P39NH/iNG4mXa9aIhNymaQikTrnspeCa2ZuJ+mH2QN/rXwtX3XwKrHqWgUQFbNZKtHM105aHzJalElw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "define-properties": "^1.1.3"
+ }
+ },
+ "globby": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+ "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^1.0.2",
+ "dir-glob": "^2.2.2",
+ "fast-glob": "^2.2.6",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.3",
+ "pify": "^4.0.1",
+ "slash": "^2.0.0"
+ }
+ },
+ "google-fonts-webpack-plugin": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/google-fonts-webpack-plugin/-/google-fonts-webpack-plugin-0.4.4.tgz",
+ "integrity": "sha512-+e2D9/DVBG9EDydRovzoqMZ658SsTBGbC0c65GyZqkwNvdj8vRSYQKXqbz7/yt7QaXsCPT1MpH45r3ivWOitcw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.4",
+ "node-fetch": "^1.6.3",
+ "webpack-sources": "^0.2.0",
+ "yauzl": "^2.8.0"
+ },
+ "dependencies": {
+ "source-list-map": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz",
+ "integrity": "sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=",
+ "dev": true
+ },
+ "webpack-sources": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz",
+ "integrity": "sha1-F8Yr+vE8cH+dAsR54Nzd6DgGl/s=",
+ "dev": true,
+ "requires": {
+ "source-list-map": "^1.1.1",
+ "source-map": "~0.5.3"
+ }
+ }
+ }
+ },
+ "got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw=="
+ },
+ "growly": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
+ "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
+ "dev": true
+ },
+ "gsap": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/gsap/-/gsap-2.1.3.tgz",
+ "integrity": "sha512-8RFASCqi2FOCBuv7X4o7M6bLdy+1hbR0azg+MG7zz+EVsI+OmJblYsTk0GEepQd2Jg/ItMPiVTibF7r3EVxjZQ=="
+ },
+ "gzip-size": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
+ "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==",
+ "dev": true,
+ "requires": {
+ "duplexer": "^0.1.1",
+ "pify": "^4.0.1"
+ }
+ },
+ "handle-thing": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
+ "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
+ "dev": true
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "requires": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "harmony-reflect": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.1.tgz",
+ "integrity": "sha512-WJTeyp0JzGtHcuMsi7rw2VwtkvLa+JyfEKJCFyfcS0+CDkjQ5lHPu7zEhFZP+PDSRrEgXa5Ah0l1MbgbE41XjA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg=="
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "has-yarn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+ "dev": true
+ },
+ "hash-base": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+ "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.6.0",
+ "safe-buffer": "^5.2.0"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "hash-sum": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
+ "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
+ "dev": true
+ },
+ "hash.js": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+ "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.1"
+ }
+ },
+ "he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true
+ },
+ "hex-color-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
+ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
+ "dev": true
+ },
+ "highlight.js": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.5.0.tgz",
+ "integrity": "sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw==",
+ "dev": true
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
+ "requires": {
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
+ }
+ },
+ "hoopy": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz",
+ "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.8.8",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
+ "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
+ "dev": true
+ },
+ "hpack.js": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
+ "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
+ }
+ },
+ "hsl-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
+ "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
+ "dev": true
+ },
+ "hsla-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
+ "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
+ "dev": true
+ },
+ "html-comment-regex": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
+ "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
+ "dev": true
+ },
+ "html-encoding-sniffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+ "dev": true,
+ "requires": {
+ "whatwg-encoding": "^1.0.1"
+ }
+ },
+ "html-entities": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz",
+ "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==",
+ "dev": true
+ },
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "html-minifier": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz",
+ "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==",
+ "dev": true,
+ "requires": {
+ "camel-case": "3.0.x",
+ "clean-css": "4.2.x",
+ "commander": "2.17.x",
+ "he": "1.2.x",
+ "param-case": "2.1.x",
+ "relateurl": "0.2.x",
+ "uglify-js": "3.4.x"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.17.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
+ "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==",
+ "dev": true
+ }
+ }
+ },
+ "html-tags": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz",
+ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==",
+ "dev": true
+ },
+ "html-webpack-plugin": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz",
+ "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=",
+ "dev": true,
+ "requires": {
+ "html-minifier": "^3.2.3",
+ "loader-utils": "^0.2.16",
+ "lodash": "^4.17.3",
+ "pretty-error": "^2.0.2",
+ "tapable": "^1.0.0",
+ "toposort": "^1.0.0",
+ "util.promisify": "1.0.0"
+ },
+ "dependencies": {
+ "big.js": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
+ "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=",
+ "dev": true
+ },
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "0.2.17",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
+ "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
+ "dev": true,
+ "requires": {
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.0",
+ "object-assign": "^4.0.1"
+ }
+ },
+ "util.promisify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+ "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "object.getownpropertydescriptors": "^2.0.3"
+ }
+ }
+ }
+ },
+ "htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ },
+ "dependencies": {
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "http-cache-semantics": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
+ "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
+ "dev": true
+ },
+ "http-deceiver": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz",
+ "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=",
+ "dev": true
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ }
+ }
+ },
+ "http-parser-js": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz",
+ "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==",
+ "dev": true
+ },
+ "http-proxy": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
+ "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
+ "dev": true,
+ "requires": {
+ "eventemitter3": "^4.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "http-proxy-middleware": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz",
+ "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==",
+ "dev": true,
+ "requires": {
+ "http-proxy": "^1.17.0",
+ "is-glob": "^4.0.0",
+ "lodash": "^4.17.11",
+ "micromatch": "^3.1.10"
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "http2-wrapper": {
+ "version": "1.0.0-beta.5.2",
+ "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.0-beta.5.2.tgz",
+ "integrity": "sha512-xYz9goEyBnC8XwXDTuC/MZ6t+MrKVQZOk4s7+PaDkwIsQd8IwqvM+0M6bA/2lvG8GHXcPdf+MejTUeO2LCPCeQ==",
+ "dev": true,
+ "requires": {
+ "quick-lru": "^5.1.1",
+ "resolve-alpn": "^1.0.0"
+ }
+ },
+ "https-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz",
+ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
+ "dev": true
+ },
+ "human-signals": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
+ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "icss-utils": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz",
+ "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14"
+ }
+ },
+ "identity-obj-proxy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz",
+ "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=",
+ "dev": true,
+ "requires": {
+ "harmony-reflect": "^1.4.6"
+ }
+ },
+ "ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
+ },
+ "iferr": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz",
+ "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
+ "dev": true
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "ignore-walk": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz",
+ "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
+ "dev": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "image-size": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+ "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+ "dev": true,
+ "optional": true
+ },
+ "import-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+ "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+ "dev": true,
+ "requires": {
+ "import-from": "^2.1.0"
+ }
+ },
+ "import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "import-from": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+ "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": true
+ },
+ "import-local": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz",
+ "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^3.0.0",
+ "resolve-cwd": "^2.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ }
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "infer-owner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "inquirer": {
+ "version": "7.3.3",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
+ "integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.1.0",
+ "cli-cursor": "^3.1.0",
+ "cli-width": "^3.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^3.0.0",
+ "lodash": "^4.17.19",
+ "mute-stream": "0.0.8",
+ "run-async": "^2.4.0",
+ "rxjs": "^6.6.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
+ "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "cli-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
+ "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^3.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "emojis-list": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
+ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k="
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "dev": true,
+ "requires": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
+ "internal-ip": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz",
+ "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==",
+ "dev": true,
+ "requires": {
+ "default-gateway": "^4.2.0",
+ "ipaddr.js": "^1.9.0"
+ },
+ "dependencies": {
+ "default-gateway": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
+ "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0",
+ "ip-regex": "^2.1.0"
+ }
+ }
+ }
+ },
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=",
+ "dev": true
+ },
+ "ip-regex": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
+ "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=",
+ "dev": true
+ },
+ "ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "dev": true
+ },
+ "is-absolute-url": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+ "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-arguments": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz",
+ "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^2.0.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz",
+ "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
+ "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^1.5.0"
+ }
+ },
+ "is-color-stop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
+ "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
+ "dev": true,
+ "requires": {
+ "css-color-names": "^0.0.4",
+ "hex-color-regex": "^1.1.0",
+ "hsl-regex": "^1.0.0",
+ "hsla-regex": "^1.0.0",
+ "rgb-regex": "^1.0.1",
+ "rgba-regex": "^1.0.0"
+ }
+ },
+ "is-core-module": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
+ "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+ "dev": true
+ },
+ "is-docker": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz",
+ "integrity": "sha512-ZOoqiXfEwtGknTiuDEy8pN2CfE3TxMHprvNer1mXiqwkOT77Rw3YVrUQ52EqAOU3QAWDQ+bQdx7HJzrv7LS2Hw==",
+ "dev": true
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-installed-globally": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.3.2.tgz",
+ "integrity": "sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==",
+ "dev": true,
+ "requires": {
+ "global-dirs": "^2.0.1",
+ "is-path-inside": "^3.0.1"
+ },
+ "dependencies": {
+ "is-path-inside": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
+ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
+ "dev": true
+ }
+ }
+ },
+ "is-interactive": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
+ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
+ "dev": true
+ },
+ "is-negative-zero": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz",
+ "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==",
+ "dev": true
+ },
+ "is-npm": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-4.0.0.tgz",
+ "integrity": "sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true
+ },
+ "is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true
+ },
+ "is-path-in-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
+ "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
+ "dev": true,
+ "requires": {
+ "is-path-inside": "^2.1.0"
+ }
+ },
+ "is-path-inside": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
+ "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "^1.0.2"
+ }
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz",
+ "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-svg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
+ "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
+ "dev": true,
+ "requires": {
+ "html-comment-regex": "^1.1.0"
+ }
+ },
+ "is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "dev": true,
+ "requires": {
+ "has-symbols": "^1.0.1"
+ }
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "is-what": {
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.12.0.tgz",
+ "integrity": "sha512-2ilQz5/f/o9V7WRWJQmpFYNmQFZ9iM+OXRonZKcYgTkCzjb949Vi4h282PD1UfmgHk666rcWonbRJ++KI41VGw==",
+ "dev": true
+ },
+ "is-whitespace": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
+ "integrity": "sha1-Fjnssb4DauxppUy7QBz77XEUq38=",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "is-yarn-global": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isbinaryfile": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.6.tgz",
+ "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "istanbul-lib-coverage": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz",
+ "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz",
+ "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==",
+ "dev": true,
+ "requires": {
+ "@babel/generator": "^7.4.0",
+ "@babel/parser": "^7.4.3",
+ "@babel/template": "^7.4.0",
+ "@babel/traverse": "^7.4.3",
+ "@babel/types": "^7.4.0",
+ "istanbul-lib-coverage": "^2.0.5",
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz",
+ "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz",
+ "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^2.0.5",
+ "make-dir": "^2.1.0",
+ "rimraf": "^2.6.3",
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "istanbul-reports": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz",
+ "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0"
+ }
+ },
+ "jake": {
+ "version": "10.8.2",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.2.tgz",
+ "integrity": "sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==",
+ "dev": true,
+ "requires": {
+ "async": "0.9.x",
+ "chalk": "^2.4.2",
+ "filelist": "^1.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "async": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
+ "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=",
+ "dev": true
+ }
+ }
+ },
+ "javascript-stringify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz",
+ "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==",
+ "dev": true
+ },
+ "jest": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-25.5.4.tgz",
+ "integrity": "sha512-hHFJROBTqZahnO+X+PMtT6G2/ztqAZJveGqz//FnWWHurizkD05PQGzRZOhF3XP6z7SJmL+5tCfW8qV06JypwQ==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^25.5.4",
+ "import-local": "^3.0.2",
+ "jest-cli": "^25.5.4"
+ },
+ "dependencies": {
+ "@jest/console": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz",
+ "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "jest-message-util": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "slash": "^3.0.0"
+ }
+ },
+ "@jest/core": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz",
+ "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^25.5.0",
+ "@jest/reporters": "^25.5.1",
+ "@jest/test-result": "^25.5.0",
+ "@jest/transform": "^25.5.1",
+ "@jest/types": "^25.5.0",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^3.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-changed-files": "^25.5.0",
+ "jest-config": "^25.5.4",
+ "jest-haste-map": "^25.5.1",
+ "jest-message-util": "^25.5.0",
+ "jest-regex-util": "^25.2.6",
+ "jest-resolve": "^25.5.1",
+ "jest-resolve-dependencies": "^25.5.4",
+ "jest-runner": "^25.5.4",
+ "jest-runtime": "^25.5.4",
+ "jest-snapshot": "^25.5.1",
+ "jest-util": "^25.5.0",
+ "jest-validate": "^25.5.0",
+ "jest-watcher": "^25.5.0",
+ "micromatch": "^4.0.2",
+ "p-each-series": "^2.1.0",
+ "realpath-native": "^2.0.0",
+ "rimraf": "^3.0.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "@jest/environment": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz",
+ "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "jest-mock": "^25.5.0"
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz",
+ "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-mock": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "lolex": "^5.0.0"
+ }
+ },
+ "@jest/reporters": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz",
+ "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==",
+ "dev": true,
+ "requires": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^25.5.0",
+ "@jest/test-result": "^25.5.0",
+ "@jest/transform": "^25.5.1",
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.2",
+ "graceful-fs": "^4.2.4",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^4.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.0.2",
+ "jest-haste-map": "^25.5.1",
+ "jest-resolve": "^25.5.1",
+ "jest-util": "^25.5.0",
+ "jest-worker": "^25.5.0",
+ "node-notifier": "^6.0.0",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.0",
+ "string-length": "^3.1.0",
+ "terminal-link": "^2.0.0",
+ "v8-to-istanbul": "^4.1.3"
+ }
+ },
+ "@jest/source-map": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz",
+ "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "source-map": "^0.6.0"
+ }
+ },
+ "@jest/test-result": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz",
+ "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ }
+ },
+ "@jest/test-sequencer": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz",
+ "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^25.5.0",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^25.5.1",
+ "jest-runner": "^25.5.4",
+ "jest-runtime": "^25.5.4"
+ }
+ },
+ "@jest/transform": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz",
+ "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/types": "^25.5.0",
+ "babel-plugin-istanbul": "^6.0.0",
+ "chalk": "^3.0.0",
+ "convert-source-map": "^1.4.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-haste-map": "^25.5.1",
+ "jest-regex-util": "^25.2.6",
+ "jest-util": "^25.5.0",
+ "micromatch": "^4.0.2",
+ "pirates": "^4.0.1",
+ "realpath-native": "^2.0.0",
+ "slash": "^3.0.0",
+ "source-map": "^0.6.1",
+ "write-file-atomic": "^3.0.0"
+ }
+ },
+ "@jest/types": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz",
+ "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^1.1.1",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^3.0.0"
+ }
+ },
+ "@types/yargs": {
+ "version": "15.0.12",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.12.tgz",
+ "integrity": "sha512-f+fD/fQAo3BCbCDlrUpznF1A5Zp9rB0noS5vnoormHSIPFKL0Z2DcUJ3Gxp5ytH4uLRNxy7AwYUC9exZzqGMAw==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz",
+ "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^4.0.0",
+ "test-exclude": "^6.0.0"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "cssom": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+ "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "requires": {
+ "cssom": "~0.3.6"
+ },
+ "dependencies": {
+ "cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ }
+ }
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz",
+ "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "execa": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz",
+ "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.0",
+ "get-stream": "^5.0.0",
+ "human-signals": "^1.1.1",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.0",
+ "onetime": "^5.1.0",
+ "p-finally": "^2.0.0",
+ "signal-exit": "^3.0.2",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "expect": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz",
+ "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "ansi-styles": "^4.0.0",
+ "jest-get-type": "^25.2.6",
+ "jest-matcher-utils": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-regex-util": "^25.2.6"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "get-stream": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
+ "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "import-local": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz",
+ "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "istanbul-lib-coverage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+ "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.7.5",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.0.0",
+ "semver": "^6.3.0"
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+ "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+ "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
+ "jest-changed-files": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz",
+ "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "execa": "^3.2.0",
+ "throat": "^5.0.0"
+ }
+ },
+ "jest-cli": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz",
+ "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^25.5.4",
+ "@jest/test-result": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "import-local": "^3.0.2",
+ "is-ci": "^2.0.0",
+ "jest-config": "^25.5.4",
+ "jest-util": "^25.5.0",
+ "jest-validate": "^25.5.0",
+ "prompts": "^2.0.1",
+ "realpath-native": "^2.0.0",
+ "yargs": "^15.3.1"
+ }
+ },
+ "jest-config": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz",
+ "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/test-sequencer": "^25.5.4",
+ "@jest/types": "^25.5.0",
+ "babel-jest": "^25.5.1",
+ "chalk": "^3.0.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.1",
+ "graceful-fs": "^4.2.4",
+ "jest-environment-jsdom": "^25.5.0",
+ "jest-environment-node": "^25.5.0",
+ "jest-get-type": "^25.2.6",
+ "jest-jasmine2": "^25.5.4",
+ "jest-regex-util": "^25.2.6",
+ "jest-resolve": "^25.5.1",
+ "jest-util": "^25.5.0",
+ "jest-validate": "^25.5.0",
+ "micromatch": "^4.0.2",
+ "pretty-format": "^25.5.0",
+ "realpath-native": "^2.0.0"
+ }
+ },
+ "jest-diff": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz",
+ "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==",
+ "dev": true,
+ "requires": {
+ "chalk": "^3.0.0",
+ "diff-sequences": "^25.2.6",
+ "jest-get-type": "^25.2.6",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-docblock": {
+ "version": "25.3.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz",
+ "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^3.0.0"
+ }
+ },
+ "jest-each": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz",
+ "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "jest-get-type": "^25.2.6",
+ "jest-util": "^25.5.0",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-environment-jsdom": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz",
+ "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^25.5.0",
+ "@jest/fake-timers": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "jest-mock": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "jsdom": "^15.2.1"
+ }
+ },
+ "jest-environment-node": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz",
+ "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^25.5.0",
+ "@jest/fake-timers": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "jest-mock": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "semver": "^6.3.0"
+ }
+ },
+ "jest-get-type": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz",
+ "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz",
+ "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "@types/graceful-fs": "^4.1.2",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^2.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-serializer": "^25.5.0",
+ "jest-util": "^25.5.0",
+ "jest-worker": "^25.5.0",
+ "micromatch": "^4.0.2",
+ "sane": "^4.0.3",
+ "walker": "^1.0.7",
+ "which": "^2.0.2"
+ }
+ },
+ "jest-jasmine2": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz",
+ "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==",
+ "dev": true,
+ "requires": {
+ "@babel/traverse": "^7.1.0",
+ "@jest/environment": "^25.5.0",
+ "@jest/source-map": "^25.5.0",
+ "@jest/test-result": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "co": "^4.6.0",
+ "expect": "^25.5.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^25.5.0",
+ "jest-matcher-utils": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-runtime": "^25.5.4",
+ "jest-snapshot": "^25.5.1",
+ "jest-util": "^25.5.0",
+ "pretty-format": "^25.5.0",
+ "throat": "^5.0.0"
+ }
+ },
+ "jest-leak-detector": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz",
+ "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^25.2.6",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz",
+ "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^3.0.0",
+ "jest-diff": "^25.5.0",
+ "jest-get-type": "^25.2.6",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-message-util": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz",
+ "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@jest/types": "^25.5.0",
+ "@types/stack-utils": "^1.0.1",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "micromatch": "^4.0.2",
+ "slash": "^3.0.0",
+ "stack-utils": "^1.0.1"
+ }
+ },
+ "jest-mock": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz",
+ "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0"
+ }
+ },
+ "jest-regex-util": {
+ "version": "25.2.6",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz",
+ "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz",
+ "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "browser-resolve": "^1.11.3",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "jest-pnp-resolver": "^1.2.1",
+ "read-pkg-up": "^7.0.1",
+ "realpath-native": "^2.0.0",
+ "resolve": "^1.17.0",
+ "slash": "^3.0.0"
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz",
+ "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "jest-regex-util": "^25.2.6",
+ "jest-snapshot": "^25.5.1"
+ }
+ },
+ "jest-runner": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz",
+ "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^25.5.0",
+ "@jest/environment": "^25.5.0",
+ "@jest/test-result": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.4",
+ "jest-config": "^25.5.4",
+ "jest-docblock": "^25.3.0",
+ "jest-haste-map": "^25.5.1",
+ "jest-jasmine2": "^25.5.4",
+ "jest-leak-detector": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-resolve": "^25.5.1",
+ "jest-runtime": "^25.5.4",
+ "jest-util": "^25.5.0",
+ "jest-worker": "^25.5.0",
+ "source-map-support": "^0.5.6",
+ "throat": "^5.0.0"
+ }
+ },
+ "jest-runtime": {
+ "version": "25.5.4",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz",
+ "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^25.5.0",
+ "@jest/environment": "^25.5.0",
+ "@jest/globals": "^25.5.2",
+ "@jest/source-map": "^25.5.0",
+ "@jest/test-result": "^25.5.0",
+ "@jest/transform": "^25.5.1",
+ "@jest/types": "^25.5.0",
+ "@types/yargs": "^15.0.0",
+ "chalk": "^3.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.4",
+ "jest-config": "^25.5.4",
+ "jest-haste-map": "^25.5.1",
+ "jest-message-util": "^25.5.0",
+ "jest-mock": "^25.5.0",
+ "jest-regex-util": "^25.2.6",
+ "jest-resolve": "^25.5.1",
+ "jest-snapshot": "^25.5.1",
+ "jest-util": "^25.5.0",
+ "jest-validate": "^25.5.0",
+ "realpath-native": "^2.0.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0",
+ "yargs": "^15.3.1"
+ }
+ },
+ "jest-serializer": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz",
+ "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.4"
+ }
+ },
+ "jest-snapshot": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz",
+ "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0",
+ "@jest/types": "^25.5.0",
+ "@types/prettier": "^1.19.0",
+ "chalk": "^3.0.0",
+ "expect": "^25.5.0",
+ "graceful-fs": "^4.2.4",
+ "jest-diff": "^25.5.0",
+ "jest-get-type": "^25.2.6",
+ "jest-matcher-utils": "^25.5.0",
+ "jest-message-util": "^25.5.0",
+ "jest-resolve": "^25.5.1",
+ "make-dir": "^3.0.0",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^25.5.0",
+ "semver": "^6.3.0"
+ }
+ },
+ "jest-util": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz",
+ "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "chalk": "^3.0.0",
+ "graceful-fs": "^4.2.4",
+ "is-ci": "^2.0.0",
+ "make-dir": "^3.0.0"
+ }
+ },
+ "jest-validate": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz",
+ "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^3.0.0",
+ "jest-get-type": "^25.2.6",
+ "leven": "^3.1.0",
+ "pretty-format": "^25.5.0"
+ }
+ },
+ "jest-watcher": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz",
+ "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^25.5.0",
+ "@jest/types": "^25.5.0",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^3.0.0",
+ "jest-util": "^25.5.0",
+ "string-length": "^3.1.0"
+ }
+ },
+ "jest-worker": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
+ "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^7.0.0"
+ }
+ },
+ "jsdom": {
+ "version": "15.2.1",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
+ "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "acorn": "^7.1.0",
+ "acorn-globals": "^4.3.2",
+ "array-equal": "^1.0.0",
+ "cssom": "^0.4.1",
+ "cssstyle": "^2.0.0",
+ "data-urls": "^1.1.0",
+ "domexception": "^1.0.1",
+ "escodegen": "^1.11.1",
+ "html-encoding-sniffer": "^1.0.2",
+ "nwsapi": "^2.2.0",
+ "parse5": "5.1.0",
+ "pn": "^1.1.0",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.7",
+ "saxes": "^3.1.9",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^3.0.1",
+ "w3c-hr-time": "^1.0.1",
+ "w3c-xmlserializer": "^1.1.2",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^7.0.0",
+ "ws": "^7.0.0",
+ "xml-name-validator": "^3.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "node-notifier": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz",
+ "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "growly": "^1.3.0",
+ "is-wsl": "^2.1.1",
+ "semver": "^6.3.0",
+ "shellwords": "^0.1.1",
+ "which": "^1.3.1"
+ },
+ "dependencies": {
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "p-each-series": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz",
+ "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz",
+ "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==",
+ "dev": true
+ },
+ "parse5": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "25.5.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz",
+ "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^25.5.0",
+ "ansi-regex": "^5.0.0",
+ "ansi-styles": "^4.0.0",
+ "react-is": "^16.12.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true
+ }
+ }
+ },
+ "read-pkg-up": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
+ "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.1.0",
+ "read-pkg": "^5.2.0",
+ "type-fest": "^0.8.1"
+ }
+ },
+ "realpath-native": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz",
+ "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==",
+ "dev": true
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "string-length": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz",
+ "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==",
+ "dev": true,
+ "requires": {
+ "astral-regex": "^1.0.0",
+ "strip-ansi": "^5.2.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "throat": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
+ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "tough-cookie": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+ "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+ "dev": true,
+ "requires": {
+ "ip-regex": "^2.1.0",
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "ws": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
+ "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dev": true,
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ },
+ "dependencies": {
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "dependencies": {
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "jest-changed-files": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz",
+ "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "execa": "^1.0.0",
+ "throat": "^4.0.0"
+ }
+ },
+ "jest-config": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz",
+ "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.1.0",
+ "@jest/test-sequencer": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "babel-jest": "^24.9.0",
+ "chalk": "^2.0.1",
+ "glob": "^7.1.1",
+ "jest-environment-jsdom": "^24.9.0",
+ "jest-environment-node": "^24.9.0",
+ "jest-get-type": "^24.9.0",
+ "jest-jasmine2": "^24.9.0",
+ "jest-regex-util": "^24.3.0",
+ "jest-resolve": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-validate": "^24.9.0",
+ "micromatch": "^3.1.10",
+ "pretty-format": "^24.9.0",
+ "realpath-native": "^1.1.0"
+ },
+ "dependencies": {
+ "babel-jest": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz",
+ "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/babel__core": "^7.1.0",
+ "babel-plugin-istanbul": "^5.1.0",
+ "babel-preset-jest": "^24.9.0",
+ "chalk": "^2.4.2",
+ "slash": "^2.0.0"
+ }
+ }
+ }
+ },
+ "jest-diff": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz",
+ "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1",
+ "diff-sequences": "^24.9.0",
+ "jest-get-type": "^24.9.0",
+ "pretty-format": "^24.9.0"
+ }
+ },
+ "jest-docblock": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz",
+ "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^2.1.0"
+ }
+ },
+ "jest-each": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz",
+ "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "chalk": "^2.0.1",
+ "jest-get-type": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "pretty-format": "^24.9.0"
+ }
+ },
+ "jest-environment-jsdom": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz",
+ "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^24.9.0",
+ "@jest/fake-timers": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "jest-mock": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jsdom": "^11.5.1"
+ }
+ },
+ "jest-environment-jsdom-fifteen": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom-fifteen/-/jest-environment-jsdom-fifteen-1.0.2.tgz",
+ "integrity": "sha512-nfrnAfwklE1872LIB31HcjM65cWTh1wzvMSp10IYtPJjLDUbTTvDpajZgIxUnhRmzGvogdHDayCIlerLK0OBBg==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^24.3.0",
+ "@jest/fake-timers": "^24.3.0",
+ "@jest/types": "^24.3.0",
+ "jest-mock": "^24.0.0",
+ "jest-util": "^24.0.0",
+ "jsdom": "^15.2.1"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "cssom": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
+ "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "requires": {
+ "cssom": "~0.3.6"
+ },
+ "dependencies": {
+ "cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true
+ }
+ }
+ },
+ "jsdom": {
+ "version": "15.2.1",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz",
+ "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "acorn": "^7.1.0",
+ "acorn-globals": "^4.3.2",
+ "array-equal": "^1.0.0",
+ "cssom": "^0.4.1",
+ "cssstyle": "^2.0.0",
+ "data-urls": "^1.1.0",
+ "domexception": "^1.0.1",
+ "escodegen": "^1.11.1",
+ "html-encoding-sniffer": "^1.0.2",
+ "nwsapi": "^2.2.0",
+ "parse5": "5.1.0",
+ "pn": "^1.1.0",
+ "request": "^2.88.0",
+ "request-promise-native": "^1.0.7",
+ "saxes": "^3.1.9",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^3.0.1",
+ "w3c-hr-time": "^1.0.1",
+ "w3c-xmlserializer": "^1.1.2",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.5",
+ "whatwg-mimetype": "^2.3.0",
+ "whatwg-url": "^7.0.0",
+ "ws": "^7.0.0",
+ "xml-name-validator": "^3.0.0"
+ }
+ },
+ "parse5": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
+ "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
+ "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
+ "dev": true,
+ "requires": {
+ "ip-regex": "^2.1.0",
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "whatwg-url": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
+ "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "ws": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz",
+ "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==",
+ "dev": true
+ }
+ }
+ },
+ "jest-environment-node": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz",
+ "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^24.9.0",
+ "@jest/fake-timers": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "jest-mock": "^24.9.0",
+ "jest-util": "^24.9.0"
+ }
+ },
+ "jest-get-type": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz",
+ "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz",
+ "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "anymatch": "^2.0.0",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^1.2.7",
+ "graceful-fs": "^4.1.15",
+ "invariant": "^2.2.4",
+ "jest-serializer": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-worker": "^24.9.0",
+ "micromatch": "^3.1.10",
+ "sane": "^4.0.3",
+ "walker": "^1.0.7"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "jest-jasmine2": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz",
+ "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==",
+ "dev": true,
+ "requires": {
+ "@babel/traverse": "^7.1.0",
+ "@jest/environment": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "chalk": "^2.0.1",
+ "co": "^4.6.0",
+ "expect": "^24.9.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^24.9.0",
+ "jest-matcher-utils": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-runtime": "^24.9.0",
+ "jest-snapshot": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "pretty-format": "^24.9.0",
+ "throat": "^4.0.0"
+ }
+ },
+ "jest-leak-detector": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz",
+ "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^24.9.0",
+ "pretty-format": "^24.9.0"
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz",
+ "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1",
+ "jest-diff": "^24.9.0",
+ "jest-get-type": "^24.9.0",
+ "pretty-format": "^24.9.0"
+ }
+ },
+ "jest-message-util": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz",
+ "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/stack-utils": "^1.0.1",
+ "chalk": "^2.0.1",
+ "micromatch": "^3.1.10",
+ "slash": "^2.0.0",
+ "stack-utils": "^1.0.1"
+ }
+ },
+ "jest-mock": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz",
+ "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0"
+ }
+ },
+ "jest-pnp-resolver": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz",
+ "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==",
+ "dev": true
+ },
+ "jest-regex-util": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz",
+ "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
+ "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "browser-resolve": "^1.11.3",
+ "chalk": "^2.0.1",
+ "jest-pnp-resolver": "^1.2.1",
+ "realpath-native": "^1.1.0"
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz",
+ "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "jest-regex-util": "^24.3.0",
+ "jest-snapshot": "^24.9.0"
+ }
+ },
+ "jest-runner": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz",
+ "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.7.1",
+ "@jest/environment": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "chalk": "^2.4.2",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.1.15",
+ "jest-config": "^24.9.0",
+ "jest-docblock": "^24.3.0",
+ "jest-haste-map": "^24.9.0",
+ "jest-jasmine2": "^24.9.0",
+ "jest-leak-detector": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-resolve": "^24.9.0",
+ "jest-runtime": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-worker": "^24.6.0",
+ "source-map-support": "^0.5.6",
+ "throat": "^4.0.0"
+ }
+ },
+ "jest-runtime": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz",
+ "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.7.1",
+ "@jest/environment": "^24.9.0",
+ "@jest/source-map": "^24.3.0",
+ "@jest/transform": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/yargs": "^13.0.0",
+ "chalk": "^2.0.1",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.1.15",
+ "jest-config": "^24.9.0",
+ "jest-haste-map": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-mock": "^24.9.0",
+ "jest-regex-util": "^24.3.0",
+ "jest-resolve": "^24.9.0",
+ "jest-snapshot": "^24.9.0",
+ "jest-util": "^24.9.0",
+ "jest-validate": "^24.9.0",
+ "realpath-native": "^1.1.0",
+ "slash": "^2.0.0",
+ "strip-bom": "^3.0.0",
+ "yargs": "^13.3.0"
+ }
+ },
+ "jest-serializer": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz",
+ "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==",
+ "dev": true
+ },
+ "jest-serializer-vue": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/jest-serializer-vue/-/jest-serializer-vue-2.0.2.tgz",
+ "integrity": "sha1-sjjvKGNX7GtIBCG9RxRQUJh9WbM=",
+ "dev": true,
+ "requires": {
+ "pretty": "2.0.0"
+ }
+ },
+ "jest-snapshot": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz",
+ "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0",
+ "@jest/types": "^24.9.0",
+ "chalk": "^2.0.1",
+ "expect": "^24.9.0",
+ "jest-diff": "^24.9.0",
+ "jest-get-type": "^24.9.0",
+ "jest-matcher-utils": "^24.9.0",
+ "jest-message-util": "^24.9.0",
+ "jest-resolve": "^24.9.0",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^24.9.0",
+ "semver": "^6.2.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "jest-transform-stub": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/jest-transform-stub/-/jest-transform-stub-2.0.0.tgz",
+ "integrity": "sha512-lspHaCRx/mBbnm3h4uMMS3R5aZzMwyNpNIJLXj4cEsV0mIUtS4IjYJLSoyjRCtnxb6RIGJ4NL2quZzfIeNhbkg==",
+ "dev": true
+ },
+ "jest-util": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz",
+ "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^24.9.0",
+ "@jest/fake-timers": "^24.9.0",
+ "@jest/source-map": "^24.9.0",
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "callsites": "^3.0.0",
+ "chalk": "^2.0.1",
+ "graceful-fs": "^4.1.15",
+ "is-ci": "^2.0.0",
+ "mkdirp": "^0.5.1",
+ "slash": "^2.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "jest-validate": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz",
+ "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^2.0.1",
+ "jest-get-type": "^24.9.0",
+ "leven": "^3.1.0",
+ "pretty-format": "^24.9.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ }
+ }
+ },
+ "jest-watch-typeahead": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.2.tgz",
+ "integrity": "sha512-f7VpLebTdaXs81rg/oj4Vg/ObZy2QtGzAmGLNsqUS5G5KtSN68tFcIsbvNODfNyQxU78g7D8x77o3bgfBTR+2Q==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^2.4.1",
+ "jest-regex-util": "^24.9.0",
+ "jest-watcher": "^24.3.0",
+ "slash": "^3.0.0",
+ "string-length": "^3.1.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ }
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "string-length": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz",
+ "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==",
+ "dev": true,
+ "requires": {
+ "astral-regex": "^1.0.0",
+ "strip-ansi": "^5.2.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
+ "jest-watcher": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz",
+ "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^24.9.0",
+ "@jest/types": "^24.9.0",
+ "@types/yargs": "^13.0.0",
+ "ansi-escapes": "^3.0.0",
+ "chalk": "^2.0.1",
+ "jest-util": "^24.9.0",
+ "string-length": "^2.0.0"
+ }
+ },
+ "jest-worker": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz",
+ "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==",
+ "dev": true,
+ "requires": {
+ "merge-stream": "^2.0.0",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "js-base64": {
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
+ "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==",
+ "dev": true
+ },
+ "js-beautify": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.13.4.tgz",
+ "integrity": "sha512-M5yEWwonlEO3kPcCZ3K3KBSpFRZAEO3FAWC6wtbIGeyg7dusStxvF0WG+HRLBoMZqREXSRSxkkqClDE865x1sg==",
+ "dev": true,
+ "requires": {
+ "config-chain": "^1.1.12",
+ "editorconfig": "^0.15.3",
+ "glob": "^7.1.3",
+ "mkdirp": "^1.0.4",
+ "nopt": "^5.0.0"
+ },
+ "dependencies": {
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ }
+ }
+ },
+ "js-calendar": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/js-calendar/-/js-calendar-1.2.3.tgz",
+ "integrity": "sha512-dAA1/Zbp4+c5E+ARCVTIuKepXsNLzSYfzvOimiYD4S5eeP9QuplSHLcdhfqFSwyM1o1u6ku6RRRCyaZ0YAjiBw=="
+ },
+ "js-message": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
+ "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==",
+ "dev": true
+ },
+ "js-queue": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz",
+ "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==",
+ "dev": true,
+ "requires": {
+ "easy-stack": "^1.0.1"
+ }
+ },
+ "js-sha256": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz",
+ "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==",
+ "dev": true
+ },
+ "js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==",
+ "dev": true
+ },
+ "js-sha512": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz",
+ "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==",
+ "dev": true
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "jsdom": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
+ "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "acorn": "^5.5.3",
+ "acorn-globals": "^4.1.0",
+ "array-equal": "^1.0.0",
+ "cssom": ">= 0.3.2 < 0.4.0",
+ "cssstyle": "^1.0.0",
+ "data-urls": "^1.0.0",
+ "domexception": "^1.0.1",
+ "escodegen": "^1.9.1",
+ "html-encoding-sniffer": "^1.0.2",
+ "left-pad": "^1.3.0",
+ "nwsapi": "^2.0.7",
+ "parse5": "4.0.0",
+ "pn": "^1.1.0",
+ "request": "^2.87.0",
+ "request-promise-native": "^1.0.5",
+ "sax": "^1.2.4",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^2.3.4",
+ "w3c-hr-time": "^1.0.1",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.3",
+ "whatwg-mimetype": "^2.1.0",
+ "whatwg-url": "^6.4.1",
+ "ws": "^5.2.0",
+ "xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.7.4",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
+ "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
+ "dev": true
+ }
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "dev": true
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "json2csv": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-5.0.5.tgz",
+ "integrity": "sha512-/UyvnfuUghRM+C/AiQ02X0LS+/AKfugcwaWo/gAz1pi203v29sUMrMSNEC088i+h0EG39eSsmeL9Z0iK+9MM0A==",
+ "requires": {
+ "commander": "^6.1.0",
+ "jsonparse": "^1.3.1",
+ "lodash.get": "^4.4.2"
+ }
+ },
+ "json3": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz",
+ "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz",
+ "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==",
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ },
+ "dependencies": {
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
+ "dev": true
+ }
+ }
+ },
+ "jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA="
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "jsqr": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.3.1.tgz",
+ "integrity": "sha512-zCTP6Qd/WwjrpuHFkJuXc5opRdKprUr7eI7+JCCtcetThJt45qptu82MWQ+eET+FtDrMo7+BYjo3iD0XIq1L9Q=="
+ },
+ "junk": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz",
+ "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
+ "dev": true
+ },
+ "keyboardevent-from-electron-accelerator": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz",
+ "integrity": "sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA=="
+ },
+ "keyboardevents-areequal": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz",
+ "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw=="
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "killable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
+ "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true
+ },
+ "kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true
+ },
+ "latest-version": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+ "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+ "dev": true,
+ "requires": {
+ "package-json": "^6.3.0"
+ }
+ },
+ "launch-editor": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz",
+ "integrity": "sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "shell-quote": "^1.6.1"
+ }
+ },
+ "launch-editor-middleware": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz",
+ "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==",
+ "dev": true,
+ "requires": {
+ "launch-editor": "^2.2.1"
+ }
+ },
+ "lazy-val": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.4.tgz",
+ "integrity": "sha512-u93kb2fPbIrfzBuLjZE+w+fJbUUMhNDXxNmMfaqNgpfQf1CO5ZSe2LfsnBqVAk7i/2NF48OSoRj+Xe2VT+lE8Q==",
+ "dev": true
+ },
+ "lazystream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.5"
+ }
+ },
+ "left-pad": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
+ "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
+ "dev": true
+ },
+ "less": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz",
+ "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==",
+ "dev": true,
+ "requires": {
+ "copy-anything": "^2.0.1",
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "make-dir": "^2.1.0",
+ "mime": "^1.4.1",
+ "native-request": "^1.0.5",
+ "source-map": "~0.6.0",
+ "tslib": "^1.10.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true,
+ "optional": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "less-loader": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz",
+ "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "loader-utils": "^1.1.0",
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "lines-and-columns": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
+ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "loader-runner": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz",
+ "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==",
+ "dev": true
+ },
+ "loader-utils": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
+ "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^1.0.1"
+ },
+ "dependencies": {
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ }
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.20",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
+ "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
+ },
+ "lodash.defaultsdeep": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+ "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+ "dev": true
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+ "dev": true
+ },
+ "lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+ "dev": true
+ },
+ "lodash.mapvalues": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
+ "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+ "dev": true
+ },
+ "lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ="
+ },
+ "lodash.transform": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz",
+ "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=",
+ "dev": true
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ }
+ },
+ "loglevel": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz",
+ "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==",
+ "dev": true
+ },
+ "lolex": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz",
+ "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "long": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
+ "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
+ "dev": true
+ },
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
+ "lower-case": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
+ "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=",
+ "dev": true
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "lzma-native": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-6.0.1.tgz",
+ "integrity": "sha512-O6oWF0xe1AFvOCjU8uOZBZ/lhjaMNwHfVNaqVMqmoQXlRwBcFWpCAToiZOdXcKVMdo/5s/D0a2QgA5laMErxHQ==",
+ "dev": true,
+ "requires": {
+ "node-addon-api": "^1.6.0",
+ "node-pre-gyp": "^0.11.0",
+ "readable-stream": "^2.3.5",
+ "rimraf": "^2.7.1"
+ },
+ "dependencies": {
+ "node-pre-gyp": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz",
+ "integrity": "sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q==",
+ "dev": true,
+ "requires": {
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.1",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.2.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4"
+ }
+ },
+ "nopt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
+ "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "makeerror": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz",
+ "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=",
+ "dev": true,
+ "requires": {
+ "tmpl": "1.0.x"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "matcher": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
+ "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "escape-string-regexp": "^4.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "mdn-data": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
+ "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
+ "dev": true
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "dev": true
+ },
+ "memfs": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.2.tgz",
+ "integrity": "sha512-RE0CwmIM3CEvpcdK3rZ19BC4E6hv9kADkMN5rPduRak58cNArWLi/9jFLsa4rhsjfVxMP3v0jO7FHXq7SvFY5Q==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "fs-monkey": "1.0.3"
+ }
+ },
+ "memory-fs": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
+ "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
+ "dev": true,
+ "requires": {
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+ "dev": true
+ },
+ "merge-source-map": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
+ "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true
+ },
+ "merkletreejs": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.2.13.tgz",
+ "integrity": "sha512-hnM1XX0C+3yfAytRiX7FKC+bYg+GC83aQq7EytAp6nbcUBRdXU6/AVkmNdsAaJJ9IaKZt0w76r0QeWY/Fq+uFw==",
+ "dev": true,
+ "requires": {
+ "buffer-reverse": "^1.0.1",
+ "crypto-js": "^3.1.9-1",
+ "treeify": "^1.1.0"
+ },
+ "dependencies": {
+ "crypto-js": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
+ "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==",
+ "dev": true
+ }
+ }
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
+ "dev": true
+ },
+ "microevent.ts": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz",
+ "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "mime": {
+ "version": "2.4.7",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.7.tgz",
+ "integrity": "sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA==",
+ "dev": true
+ },
+ "mime-db": {
+ "version": "1.45.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
+ "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w=="
+ },
+ "mime-types": {
+ "version": "2.1.28",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
+ "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
+ "requires": {
+ "mime-db": "1.45.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true
+ },
+ "mini-css-extract-plugin": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
+ "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.1.0",
+ "normalize-url": "1.9.1",
+ "schema-utils": "^1.0.0",
+ "webpack-sources": "^1.1.0"
+ },
+ "dependencies": {
+ "normalize-url": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
+ "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.0.1",
+ "prepend-http": "^1.0.0",
+ "query-string": "^4.1.0",
+ "sort-keys": "^1.0.0"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ }
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
+ },
+ "minipass": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz",
+ "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz",
+ "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+ "dev": true,
+ "requires": {
+ "minipass": "^2.9.0"
+ },
+ "dependencies": {
+ "minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "mississippi": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
+ "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.5.0",
+ "duplexify": "^3.4.2",
+ "end-of-stream": "^1.1.0",
+ "flush-write-stream": "^1.0.0",
+ "from2": "^2.1.0",
+ "parallel-transform": "^1.1.0",
+ "pump": "^3.0.0",
+ "pumpify": "^1.3.3",
+ "stream-each": "^1.1.0",
+ "through2": "^2.0.0"
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
+ "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+ },
+ "modify-filename": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/modify-filename/-/modify-filename-1.1.0.tgz",
+ "integrity": "sha1-mi3sg4Bvuy2XXyK+7IWcoms5OqE="
+ },
+ "moment": {
+ "version": "2.29.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
+ },
+ "moment-timezone": {
+ "version": "0.5.32",
+ "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz",
+ "integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==",
+ "dev": true,
+ "requires": {
+ "moment": ">= 2.9.0"
+ }
+ },
+ "move-concurrently": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
+ "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.1.1",
+ "copy-concurrently": "^1.0.0",
+ "fs-write-stream-atomic": "^1.0.8",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.4",
+ "run-queue": "^1.0.3"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "multicast-dns": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
+ "dev": true,
+ "requires": {
+ "dns-packet": "^1.3.1",
+ "thunky": "^1.0.2"
+ }
+ },
+ "multicast-dns-service-types": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
+ "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
+ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
+ "dev": true
+ },
+ "mz": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "requires": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "nan": {
+ "version": "2.14.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
+ "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "napi-build-utils": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
+ "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
+ },
+ "native-request": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.0.8.tgz",
+ "integrity": "sha512-vU2JojJVelUGp6jRcLwToPoWGxSx23z/0iX+I77J3Ht17rf2INGjrhOoQnjVo60nQd8wVsgzKkPfRXBiVdD2ag==",
+ "dev": true,
+ "optional": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "needle": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz",
+ "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.6",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "no-case": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
+ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
+ "dev": true,
+ "requires": {
+ "lower-case": "^1.1.1"
+ }
+ },
+ "node-abi": {
+ "version": "2.19.3",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.19.3.tgz",
+ "integrity": "sha512-9xZrlyfvKhWme2EXFKQhZRp1yNWT/uI1luYPr3sFl+H4keYY4xR+1jO7mvTTijIsHf1M+QDe9uWuKeEpLInIlg==",
+ "requires": {
+ "semver": "^5.4.1"
+ }
+ },
+ "node-addon-api": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
+ "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
+ "dev": true
+ },
+ "node-cache": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.2.1.tgz",
+ "integrity": "sha512-BOb67bWg2dTyax5kdef5WfU3X8xu4wPg+zHzkvls0Q/QpYycIFRLEEIdAx9Wma43DxG6Qzn4illdZoYseKWa4A==",
+ "dev": true,
+ "requires": {
+ "clone": "2.x",
+ "lodash": "^4.17.15"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ }
+ }
+ },
+ "node-fetch": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+ "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+ "dev": true,
+ "requires": {
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
+ }
+ },
+ "node-forge": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+ "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
+ "dev": true
+ },
+ "node-gyp": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz",
+ "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==",
+ "dev": true,
+ "requires": {
+ "env-paths": "^2.2.0",
+ "glob": "^7.1.4",
+ "graceful-fs": "^4.2.3",
+ "nopt": "^5.0.0",
+ "npmlog": "^4.1.2",
+ "request": "^2.88.2",
+ "rimraf": "^3.0.2",
+ "semver": "^7.3.2",
+ "tar": "^6.0.2",
+ "which": "^2.0.2"
+ },
+ "dependencies": {
+ "chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "dev": true
+ },
+ "minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dev": true,
+ "requires": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ }
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+ "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "tar": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz",
+ "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^3.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "node-gyp-build": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz",
+ "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==",
+ "dev": true
+ },
+ "node-hid": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/node-hid/-/node-hid-2.1.1.tgz",
+ "integrity": "sha512-Skzhqow7hyLZU93eIPthM9yjot9lszg9xrKxESleEs05V2NcbUptZc5HFqzjOkSmL0sFlZFr3kmvaYebx06wrw==",
+ "requires": {
+ "bindings": "^1.5.0",
+ "node-addon-api": "^3.0.2",
+ "prebuild-install": "^6.0.0"
+ },
+ "dependencies": {
+ "node-addon-api": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.1.0.tgz",
+ "integrity": "sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw=="
+ }
+ }
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=",
+ "dev": true
+ },
+ "node-ipc": {
+ "version": "9.1.3",
+ "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.3.tgz",
+ "integrity": "sha512-8RS4RZyS/KMKKYG8mrje+cLxwATe9dBCuOiqKFSWND4oOuKytfuKCiR9yinvhoXF/nGdX/WnbywaUee+9U87zA==",
+ "dev": true,
+ "requires": {
+ "event-pubsub": "4.3.0",
+ "js-message": "1.0.7",
+ "js-queue": "2.0.2"
+ }
+ },
+ "node-libs-browser": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz",
+ "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==",
+ "dev": true,
+ "requires": {
+ "assert": "^1.1.1",
+ "browserify-zlib": "^0.2.0",
+ "buffer": "^4.3.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "^1.0.0",
+ "crypto-browserify": "^3.11.0",
+ "domain-browser": "^1.1.1",
+ "events": "^3.0.0",
+ "https-browserify": "^1.0.0",
+ "os-browserify": "^0.3.0",
+ "path-browserify": "0.0.1",
+ "process": "^0.11.10",
+ "punycode": "^1.2.4",
+ "querystring-es3": "^0.2.0",
+ "readable-stream": "^2.3.3",
+ "stream-browserify": "^2.0.1",
+ "stream-http": "^2.7.2",
+ "string_decoder": "^1.0.0",
+ "timers-browserify": "^2.0.4",
+ "tty-browserify": "0.0.0",
+ "url": "^0.11.0",
+ "util": "^0.11.0",
+ "vm-browserify": "^1.0.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ }
+ }
+ },
+ "node-modules-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz",
+ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA="
+ },
+ "node-notifier": {
+ "version": "5.4.3",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz",
+ "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==",
+ "dev": true,
+ "requires": {
+ "growly": "^1.3.0",
+ "is-wsl": "^1.1.0",
+ "semver": "^5.5.0",
+ "shellwords": "^0.1.1",
+ "which": "^1.3.0"
+ }
+ },
+ "node-pre-gyp": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz",
+ "integrity": "sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==",
+ "dev": true,
+ "requires": {
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.1",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.2.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4"
+ },
+ "dependencies": {
+ "nopt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
+ "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "node-releases": {
+ "version": "1.1.69",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.69.tgz",
+ "integrity": "sha512-DGIjo79VDEyAnRlfSqYTsy+yoHd2IOjJiKUozD2MV2D85Vso6Bug56mb9tT/fY5Urt0iqk01H7x+llAruDR2zA==",
+ "dev": true
+ },
+ "noop-logger": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
+ "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI="
+ },
+ "nopt": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
+ "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "dev": true,
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+ "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
+ "dev": true
+ },
+ "npm-build-zip": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/npm-build-zip/-/npm-build-zip-1.0.2.tgz",
+ "integrity": "sha512-4cHCllS1EUxVZ/B2M9uG0zzUDS1lQUhYNrDIpGerWkOwseIKwCz5AiSvyOzfWZ/ZP1weNbzP1AeorUvKxrhHkw==",
+ "dev": true,
+ "requires": {
+ "archiver-promise": "1.0.0",
+ "npm-packlist": "1.4.4",
+ "sanitize-filename": "1.6.3",
+ "yargs": "13.3.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "npm-packlist": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz",
+ "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==",
+ "dev": true,
+ "requires": {
+ "ignore-walk": "^3.0.1",
+ "npm-bundled": "^1.0.1"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
+ "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.1"
+ }
+ }
+ }
+ },
+ "npm-bundled": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz",
+ "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
+ "dev": true,
+ "requires": {
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-conf": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz",
+ "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "config-chain": "^1.1.11",
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "npm-normalize-package-bin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz",
+ "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==",
+ "dev": true
+ },
+ "npm-packlist": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz",
+ "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==",
+ "dev": true,
+ "requires": {
+ "ignore-walk": "^3.0.1",
+ "npm-bundled": "^1.0.1",
+ "npm-normalize-package-bin": "^1.0.1"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "nth-check": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+ "dev": true,
+ "requires": {
+ "boolbase": "~1.0.0"
+ }
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+ },
+ "nwsapi": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "object-inspect": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz",
+ "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==",
+ "dev": true
+ },
+ "object-is": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz",
+ "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz",
+ "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "object.values": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz",
+ "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.18.0-next.1",
+ "has": "^1.0.3"
+ }
+ },
+ "obuf": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
+ "dev": true
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dev": true,
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "on-headers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
+ "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "open": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
+ "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ },
+ "opener": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz",
+ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==",
+ "dev": true
+ },
+ "opn": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz",
+ "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "ora": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz",
+ "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-spinners": "^2.0.0",
+ "log-symbols": "^2.2.0",
+ "strip-ansi": "^5.2.0",
+ "wcwidth": "^1.0.1"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "original": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz",
+ "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==",
+ "dev": true,
+ "requires": {
+ "url-parse": "^1.4.3"
+ }
+ },
+ "os-browserify": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
+ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=",
+ "dev": true
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true
+ },
+ "p-each-series": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz",
+ "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=",
+ "dev": true,
+ "requires": {
+ "p-reduce": "^1.0.0"
+ }
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-map": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.0"
+ }
+ },
+ "p-reduce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz",
+ "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=",
+ "dev": true
+ },
+ "p-retry": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
+ "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==",
+ "dev": true,
+ "requires": {
+ "retry": "^0.12.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "package-json": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+ "dev": true,
+ "requires": {
+ "got": "^9.6.0",
+ "registry-auth-token": "^4.0.0",
+ "registry-url": "^5.0.0",
+ "semver": "^6.2.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "pako": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+ "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
+ "dev": true
+ },
+ "parallel-transform": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz",
+ "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==",
+ "dev": true,
+ "requires": {
+ "cyclist": "^1.0.1",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.1.5"
+ }
+ },
+ "param-case": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
+ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=",
+ "dev": true,
+ "requires": {
+ "no-case": "^2.2.0"
+ }
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parse-asn1": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz",
+ "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==",
+ "dev": true,
+ "requires": {
+ "asn1.js": "^5.2.0",
+ "browserify-aes": "^1.0.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "parse-author": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz",
+ "integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=",
+ "dev": true,
+ "requires": {
+ "author-regex": "^1.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz",
+ "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ }
+ },
+ "parse5": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
+ "dev": true
+ },
+ "parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "requires": {
+ "parse5": "^6.0.1"
+ },
+ "dependencies": {
+ "parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true
+ }
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz",
+ "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "optional": true
+ },
+ "pbkdf2": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz",
+ "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==",
+ "dev": true,
+ "requires": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "pdf-lib": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.10.0.tgz",
+ "integrity": "sha512-r9+GL84EI7HIwkgDo191ArhGZgbUPqPRwddTrfV6Th7U4u8UayPixx0FZ/Sv8Dl3K/AZLQ1nrUVFqjTlmy9uJQ==",
+ "dev": true,
+ "requires": {
+ "@pdf-lib/standard-fonts": "^0.0.4",
+ "@pdf-lib/upng": "^1.0.1",
+ "pako": "^1.0.11",
+ "tslib": "^1.11.1"
+ }
+ },
+ "pdfjs-dist": {
+ "version": "2.6.347",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.6.347.tgz",
+ "integrity": "sha512-QC+h7hG2su9v/nU1wEI3SnpPIrqJODL7GTDFvR74ANKGq1AFJW16PH8VWnhpiTi9YcLSFV9xLeWSgq+ckHLdVQ=="
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
+ "dev": true
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "picomatch": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz",
+ "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pirates": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz",
+ "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==",
+ "requires": {
+ "node-modules-regexp": "^1.0.0"
+ }
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "plist": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz",
+ "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.2.3",
+ "xmlbuilder": "^9.0.7",
+ "xmldom": "0.1.x"
+ },
+ "dependencies": {
+ "xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
+ "dev": true
+ }
+ }
+ },
+ "pn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "dev": true
+ },
+ "pngjs": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz",
+ "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==",
+ "dev": true
+ },
+ "pnp-webpack-plugin": {
+ "version": "1.6.4",
+ "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz",
+ "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==",
+ "dev": true,
+ "requires": {
+ "ts-pnp": "^1.1.6"
+ }
+ },
+ "popper.js": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
+ },
+ "portfinder": {
+ "version": "1.0.28",
+ "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz",
+ "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==",
+ "dev": true,
+ "requires": {
+ "async": "^2.6.2",
+ "debug": "^3.1.1",
+ "mkdirp": "^0.5.5"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.35",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz",
+ "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-calc": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz",
+ "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.27",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
+ "postcss-colormin": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
+ "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "color": "^3.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-convert-values": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz",
+ "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-discard-comments": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz",
+ "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-discard-duplicates": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz",
+ "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-discard-empty": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz",
+ "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-discard-overridden": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz",
+ "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-import": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz",
+ "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.1",
+ "postcss-value-parser": "^3.2.3",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-load-config": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz",
+ "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^5.0.0",
+ "import-cwd": "^2.0.0"
+ },
+ "dependencies": {
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ }
+ },
+ "import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "postcss-loader": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz",
+ "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.1.0",
+ "postcss": "^7.0.0",
+ "postcss-load-config": "^2.0.0",
+ "schema-utils": "^1.0.0"
+ },
+ "dependencies": {
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ }
+ }
+ },
+ "postcss-merge-longhand": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
+ "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==",
+ "dev": true,
+ "requires": {
+ "css-color-names": "0.0.4",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "stylehacks": "^4.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-merge-rules": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz",
+ "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-api": "^3.0.0",
+ "cssnano-util-same-parent": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0",
+ "vendors": "^1.0.0"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+ "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^5.2.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ }
+ }
+ },
+ "postcss-minify-font-values": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz",
+ "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz",
+ "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "is-color-stop": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-minify-params": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz",
+ "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.0",
+ "browserslist": "^4.0.0",
+ "cssnano-util-get-arguments": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "uniqs": "^2.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-minify-selectors": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz",
+ "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+ "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^5.2.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ }
+ }
+ },
+ "postcss-modules-extract-imports": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz",
+ "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.5"
+ }
+ },
+ "postcss-modules-local-by-default": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz",
+ "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^4.1.1",
+ "postcss": "^7.0.32",
+ "postcss-selector-parser": "^6.0.2",
+ "postcss-value-parser": "^4.1.0"
+ }
+ },
+ "postcss-modules-scope": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz",
+ "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.6",
+ "postcss-selector-parser": "^6.0.0"
+ }
+ },
+ "postcss-modules-values": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz",
+ "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==",
+ "dev": true,
+ "requires": {
+ "icss-utils": "^4.0.0",
+ "postcss": "^7.0.6"
+ }
+ },
+ "postcss-normalize-charset": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
+ "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-normalize-display-values": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz",
+ "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-positions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz",
+ "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-repeat-style": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz",
+ "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-string": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz",
+ "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-timing-functions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz",
+ "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-unicode": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz",
+ "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-url": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz",
+ "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==",
+ "dev": true,
+ "requires": {
+ "is-absolute-url": "^2.0.0",
+ "normalize-url": "^3.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-normalize-whitespace": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz",
+ "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-ordered-values": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz",
+ "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-pxtorem": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-pxtorem/-/postcss-pxtorem-4.0.1.tgz",
+ "integrity": "sha1-nGTQ7+SIVHPMHLAwXG/8PrtFsc0=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.0",
+ "postcss": "^5.2.10"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "js-base64": "^2.1.9",
+ "source-map": "^0.5.6",
+ "supports-color": "^3.2.3"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz",
+ "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-api": "^3.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz",
+ "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-match": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.4.tgz",
+ "integrity": "sha512-gjMeXBempyInaBqpp8gODmwZ52WaYsVOsfr4L4lDQ7n3ncD6mEyySiDtgzCT+NYC0mmeOLvtsF8iaEf0YT6dBw==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^3.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "postcss-svgo": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz",
+ "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==",
+ "dev": true,
+ "requires": {
+ "is-svg": "^3.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "svgo": "^1.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-unique-selectors": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz",
+ "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.0",
+ "postcss": "^7.0.0",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
+ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
+ "dev": true
+ },
+ "prebuild-install": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-6.0.0.tgz",
+ "integrity": "sha512-h2ZJ1PXHKWZpp1caLw0oX9sagVpL2YTk+ZwInQbQ3QqNd4J03O6MpFNmMTJlkfgPENWqe5kP0WjQLqz5OjLfsw==",
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^2.0.3",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.3",
+ "mkdirp-classic": "^0.5.3",
+ "napi-build-utils": "^1.0.1",
+ "node-abi": "^2.7.0",
+ "noop-logger": "^0.1.1",
+ "npmlog": "^4.0.1",
+ "pump": "^3.0.0",
+ "rc": "^1.2.7",
+ "simple-get": "^3.0.3",
+ "tar-fs": "^2.0.0",
+ "tunnel-agent": "^0.6.0",
+ "which-pm-runs": "^1.0.0"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "prepend-http": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+ "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+ "dev": true
+ },
+ "prettier": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz",
+ "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==",
+ "dev": true
+ },
+ "prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.2"
+ }
+ },
+ "pretty": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
+ "integrity": "sha1-rbx5YLe7/iiaVX3F9zdhmiINBqU=",
+ "dev": true,
+ "requires": {
+ "condense-newlines": "^0.2.1",
+ "extend-shallow": "^2.0.1",
+ "js-beautify": "^1.6.12"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "pretty-error": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz",
+ "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.20",
+ "renderkid": "^2.0.4"
+ }
+ },
+ "pretty-format": {
+ "version": "24.9.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz",
+ "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^24.9.0",
+ "ansi-regex": "^4.0.0",
+ "ansi-styles": "^3.2.0",
+ "react-is": "^16.8.4"
+ }
+ },
+ "private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==",
+ "dev": true
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
+ "dev": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=",
+ "dev": true
+ },
+ "prompts": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz",
+ "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==",
+ "dev": true,
+ "requires": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
+ "dev": true
+ },
+ "proxy-addr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
+ "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
+ "dev": true,
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.1"
+ }
+ },
+ "prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
+ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
+ },
+ "public-encrypt": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+ "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+ "dev": true,
+ "requires": {
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.11.9",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz",
+ "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==",
+ "dev": true
+ }
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "dev": true,
+ "requires": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "pupa": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz",
+ "integrity": "sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==",
+ "requires": {
+ "escape-goat": "^2.0.0"
+ }
+ },
+ "q": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+ "dev": true
+ },
+ "qrcode": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.4.4.tgz",
+ "integrity": "sha512-oLzEC5+NKFou9P0bMj5+v6Z40evexeE29Z9cummZXZ9QXyMr3lphkURzxjXgPJC5azpxcshoDWV1xE46z+/c3Q==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.4.3",
+ "buffer-alloc": "^1.2.0",
+ "buffer-from": "^1.1.1",
+ "dijkstrajs": "^1.0.1",
+ "isarray": "^2.0.1",
+ "pngjs": "^3.3.0",
+ "yargs": "^13.2.4"
+ },
+ "dependencies": {
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ }
+ }
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "query-string": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+ "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ }
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=",
+ "dev": true
+ },
+ "querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true
+ },
+ "quick-lru": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
+ "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
+ "dev": true
+ },
+ "randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "dev": true
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "raw-loader": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz",
+ "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==",
+ "requires": {
+ "loader-utils": "^2.0.0",
+ "schema-utils": "^3.0.0"
+ },
+ "dependencies": {
+ "loader-utils": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz",
+ "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==",
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "schema-utils": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz",
+ "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==",
+ "requires": {
+ "@types/json-schema": "^7.0.6",
+ "ajv": "^6.12.5",
+ "ajv-keywords": "^3.5.2"
+ }
+ }
+ }
+ },
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
+ "rcedit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/rcedit/-/rcedit-2.3.0.tgz",
+ "integrity": "sha512-h1gNEl9Oai1oijwyJ1WYqYSXTStHnOcv1KYljg/8WM4NAg3H1KBK3azIaKkQ1WQl+d7PoJpcBMscPfLXVKgCLQ==",
+ "dev": true
+ },
+ "react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
+ "dev": true
+ },
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.3.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "read-config-file": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.0.0.tgz",
+ "integrity": "sha512-PHjROSdpceKUmqS06wqwP92VrM46PZSTubmNIMJ5DrMwg1OgenSTSEHIkCa6TiOJ+y/J0xnG1fFwG3M+Oi1aNA==",
+ "dev": true,
+ "requires": {
+ "dotenv": "^8.2.0",
+ "dotenv-expand": "^5.1.0",
+ "js-yaml": "^3.13.1",
+ "json5": "^2.1.2",
+ "lazy-val": "^1.0.4"
+ }
+ },
+ "read-pkg": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
+ "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "dev": true,
+ "requires": {
+ "@types/normalize-package-data": "^2.4.0",
+ "normalize-package-data": "^2.5.0",
+ "parse-json": "^5.0.0",
+ "type-fest": "^0.6.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz",
+ "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0",
+ "read-pkg": "^3.0.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.7",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
+ "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
+ }
+ },
+ "readdirp": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
+ "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
+ "dev": true,
+ "requires": {
+ "picomatch": "^2.2.1"
+ }
+ },
+ "realpath-native": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz",
+ "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==",
+ "dev": true,
+ "requires": {
+ "util.promisify": "^1.0.0"
+ }
+ },
+ "regenerate": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
+ "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==",
+ "dev": true
+ },
+ "regenerate-unicode-properties": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz",
+ "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.0"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.7",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
+ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
+ },
+ "regenerator-transform": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz",
+ "integrity": "sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.8.4"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "regexp.prototype.flags": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
+ "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
+ "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ }
+ }
+ },
+ "regexpp": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
+ "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==",
+ "dev": true
+ },
+ "regexpu-core": {
+ "version": "4.7.1",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz",
+ "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.4.0",
+ "regenerate-unicode-properties": "^8.2.0",
+ "regjsgen": "^0.5.1",
+ "regjsparser": "^0.6.4",
+ "unicode-match-property-ecmascript": "^1.0.4",
+ "unicode-match-property-value-ecmascript": "^1.2.0"
+ }
+ },
+ "registry-auth-token": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz",
+ "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.2.8"
+ }
+ },
+ "registry-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+ "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.2.8"
+ }
+ },
+ "regjsgen": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz",
+ "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==",
+ "dev": true
+ },
+ "regjsparser": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.6.tgz",
+ "integrity": "sha512-jjyuCp+IEMIm3N1H1LLTJW1EISEJV9+5oHdEyrt43Pg9cDSb6rrLZei2cVWpl0xTjmmlpec/lEQGYgM7xfpGCQ==",
+ "dev": true,
+ "requires": {
+ "jsesc": "~0.5.0"
+ },
+ "dependencies": {
+ "jsesc": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+ "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+ "dev": true
+ }
+ }
+ },
+ "relateurl": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz",
+ "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=",
+ "dev": true
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "renderkid": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz",
+ "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==",
+ "dev": true,
+ "requires": {
+ "css-select": "^2.0.2",
+ "dom-converter": "^0.2",
+ "htmlparser2": "^3.10.1",
+ "lodash": "^4.17.20",
+ "strip-ansi": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ }
+ }
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "request-promise-core": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
+ "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.19"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
+ "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
+ "dev": true,
+ "requires": {
+ "request-promise-core": "1.1.4",
+ "stealthy-require": "^1.1.1",
+ "tough-cookie": "^2.3.3"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
+ "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.1.0",
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-alpn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.0.0.tgz",
+ "integrity": "sha512-rTuiIEqFmGxne4IovivKSDzld2lWW9QCjqv80SYjPgf+gS35eaCAjaP54CCwGAwBtnCsvNLYtqxe1Nw+i6JEmA==",
+ "dev": true
+ },
+ "resolve-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "retry": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+ "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+ "dev": true
+ },
+ "rgb-regex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
+ "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
+ "dev": true
+ },
+ "rgba-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
+ "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dev": true,
+ "requires": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "roarr": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz",
+ "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "boolean": "^3.0.1",
+ "detect-node": "^2.0.4",
+ "globalthis": "^1.0.1",
+ "json-stringify-safe": "^5.0.1",
+ "semver-compare": "^1.0.0",
+ "sprintf-js": "^1.1.2"
+ },
+ "dependencies": {
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "rss-parser": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/rss-parser/-/rss-parser-3.10.0.tgz",
+ "integrity": "sha512-TC6FNvEmdFeaW6r/60MSJT7cp4d95X4M9As+mvNtxRx7YXHxpV95syMnWZthZSeD1BRN7SEKdq6c3nxMLQRopw==",
+ "requires": {
+ "entities": "^2.0.3",
+ "xml2js": "^0.4.19"
+ }
+ },
+ "rsvp": {
+ "version": "4.8.5",
+ "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz",
+ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==",
+ "dev": true
+ },
+ "rtcpeerconnection-shim": {
+ "version": "1.2.15",
+ "resolved": "https://registry.npmjs.org/rtcpeerconnection-shim/-/rtcpeerconnection-shim-1.2.15.tgz",
+ "integrity": "sha512-C6DxhXt7bssQ1nHb154lqeL0SXz5Dx4RczXZu2Aa/L1NJFnEVDxFwCBo3fqtuljhHIGceg5JKBV4XJ0gW5JKyw==",
+ "requires": {
+ "sdp": "^2.6.0"
+ }
+ },
+ "run-async": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
+ "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
+ "dev": true
+ },
+ "run-queue": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
+ "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.1.1"
+ }
+ },
+ "rxjs": {
+ "version": "6.6.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
+ "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "rxjs-compat": {
+ "version": "6.6.6",
+ "resolved": "https://registry.npmjs.org/rxjs-compat/-/rxjs-compat-6.6.6.tgz",
+ "integrity": "sha512-P6JOpjCYUBdXLMktko0a6JHltGaktFJA2W3DWDIjc+I9x9IwRQprOrHQf/fIykY3wAaSbbZIt6GASGMVC1mGfQ==",
+ "dev": true
+ },
+ "safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sane": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz",
+ "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==",
+ "dev": true,
+ "requires": {
+ "@cnakazawa/watch": "^1.0.3",
+ "anymatch": "^2.0.0",
+ "capture-exit": "^2.0.0",
+ "exec-sh": "^0.3.2",
+ "execa": "^1.0.0",
+ "fb-watchman": "^2.0.0",
+ "micromatch": "^3.1.4",
+ "minimist": "^1.1.1",
+ "walker": "~1.0.5"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "sanitize-filename": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
+ "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
+ "dev": true,
+ "requires": {
+ "truncate-utf8-bytes": "^1.0.0"
+ }
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "saxes": {
+ "version": "3.1.11",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
+ "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
+ "dev": true,
+ "requires": {
+ "xmlchars": "^2.1.1"
+ }
+ },
+ "schema-utils": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
+ "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
+ "dev": true,
+ "requires": {
+ "@types/json-schema": "^7.0.5",
+ "ajv": "^6.12.4",
+ "ajv-keywords": "^3.5.2"
+ }
+ },
+ "sdp": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/sdp/-/sdp-2.12.0.tgz",
+ "integrity": "sha512-jhXqQAQVM+8Xj5EjJGVweuEzgtGWb3tmEEpl3CLP3cStInSbVHSg0QWOGQzNq8pSID4JkpeV2mPqlMDLrm0/Vw=="
+ },
+ "select-hose": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
+ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=",
+ "dev": true
+ },
+ "selfsigned": {
+ "version": "1.10.8",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
+ "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
+ "dev": true,
+ "requires": {
+ "node-forge": "^0.10.0"
+ }
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "semver-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
+ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
+ "dev": true,
+ "optional": true
+ },
+ "semver-diff": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz",
+ "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "dev": true,
+ "requires": {
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "serialize-error": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz",
+ "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "type-fest": "^0.13.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz",
+ "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "serialize-javascript": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
+ "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
+ "dev": true,
+ "requires": {
+ "randombytes": "^2.1.0"
+ }
+ },
+ "serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
+ "dev": true,
+ "requires": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "dev": true,
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "dev": true,
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
+ "dev": true
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
+ "dev": true
+ },
+ "sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shell-quote": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz",
+ "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==",
+ "dev": true
+ },
+ "shellwords": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
+ "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==",
+ "dev": true
+ },
+ "sigmund": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz",
+ "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
+ },
+ "simple-concat": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
+ "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
+ },
+ "simple-get": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.0.tgz",
+ "integrity": "sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA==",
+ "requires": {
+ "decompress-response": "^4.2.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
+ },
+ "dependencies": {
+ "decompress-response": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz",
+ "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==",
+ "requires": {
+ "mimic-response": "^2.0.0"
+ }
+ },
+ "mimic-response": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz",
+ "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA=="
+ }
+ }
+ },
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.3.1"
+ },
+ "dependencies": {
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "dev": true
+ }
+ }
+ },
+ "sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "is-fullwidth-code-point": "^2.0.0"
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "sockjs": {
+ "version": "0.3.21",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
+ "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==",
+ "dev": true,
+ "requires": {
+ "faye-websocket": "^0.11.3",
+ "uuid": "^3.4.0",
+ "websocket-driver": "^0.7.4"
+ }
+ },
+ "sockjs-client": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz",
+ "integrity": "sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.2.6",
+ "eventsource": "^1.0.7",
+ "faye-websocket": "^0.11.3",
+ "inherits": "^2.0.4",
+ "json3": "^3.3.3",
+ "url-parse": "^1.4.7"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
+ "requires": {
+ "is-plain-obj": "^1.0.0"
+ }
+ },
+ "sort-keys-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
+ "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=",
+ "requires": {
+ "sort-keys": "^1.0.0"
+ }
+ },
+ "sortablejs": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
+ "integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
+ },
+ "source-list-map": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
+ "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ },
+ "source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-support": {
+ "version": "0.5.19",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz",
+ "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "dev": true,
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
+ "dev": true
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz",
+ "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==",
+ "dev": true
+ },
+ "spdy": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz",
+ "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "handle-thing": "^2.0.0",
+ "http-deceiver": "^1.2.7",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^3.0.0"
+ }
+ },
+ "spdy-transport": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz",
+ "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "detect-node": "^2.0.4",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.2",
+ "readable-stream": "^3.0.6",
+ "wbuf": "^1.7.3"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "ssri": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz",
+ "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==",
+ "dev": true,
+ "requires": {
+ "figgy-pudding": "^3.5.1"
+ }
+ },
+ "stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.4.tgz",
+ "integrity": "sha512-IPDJfugEGbfizBwBZRZ3xpccMdRyP5lqsBWXGQWimVjua/ccLCeMOAVjlc1R7LxFjo5sEDhyNIXd8mo/AiDS9w==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "dependencies": {
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ }
+ }
+ },
+ "stackframe": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz",
+ "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==",
+ "dev": true
+ },
+ "stat-mode": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz",
+ "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==",
+ "dev": true
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true
+ },
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+ "dev": true
+ },
+ "stream-browserify": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz",
+ "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "stream-each": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz",
+ "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "stream-http": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz",
+ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "to-arraybuffer": "^1.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
+ "stream-shift": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz",
+ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==",
+ "dev": true
+ },
+ "strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
+ "dev": true
+ },
+ "string-length": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
+ "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=",
+ "dev": true,
+ "requires": {
+ "astral-regex": "^1.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "string.prototype.trimend": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz",
+ "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "string.prototype.trimstart": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz",
+ "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ },
+ "dependencies": {
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "requires": {
+ "ansi-regex": "^5.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg=="
+ }
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "strip-outer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+ "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.2"
+ }
+ },
+ "stylehacks": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
+ "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz",
+ "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^5.2.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ }
+ }
+ },
+ "sumchecker": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz",
+ "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-hyperlinks": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz",
+ "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
+ "dev": true
+ },
+ "svgo": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
+ "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "coa": "^2.0.2",
+ "css-select": "^2.0.0",
+ "css-select-base-adapter": "^0.1.1",
+ "css-tree": "1.0.0-alpha.37",
+ "csso": "^4.0.2",
+ "js-yaml": "^3.13.1",
+ "mkdirp": "~0.5.1",
+ "object.values": "^1.1.0",
+ "sax": "~1.2.4",
+ "stable": "^0.1.8",
+ "unquote": "~1.1.1",
+ "util.promisify": "~1.0.0"
+ },
+ "dependencies": {
+ "es-abstract": {
+ "version": "1.17.7",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz",
+ "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.2.2",
+ "is-regex": "^1.1.1",
+ "object-inspect": "^1.8.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.1",
+ "string.prototype.trimend": "^1.0.1",
+ "string.prototype.trimstart": "^1.0.1"
+ }
+ },
+ "util.promisify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz",
+ "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.2",
+ "has-symbols": "^1.0.1",
+ "object.getownpropertydescriptors": "^2.1.0"
+ }
+ }
+ }
+ },
+ "symbol-address-book": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/symbol-address-book/-/symbol-address-book-1.0.0.tgz",
+ "integrity": "sha512-exdGgPo+j9uK1Ag8McVmCxtR6lsNUwo1T4ZnAgQqLDrel+XH80oU3qDLBjzPS3DeFSLplc4yqBkWDRPNirLsvQ==",
+ "dev": true,
+ "requires": {
+ "typescript": "^3.7.4"
+ }
+ },
+ "symbol-hd-wallets": {
+ "version": "0.14.1-alpha-202103051108",
+ "resolved": "https://registry.npmjs.org/symbol-hd-wallets/-/symbol-hd-wallets-0.14.1-alpha-202103051108.tgz",
+ "integrity": "sha512-EF0ptcwJGdm7yF2CFAAhybN2f7EN9YlZU7OwjwJh7Ae23UeNB/dkJfxfQk//Tfor9776dksId3YdUsO2oD0T6A==",
+ "dev": true,
+ "requires": {
+ "bip32": "^1.0.4",
+ "bip39": "^3.0.2",
+ "bip44-constants": "^8.0.5",
+ "bs58check": "^2.1.2",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "crypto-js": "^4.0.0",
+ "js-sha3": "^0.8.0",
+ "tiny-secp256k1": "^1.1.3",
+ "tweetnacl": "^1.0.3"
+ },
+ "dependencies": {
+ "tweetnacl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+ "dev": true
+ }
+ }
+ },
+ "symbol-openapi-typescript-fetch-client": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/symbol-openapi-typescript-fetch-client/-/symbol-openapi-typescript-fetch-client-0.11.2.tgz",
+ "integrity": "sha512-A1MAN8/UWlaCEibBf6zxkduZwDNSvWwLPp6JB0GeYI/FAOrw/9nLyuS/NJQ3siGAUclnuejH1wG7KdUg0/4RSw==",
+ "dev": true
+ },
+ "symbol-paper-wallets": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/symbol-paper-wallets/-/symbol-paper-wallets-1.0.2.tgz",
+ "integrity": "sha512-JqK46bfGHwX9ZXJ2WnRfxB786ZjyjJGB+/l8ASNoRsWkfikKpqEzazJwn+2C0otdLqChBnTr3NKd1EMWZDtjhQ==",
+ "dev": true,
+ "requires": {
+ "@pdf-lib/fontkit": "1.0.0",
+ "pdf-lib": "1.10.0",
+ "symbol-qr-library": "^0.13.1-alpha-202010241730",
+ "typescript": "^3.7.4"
+ },
+ "dependencies": {
+ "crypto-js": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
+ "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "open": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.3.1.tgz",
+ "integrity": "sha512-f2wt9DCBKKjlFbjzGb8MOAW8LH8F0mrs1zc7KTjAJ9PZNQbfenzWbNP1VZJvw6ICMG9r14Ah6yfwPn7T7i646A==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ }
+ },
+ "symbol-qr-library": {
+ "version": "0.13.1-alpha-202012220953",
+ "resolved": "https://registry.npmjs.org/symbol-qr-library/-/symbol-qr-library-0.13.1-alpha-202012220953.tgz",
+ "integrity": "sha512-76f23EZUKOUH7EdY183uIefoTN4fCq00cNVdvrKHIo73i1W0QPwL5xQt4ygd9RGYoip/st6Zc0AlkW1+ymS0Eg==",
+ "dev": true,
+ "requires": {
+ "braces": ">=2.3.1",
+ "canvas": "^2.6.1",
+ "crypto-js": "^3.3.0",
+ "open": "^7.0.2",
+ "qrcode": "^1.4.4"
+ }
+ }
+ }
+ },
+ "symbol-qr-library": {
+ "version": "0.14.1-alpha-202103081047",
+ "resolved": "https://registry.npmjs.org/symbol-qr-library/-/symbol-qr-library-0.14.1-alpha-202103081047.tgz",
+ "integrity": "sha512-pxKw30XP1cYaCH5r0VIsHp0GDJDURFFs7Uvl3bR1lyUJgNN16mp4AhiDt5HogXeaZJvb/7+bNVHRJa4RGFpsJg==",
+ "dev": true,
+ "requires": {
+ "braces": ">=2.3.1",
+ "canvas": "^2.6.1",
+ "crypto-js": "^3.3.0",
+ "open": "^7.0.2",
+ "qrcode": "^1.4.4"
+ },
+ "dependencies": {
+ "crypto-js": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.3.0.tgz",
+ "integrity": "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0"
+ }
+ },
+ "open": {
+ "version": "7.4.2",
+ "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz",
+ "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
+ "dev": true,
+ "requires": {
+ "is-docker": "^2.0.0",
+ "is-wsl": "^2.1.1"
+ }
+ }
+ }
+ },
+ "symbol-sdk": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/symbol-sdk/-/symbol-sdk-1.0.0.tgz",
+ "integrity": "sha512-j7HR5288sNXLHAMRWc6VgXiVBiyY6FJ0b+ug//cJPg63beKF+ZJkAZbzcrQqdrMTuGhIy80jG9HFodQIthLoUg==",
+ "dev": true,
+ "requires": {
+ "@js-joda/core": "^3.2.0",
+ "bluebird": "^3.7.2",
+ "catbuffer-typescript": "0.1.1",
+ "crypto-js": "^4.0.0",
+ "diff": "^4.0.2",
+ "futoin-hkdf": "^1.3.2",
+ "js-sha256": "^0.9.0",
+ "js-sha3": "^0.8.0",
+ "js-sha512": "^0.8.0",
+ "long": "^4.0.0",
+ "merkletreejs": "^0.2.9",
+ "minimist": "^1.2.5",
+ "node-fetch": "^2.6.0",
+ "ripemd160": "^2.0.2",
+ "rxjs": "^6.6.3",
+ "rxjs-compat": "^6.6.3",
+ "symbol-openapi-typescript-fetch-client": "0.11.2",
+ "tweetnacl": "^1.0.3",
+ "ws": "^7.3.1"
+ },
+ "dependencies": {
+ "node-fetch": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
+ "dev": true
+ },
+ "tweetnacl": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
+ "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==",
+ "dev": true
+ },
+ "ws": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz",
+ "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==",
+ "dev": true
+ }
+ }
+ },
+ "symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true
+ },
+ "symbol-uri-scheme": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/symbol-uri-scheme/-/symbol-uri-scheme-0.6.0.tgz",
+ "integrity": "sha512-fg3cvpS3REgoQy/Q63CuG1eIF8APKTSXUW921WazJECsUEHNN6VpuXi1vecOa52SG+W26kY5wJPSOMdF11F25g==",
+ "dev": true,
+ "requires": {
+ "url-parse": "1.4.7"
+ }
+ },
+ "table": {
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
+ "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.10.2",
+ "lodash": "^4.17.14",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ }
+ },
+ "tapable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
+ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
+ "dev": true
+ },
+ "tar": {
+ "version": "4.4.13",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz",
+ "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+ "dev": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.8.6",
+ "minizlib": "^1.2.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.3"
+ },
+ "dependencies": {
+ "fs-minipass": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz",
+ "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+ "dev": true,
+ "requires": {
+ "minipass": "^2.6.0"
+ }
+ },
+ "minipass": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz",
+ "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "requires": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ },
+ "dependencies": {
+ "bl": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
+ "integrity": "sha512-fs4G6/Hu4/EE+F75J8DuN/0IpQqNjAdC7aEQv7Qt8MHGUH7Ckv2MwTEEeN9QehD0pfIDkMI1bkHYkKy7xHyKIg==",
+ "requires": {
+ "buffer": "^5.5.0",
+ "inherits": "^2.0.4",
+ "readable-stream": "^3.4.0"
+ }
+ },
+ "buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "requires": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "tar-stream": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
+ "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
+ "requires": {
+ "bl": "^4.0.3",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
+ }
+ }
+ }
+ },
+ "tar-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+ "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+ "dev": true,
+ "requires": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.2.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.1",
+ "xtend": "^4.0.0"
+ }
+ },
+ "temp-file": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.3.7.tgz",
+ "integrity": "sha512-9tBJKt7GZAQt/Rg0QzVWA8Am8c1EFl+CAv04/aBVqlx5oyfQ508sFIABshQ0xbZu6mBrFLWIUXO/bbLYghW70g==",
+ "dev": true,
+ "requires": {
+ "async-exit-hook": "^2.0.1",
+ "fs-extra": "^8.1.0"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
+ "dev": true
+ }
+ }
+ },
+ "term-size": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz",
+ "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==",
+ "dev": true
+ },
+ "terminal-link": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
+ "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^4.2.1",
+ "supports-hyperlinks": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz",
+ "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.11.0"
+ }
+ },
+ "type-fest": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz",
+ "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==",
+ "dev": true
+ }
+ }
+ },
+ "terser": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
+ "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
+ "dev": true,
+ "requires": {
+ "commander": "^2.20.0",
+ "source-map": "~0.6.1",
+ "source-map-support": "~0.5.12"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "terser-webpack-plugin": {
+ "version": "1.4.5",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz",
+ "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==",
+ "dev": true,
+ "requires": {
+ "cacache": "^12.0.2",
+ "find-cache-dir": "^2.1.0",
+ "is-wsl": "^1.1.0",
+ "schema-utils": "^1.0.0",
+ "serialize-javascript": "^4.0.0",
+ "source-map": "^0.6.1",
+ "terser": "^4.1.2",
+ "webpack-sources": "^1.4.0",
+ "worker-farm": "^1.7.0"
+ },
+ "dependencies": {
+ "find-cache-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz",
+ "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^2.0.0",
+ "pkg-dir": "^3.0.0"
+ }
+ },
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dev": true,
+ "requires": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
+ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "test-exclude": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz",
+ "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3",
+ "minimatch": "^3.0.4",
+ "read-pkg-up": "^4.0.0",
+ "require-main-filename": "^2.0.0"
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "requires": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=",
+ "dev": true,
+ "requires": {
+ "thenify": ">= 3.1.0 < 4"
+ }
+ },
+ "thread-loader": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz",
+ "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==",
+ "dev": true,
+ "requires": {
+ "loader-runner": "^2.3.1",
+ "loader-utils": "^1.1.0",
+ "neo-async": "^2.6.0"
+ }
+ },
+ "throat": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz",
+ "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "thunky": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
+ "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
+ "dev": true
+ },
+ "timers-browserify": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz",
+ "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==",
+ "dev": true,
+ "requires": {
+ "setimmediate": "^1.0.4"
+ }
+ },
+ "timsort": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
+ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
+ "dev": true
+ },
+ "tiny-secp256k1": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz",
+ "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==",
+ "dev": true,
+ "requires": {
+ "bindings": "^1.3.0",
+ "bn.js": "^4.11.8",
+ "create-hmac": "^1.1.7",
+ "elliptic": "^6.4.0",
+ "nan": "^2.13.2"
+ },
+ "dependencies": {
+ "bn.js": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz",
+ "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==",
+ "dev": true
+ }
+ }
+ },
+ "tinycolor2": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz",
+ "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA=="
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "tmpl": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz",
+ "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=",
+ "dev": true
+ },
+ "to-arraybuffer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
+ "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=",
+ "dev": true
+ },
+ "to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
+ "dev": true
+ },
+ "toposort": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz",
+ "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
+ "dev": true
+ },
+ "tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "requires": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ }
+ },
+ "tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "treeify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
+ "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==",
+ "dev": true
+ },
+ "trezor-connect": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/trezor-connect/-/trezor-connect-7.0.5.tgz",
+ "integrity": "sha512-cGHcNuO/kGVF6b1mp5VB/RwXcXwqZJDPLp3opx7vM+BQ8xB4oDAUdL+T8aCKRbDv6HwP/wvGwoaok/+9kYOPfA==",
+ "requires": {
+ "@babel/runtime": "^7.3.1",
+ "events": "^3.0.0",
+ "whatwg-fetch": "^3.0.0"
+ }
+ },
+ "trim-repeated": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+ "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.2"
+ }
+ },
+ "truncate-utf8-bytes": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
+ "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
+ "dev": true,
+ "requires": {
+ "utf8-byte-length": "^1.0.1"
+ }
+ },
+ "tryer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz",
+ "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==",
+ "dev": true
+ },
+ "ts-custom-error": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.2.0.tgz",
+ "integrity": "sha512-cBvC2QjtvJ9JfWLvstVnI45Y46Y5dMxIaG1TDMGAD/R87hpvqFL+7LhvUDhnRCfOnx/xitollFWWvUKKKhbN0A=="
+ },
+ "ts-jest": {
+ "version": "25.5.1",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.5.1.tgz",
+ "integrity": "sha512-kHEUlZMK8fn8vkxDjwbHlxXRB9dHYpyzqKIGDNxbzs+Rz+ssNDSDNusEK8Fk/sDd4xE6iKoQLfFkFVaskmTJyw==",
+ "dev": true,
+ "requires": {
+ "bs-logger": "0.x",
+ "buffer-from": "1.x",
+ "fast-json-stable-stringify": "2.x",
+ "json5": "2.x",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "micromatch": "4.x",
+ "mkdirp": "0.x",
+ "semver": "6.x",
+ "yargs-parser": "18.x"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "dependencies": {
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "ts-loader": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz",
+ "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "enhanced-resolve": "^4.0.0",
+ "loader-utils": "^1.0.2",
+ "micromatch": "^4.0.0",
+ "semver": "^6.0.0"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "ts-mockito": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/ts-mockito/-/ts-mockito-2.6.1.tgz",
+ "integrity": "sha512-qU9m/oEBQrKq5hwfbJ7MgmVN5Gu6lFnIGWvpxSjrqq6YYEVv+RwVFWySbZMBgazsWqv6ctAyVBpo9TmAxnOEKw==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.5"
+ }
+ },
+ "ts-pnp": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz",
+ "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==",
+ "dev": true
+ },
+ "tsconfig": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz",
+ "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==",
+ "dev": true,
+ "requires": {
+ "@types/strip-bom": "^3.0.0",
+ "@types/strip-json-comments": "0.0.30",
+ "strip-bom": "^3.0.0",
+ "strip-json-comments": "^2.0.0"
+ }
+ },
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
+ "tslint": {
+ "version": "5.20.1",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz",
+ "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "builtin-modules": "^1.1.1",
+ "chalk": "^2.3.0",
+ "commander": "^2.12.1",
+ "diff": "^4.0.1",
+ "glob": "^7.1.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "resolve": "^1.3.2",
+ "semver": "^5.3.0",
+ "tslib": "^1.8.0",
+ "tsutils": "^2.29.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "tsutils": {
+ "version": "2.29.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+ "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ }
+ }
+ },
+ "tsutils": {
+ "version": "3.19.1",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.19.1.tgz",
+ "integrity": "sha512-GEdoBf5XI324lu7ycad7s6laADfnAqCw6wLGI+knxvw9vsIYBaJfYdmeCEG3FMMUiSm3OGgNb+m6utsWf5h9Vw==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.8.1"
+ }
+ },
+ "tty-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=",
+ "dev": true
+ },
+ "tunnel": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
+ "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==",
+ "dev": true,
+ "optional": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
+ "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
+ "dev": true
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dev": true,
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "requires": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "typeforce": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
+ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "3.9.7",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz",
+ "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==",
+ "dev": true
+ },
+ "uglify-js": {
+ "version": "3.4.10",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
+ "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==",
+ "dev": true,
+ "requires": {
+ "commander": "~2.19.0",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz",
+ "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "unicode-canonical-property-names-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==",
+ "dev": true
+ },
+ "unicode-match-property-ecmascript": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz",
+ "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==",
+ "dev": true,
+ "requires": {
+ "unicode-canonical-property-names-ecmascript": "^1.0.4",
+ "unicode-property-aliases-ecmascript": "^1.0.4"
+ }
+ },
+ "unicode-match-property-value-ecmascript": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz",
+ "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==",
+ "dev": true
+ },
+ "unicode-property-aliases-ecmascript": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz",
+ "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==",
+ "dev": true
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "uniqs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+ "dev": true
+ },
+ "unique-filename": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
+ "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
+ "dev": true,
+ "requires": {
+ "unique-slug": "^2.0.0"
+ }
+ },
+ "unique-slug": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
+ "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4"
+ }
+ },
+ "unique-string": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
+ "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
+ "dev": true,
+ "requires": {
+ "crypto-random-string": "^2.0.0"
+ }
+ },
+ "universalify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
+ "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "unquote": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
+ "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ }
+ }
+ },
+ "unused-filename": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/unused-filename/-/unused-filename-2.1.0.tgz",
+ "integrity": "sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==",
+ "requires": {
+ "modify-filename": "^1.1.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true
+ },
+ "update-notifier": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-4.1.3.tgz",
+ "integrity": "sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==",
+ "dev": true,
+ "requires": {
+ "boxen": "^4.2.0",
+ "chalk": "^3.0.0",
+ "configstore": "^5.0.1",
+ "has-yarn": "^2.1.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.3.1",
+ "is-npm": "^4.0.0",
+ "is-yarn-global": "^0.3.0",
+ "latest-version": "^5.0.0",
+ "pupa": "^2.0.1",
+ "semver-diff": "^3.1.1",
+ "xdg-basedir": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
+ "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "ci-info": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
+ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "upper-case": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
+ "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=",
+ "dev": true
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "url-loader": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz",
+ "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==",
+ "dev": true,
+ "requires": {
+ "loader-utils": "^1.2.3",
+ "mime": "^2.4.4",
+ "schema-utils": "^2.5.0"
+ }
+ },
+ "url-parse": {
+ "version": "1.4.7",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
+ "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
+ "dev": true,
+ "requires": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "requires": {
+ "prepend-http": "^2.0.0"
+ },
+ "dependencies": {
+ "prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true
+ }
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "utf-8-validate": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.4.tgz",
+ "integrity": "sha512-MEF05cPSq3AwJ2C7B7sHAA6i53vONoZbMGX8My5auEVm6W+dJ2Jd/TZPyGJ5CH42V2XtbI5FD28HeHeqlPzZ3Q==",
+ "dev": true,
+ "requires": {
+ "node-gyp-build": "^4.2.0"
+ }
+ },
+ "utf8": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
+ "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ=="
+ },
+ "utf8-byte-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
+ "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=",
+ "dev": true
+ },
+ "util": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
+ "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "2.0.3"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
+ "dev": true
+ }
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "util.promisify": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.1.tgz",
+ "integrity": "sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==",
+ "dev": true,
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "for-each": "^0.3.3",
+ "has-symbols": "^1.0.1",
+ "object.getownpropertydescriptors": "^2.1.1"
+ }
+ },
+ "utila": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz",
+ "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=",
+ "dev": true
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
+ "dev": true
+ },
+ "uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
+ },
+ "v-click-outside-x": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/v-click-outside-x/-/v-click-outside-x-3.7.1.tgz",
+ "integrity": "sha512-WmUgmcIXr9clVpm1AYS/FgHtcDicfnfoxgQCNg4O6vfk9GVnxA0vSqO321ogUo0b7czYTidj7fQENvWFMWOkUg=="
+ },
+ "v8-compile-cache": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
+ "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
+ "dev": true
+ },
+ "v8-to-istanbul": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz",
+ "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0",
+ "source-map": "^0.7.3"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
+ "dev": true
+ }
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "dev": true
+ },
+ "vee-validate": {
+ "version": "3.4.5",
+ "resolved": "https://registry.npmjs.org/vee-validate/-/vee-validate-3.4.5.tgz",
+ "integrity": "sha512-ZEcLqOAZzSkMhDvPcTx0xcwVOijFnMW9J+BA20j+rDmo24T8RCCqVQyRwwrDrcWJZV2dRYl/yYNa2GB6UCoBvg=="
+ },
+ "vendors": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz",
+ "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "view-design": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/view-design/-/view-design-4.4.0.tgz",
+ "integrity": "sha512-2+xbda6/USUm9Pn+D25NPsIBg7XVhkFC90Ycs0GcFQ4AHZ1QRwDGOj0PGA3eeL4yuVpigdDfmwmNJAoczYXlPA==",
+ "requires": {
+ "async-validator": "^3.3.0",
+ "deepmerge": "^2.2.1",
+ "element-resize-detector": "^1.2.0",
+ "js-calendar": "^1.2.3",
+ "lodash.throttle": "^4.1.1",
+ "popper.js": "^1.14.6",
+ "tinycolor2": "^1.4.1",
+ "v-click-outside-x": "^3.7.1"
+ }
+ },
+ "vm-browserify": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
+ "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==",
+ "dev": true
+ },
+ "vue": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz",
+ "integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg=="
+ },
+ "vue-class-component": {
+ "version": "7.2.6",
+ "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-7.2.6.tgz",
+ "integrity": "sha512-+eaQXVrAm/LldalI272PpDe3+i4mPis0ORiMYxF6Ae4hyuCh15W8Idet7wPUEs4N4YptgFHGys4UrgNQOMyO6w=="
+ },
+ "vue-eslint-parser": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.3.0.tgz",
+ "integrity": "sha512-n5PJKZbyspD0+8LnaZgpEvNCrjQx1DyDHw8JdWwoxhhC+yRip4TAvSDpXGf9SWX6b0umeB5aR61gwUo6NVvFxw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "eslint-scope": "^5.0.0",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.2.1",
+ "esquery": "^1.0.1",
+ "lodash": "^4.17.15"
+ }
+ },
+ "vue-hot-reload-api": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz",
+ "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
+ "dev": true
+ },
+ "vue-i18n": {
+ "version": "8.22.3",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.22.3.tgz",
+ "integrity": "sha512-Vhyx7sZEmmW/aZLkzSlXei08Rv3hTondx4J9wbOjnThocTIK1QiXV6QRdT4BTnhT24JixDSf6kGkxqCXSaJ3Jw=="
+ },
+ "vue-infinite-scroll": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/vue-infinite-scroll/-/vue-infinite-scroll-2.0.2.tgz",
+ "integrity": "sha512-n+YghR059YmciANGJh9SsNWRi1YZEBVlODtmnb/12zI+4R72QZSWd+EuZ5mW6auEo/yaJXgxzwsuhvALVnm73A=="
+ },
+ "vue-jest": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/vue-jest/-/vue-jest-3.0.7.tgz",
+ "integrity": "sha512-PIOxFM+wsBMry26ZpfBvUQ/DGH2hvp5khDQ1n51g3bN0TwFwTy4J85XVfxTRMukqHji/GnAoGUnlZ5Ao73K62w==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.26.0",
+ "chalk": "^2.1.0",
+ "deasync": "^0.1.15",
+ "extract-from-css": "^0.4.4",
+ "find-babel-config": "^1.1.0",
+ "js-beautify": "^1.6.14",
+ "node-cache": "^4.1.1",
+ "object-assign": "^4.1.1",
+ "source-map": "^0.5.6",
+ "tsconfig": "^7.0.0",
+ "vue-template-es2015-compiler": "^1.6.0"
+ }
+ },
+ "vue-loader": {
+ "version": "15.9.6",
+ "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.6.tgz",
+ "integrity": "sha512-j0cqiLzwbeImIC6nVIby2o/ABAWhlppyL/m5oJ67R5MloP0hj/DtFgb0Zmq3J9CG7AJ+AXIvHVnJAPBvrLyuDg==",
+ "dev": true,
+ "requires": {
+ "@vue/component-compiler-utils": "^3.1.0",
+ "hash-sum": "^1.0.2",
+ "loader-utils": "^1.1.0",
+ "vue-hot-reload-api": "^2.3.0",
+ "vue-style-loader": "^4.1.0"
+ },
+ "dependencies": {
+ "hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+ "dev": true
+ }
+ }
+ },
+ "vue-moment": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/vue-moment/-/vue-moment-4.1.0.tgz",
+ "integrity": "sha512-Gzisqpg82ItlrUyiD9d0Kfru+JorW2o4mQOH06lEDZNgxci0tv/fua1Hl0bo4DozDV2JK1r52Atn/8QVCu8qQw==",
+ "requires": {
+ "moment": "^2.19.2"
+ }
+ },
+ "vue-number-animation": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/vue-number-animation/-/vue-number-animation-1.0.5.tgz",
+ "integrity": "sha1-R7+WXwMmvlgrZAJ6yoOXCj7NX8Q=",
+ "requires": {
+ "gsap": "^2.0.1"
+ }
+ },
+ "vue-pdf": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/vue-pdf/-/vue-pdf-4.2.0.tgz",
+ "integrity": "sha512-GpAbZfM48Hom1R8f4XL5ZzoVBLlbyy+4z0VYmTQORVOSieVIIu+XtnNl0RY6EXg60Qni6T6nIgrmsCcCkWv39A==",
+ "requires": {
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
+ "loader-utils": "^1.4.0",
+ "pdfjs-dist": "^2.5.207",
+ "raw-loader": "^4.0.1",
+ "vue-resize-sensor": "^2.0.0",
+ "worker-loader": "^2.0.0"
+ }
+ },
+ "vue-property-decorator": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz",
+ "integrity": "sha512-O6OUN2OMsYTGPvgFtXeBU3jPnX5ffQ9V4I1WfxFQ6dqz6cOUbR3Usou7kgFpfiXDvV7dJQSFcJ5yUPgOtPPm1Q==",
+ "requires": {
+ "vue-class-component": "^7.1.0"
+ }
+ },
+ "vue-qrcode-reader": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/vue-qrcode-reader/-/vue-qrcode-reader-3.0.0.tgz",
+ "integrity": "sha512-44TT0PQxMOBtSiJg+8/lM9jXGIBEtp2U3sy642uv13IfKquwEv1UtNyof2y8lILsRX7cn7xt0XkUahIHWyEXAQ==",
+ "requires": {
+ "barcode-detector": "^0.5.0",
+ "callforth": "^0.3.1",
+ "core-js": "^3.6.5",
+ "vue": "^2.6.11",
+ "webrtc-adapter": "7.7.0"
+ }
+ },
+ "vue-resize-sensor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/vue-resize-sensor/-/vue-resize-sensor-2.0.0.tgz",
+ "integrity": "sha512-W+y2EAI/BxS4Vlcca9scQv8ifeBFck56DRtSwWJ2H4Cw1GLNUYxiZxUHHkuzuI5JPW/cYtL1bPO5xPyEXx4LmQ=="
+ },
+ "vue-responsive-video-background-player": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/vue-responsive-video-background-player/-/vue-responsive-video-background-player-1.2.2.tgz",
+ "integrity": "sha512-noe0ElSJyF15vtAATXq1BgyqDBtw2UZMO5a/+9iHK3OwlNE7yiCtH29gKFKPrbffoZ/g28YwXB7XbH0IoYbshA=="
+ },
+ "vue-router": {
+ "version": "3.4.9",
+ "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.4.9.tgz",
+ "integrity": "sha512-CGAKWN44RqXW06oC+u4mPgHLQQi2t6vLD/JbGRDAXm0YpMv0bgpKuU5bBd7AvMgfTz9kXVRIWKHqRwGEb8xFkA=="
+ },
+ "vue-rx": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/vue-rx/-/vue-rx-6.2.0.tgz",
+ "integrity": "sha512-tpKUcqS5IUYS+HsdbR5TlE5LL9PK4zwlplEtmMeydnbqaUTa9ciLMplJXAtFSiQw1vuURoyEJmCXqMxaVEIloQ=="
+ },
+ "vue-style-loader": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
+ "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==",
+ "dev": true,
+ "requires": {
+ "hash-sum": "^1.0.2",
+ "loader-utils": "^1.0.2"
+ },
+ "dependencies": {
+ "hash-sum": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
+ "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=",
+ "dev": true
+ }
+ }
+ },
+ "vue-template-compiler": {
+ "version": "2.6.12",
+ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
+ "integrity": "sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==",
+ "dev": true,
+ "requires": {
+ "de-indent": "^1.0.2",
+ "he": "^1.1.0"
+ }
+ },
+ "vue-template-es2015-compiler": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
+ "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
+ "dev": true
+ },
+ "vue-toastification": {
+ "version": "1.7.11",
+ "resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-1.7.11.tgz",
+ "integrity": "sha512-CT/DYttb/VtWDNdhJG0BskLVfveZq5rGOgO/u3qTX+RPQQzX0WSai8VVxxUuvR8UpxfSGPS+JQleR33bo3Vadg=="
+ },
+ "vuedraggable": {
+ "version": "2.24.3",
+ "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
+ "integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
+ "requires": {
+ "sortablejs": "1.10.2"
+ }
+ },
+ "vuex": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.0.tgz",
+ "integrity": "sha512-W74OO2vCJPs9/YjNjW8lLbj+jzT24waTo2KShI8jLvJW8OaIkgb3wuAMA7D+ZiUxDOx3ubwSZTaJBip9G8a3aQ=="
+ },
+ "w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "dev": true,
+ "requires": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "w3c-xmlserializer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz",
+ "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==",
+ "dev": true,
+ "requires": {
+ "domexception": "^1.0.1",
+ "webidl-conversions": "^4.0.2",
+ "xml-name-validator": "^3.0.0"
+ }
+ },
+ "walkdir": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
+ "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
+ "dev": true
+ },
+ "walker": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz",
+ "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=",
+ "dev": true,
+ "requires": {
+ "makeerror": "1.0.x"
+ }
+ },
+ "watchpack": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
+ "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==",
+ "dev": true,
+ "requires": {
+ "chokidar": "^3.4.1",
+ "graceful-fs": "^4.1.2",
+ "neo-async": "^2.5.0",
+ "watchpack-chokidar2": "^2.0.1"
+ }
+ },
+ "watchpack-chokidar2": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz",
+ "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chokidar": "^2.1.8"
+ },
+ "dependencies": {
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true,
+ "optional": true
+ },
+ "chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "fsevents": "^1.2.7",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ }
+ },
+ "fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ }
+ }
+ }
+ },
+ "wbuf": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
+ "dev": true,
+ "requires": {
+ "minimalistic-assert": "^1.0.0"
+ }
+ },
+ "wcwidth": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
+ "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
+ "dev": true,
+ "requires": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ },
+ "webpack": {
+ "version": "4.46.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz",
+ "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==",
+ "dev": true,
+ "requires": {
+ "@webassemblyjs/ast": "1.9.0",
+ "@webassemblyjs/helper-module-context": "1.9.0",
+ "@webassemblyjs/wasm-edit": "1.9.0",
+ "@webassemblyjs/wasm-parser": "1.9.0",
+ "acorn": "^6.4.1",
+ "ajv": "^6.10.2",
+ "ajv-keywords": "^3.4.1",
+ "chrome-trace-event": "^1.0.2",
+ "enhanced-resolve": "^4.5.0",
+ "eslint-scope": "^4.0.3",
+ "json-parse-better-errors": "^1.0.2",
+ "loader-runner": "^2.4.0",
+ "loader-utils": "^1.2.3",
+ "memory-fs": "^0.4.1",
+ "micromatch": "^3.1.10",
+ "mkdirp": "^0.5.3",
+ "neo-async": "^2.6.1",
+ "node-libs-browser": "^2.2.1",
+ "schema-utils": "^1.0.0",
+ "tapable": "^1.1.3",
+ "terser-webpack-plugin": "^1.4.3",
+ "watchpack": "^1.7.4",
+ "webpack-sources": "^1.4.1"
+ },
+ "dependencies": {
+ "eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ }
+ }
+ },
+ "webpack-bundle-analyzer": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz",
+ "integrity": "sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1",
+ "bfj": "^6.1.1",
+ "chalk": "^2.4.1",
+ "commander": "^2.18.0",
+ "ejs": "^2.6.1",
+ "express": "^4.16.3",
+ "filesize": "^3.6.1",
+ "gzip-size": "^5.0.0",
+ "lodash": "^4.17.19",
+ "mkdirp": "^0.5.1",
+ "opener": "^1.5.1",
+ "ws": "^6.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "ws": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+ },
+ "webpack-chain": {
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz",
+ "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==",
+ "dev": true,
+ "requires": {
+ "deepmerge": "^1.5.2",
+ "javascript-stringify": "^2.0.1"
+ },
+ "dependencies": {
+ "deepmerge": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
+ "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
+ "dev": true
+ }
+ }
+ },
+ "webpack-dev-middleware": {
+ "version": "3.7.3",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz",
+ "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==",
+ "dev": true,
+ "requires": {
+ "memory-fs": "^0.4.1",
+ "mime": "^2.4.4",
+ "mkdirp": "^0.5.1",
+ "range-parser": "^1.2.1",
+ "webpack-log": "^2.0.0"
+ }
+ },
+ "webpack-dev-server": {
+ "version": "3.11.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz",
+ "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==",
+ "dev": true,
+ "requires": {
+ "ansi-html": "0.0.7",
+ "bonjour": "^3.5.0",
+ "chokidar": "^2.1.8",
+ "compression": "^1.7.4",
+ "connect-history-api-fallback": "^1.6.0",
+ "debug": "^4.1.1",
+ "del": "^4.1.1",
+ "express": "^4.17.1",
+ "html-entities": "^1.3.1",
+ "http-proxy-middleware": "0.19.1",
+ "import-local": "^2.0.0",
+ "internal-ip": "^4.3.0",
+ "ip": "^1.1.5",
+ "is-absolute-url": "^3.0.3",
+ "killable": "^1.0.1",
+ "loglevel": "^1.6.8",
+ "opn": "^5.5.0",
+ "p-retry": "^3.0.1",
+ "portfinder": "^1.0.26",
+ "schema-utils": "^1.0.0",
+ "selfsigned": "^1.10.8",
+ "semver": "^6.3.0",
+ "serve-index": "^1.9.1",
+ "sockjs": "^0.3.21",
+ "sockjs-client": "^1.5.0",
+ "spdy": "^4.0.2",
+ "strip-ansi": "^3.0.1",
+ "supports-color": "^6.1.0",
+ "url": "^0.11.0",
+ "webpack-dev-middleware": "^3.7.2",
+ "webpack-log": "^2.0.0",
+ "ws": "^6.2.1",
+ "yargs": "^13.3.2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ },
+ "dependencies": {
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ }
+ }
+ },
+ "binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true
+ },
+ "chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "fsevents": "^1.2.7",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ }
+ },
+ "fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "is-absolute-url": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz",
+ "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==",
+ "dev": true
+ },
+ "is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "schema-utils": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz",
+ "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-errors": "^1.0.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "ws": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz",
+ "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+ },
+ "webpack-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
+ "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^3.0.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "webpack-merge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz",
+ "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15"
+ }
+ },
+ "webpack-sources": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz",
+ "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==",
+ "dev": true,
+ "requires": {
+ "source-list-map": "^2.0.0",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ }
+ }
+ },
+ "webrtc-adapter": {
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/webrtc-adapter/-/webrtc-adapter-7.7.0.tgz",
+ "integrity": "sha512-7Bp9OBnx642oJRkom1tNAbeJjUadAq2rh5xLL9YXPw5hVyt2h4hHr5bcoPYDs1stp/mZHSPSQA34YISdnr0DBQ==",
+ "requires": {
+ "rtcpeerconnection-shim": "^1.2.15",
+ "sdp": "^2.12.0"
+ }
+ },
+ "websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "requires": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ }
+ },
+ "websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true
+ },
+ "whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "whatwg-fetch": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz",
+ "integrity": "sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A=="
+ },
+ "whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+ "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "which-pm-runs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "widest-line": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+ "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.0.0"
+ },
+ "dependencies": {
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ }
+ }
+ }
+ },
+ "wif": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
+ "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=",
+ "dev": true,
+ "requires": {
+ "bs58check": "<3.0.0"
+ }
+ },
+ "word-wrap": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
+ "dev": true
+ },
+ "worker-farm": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz",
+ "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+ "dev": true,
+ "requires": {
+ "errno": "~0.1.7"
+ }
+ },
+ "worker-loader": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/worker-loader/-/worker-loader-2.0.0.tgz",
+ "integrity": "sha512-tnvNp4K3KQOpfRnD20m8xltE3eWh89Ye+5oj7wXEEHKac1P4oZ6p9oTj8/8ExqoSBnk9nu5Pr4nKfQ1hn2APJw==",
+ "requires": {
+ "loader-utils": "^1.0.0",
+ "schema-utils": "^0.4.0"
+ },
+ "dependencies": {
+ "schema-utils": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz",
+ "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==",
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ }
+ }
+ },
+ "worker-rpc": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz",
+ "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==",
+ "dev": true,
+ "requires": {
+ "microevent.ts": "~0.1.1"
+ }
+ },
+ "wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "write-file-atomic": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz",
+ "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ws": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+ "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "xdg-basedir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
+ "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
+ "dev": true
+ },
+ "xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "xml2js": {
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz",
+ "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~11.0.0"
+ }
+ },
+ "xmlbuilder": {
+ "version": "11.0.1",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
+ "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
+ },
+ "xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true
+ },
+ "xmldom": {
+ "version": "0.1.31",
+ "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
+ "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
+ "dev": true
+ },
+ "xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true
+ },
+ "y18n": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz",
+ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "dev": true,
+ "optional": true
+ },
+ "yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^3.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.0.0"
+ }
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
+ "dev": true,
+ "requires": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "yorkie": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz",
+ "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==",
+ "dev": true,
+ "requires": {
+ "execa": "^0.8.0",
+ "is-ci": "^1.0.10",
+ "normalize-path": "^1.0.0",
+ "strip-indent": "^2.0.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "execa": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
+ "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "normalize-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
+ "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ }
+ }
+ },
+ "zip-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
+ "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
+ "dev": true,
+ "requires": {
+ "archiver-utils": "^1.3.0",
+ "compress-commons": "^1.2.0",
+ "lodash": "^4.8.0",
+ "readable-stream": "^2.0.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..5534746
--- /dev/null
+++ b/package.json
@@ -0,0 +1,209 @@
+{
+ "name": "dhealth-wallet",
+ "description": "dHealth Wallet",
+ "homepage": "https://github.com/dhealthproject/dhealth-wallet",
+ "version": "1.0.0",
+ "author": {
+ "name": "Using Blockchain Ltd",
+ "email": "info@ubc.digital",
+ "url": "https://using-blockchain.org"
+ },
+ "contributors": [
+ {
+ "name": "Grégory Saive",
+ "email": "greg@ubc.digital",
+ "url": "https://ubc.digital"
+ },
+ {
+ "name": "NEM Group",
+ "email": "support@nem.group"
+ }
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/dhealthproject/dhealth-wallet.git"
+ },
+ "license": "Apache-2.0",
+ "scripts": {
+ "start": "npm run node-hid:prebuild-install && electron .",
+ "test": "vue-cli-service test:unit",
+ "dev": "vue-cli-service serve ",
+ "build": "npm run build:web",
+ "build:web": "rimraf dist && mkdir dist && tsc && vue-cli-service build",
+ "release": "npm run build && npm run release:all",
+ "release:all": "npm run release:win && npm run release:lin && npm run release:mac && npm run release:zip",
+ "release:mac": "npm run node-hid:prebuild-install:mac && electron-builder --mac",
+ "release:win": "npm run node-hid:prebuild-install:win && electron-builder --win",
+ "release:lin": "npm run node-hid:prebuild-install:lin && electron-builder --linux deb snap tar.xz",
+ "release:zip": "npm-build-zip --source=dist --destination=release --name=all",
+ "lint": "npm run prettier && npm run eslint",
+ "lint:fix": "npm run prettier:fix && npm run eslint:fix",
+ "eslint": "eslint src/ --ext .ts && eslint src/ --ext .vue && eslint __tests__/ --ext .ts && eslint __mocks__/ --ext .ts",
+ "eslint:fix": "eslint src/ --ext .ts --fix && eslint src/ --ext .vue --fix && eslint __tests__/ --ext .ts --fix && eslint __mocks__/ --ext .ts --fix",
+ "prettier": "prettier --check ./src ./__tests__ ./__mocks__",
+ "prettier:fix": "prettier --write ./src ./__tests__ ./__mocks__",
+ "electron-rebuild": "$(npm bin)/electron-rebuild",
+ "node-hid:prebuild-install": "cd ./node_modules/node-hid && npm run install && cd ../..",
+ "node-hid:prebuild-install:mac": "export npm_config_platform=darwin && npm run node-hid:prebuild-install",
+ "node-hid:prebuild-install:win": "export npm_config_platform=win32 && npm run node-hid:prebuild-install",
+ "node-hid:prebuild-install:lin": "export npm_config_platform=linux && npm run node-hid:prebuild-install",
+ "version": "echo $npm_package_version"
+ },
+ "dependencies": {
+ "@fortawesome/fontawesome-svg-core": "^1.2.34",
+ "@fortawesome/free-solid-svg-icons": "^5.15.2",
+ "@fortawesome/vue-fontawesome": "^2.0.2",
+ "@js-joda/core": "^3.2.0",
+ "@ledgerhq/hw-transport-node-hid-noevents": "^5.41.0",
+ "@ledgerhq/hw-transport-webusb": "^5.41.0",
+ "animate.css": "^3.7.2",
+ "await-lock": "^2.0.1",
+ "axios": "0.21.1",
+ "bip32-path": "^0.4.2",
+ "call-bind": "^1.0.2",
+ "decamelize": "^5.0.0",
+ "electron-context-menu": "^2.4.0",
+ "electron-localshortcut": "^3.2.1",
+ "file-saver": "^2.0.2",
+ "json2csv": "^5.0.1",
+ "lodash": "^4.17.20",
+ "request": "^2.88.0",
+ "rss-parser": "^3.7.3",
+ "rxjs": "^6.5.2",
+ "trezor-connect": "^7.0.5",
+ "utf8": "^3.0.0",
+ "vee-validate": "^3.2.3",
+ "view-design": "^4.0.0",
+ "vue": "^2.6.10",
+ "vue-class-component": "^7.0.2",
+ "vue-i18n": "^8.11.2",
+ "vue-infinite-scroll": "^2.0.2",
+ "vue-moment": "^4.1.0",
+ "vue-number-animation": "1.0.5",
+ "vue-pdf": "^4.2.0",
+ "vue-property-decorator": "^8.1.0",
+ "vue-qrcode-reader": "^3.0.0",
+ "vue-responsive-video-background-player": "^1.1.4",
+ "vue-router": "^3.1.3",
+ "vue-rx": "^6.2.0",
+ "vue-toastification": "^1.7.11",
+ "vuedraggable": "^2.23.2",
+ "vuex": "^3.0.1"
+ },
+ "devDependencies": {
+ "@babel/compat-data": "^7.9.6",
+ "@babel/core": "^7.7.2",
+ "@types/file-saver": "^2.0.1",
+ "@types/jest": "^23.3.1",
+ "@types/json2csv": "^5.0.1",
+ "@types/lodash": "^4.14.168",
+ "@types/node": "^9.6.50",
+ "@types/request": "^2.47.1",
+ "@types/vue-moment": "^4.0.0",
+ "@typescript-eslint/eslint-plugin": "^2.15.0",
+ "@typescript-eslint/parser": "^2.15.0",
+ "@vue/cli-plugin-babel": "^4.0.5",
+ "@vue/cli-plugin-typescript": "^4.3.0",
+ "@vue/cli-plugin-unit-jest": "^4.0.5",
+ "@vue/cli-service": "^4.0.5",
+ "@vue/eslint-config-typescript": "^5.0.1",
+ "@vue/test-utils": "^1.0.0-beta.29",
+ "babel-core": "7.0.0-bridge.0",
+ "babel-jest": "^25.2.6",
+ "babel-plugin-syntax-dynamic-import": "^6.18.0",
+ "babel-preset-env": "^1.7.0",
+ "bufferutil": "^4.0.1",
+ "cross-env": "^5.1.1",
+ "electron": "11.1.0",
+ "electron-builder": "22.9.1",
+ "electron-notarize": "1.0.0",
+ "electron-packager": "15.2.0",
+ "electron-rebuild": "^2.3.4",
+ "electron-updater": "4.3.5",
+ "eslint": "^6.8.0",
+ "eslint-config-prettier": "^6.11.0",
+ "eslint-plugin-prettier": "^3.1.3",
+ "eslint-plugin-vue": "^6.1.2",
+ "flush-promises": "^1.0.2",
+ "google-fonts-webpack-plugin": "^0.4.4",
+ "identity-obj-proxy": "^3.0.0",
+ "jest": "^25.2.6",
+ "less": "^3.0.4",
+ "less-loader": "^4.1.0",
+ "moment-timezone": "^0.5.26",
+ "node-pre-gyp": "^0.13.0",
+ "npm-build-zip": "^1.0.2",
+ "postcss-import": "^12.0.1",
+ "postcss-pxtorem": "^4.0.1",
+ "prettier": "2.0.5",
+ "rimraf": "^3.0.2",
+ "symbol-address-book": "^1.0.0",
+ "symbol-hd-wallets": "0.14.1-alpha-202103051108",
+ "symbol-paper-wallets": "^1.0.2",
+ "symbol-qr-library": "0.14.1-alpha-202103081047",
+ "symbol-sdk": "1.0.0",
+ "symbol-uri-scheme": "0.6.0",
+ "ts-jest": "^25.3.0",
+ "ts-mockito": "^2.6.1",
+ "typescript": "^3.7.2",
+ "utf-8-validate": "^5.0.2",
+ "vue-jest": "^3.0.5",
+ "vue-template-compiler": "^2.6.10"
+ },
+ "resolutions": {
+ "@babel/preset-env": "7.5.5"
+ },
+ "main": "./public/build.js",
+ "build": {
+ "appId": "network.dhealth.wallet",
+ "extends": null,
+ "copyright": "Copyright © 2021 dHealth Network",
+ "productName": "dHealth Wallet",
+ "artifactName": "${name}-${os}-${arch}-${version}.${ext}",
+ "icon": "./dist/assets/icons/Icon.icns",
+ "files": [
+ "dist/**/*",
+ "package.json",
+ "./public/build.js",
+ "./public/preload.js"
+ ],
+ "directories": {
+ "buildResources": "assets",
+ "output": "release"
+ },
+ "npmRebuild": false
+ },
+ "mac": {
+ "category": "public.app-category.finance",
+ "target": "dmg",
+ "icon": "./assets/icons/Icon.icns",
+ "hardenedRuntime": true,
+ "gatekeeperAssess": false,
+ "asarUnpack": [
+ "**/*.node"
+ ],
+ "entitlements": "./electron/entitlements.mac.plist",
+ "extendInfo": {
+ "NSCameraUsageDescription": "This app requires camera access to scan qrcodes."
+ }
+ },
+ "dmg": {
+ "window": {
+ "x": 100,
+ "y": 100,
+ "width": 500,
+ "height": 400
+ }
+ },
+ "nsis": {
+ "oneClick": false,
+ "perMachine": false,
+ "allowToChangeInstallationDirectory": true,
+ "publisherName": "dHealth Network",
+ "installerIcon": "./assets/icons/favicon.dhealth.ico"
+ },
+ "linux": {
+ "category": "Finance",
+ "icon": "./assets/icons/Icon.icns"
+ }
+}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 0000000..87a3118
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,12 @@
+
+module.exports = {
+ plugins: {
+ "postcss-import": {},
+ "autoprefixer": {},
+ "postcss-pxtorem": {
+ "rootValue": 100,
+ "propList": ["*"],
+ "selectorBlackList": ["mint-"],
+ }
+ }
+}
\ No newline at end of file
diff --git a/public/assets/icons/Icon.icns b/public/assets/icons/Icon.icns
new file mode 100644
index 0000000..6a998d3
Binary files /dev/null and b/public/assets/icons/Icon.icns differ
diff --git a/public/assets/icons/Info.plist b/public/assets/icons/Info.plist
new file mode 100644
index 0000000..aba9256
--- /dev/null
+++ b/public/assets/icons/Info.plist
@@ -0,0 +1,48 @@
+
+
+
+
+ BuildMachineOSBuild
+ 16F73
+ CFBundleDisplayName
+ dHealth Wallet
+ CFBundleExecutable
+ dhealth-wallet
+ CFBundleIconFile
+ electron.icns
+ CFBundleIdentifier
+ network.dhealth.wallet/string>
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ dHealth Wallet
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ 0.9.7
+ CFBundleVersion
+ 0.9.7
+ DTCompiler
+ com.apple.compilers.llvm.clang.1_0
+ DTSDKBuild
+ 10.12
+ DTSDKName
+ macosx10.12
+ DTXcode
+ 0833
+ DTXcodeBuild
+ 8E3004b
+ LSApplicationCategoryType
+ public.app-category.finance
+ LSMinimumSystemVersion
+ 10.10.0
+ NSHighResolutionCapable
+
+ NSMainNibFile
+ MainMenu
+ NSPrincipalClass
+ AtomApplication
+ NSSupportsAutomaticGraphicsSwitching
+
+
+
\ No newline at end of file
diff --git a/public/assets/icons/favicon.dhealth.ico b/public/assets/icons/favicon.dhealth.ico
new file mode 100644
index 0000000..e7f05f8
Binary files /dev/null and b/public/assets/icons/favicon.dhealth.ico differ
diff --git a/public/assets/icons/favicon.dhealth.png b/public/assets/icons/favicon.dhealth.png
new file mode 100644
index 0000000..f978487
Binary files /dev/null and b/public/assets/icons/favicon.dhealth.png differ
diff --git a/public/assets/icons/favicon.symbol.ico b/public/assets/icons/favicon.symbol.ico
new file mode 100644
index 0000000..53bd829
Binary files /dev/null and b/public/assets/icons/favicon.symbol.ico differ
diff --git a/public/assets/icons/favicon.yourdlt.ico b/public/assets/icons/favicon.yourdlt.ico
new file mode 100644
index 0000000..de433eb
Binary files /dev/null and b/public/assets/icons/favicon.yourdlt.ico differ
diff --git a/public/assets/icons/favicon.yourdlt.png b/public/assets/icons/favicon.yourdlt.png
new file mode 100644
index 0000000..581f526
Binary files /dev/null and b/public/assets/icons/favicon.yourdlt.png differ
diff --git a/public/assets/icons/icons.iconset/Icon.icns b/public/assets/icons/icons.iconset/Icon.icns
new file mode 100644
index 0000000..6a998d3
Binary files /dev/null and b/public/assets/icons/icons.iconset/Icon.icns differ
diff --git a/public/assets/icons/icons.iconset/icon-512.png b/public/assets/icons/icons.iconset/icon-512.png
new file mode 100644
index 0000000..8a41abf
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon-512.png differ
diff --git a/public/assets/icons/icons.iconset/icon-bash b/public/assets/icons/icons.iconset/icon-bash
new file mode 100644
index 0000000..59e7af6
--- /dev/null
+++ b/public/assets/icons/icons.iconset/icon-bash
@@ -0,0 +1,25 @@
+sips -z 16 16 icon-512.png --out icon_16x16.png
+
+sips -z 32 32 icon-512.png --out icon_16x16@2x.png
+
+sips -z 32 32 icon-512.png --out icon_32x32.png
+
+sips -z 64 64 icon-512.png --out icon_32x32@2x.png
+
+sips -z 64 64 icon-512.png --out icon_64x64.png
+
+sips -z 128 128 icon-512.png --out icon_64x64@2x.png
+
+sips -z 128 128 icon-512.png --out icon_128x128.png
+
+sips -z 256 256 icon-512.png --out icon_128x128@2x.png
+
+sips -z 256 256 icon-512.png --out icon_256x256.png
+
+sips -z 512 512 icon-512.png --out icon_256x256@2x.png
+
+sips -z 512 512 icon-512.png --out icon_512x512.png
+
+sips -z 1024 1024 icon-512.png --out icon_512x512@2x.png
+
+iconutil -c icns ../icons.iconset -o Icon.icns
diff --git a/public/assets/icons/icons.iconset/icon_128x128.png b/public/assets/icons/icons.iconset/icon_128x128.png
new file mode 100644
index 0000000..cddaeee
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_128x128.png differ
diff --git a/public/assets/icons/icons.iconset/icon_128x128@2x.png b/public/assets/icons/icons.iconset/icon_128x128@2x.png
new file mode 100644
index 0000000..04fab7a
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_128x128@2x.png differ
diff --git a/public/assets/icons/icons.iconset/icon_16x16.png b/public/assets/icons/icons.iconset/icon_16x16.png
new file mode 100644
index 0000000..9c0aeee
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_16x16.png differ
diff --git a/public/assets/icons/icons.iconset/icon_16x16@2x.png b/public/assets/icons/icons.iconset/icon_16x16@2x.png
new file mode 100644
index 0000000..fc38e09
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_16x16@2x.png differ
diff --git a/public/assets/icons/icons.iconset/icon_256x256.png b/public/assets/icons/icons.iconset/icon_256x256.png
new file mode 100644
index 0000000..04fab7a
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_256x256.png differ
diff --git a/public/assets/icons/icons.iconset/icon_256x256@2x.png b/public/assets/icons/icons.iconset/icon_256x256@2x.png
new file mode 100644
index 0000000..8a41abf
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_256x256@2x.png differ
diff --git a/public/assets/icons/icons.iconset/icon_32x32.png b/public/assets/icons/icons.iconset/icon_32x32.png
new file mode 100644
index 0000000..fc38e09
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_32x32.png differ
diff --git a/public/assets/icons/icons.iconset/icon_32x32@2x.png b/public/assets/icons/icons.iconset/icon_32x32@2x.png
new file mode 100644
index 0000000..6ec7fc0
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_32x32@2x.png differ
diff --git a/public/assets/icons/icons.iconset/icon_512x512.png b/public/assets/icons/icons.iconset/icon_512x512.png
new file mode 100644
index 0000000..8a41abf
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_512x512.png differ
diff --git a/public/assets/icons/icons.iconset/icon_512x512@2x.png b/public/assets/icons/icons.iconset/icon_512x512@2x.png
new file mode 100644
index 0000000..bf7a6b1
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_512x512@2x.png differ
diff --git a/public/assets/icons/icons.iconset/icon_64x64.png b/public/assets/icons/icons.iconset/icon_64x64.png
new file mode 100644
index 0000000..6ec7fc0
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_64x64.png differ
diff --git a/public/assets/icons/icons.iconset/icon_64x64@2x.png b/public/assets/icons/icons.iconset/icon_64x64@2x.png
new file mode 100644
index 0000000..71fc5e1
Binary files /dev/null and b/public/assets/icons/icons.iconset/icon_64x64@2x.png differ
diff --git a/public/assets/logo.png b/public/assets/logo.png
new file mode 100644
index 0000000..cddaeee
Binary files /dev/null and b/public/assets/logo.png differ
diff --git a/public/build.js b/public/build.js
new file mode 100644
index 0000000..a74bd20
--- /dev/null
+++ b/public/build.js
@@ -0,0 +1,341 @@
+/* eslint-disable prettier/prettier */
+/* eslint-disable @typescript-eslint/no-var-requires */
+
+const path = require('path')
+const { app, BrowserWindow, shell, globalShortcut, Menu, ipcMain } = require('electron')
+const electron = require('electron')
+const name = electron.app.getName()
+const electronLocalshortcut = require('electron-localshortcut');
+const contextMenu = require('electron-context-menu');
+contextMenu({});
+
+// Set the path of the folder where the persisted data is stored
+electron.app.setPath('userData', path.join(electron.app.getPath('home'), '.dhealth-wallet'))
+
+const iconUrlPath =
+ process.platform === 'darwin' ? './dist/assets/logo.png' : `file://${__dirname}/../dist/assets/logo.png`
+const loadUrlPath = process.platform === 'darwin' ? './dist/index.html' : `file://${__dirname}/../dist/index.html`
+
+let mainWindow = null
+
+const template = [
+ {
+ label: 'Window',
+ role: 'window',
+ submenu: [
+ {
+ label: 'Minimize',
+ accelerator: 'CmdOrCtrl+M',
+ role: 'minimize',
+ },
+ {
+ label: 'Close',
+ accelerator: 'CmdOrCtrl+W',
+ role: 'close',
+ },
+ {
+ label: 'Toggle Full Screen',
+ accelerator: (function () {
+ if (process.platform === 'darwin') {
+ return 'Ctrl+Command+F'
+ }
+
+ return 'F11'
+ })(),
+ click: function (item, focusedWindow) {
+ if (focusedWindow) {
+ focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
+ }
+ },
+ },
+ {
+ label: 'Toggle Developer Tools',
+ accelerator: (function () {
+ if (process.platform === 'darwin') {
+ return 'Alt+Command+I'
+ }
+
+ return 'Ctrl+Shift+I'
+ })(),
+ click: function (item, focusedWindow) {
+ if (focusedWindow) {
+ focusedWindow.toggleDevTools()
+ }
+ },
+ },
+ ],
+ },
+ {
+ label: 'Edit',
+ role: 'edit',
+ submenu: [
+ {
+ label: 'Cut',
+ accelerator: 'CmdOrCtrl+X',
+ role: 'cut',
+ },
+ {
+ label: 'Copy',
+ accelerator: 'CmdOrCtrl+C',
+ role: 'copy',
+ },
+ {
+ label: 'Paste',
+ accelerator: 'CmdOrCtrl+V',
+ role: 'paste',
+ },
+ {
+ label: 'Select All',
+ accelerator: 'CmdOrCtrl+A',
+ role: 'selectAll',
+ },
+ ],
+ },
+ {
+ label: 'Help',
+ role: 'help',
+ submenu: [
+ {
+ label: 'Learn More',
+ click: function () {
+ electron.shell.openExternal('https://github.com/dhealthproject/dhealth-wallet')
+ },
+ },
+ {
+ label: 'About NEM',
+ click: function () {
+ electron.shell.openExternal('https://nem.io/')
+ },
+ },
+ {
+ label: 'About dHealth',
+ click: function () {
+ electron.shell.openExternal('https://dhealth.network/')
+ },
+ },
+ {
+ label: 'About YourDLT',
+ click: function () {
+ electron.shell.openExternal('https://docs.yourdlt.tools/')
+ },
+ },
+ {
+ label: 'About UBC Digital',
+ click: function () {
+ electron.shell.openExternal('https://ubc.digital')
+ },
+ },
+ ],
+ },
+]
+if (process.platform === 'darwin') {
+ template.unshift({
+ label: name,
+ submenu: [
+ {
+ label: `About ${name}`,
+ role: 'about',
+ },
+ {
+ type: 'separator',
+ },
+ {
+ label: 'Services',
+ role: 'services',
+ submenu: [],
+ },
+ {
+ type: 'separator',
+ },
+ {
+ label: `Hide ${name}`,
+ accelerator: 'Command+H',
+ role: 'hide',
+ },
+ {
+ label: 'Hide others',
+ accelerator: 'Command+Alt+H',
+ role: 'hideothers',
+ },
+ {
+ label: 'Show',
+ role: 'unhide',
+ },
+ {
+ type: 'separator',
+ },
+ {
+ label: 'Quit',
+ accelerator: 'Command+Q',
+ click: function () {
+ app.quit()
+ },
+ },
+ ],
+ })
+ if (process.mas) app.setName('·')
+ ipcMain.on('app', (event, arg) => {
+ switch (arg) {
+ case 'quit':
+ mainWindow.close()
+ break
+ case 'max':
+ if (mainWindow.isMaximized()) {
+ mainWindow.restore()
+ } else {
+ mainWindow.maximize()
+ }
+ break
+ case 'min':
+ mainWindow.minimize()
+ break
+ }
+ })
+}
+
+if (process.platform !== 'darwin') {
+ const gotTheLock = app.requestSingleInstanceLock()
+
+ if (!gotTheLock) {
+ app.quit()
+ } else {
+ app.on('second-instance', () => {
+ // Do not allow the creation of multiple instances
+ if (mainWindow) {
+ if (mainWindow.isMinimized()) mainWindow.restore()
+ mainWindow.focus()
+ }
+ })
+
+ app.on('ready', () => {
+ /** This function body is needed */
+ })
+ }
+
+ ipcMain.on('app', (event, arg) => {
+ switch (arg) {
+ case 'quit':
+ mainWindow.close()
+ break
+ case 'max':
+ mainWindow.maximize()
+ break
+ case 'unMaximize':
+ mainWindow.unmaximize()
+ break
+ case 'min':
+ mainWindow.minimize()
+ break
+ default:
+ mainWindow.unmaximize()
+ }
+ })
+}
+
+function initialize() {
+ function createMac() {
+ const size = require('electron').screen.getPrimaryDisplay().workAreaSize
+ const width = parseInt(size.width)
+ const widthTag = width * 0.3
+ let height = width * 0.45
+ if (width >= 1920) {
+ mainWindow = new BrowserWindow({
+ width: width - widthTag,
+ height: height,
+ autoHideMenuBar: false,
+ resizable: true,
+ webPreferences: {
+ nodeIntegration: false,
+ enableRemoteModule: false,
+ preload: path.resolve(__dirname, 'preload.js')
+ }
+ })
+ } else {
+ height = parseInt((1080 * size.width) / 1920 + 30)
+ mainWindow = new BrowserWindow({
+ width: width - 100,
+ height: height - 50,
+ autoHideMenuBar: false,
+ resizable: true,
+ webPreferences: {
+ nodeIntegration: false,
+ enableRemoteModule: false,
+ preload: path.resolve(__dirname, 'preload.js')
+ }
+ })
+ }
+ mainWindow.loadFile(loadUrlPath)
+ mainWindow.on('closed', function () {
+ mainWindow = null
+ })
+ const menu = Menu.buildFromTemplate(template)
+ Menu.setApplicationMenu(menu)
+ }
+
+ function createWindow() {
+ const size = electron.screen.getPrimaryDisplay().workAreaSize
+
+ const originWidth = size.width
+
+ let width = originWidth
+
+ if (originWidth > 1080) {
+ width = parseInt(1080 + (originWidth - 1080) * 0.5)
+ }
+ const height = parseInt(width / (1920 / 1080))
+
+ const windowOptions = {
+ minWidth: width,
+ minHeight: height,
+ width: width,
+ height: height,
+ title: app.getName(),
+ titleBarStyle: 'hiddenInset',
+ webPreferences: {
+ nodeIntegration: false,
+ enableRemoteModule: false,
+ preload: path.resolve(__dirname, 'preload.js')
+ },
+ resizable: true,
+ }
+ windowOptions.icon = iconUrlPath
+ mainWindow = new BrowserWindow(windowOptions)
+ mainWindow.setMenu(null)
+ mainWindow.loadURL(loadUrlPath)
+
+ mainWindow.once('ready-to-show', () => {
+ mainWindow.show()
+ })
+ mainWindow.on('closed', () => {
+ mainWindow = null
+ })
+ mainWindow.on('will-resize', (event) => {
+ event.preventDefault()
+ })
+ }
+
+ if (process.platform === 'darwin') {
+ app.on('ready', createMac)
+ } else {
+ app.on('ready', createWindow)
+ app.on('ready', function () {
+ electronLocalshortcut.register('CommandOrControl+R', function () {
+ mainWindow.reload();
+ })
+ })
+ }
+ app.on('window-all-closed', function () {
+ app.quit()
+ })
+ app.on('web-contents-created', (e, webContents) => {
+ webContents.on('new-window', (event, url) => {
+ event.preventDefault();
+
+ if (url.match(/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/g)) {
+ shell.openExternal(url)
+ }
+ })
+ })
+}
+
+initialize()
diff --git a/public/config/app.conf.js b/public/config/app.conf.js
new file mode 100644
index 0000000..6acfc69
--- /dev/null
+++ b/public/config/app.conf.js
@@ -0,0 +1 @@
+// Extension point to inject custom configuration in the window object
diff --git a/public/config/fees.conf.js b/public/config/fees.conf.js
new file mode 100644
index 0000000..42946d1
--- /dev/null
+++ b/public/config/fees.conf.js
@@ -0,0 +1 @@
+// Extension point to inject custom configuration in window object
diff --git a/public/config/network.conf.js b/public/config/network.conf.js
new file mode 100644
index 0000000..6acfc69
--- /dev/null
+++ b/public/config/network.conf.js
@@ -0,0 +1 @@
+// Extension point to inject custom configuration in the window object
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..e7f05f8
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..73d6b07
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+ dHealth Wallet
+
+
+
+ dHealth Wallet doesn't work without JavaScript enabled. Please enable it to continue.
+
+
+
+
+
+
+
+
+
+
diff --git a/public/preload.js b/public/preload.js
new file mode 100644
index 0000000..0885a02
--- /dev/null
+++ b/public/preload.js
@@ -0,0 +1,3 @@
+try {
+ window.TransportNodeHid = require('@ledgerhq/hw-transport-node-hid-noevents');
+} catch (e) {}
diff --git a/scripts/notarize.js b/scripts/notarize.js
new file mode 100644
index 0000000..2d7d688
--- /dev/null
+++ b/scripts/notarize.js
@@ -0,0 +1,18 @@
+// eslint-disable-next-line @typescript-eslint/no-var-requires
+const {notarize} = require('electron-notarize')
+
+exports.default = async function notarizing(context) {
+ const {electronPlatformName, appOutDir} = context
+
+ // Skip notarization when not on Mac OS.
+ if (electronPlatformName !== 'darwin') return
+
+ const appName = context.packager.appInfo.productFilename
+
+ return notarize({
+ appBundleId: 'network.dhealth.wallet',
+ appPath: `${appOutDir}/${appName}.app`,
+ appleApiKey: process.env.APPLE_API_KEY_ID,
+ appleApiIssuer: process.env.APPLE_API_KEY_ISSUER_ID,
+ })
+}
diff --git a/src/app/App.vue b/src/app/App.vue
new file mode 100644
index 0000000..43f496e
--- /dev/null
+++ b/src/app/App.vue
@@ -0,0 +1,24 @@
+
+
+
{{ $t('web_wallet_warning') }}
+
+ {{ $t('version') }}: {{ packageVersion }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/AppStore.ts b/src/app/AppStore.ts
new file mode 100644
index 0000000..121c05d
--- /dev/null
+++ b/src/app/AppStore.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import store from '@/store/index.ts';
+
+/// region app state store initializations
+export const AppStore = store;
+/// end-region app state store initializations
diff --git a/src/app/AppTs.ts b/src/app/AppTs.ts
new file mode 100644
index 0000000..c0bccf7
--- /dev/null
+++ b/src/app/AppTs.ts
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// child components
+// @ts-ignore
+import DisabledUiOverlay from '@/components/DisabledUiOverlay/DisabledUiOverlay.vue';
+// @ts-ignore
+import SpinnerLoading from '@/components/SpinnerLoading/SpinnerLoading.vue';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ hasLoadingOverlay: 'app/shouldShowLoadingOverlay',
+ currentProfile: 'profile/currentProfile',
+ }),
+ },
+ components: {
+ DisabledUiOverlay,
+ SpinnerLoading,
+ },
+})
+export class AppTs extends Vue {
+ /**
+ * Display the application version. This is injected in the app when built.
+ */
+ public packageVersion = process.env.PACKAGE_VERSION || '0';
+
+ /**
+ * Display the web wallet warning. This is injected in the app when built.
+ */
+ public web = process.env.WEB || false;
+ /**
+ * Currently active profile
+ * @see {Store.Profile}
+ * @var {string}
+ */
+ public currentProfile: string;
+
+ /**
+ * Whether a loading overlay must be displayed
+ * @see {Store.App}
+ * @var {boolean}
+ */
+ public hasLoadingOverlay: boolean;
+
+ /**
+ * Hook called when the app is started
+ * @return {void}
+ */
+ public created() {
+ this.initialize();
+ }
+
+ /**
+ * Hook called when the app is closed
+ * @return {void}
+ */
+ public destroyed() {
+ this.uninitialize();
+ }
+
+ /**
+ * Initialize the app store
+ * @see {Store.AppInfo}
+ */
+ protected initialize() {
+ this.$store.dispatch('initialize').catch((error) => console.log(error));
+ }
+
+ /**
+ * Uninitialize the app store
+ * @see {Store.AppInfo}
+ */
+ protected uninitialize() {
+ this.$store.dispatch('uninitialize');
+ }
+}
diff --git a/src/app/UIBootstrapper.ts b/src/app/UIBootstrapper.ts
new file mode 100644
index 0000000..e7c764d
--- /dev/null
+++ b/src/app/UIBootstrapper.ts
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import Vue from 'vue';
+import { Electron } from '@/core/utils/Electron';
+
+export class UIBootstrapper {
+ /**
+ * Bootstrap a Vue app instance
+ * @param {Vue} app
+ * @return {Vue}
+ */
+ public static configure(app: Vue): Vue {
+ /// region electron fixes
+ Electron.htmlRem();
+ /// end-region electron fixes
+
+ /// region vue directives
+ Vue.directive('focus', {
+ inserted: function (el) {
+ Vue.nextTick(() => el.focus());
+ },
+ });
+ Vue.directive('click-focus', {
+ inserted: function (el) {
+ el.addEventListener('click', function () {
+ el.querySelector('input').focus();
+ });
+ },
+ });
+ Vue.directive('auto-scroll', {
+ componentUpdated: function (el, { value }) {
+ if (value && value.length) {
+ const className = value.charAt(0) === '.' ? value : '.' + value;
+ if (el.querySelector(className)) {
+ const offsetTop = (el.querySelector(className) as HTMLElement).offsetTop;
+ el.scrollTo(0, offsetTop);
+ }
+ }
+ },
+ });
+ /// end-region vue directives
+
+ return app;
+ }
+}
diff --git a/src/components/AccountActions/AccountActions.less b/src/components/AccountActions/AccountActions.less
new file mode 100644
index 0000000..a8b3fbd
--- /dev/null
+++ b/src/components/AccountActions/AccountActions.less
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.harvesting-options-container {
+ display: grid;
+ grid-template-rows: 2.6rem 2.6rem 2.6rem;
+ grid-template-columns: 100%;
+
+ .single-harvesting-option {
+ display: grid;
+ grid-template-columns: 8rem 4.2rem;
+ padding-bottom: 0.2rem;
+
+ .harvesting-explain {
+ padding: 0.2rem;
+ padding-left: 0.4rem;
+ font-size: @normalFont;
+
+ .subtitle {
+ color: @primary;
+ font-weight: @boldest;
+ }
+
+ p {
+ padding-top: 0.05rem;
+ text-align: justify;
+ }
+ }
+
+ .harvesting-options {
+ height: 2.2rem;
+ min-width: 3rem;
+ margin: 0.15rem 0;
+ display: flex;
+ justify-content: space-around;
+
+ .harvesting-item:hover {
+ background: @grayLightest;
+ }
+
+ .harvesting-item.danger:hover {
+ background: @redLightest;
+ }
+
+ .harvesting-item {
+ text-align: center;
+ background: @white;
+ box-shadow: 0 2px 10px 0 @boxShadow;
+ border-radius: 4px;
+ margin-right: 0.3rem;
+ cursor: pointer;
+
+ .img-box {
+ img {
+ width: 68px;
+ /*border: 1px dashed @black;*/
+ margin: 30px auto 15px;
+ }
+ }
+
+ .access-name {
+ font-size: 28px;
+ font-weight: 600;
+ color: @black;
+ line-height: 24px;
+ // margin-top: -15px;
+ }
+
+ .access-info {
+ margin: 20px auto 0 auto;
+ width: 280px;
+ font-size: 20px;
+ color: @grayDark;
+ line-height: 30px;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/AccountActions/AccountActions.vue b/src/components/AccountActions/AccountActions.vue
new file mode 100644
index 0000000..59025eb
--- /dev/null
+++ b/src/components/AccountActions/AccountActions.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
{{ $t('accounts_harvesting_title_remote') }}
+
{{ $t('accounts_harvesting_remote_explain_p1') }}
+
{{ $t('accounts_harvesting_remote_explain_p2') }}
+
+
+
+
+
+
+
+ {{ $t('accounts_harvesting_tile_remote') }}
+
+
+ {{ $t('accounts_harvesting_tile_remote_description') }}
+
+
+
+
+
+
+
{{ $t('accounts_harvesting_title_request') }}
+
{{ $t('accounts_harvesting_request_explain_p1') }}
+
{{ $t('accounts_harvesting_request_explain_p2') }}
+
+
+
+
+
+
+
+ {{ $t('accounts_harvesting_tile_request') }}
+
+
+ {{ $t('accounts_harvesting_tile_request_description') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountActions/AccountActionsTs.ts b/src/components/AccountActions/AccountActionsTs.ts
new file mode 100644
index 0000000..1555ad3
--- /dev/null
+++ b/src/components/AccountActions/AccountActionsTs.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+
+@Component
+export class AccountActionsTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ /// region computed properties getter/setter
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountAddressDisplay/AccountAddressDisplay.vue b/src/components/AccountAddressDisplay/AccountAddressDisplay.vue
new file mode 100644
index 0000000..3fe45a1
--- /dev/null
+++ b/src/components/AccountAddressDisplay/AccountAddressDisplay.vue
@@ -0,0 +1,21 @@
+
+
+
{{ $t('account_address') }}:
+
{{ prettyAddress }}
+
+
+
+
+
+
+
diff --git a/src/components/AccountAddressDisplay/AccountAddressDisplayTs.ts b/src/components/AccountAddressDisplay/AccountAddressDisplayTs.ts
new file mode 100644
index 0000000..66d4cef
--- /dev/null
+++ b/src/components/AccountAddressDisplay/AccountAddressDisplayTs.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address } from 'symbol-sdk';
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+//@ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+
+@Component({
+ components: {
+ ButtonCopyToClipboard,
+ },
+})
+export class AccountAddressDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ address: string;
+
+ public get prettyAddress(): string {
+ return this.address ? Address.createFromRawAddress(this.address).pretty() : '';
+ }
+
+ /// region computed properties getter/setter
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountAliasDisplay/AccountAliasDisplay.vue b/src/components/AccountAliasDisplay/AccountAliasDisplay.vue
new file mode 100644
index 0000000..e6d2c15
--- /dev/null
+++ b/src/components/AccountAliasDisplay/AccountAliasDisplay.vue
@@ -0,0 +1,31 @@
+
+
+
{{ $t('aliases') }}:
+
+
+ {{ index === accountAliasNames.length - 1 ? `${alias}` : `${alias},` }}
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountAliasDisplay/AccountAliasDisplayTs.ts b/src/components/AccountAliasDisplay/AccountAliasDisplayTs.ts
new file mode 100644
index 0000000..cd9ac8f
--- /dev/null
+++ b/src/components/AccountAliasDisplay/AccountAliasDisplayTs.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { AccountNames } from 'symbol-sdk';
+
+@Component({
+ computed: mapGetters({
+ currentAccountAliases: 'account/currentAccountAliases',
+ }),
+})
+export class AccountAliasDisplayTs extends Vue {
+ @Prop({ default: null }) account: AccountModel;
+
+ /**
+ * NamespaceModel
+ */
+ protected currentAccountAliases: AccountNames[];
+
+ get accountAliasNames(): string[] {
+ const names = this.currentAccountAliases.find((alias) => alias.address.plain() === this.account.address)?.names;
+ if (!this.currentAccountAliases || !this.account || !names) {
+ return [];
+ } else {
+ return names.map((aliasName) => aliasName.name);
+ }
+ }
+}
diff --git a/src/components/AccountBackupOptions/AccountBackupOptions.less b/src/components/AccountBackupOptions/AccountBackupOptions.less
new file mode 100644
index 0000000..41e4fc4
--- /dev/null
+++ b/src/components/AccountBackupOptions/AccountBackupOptions.less
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.backup-options-container {
+ display: grid;
+ grid-template-rows: 2.6rem 2.6rem 2.6rem;
+ grid-template-columns: 100%;
+
+ .single-backup-option {
+ display: grid;
+ grid-template-columns: 8rem 4.2rem;
+ padding-bottom: 0.2rem;
+
+ .backup-explain {
+ padding: 0.2rem;
+ padding-left: 0.4rem;
+ font-size: @normalFont;
+ color: @black;
+
+ .subtitle {
+ color: @primary;
+ font-weight: 400;
+ }
+
+ p {
+ padding-top: 0.05rem;
+ text-align: justify;
+ }
+ }
+
+ /deep/.backup-options {
+ height: 2.2rem;
+ min-width: 3rem;
+ margin: 0.15rem 0;
+ display: flex;
+ justify-content: space-around;
+
+ .backup-item:hover {
+ background: @grayLightest;
+ }
+
+ .backup-item.danger:hover {
+ background: @redLightest;
+ }
+
+ div .backup-item,
+ .backup-item {
+ text-align: center;
+ background: @grayLightest;
+ box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
+ border-radius: 4px;
+ margin-right: 0.3rem;
+ cursor: pointer;
+ min-height: 200px;
+ min-width: 225px;
+
+ .img-box {
+ img {
+ width: 68px;
+ /*border: 1px dashed @black;*/
+ margin: 30px auto 15px;
+ }
+ }
+
+ .access-name {
+ font-size: 16px;
+ font-weight: 600;
+ color: @black;
+ line-height: 24px;
+ margin-top: 15px;
+ }
+
+ .access-info {
+ font-size: 13px;
+ color: @grayDark;
+ margin-top: 5px;
+ line-height: 30px;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/AccountBackupOptions/AccountBackupOptions.vue b/src/components/AccountBackupOptions/AccountBackupOptions.vue
new file mode 100644
index 0000000..17332a4
--- /dev/null
+++ b/src/components/AccountBackupOptions/AccountBackupOptions.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
{{ $t('accounts_backup_title_qrcode') }}
+
{{ $t('accounts_backup_qrcode_explain_p1') }}
+
{{ $t('accounts_backup_qrcode_explain_p2') }}
+
+
+
+
+
+
{{ $t('accounts_backup_title_mnemonic') }}
+
{{ $t('accounts_backup_mnemonic_explain_p1') }}
+
{{ $t('accounts_backup_mnemonic_explain_p2') }}
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountBackupOptions/AccountBackupOptionsTs.ts b/src/components/AccountBackupOptions/AccountBackupOptionsTs.ts
new file mode 100644
index 0000000..efeb951
--- /dev/null
+++ b/src/components/AccountBackupOptions/AccountBackupOptionsTs.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+// child components
+// @ts-ignore
+import ModalFormProfileUnlock from '@/views/modals/ModalFormProfileUnlock/ModalFormProfileUnlock.vue';
+// @ts-ignore
+import ProtectedMnemonicQRButton from '@/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButton.vue';
+// @ts-ignore
+import ProtectedMnemonicDisplayButton from '@/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButton.vue';
+
+@Component({
+ components: {
+ ModalFormProfileUnlock,
+ ProtectedMnemonicQRButton,
+ ProtectedMnemonicDisplayButton,
+ },
+})
+export class AccountBackupOptionsTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ /**
+ * Whether account is currently being unlocked
+ * @var {boolean}
+ */
+ public isUnlockingAccount: boolean = false;
+
+ /// region computed properties getter/setter
+ public get hasAccountUnlockModal(): boolean {
+ return this.isUnlockingAccount;
+ }
+
+ public set hasAccountUnlockModal(f: boolean) {
+ this.isUnlockingAccount = f;
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountContactQR/AccountContactQR.vue b/src/components/AccountContactQR/AccountContactQR.vue
new file mode 100644
index 0000000..2013b62
--- /dev/null
+++ b/src/components/AccountContactQR/AccountContactQR.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/components/AccountContactQR/AccountContactQRTs.ts b/src/components/AccountContactQR/AccountContactQRTs.ts
new file mode 100644
index 0000000..4bf711b
--- /dev/null
+++ b/src/components/AccountContactQR/AccountContactQRTs.ts
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { ContactQR } from 'symbol-qr-library';
+import { PublicAccount } from 'symbol-sdk';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+// resources
+import { mapGetters } from 'vuex';
+// @ts-ignore
+import QRCodeDisplay from '@/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue';
+@Component({
+ components: {
+ QRCodeDisplay,
+ },
+ computed: {
+ ...mapGetters({
+ generationHash: 'network/generationHash',
+ }),
+ },
+})
+export class AccountContactQRTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ /**
+ * Current network's generation hash
+ * @var {string}
+ */
+ public generationHash: string;
+
+ /// region computed properties getter/setter
+ get qrCodeArgs(): ContactQR {
+ if (!this.account) {
+ return null;
+ }
+
+ try {
+ const publicAccount: PublicAccount = AccountModel.getObjects(this.account).publicAccount;
+ return new ContactQR(this.account.name, publicAccount.publicKey, publicAccount.address.networkType, this.generationHash);
+ } catch (error) {
+ return null;
+ }
+ }
+
+ get downloadName(): string {
+ return this.account ? `address-qr-${this.account.name}.png` : '';
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountDetailsDisplay/AccountDetailsDisplay.vue b/src/components/AccountDetailsDisplay/AccountDetailsDisplay.vue
new file mode 100644
index 0000000..f0e00bc
--- /dev/null
+++ b/src/components/AccountDetailsDisplay/AccountDetailsDisplay.vue
@@ -0,0 +1,40 @@
+
+
+
+
+
{{ $t('account_address') }}
+
{{ AccountModel.getObjects(account).address.pretty() }}
+
+
+
+
+
+
+
+
+
+
{{ $t('account_public_key') }}
+
{{ account.publicKey }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountDetailsDisplay/AccountDetailsDisplayTs.ts b/src/components/AccountDetailsDisplay/AccountDetailsDisplayTs.ts
new file mode 100644
index 0000000..41da43e
--- /dev/null
+++ b/src/components/AccountDetailsDisplay/AccountDetailsDisplayTs.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+//@ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+
+@Component({
+ components: {
+ ButtonCopyToClipboard,
+ },
+})
+export class AccountDetailsDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ public AccountModel = AccountModel;
+}
diff --git a/src/components/AccountLinks/AccountLinks.less b/src/components/AccountLinks/AccountLinks.less
new file mode 100644
index 0000000..c57800d
--- /dev/null
+++ b/src/components/AccountLinks/AccountLinks.less
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+.account-detail-row {
+ display: grid;
+ grid-template-columns: 1.4rem auto;
+}
+.edit-button {
+ height: 0.35rem !important;
+ padding: 0 0.3rem;
+}
+
+.trigger-accountlink {
+ font-size: @normalFont !important;
+ color: @purpleDark;
+ display: flex;
+ align-items: center;
+}
+
+.navbar-icon {
+ display: inline;
+ margin-right: 10px;
+ width: 0.15rem;
+ height: 0.15rem;
+}
diff --git a/src/components/AccountLinks/AccountLinks.vue b/src/components/AccountLinks/AccountLinks.vue
new file mode 100644
index 0000000..ecd10ec
--- /dev/null
+++ b/src/components/AccountLinks/AccountLinks.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/src/components/AccountLinks/AccountLinksTs.ts b/src/components/AccountLinks/AccountLinksTs.ts
new file mode 100644
index 0000000..ff893aa
--- /dev/null
+++ b/src/components/AccountLinks/AccountLinksTs.ts
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { mapGetters } from 'vuex';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ explorerBaseUrl: 'app/explorerUrl',
+ faucetBaseUrl: 'app/faucetUrl',
+ }),
+ },
+})
+export class AccountLinksTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+ @Prop({ default: '' }) title: string;
+ @Prop({ default: '' }) link: string;
+ @Prop({ default: '' }) icon: string;
+
+ public explorerBaseUrl: string;
+ public faucetBaseUrl: string;
+
+ /// region computed properties getter/setter
+ /// end-region computed properties getter/setter
+
+ public get explorerUrl() {
+ return this.explorerBaseUrl.replace(/\/+$/, '') + '/accounts/' + this.account.address;
+ }
+
+ public get faucetUrl() {
+ return this.faucetBaseUrl + '?recipient=' + this.account.address;
+ }
+}
diff --git a/src/components/AccountMetadataDisplay/AccountMetadataDisplay.less b/src/components/AccountMetadataDisplay/AccountMetadataDisplay.less
new file mode 100644
index 0000000..aa2bffc
--- /dev/null
+++ b/src/components/AccountMetadataDisplay/AccountMetadataDisplay.less
@@ -0,0 +1,20 @@
+@import '../../views/resources/css/variables.less';
+
+.account-detail-row-3cols {
+ align-items: center;
+ .select-style {
+ position: relative;
+ overflow: initial;
+ .metadata-row {
+ display: grid;
+ grid-template-columns: 1.5fr 2fr;
+ }
+ }
+ .metadata-detail-button {
+ color: @purple;
+ cursor: pointer;
+ margin-left: 5px;
+ width: 30px;
+ padding: 2%;
+ }
+}
diff --git a/src/components/AccountMetadataDisplay/AccountMetadataDisplay.vue b/src/components/AccountMetadataDisplay/AccountMetadataDisplay.vue
new file mode 100644
index 0000000..3032aeb
--- /dev/null
+++ b/src/components/AccountMetadataDisplay/AccountMetadataDisplay.vue
@@ -0,0 +1,23 @@
+
+
+
{{ $t('metadata') }}:
+
+
+ {{ `${metadataModel.scopedMetadataKey} : ${metadataModel.value}` }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountMetadataDisplay/AccountMetadataDisplayTs.ts b/src/components/AccountMetadataDisplay/AccountMetadataDisplayTs.ts
new file mode 100644
index 0000000..4de3ea3
--- /dev/null
+++ b/src/components/AccountMetadataDisplay/AccountMetadataDisplayTs.ts
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+
+import { MetadataModel } from '@/core/database/entities/MetadataModel';
+
+@Component({})
+export class AccountMetadataDisplayTs extends Vue {
+ /**
+ * account metadata list
+ */
+ @Prop({
+ default: [],
+ })
+ protected metadataList: MetadataModel[];
+
+ @Prop({
+ default: false,
+ })
+ visible: boolean;
+ /**
+ * selected metadata model id
+ */
+ protected value: string = '';
+
+ set chosenValue(newValue: string) {
+ this.value = newValue;
+ }
+
+ get chosenValue(): string {
+ return this.value;
+ }
+
+ /**
+ * Visibility state
+ * @type {boolean}
+ */
+ get show(): boolean {
+ return this.visible;
+ }
+ /**
+ * Hook called when the layout is mounted
+ * @return {void}
+ */
+ public mounted(): void {
+ // set default value to the first namespace in the list
+ if (this.metadataList.length) {
+ this.chosenValue = this.metadataList[0].metadataId;
+ }
+ }
+ public emitMetadataValue() {
+ const metadataEntry = this.metadataList.find((item) => item.metadataId == this.chosenValue);
+ this.$emit('on-edit-metadata', metadataEntry);
+ }
+}
diff --git a/src/components/AccountMultisigGraph/AccountMultisigGraph.vue b/src/components/AccountMultisigGraph/AccountMultisigGraph.vue
new file mode 100644
index 0000000..ab806c5
--- /dev/null
+++ b/src/components/AccountMultisigGraph/AccountMultisigGraph.vue
@@ -0,0 +1,28 @@
+
+
+
{{ $t('multisig_account_graph') }}:
+
+
+
+
+
+
+
diff --git a/src/components/AccountMultisigGraph/AccountMultisigGraphTs.ts b/src/components/AccountMultisigGraph/AccountMultisigGraphTs.ts
new file mode 100644
index 0000000..6aa35ef
--- /dev/null
+++ b/src/components/AccountMultisigGraph/AccountMultisigGraphTs.ts
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { mapGetters } from 'vuex';
+import { MultisigAccountInfo } from 'symbol-sdk';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ multisigAccountGraphInfo: 'account/multisigAccountGraph',
+ knownAccounts: 'account/knownAccounts',
+ }),
+ },
+})
+export class AccountMultisigGraphTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ @Prop({
+ default: null,
+ })
+ visible: boolean;
+ public multisigAccountGraphInfo: Map;
+ public knownAccounts: AccountModel[];
+
+ get multisigGraphTree(): any[] {
+ if (this.multisigAccountGraphInfo) {
+ return this.getMultisigDisplayGraph(this.multisigAccountGraphInfo);
+ }
+ return [];
+ }
+
+ public getMultisigDisplayGraph(multisigEntries: Map): any[] {
+ const firstLevelNumber = [...multisigEntries.keys()].sort()[0];
+ const firstLevel = multisigEntries.get(firstLevelNumber);
+ const graph = [];
+ for (const entry of firstLevel) {
+ graph.push({
+ info: entry,
+ address: entry.accountAddress.plain(),
+ title: this.getAccountLabel(entry, this.knownAccounts),
+ children: [this.getMultisigDisplayGraphChildren(firstLevelNumber + 1, entry, multisigEntries)],
+ selected: this.account.address === entry.accountAddress.plain(),
+ });
+ }
+ return graph[0].children;
+ }
+
+ private getMultisigDisplayGraphChildren(
+ level: number,
+ info: MultisigAccountInfo,
+ multisigEntries: Map,
+ ): any {
+ const entries = multisigEntries.get(level);
+ if (!entries) {
+ return {
+ info: info,
+ address: info.accountAddress.plain(),
+ title: this.getAccountLabel(info, this.knownAccounts),
+ children: [],
+ selected: this.account.address === info.accountAddress.plain(),
+ };
+ }
+ const children = [];
+ for (const entry of entries) {
+ const isFromParent = entry.multisigAddresses.find((address) => address.plain() === info.accountAddress.plain());
+ if (isFromParent) {
+ children.push(this.getMultisigDisplayGraphChildren(level + 1, entry, multisigEntries));
+ }
+ }
+ return {
+ info: info,
+ address: info.accountAddress.plain(),
+ title: this.getAccountLabel(info, this.knownAccounts),
+ children: children,
+ selected: this.account.address === info.accountAddress.plain(),
+ };
+ }
+
+ getAccountLabel(info: MultisigAccountInfo, accounts: AccountModel[]): string {
+ const account = accounts.find((wlt) => info.accountAddress.plain() === wlt.address);
+ const addressOrName = (account && account.name) || info.accountAddress.plain();
+ return addressOrName + (info.isMultisig() ? ` - ${info.minApproval} of ${info.minRemoval}` : '');
+ }
+}
diff --git a/src/components/AccountNameDisplay/AccountNameDisplay.vue b/src/components/AccountNameDisplay/AccountNameDisplay.vue
new file mode 100644
index 0000000..56f97a5
--- /dev/null
+++ b/src/components/AccountNameDisplay/AccountNameDisplay.vue
@@ -0,0 +1,44 @@
+
+
+
{{ $t('account_name') }}:
+
+
+ {{ account.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountNameDisplay/AccountNameDisplayTs.ts b/src/components/AccountNameDisplay/AccountNameDisplayTs.ts
new file mode 100644
index 0000000..57c700d
--- /dev/null
+++ b/src/components/AccountNameDisplay/AccountNameDisplayTs.ts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { ValidationProvider } from 'vee-validate';
+
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+
+// child components
+// @ts-ignore
+import ModalFormAccountNameUpdate from '@/views/modals/ModalFormAccountNameUpdate/ModalFormAccountNameUpdate.vue';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormLabel from '@/components/FormLabel/FormLabel.vue';
+
+@Component({
+ components: {
+ ModalFormAccountNameUpdate,
+ ValidationProvider,
+ ErrorTooltip,
+ FormLabel,
+ },
+})
+export class AccountNameDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ @Prop({
+ default: false,
+ })
+ editable: boolean;
+
+ /**
+ * Whether name is currently being edited
+ * @var {boolean}
+ */
+ public isEditingName: boolean = false;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /// region computed properties getter/setter
+ public get hasNameFormModal(): boolean {
+ return this.editable && this.isEditingName;
+ }
+
+ public set hasNameFormModal(f: boolean) {
+ this.isEditingName = f;
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountPublicKeyDisplay/AccountPublicKeyDisplay.vue b/src/components/AccountPublicKeyDisplay/AccountPublicKeyDisplay.vue
new file mode 100644
index 0000000..ae28813
--- /dev/null
+++ b/src/components/AccountPublicKeyDisplay/AccountPublicKeyDisplay.vue
@@ -0,0 +1,28 @@
+
+
+
{{ $t('account_public_key') }}:
+
{{ publicKey || account.publicKey }}
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountPublicKeyDisplay/AccountPublicKeyDisplayTs.ts b/src/components/AccountPublicKeyDisplay/AccountPublicKeyDisplayTs.ts
new file mode 100644
index 0000000..bd22871
--- /dev/null
+++ b/src/components/AccountPublicKeyDisplay/AccountPublicKeyDisplayTs.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+//@ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+
+@Component({
+ components: {
+ ButtonCopyToClipboard,
+ },
+})
+export class AccountPublicKeyDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ @Prop({
+ default: null,
+ })
+ publicKey: string;
+ /// region computed properties getter/setter
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountRestrictionsList/AccountRestrictionsList.less b/src/components/AccountRestrictionsList/AccountRestrictionsList.less
new file mode 100644
index 0000000..20f3090
--- /dev/null
+++ b/src/components/AccountRestrictionsList/AccountRestrictionsList.less
@@ -0,0 +1,344 @@
+@import '../../views/resources/css/variables.less';
+
+.columns {
+ grid-template-columns: 15% 60% 15% 10%;
+ .targetAddress-header,
+ .targetAddress-cell {
+ text-align: left;
+ }
+ .targetID-header,
+ .targetID-cell {
+ text-align: left;
+ }
+ .targetType-header,
+ .targetType-cell {
+ text-align: left;
+ }
+ .scopedMetadataKey-header,
+ .scopedMetadataKey-cell {
+ text-align: left;
+ }
+ .status-header,
+ .status-cell {
+ text-align: left;
+ }
+ .changeTimes-header,
+ .changeTimes-cell {
+ text-align: left;
+ }
+}
+
+.hexId-header {
+ text-align: left;
+}
+
+.supply-header,
+.balance-header,
+.expiration-header {
+ text-align: left;
+}
+
+.name-header {
+ text-align: left;
+}
+
+.divisibility-header {
+ text-align: center;
+}
+
+.transferable-header {
+ text-align: center;
+ white-space: nowrap;
+}
+
+.supplyMutable-header {
+ text-align: center;
+ white-space: nowrap;
+}
+
+.restrictable-header {
+ text-align: center;
+ white-space: nowrap;
+}
+
+.hexId-cell {
+ text-align: left;
+}
+
+.name-cell {
+ text-align: left;
+}
+
+.supply-cell,
+.balance-cell,
+.expiration-cell {
+ text-align: left;
+}
+
+.divisibility-cell {
+ text-align: center;
+}
+
+.transferable-cell {
+ text-align: center;
+}
+
+.supplyMutable-cell {
+ text-align: center;
+}
+
+.restrictable-cell {
+ text-align: center;
+}
+
+/deep/.namespace-columns {
+ grid-template-columns: 15% 60% 15% 10%;
+}
+
+.table-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-rows: 0.3rem auto;
+ grid-template-columns: 100%;
+ font-size: 0.16rem;
+ overflow-y: auto;
+
+ .upper-section-container {
+ display: grid;
+ width: 100%;
+ height: 0.6rem;
+ grid-template-rows: 100%;
+ grid-template-columns: 100%;
+
+ .table-title-container {
+ padding-left: 0.2rem;
+ padding-top: 0.1rem;
+ position: relative;
+ .section-title {
+ font-size: 1.125em;
+ font-weight: 500;
+ color: @blackLight;
+ }
+ .user-operation {
+ display: flex;
+ justify-content: flex-end;
+ position: absolute;
+ right: 0.1rem;
+ bottom: 0.3rem;
+ color: @primary;
+ .add-metadata-button {
+ margin-right: 0.3rem;
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ user-select: none;
+ cursor: pointer;
+ .add-icon {
+ padding: 3px 5px 0px 4px;
+ }
+ }
+
+ .ivu-checkbox-wrapper {
+ margin-top: 0.08rem;
+ margin-right: 0.2rem;
+ }
+
+ .ivu-icon-ios-sync {
+ margin-left: 0.2rem;
+ font-weight: 600;
+ margin-top: 0.08rem;
+ vertical-align: middle !important;
+ &:hover {
+ cursor: pointer;
+ }
+ }
+ .table-filter-item-container {
+ }
+ /deep/.ivu-select {
+ .ivu-select-selection {
+ font-size: @normalFont;
+ background-color: @grayLightest !important;
+ border: none !important;
+ box-shadow: none !important;
+ color: @primary;
+ :hover {
+ border: none;
+ box-shadow: none;
+ }
+ .ivu-select-prefix {
+ color: @purpleDark;
+ }
+ .ivu-select-selected-value {
+ padding-right: 0.35rem !important;
+ }
+ }
+
+ .ivu-select-visible {
+ .ivu-select-selection {
+ color: @white !important;
+ background-color: @purpleDark;
+ border: 0.01rem solid @purpleDark;
+ }
+
+ .ivu-icon-ios-arrow-down::before {
+ color: @white !important;
+ }
+
+ .ivu-select-prefix {
+ color: @white;
+ }
+ }
+ .ivu-select-group-title {
+ font-size: @smallerFont !important;
+ }
+
+ .ivu-select-item {
+ font-size: @smallFont !important;
+ }
+ }
+ /deep/ .ivu-select-dropdown {
+ background-color: @grayLightest;
+
+ .ivu-select-item-selected {
+ color: @primary;
+ background-color: @grayLightest;
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+ }
+ /deep/ .ivu-select-item:hover {
+ background-color: @white !important;
+ }
+ }
+
+ /deep/ .ivu-select-dropdown {
+ background-color: @grayLightest !important;
+
+ .ivu-select-item-selected {
+ color: @primary !important;
+ background-color: @grayLightest !important;
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+ }
+
+ /deep/ .ivu-select-item:hover {
+ background-color: @white !important;
+ }
+
+ .table-actions-container {
+ text-align: right;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-auto-rows: 50%;
+ cursor: pointer;
+ }
+ }
+ .body-section-container {
+ display: grid;
+ grid-template-rows: 0.3rem auto 0.5rem;
+
+ .table-header-container {
+ display: grid;
+ width: 100%;
+ text-align: right;
+ color: @purpleDark;
+ background-color: @white;
+ font-size: @normalFont;
+ font-family: @symbolFontMedium;
+
+ .table-header-item {
+ text-align: left;
+ padding: 0 0.1rem;
+ line-height: 0.35rem;
+ font-weight: 300;
+ cursor: pointer;
+
+ .header-label {
+ }
+
+ .sort-icon {
+ }
+ }
+ }
+
+ .table-body-container {
+ text-align: left;
+ overflow-y: auto;
+ overflow-x: hidden;
+ position: relative;
+ font-family: @symbolFontLight;
+ font-size: @normalFont;
+ color: @purpleDark;
+ .table-rows-container {
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-auto-rows: 0.6rem;
+ grid-template-columns: 100%;
+ }
+
+ .no-data-inner-container {
+ display: grid;
+ grid-auto-rows: 0.6rem;
+ grid-template-columns: 100%;
+
+ > div {
+ border-bottom: 1px solid @line;
+ }
+ }
+ }
+
+ .table-footer-container {
+ text-align: right;
+ padding-top: 0.1rem;
+ padding-right: 0.7rem;
+
+ .page {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ /deep/.ivu-page-item {
+ width: 30px;
+ min-width: 30px;
+ height: 30px;
+ border: none;
+ box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.16);
+ color: @grayDark;
+ -webkit-box-shadow: none !important;
+ }
+
+ /deep/.ivu-page-item-active a,
+ /deep/.ivu-page-item-active:hover a {
+ color: @primary !important;
+ }
+
+ /deep/.ivu-page-prev,
+ /deep/.ivu-page-next {
+ border: none !important;
+ }
+ }
+ }
+}
+.animation-rotate {
+ animation: auto-rotate infinite linear 1s;
+}
+@keyframes auto-rotate {
+ from {
+ transform: rotateZ(0);
+ }
+ to {
+ transform: rotateZ(360deg);
+ }
+}
diff --git a/src/components/AccountRestrictionsList/AccountRestrictionsList.vue b/src/components/AccountRestrictionsList/AccountRestrictionsList.vue
new file mode 100644
index 0000000..5944d7f
--- /dev/null
+++ b/src/components/AccountRestrictionsList/AccountRestrictionsList.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+ {{ $t(label) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountRestrictionsList/AccountRestrictionsListTs.ts b/src/components/AccountRestrictionsList/AccountRestrictionsListTs.ts
new file mode 100644
index 0000000..8544ae6
--- /dev/null
+++ b/src/components/AccountRestrictionsList/AccountRestrictionsListTs.ts
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+// @ts-ignore
+import ButtonAdd from '@/components/ButtonAdd/ButtonAdd';
+// @ts-ignore
+import SignerFilter from '@/components/SignerFilter/SignerFilter.vue';
+// @ts-ignore
+import { TableAssetType } from '@/components/TableDisplay/TableAssetType';
+// @ts-ignore
+import { TableDisplayTs } from '@/components/TableDisplay/TableDisplayTs';
+// child components
+// @ts-ignore
+import TableRow from '@/components/TableRow/TableRow.vue';
+// @ts-ignore
+import { AccountRestrictionTableService } from '@/services/AssetTableService/AccountRestrictionTableService';
+// internal dependencies
+import { AssetTableService } from '@/services/AssetTableService/AssetTableService';
+import { AccountRestrictionTxType } from '@/views/forms/FormAccountRestrictionTransaction/FormAccountRestrictionTransactionTs';
+// @ts-ignore
+import FormAliasTransaction from '@/views/forms/FormAliasTransaction/FormAliasTransaction.vue';
+// @ts-ignore
+import FormExtendNamespaceDurationTransaction from '@/views/forms/FormExtendNamespaceDurationTransaction/FormExtendNamespaceDurationTransaction.vue';
+// @ts-ignore
+import FormMosaicSupplyChangeTransaction from '@/views/forms/FormMosaicSupplyChangeTransaction/FormMosaicSupplyChangeTransaction.vue';
+// @ts-ignore
+import ModalFormWrap from '@/views/modals/ModalFormWrap/ModalFormWrap.vue';
+// @ts-ignore
+import ModalMetadataDisplay from '@/views/modals/ModalMetadataDisplay/ModalMetadataDisplay.vue';
+// @ts-ignore
+import ModalMetadataUpdate from '@/views/modals/ModalMetadataUpdate/ModalMetadataUpdate.vue';
+import { Address } from 'symbol-sdk';
+import { Component, Prop, Watch } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+
+export type AccountRestrictionTableField = {
+ label: string;
+ name: string;
+ type: 'text' | 'check' | 'icon';
+};
+
+@Component({
+ components: {
+ TableRow,
+ ModalFormWrap,
+ FormAliasTransaction,
+ FormExtendNamespaceDurationTransaction,
+ FormMosaicSupplyChangeTransaction,
+ ModalMetadataDisplay,
+ SignerFilter,
+ ButtonAdd,
+ ModalMetadataUpdate,
+ },
+ computed: {
+ ...mapGetters({
+ accountAddressRestrictions: 'restriction/accountAddressRestrictions',
+ accountMosaicRestrictions: 'restriction/accountMosaicRestrictions',
+ accountOperationRestrictions: 'restriction/accountOperationRestrictions',
+ isFetchingRestrictions: 'restriction/isFetchingRestrictions',
+ currentSignerAddress: 'account/currentSignerAddress',
+ }),
+ },
+})
+export class AccountRestrictionsListTs extends TableDisplayTs {
+ /**
+ * Type of assets shown in the table
+ * @type {string}
+ */
+ @Prop({
+ default: TableAssetType.AccountRestrictions,
+ })
+ assetType: TableAssetType;
+
+ @Prop({
+ default: AccountRestrictionTxType.ADDRESS,
+ })
+ restrictionTxType: AccountRestrictionTxType;
+
+ public isFetchingRestrictions: boolean;
+ public accountAddressRestrictions;
+ public accountMosaicRestrictions;
+ public accountOperationRestrictions;
+ public currentSignerAddress: Address;
+
+ public get isLoading() {
+ return this.isFetchingRestrictions;
+ }
+
+ public getService(): AssetTableService {
+ let restrictions = this.accountAddressRestrictions;
+ if (this.restrictionTxType === AccountRestrictionTxType.MOSAIC) {
+ restrictions = this.accountMosaicRestrictions;
+ } else if (this.restrictionTxType === AccountRestrictionTxType.TRANSACTION_TYPE) {
+ restrictions = this.accountOperationRestrictions;
+ }
+ return new AccountRestrictionTableService(restrictions);
+ }
+
+ protected async doRefresh() {
+ await this.$store.dispatch('restriction/LOAD_ACCOUNT_RESTRICTIONS');
+ }
+
+ public handleRemoveRestriction(restriction) {
+ this.$emit('deleteRestriction', restriction);
+ }
+
+ @Watch('currentSignerAddress', { immediate: true })
+ protected watchCurrentSigner() {
+ this.doRefresh();
+ }
+}
diff --git a/src/components/AccountSelectorField/AccountSelectorField.less b/src/components/AccountSelectorField/AccountSelectorField.less
new file mode 100644
index 0000000..65fe562
--- /dev/null
+++ b/src/components/AccountSelectorField/AccountSelectorField.less
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.select-style {
+ padding: 0 !important;
+ background: transparent;
+}
+
+/deep/ .ivu-select-arrow {
+ right: 0.32rem !important;
+}
+
+/deep/ .ivu-select-selection div {
+ display: flex;
+ align-items: center;
+
+ .ivu-select-prefix {
+ display: inline-flex !important;
+ padding: 0;
+ }
+}
+
+.navbar-icon {
+ display: inline;
+ margin-right: 10px;
+ width: 0.15rem;
+ height: 0.15rem;
+}
+
+.min-width {
+ /deep/.ivu-select-dropdown {
+ min-width: 1.6rem !important;
+ }
+}
+
+/deep/.ivu-select-dropdown {
+ background-color: @grayLightest !important;
+ left: auto !important;
+
+ .ivu-select-item-selected {
+ color: @primary !important;
+ background-color: @grayLightest !important;
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+}
+
+/deep/ .ivu-select-item:hover {
+ background-color: @white !important;
+}
+
+/deep/ .select-style {
+ left: auto !important;
+}
diff --git a/src/components/AccountSelectorField/AccountSelectorField.vue b/src/components/AccountSelectorField/AccountSelectorField.vue
new file mode 100644
index 0000000..1018fcf
--- /dev/null
+++ b/src/components/AccountSelectorField/AccountSelectorField.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+ {{ truncate(name) }}
+
+
+
+
+
+
+
diff --git a/src/components/AccountSelectorField/AccountSelectorFieldTs.ts b/src/components/AccountSelectorField/AccountSelectorFieldTs.ts
new file mode 100644
index 0000000..9caa288
--- /dev/null
+++ b/src/components/AccountSelectorField/AccountSelectorFieldTs.ts
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { AccountService } from '@/services/AccountService';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ knownAccounts: 'account/knownAccounts',
+ }),
+ },
+})
+export class AccountSelectorFieldTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ value: string;
+
+ @Prop({
+ default: false,
+ })
+ defaultFormStyle: boolean;
+
+ @Prop({
+ default: false,
+ })
+ enableMinWidth: boolean;
+
+ @Prop({
+ default: true,
+ })
+ showIcon: boolean;
+
+ /**
+ * Currently active account
+ * @see {Store.Account}
+ * @var {AccountModel}
+ */
+ public currentAccount: AccountModel;
+
+ /**
+ * Known accounts
+ */
+ public knownAccounts: AccountModel[];
+
+ /**
+ * Accounts repository
+ * @var {AccountService}
+ */
+ public readonly accountService: AccountService = new AccountService();
+
+ /// region computed properties getter/setter
+ public get currentAccountIdentifier(): string {
+ if (this.value) {
+ return this.value;
+ }
+
+ if (this.currentAccount) {
+ return this.currentAccount.id;
+ }
+
+ // fallback value
+ return '';
+ }
+
+ public set currentAccountIdentifier(id: string) {
+ if (!id || !id.length) {
+ return;
+ }
+
+ this.$emit('input', id);
+
+ const account = this.accountService.getAccount(id);
+ if (!account) {
+ return;
+ }
+ }
+
+ public get currentAccounts(): AccountModel[] {
+ return this.knownAccounts;
+ }
+
+ /**
+ * Truncates the account name if it is too long
+ * @protected
+ * @param {string} str
+ * @returns {string}
+ */
+ protected truncate(str: string): string {
+ const maxStringLength = 15;
+ if (str.length <= maxStringLength) {
+ return str;
+ }
+ return `${str.substring(0, 9)}...${str.substring(str.length - 3)}`;
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountSelectorPanel/AccountSelectorPanel.less b/src/components/AccountSelectorPanel/AccountSelectorPanel.less
new file mode 100644
index 0000000..47e7a8b
--- /dev/null
+++ b/src/components/AccountSelectorPanel/AccountSelectorPanel.less
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.account-switch-container {
+ .account-switch-header-container {
+ display: grid;
+ grid-template-columns: 60% 40%;
+ grid-template-rows: 100%;
+
+ .account-switch-header-left-container {
+ padding: 0 0.4rem;
+ margin: 0.2rem 0;
+
+ .section-title {
+ font-weight: 600;
+ color: @purpleDark;
+ font-family: @symbolFont;
+ }
+ }
+
+ .account-switch-header-right-container {
+ text-align: right;
+ padding: 0.19rem 0.2rem 0 0;
+ .back-up {
+ }
+ }
+ }
+
+ @passiveTextColor: #73747a;
+
+ .account-switch-body-container {
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-auto-rows: 0.7rem;
+ position: relative;
+ .account-type-title {
+ margin-left: 30px;
+ padding-top: 40px;
+ font-size: @bigFont;
+ color: @purpleDark;
+ font-family: @symbolFontSemiBold;
+ }
+ .active-background {
+ color: @black;
+ }
+
+ .inactive-background {
+ color: @grayLight;
+ }
+
+ .account-tile {
+ margin: 0 0.24rem;
+ position: relative;
+ padding: 0.14rem 0.25rem;
+ .account-tile-inner-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-rows: 50% 50%;
+ grid-template-columns: 100%;
+ font-weight: 900;
+ overflow: hidden;
+
+ .account-tile-upper-container {
+ .account-name {
+ color: @white;
+ }
+ }
+
+ .account-tile-lower-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-rows: 100%;
+ grid-template-columns: 80% 20%;
+
+ .account-amount {
+ }
+
+ .account-icons {
+ .account-icon {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .account-switch-footer-container {
+ padding: 0.3rem 0.3rem;
+ display: grid;
+ grid-template-columns: 50% 50%;
+ grid-template-rows: 100%;
+ text-align: center;
+ font-size: @normalFont;
+ font-family: @symbolFont;
+ line-height: 22px;
+ color: @purpleLightest;
+
+ .add-account {
+ .ivu-icon {
+ padding-right: 3px;
+ padding-bottom: 2px;
+ vertical-align: center;
+ }
+ }
+
+ .account-switch-header-right-container {
+ img {
+ width: 18px;
+ height: 16px;
+ padding-right: 5px;
+ // margin-top: 5px;
+ vertical-align: center;
+ }
+ }
+ }
+}
+
+.mosaic_data {
+ height: 0.65rem;
+ padding: 0.15rem 0.25rem 0.15rem 0;
+ display: flex;
+ flex-direction: row;
+ justify-items: center;
+ justify-content: space-between;
+ align-content: center;
+ align-items: center;
+ border-bottom: 0.01rem solid @line;
+ position: relative;
+ color: @purpleDark;
+ font-family: @symbolFontLight;
+
+ .namege_img {
+ position: absolute;
+ display: inline-block;
+ top: 0.2rem;
+
+ .mosaicIcon {
+ display: inline-block;
+ width: 0.28rem;
+ height: 0.28rem;
+ margin-left: 0.1rem;
+ }
+ }
+
+ .img_container {
+ display: inline-block;
+ position: absolute;
+ top: 0.23rem;
+ margin-right: 0.15rem;
+
+ img {
+ display: inline-block;
+ width: 0.22rem;
+ height: 0.2rem;
+ }
+
+ img.grayed-xym-logo {
+ opacity: 0.4;
+ -webkit-filter: grayscale(100%);
+ -moz-filter: grayscale(100%);
+ -o-filter: grayscale(100%);
+ -ms-filter: grayscale(100%);
+ filter: grayscale(100%);
+ }
+ }
+
+ .mosaic_name {
+ position: relative;
+ top: 0;
+ left: 0.4rem;
+ width: 1.8rem;
+ font-size: @bigFont;
+ font-weight: 400;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ .active-background {
+ color: @black;
+ }
+ }
+
+ .account-type {
+ position: relative;
+ top: 0;
+ left: 0.4rem;
+ width: 1rem;
+ font-weight: 400;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .mosaic_value {
+ margin-left: 0.5rem;
+ text-align: right;
+
+ div:first-of-type {
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @blackLight;
+ }
+
+ div:nth-of-type(2) {
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @grayDark;
+ }
+ }
+
+ .small_icon {
+ width: 0.2rem;
+ height: 0.2rem;
+ margin-bottom: 0.05rem;
+ }
+}
+
+.icon-left-button {
+ width: 0.15rem;
+ height: 0.15rem;
+ color: @purpleDark;
+}
+
+.account-selector-panel {
+ height: 100%;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-template-rows: auto 1rem;
+ grid-auto-flow: row;
+ overflow: scroll;
+}
diff --git a/src/components/AccountSelectorPanel/AccountSelectorPanel.vue b/src/components/AccountSelectorPanel/AccountSelectorPanel.vue
new file mode 100644
index 0000000..2e4f234
--- /dev/null
+++ b/src/components/AccountSelectorPanel/AccountSelectorPanel.vue
@@ -0,0 +1,148 @@
+
+
+
+
Seed accounts
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+
+
+
Opt In accounts
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+
+
+
Ledger accounts
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+
+
+
Ledger Opt In accounts
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+
+
+
Private key accounts
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AccountSelectorPanel/AccountSelectorPanelTs.ts b/src/components/AccountSelectorPanel/AccountSelectorPanelTs.ts
new file mode 100644
index 0000000..e627ea8
--- /dev/null
+++ b/src/components/AccountSelectorPanel/AccountSelectorPanelTs.ts
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { MosaicId, NetworkType } from 'symbol-sdk';
+import { ValidationProvider } from 'vee-validate';
+// internal dependencies
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { AccountModel, AccountType } from '@/core/database/entities/AccountModel';
+import { AccountService } from '@/services/AccountService';
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+// child components
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormLabel from '@/components/FormLabel/FormLabel.vue';
+// @ts-ignore
+import ModalFormSubAccountCreation from '@/views/modals/ModalFormSubAccountCreation/ModalFormSubAccountCreation.vue';
+// @ts-ignore
+import AmountDisplay from '@/components/AmountDisplay/AmountDisplay.vue';
+// @ts-ignore
+import NavigationLinks from '@/components/NavigationLinks/NavigationLinks.vue';
+// @ts-ignore
+import ModalBackupProfile from '@/views/modals/ModalBackupProfile/ModalBackupProfile.vue';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+
+@Component({
+ components: {
+ MosaicAmountDisplay,
+ ModalFormSubAccountCreation,
+ ErrorTooltip,
+ FormLabel,
+ ValidationProvider,
+ AmountDisplay,
+ ModalBackupProfile,
+ NavigationLinks,
+ },
+ computed: {
+ ...mapGetters({
+ currentProfile: 'profile/currentProfile',
+ currentAccount: 'account/currentAccount',
+ knownAccounts: 'account/knownAccounts',
+ networkType: 'network/networkType',
+ mosaics: 'mosaic/mosaics',
+ networkMosaic: 'mosaic/networkMosaic',
+ networkCurrency: 'mosaic/networkCurrency',
+ isPrivateKeyProfile: 'profile/isPrivateKeyProfile',
+ }),
+ },
+})
+export class AccountSelectorPanelTs extends Vue {
+ /**
+ * The network currency.
+ */
+ public networkCurrency: NetworkCurrencyModel;
+
+ /**
+ * Currently active networkType
+ * @see {Store.Network}
+ * @var {NetworkType}
+ */
+ public networkType: NetworkType;
+
+ /**
+ * Currently active profile
+ * @see {Store.Profile}
+ * @var {ProfileModel}
+ */
+ public currentProfile: ProfileModel;
+
+ /**
+ * Currently active account
+ * @see {Store.Account}
+ * @var {AccountModel}
+ */
+ public currentAccount: AccountModel;
+
+ /**
+ * Known accounts identifiers
+ * @var {string[]}
+ */
+ public knownAccounts: AccountModel[];
+ /**
+ * Networks currency mosaic
+ * @var {MosaicId}
+ */
+ public networkMosaic: MosaicId;
+
+ /**
+ * Current account owned mosaics
+ * @private
+ * @type {MosaicInfo[]}
+ */
+ private mosaics: MosaicModel[];
+
+ /**
+ * Accounts repository
+ * @var {AccountService}
+ */
+ public accountService: AccountService;
+
+ /**
+ * Whether user is currently adding an account (modal)
+ * @var {boolean}
+ */
+ public isAddingAccount: boolean = false;
+ /**
+ * Whether currently viewing export
+ * @var {boolean}
+ */
+ public isViewingExportModal: boolean = false;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ public isPrivateKeyProfile: boolean;
+
+ /**
+ * Hook called when the component is created
+ * @return {void}
+ */
+ public async created() {
+ this.accountService = new AccountService();
+ }
+
+ /// region computed properties getter/setter
+ public get balances(): Map {
+ const networkMosaics = this.mosaics.filter((m) => m.mosaicIdHex === this.networkMosaic.toHex());
+ return Object.assign({}, ...networkMosaics.map((s) => ({ [s.addressRawPlain]: s.balance })));
+ // return this.addressesBalances
+ }
+
+ public get currentAccountIdentifier(): string {
+ return !this.currentAccount ? '' : this.currentAccount.id;
+ }
+
+ public set currentAccountIdentifier(id: string) {
+ if (!id || !id.length) {
+ return;
+ }
+
+ const account = this.accountService.getAccount(id);
+ if (!account) {
+ return;
+ }
+
+ if (!this.currentAccount || id !== this.currentAccount.id) {
+ this.$store.dispatch('account/SET_CURRENT_ACCOUNT', account);
+ this.$emit('input', account.id);
+ }
+ }
+
+ public get currentAccounts(): AccountModel[] {
+ return this.knownAccounts;
+ }
+
+ public get seedAccounts(): AccountModel[] {
+ return this.knownAccounts.filter((_) => _.type === AccountType.SEED);
+ }
+
+ public get optInAccounts(): AccountModel[] {
+ return this.knownAccounts.filter((_) => _.type === AccountType.OPT_IN);
+ }
+
+ public get pkAccounts(): AccountModel[] {
+ return this.knownAccounts.filter((_) => _.type === AccountType.PRIVATE_KEY);
+ }
+
+ public get ledgerAccount(): AccountModel[] {
+ return this.knownAccounts.filter((_) => _.type === AccountType.LEDGER);
+ }
+
+ public get ledgerOptInAccount(): AccountModel[] {
+ return this.knownAccounts.filter((_) => _.type === AccountType.LEDGER_OPT_IN);
+ }
+
+ public get hasAddAccountModal(): boolean {
+ return this.isAddingAccount;
+ }
+
+ public set hasAddAccountModal(f: boolean) {
+ this.isAddingAccount = f;
+ }
+
+ public get hasBackupProfileModal(): boolean {
+ return this.isViewingExportModal;
+ }
+
+ public set hasBackupProfileModal(f: boolean) {
+ this.isViewingExportModal = f;
+ }
+
+ /// end-region computed properties getter/setter
+
+ /**
+ * Whether the account item is the current account
+ * @param item
+ * @return {boolean}
+ */
+ public isActiveAccount(item): boolean {
+ return item.id === this.currentAccount.id;
+ }
+}
diff --git a/src/components/AccountSignerSelector/AccountSignerSelector.ts b/src/components/AccountSignerSelector/AccountSignerSelector.ts
new file mode 100644
index 0000000..d11175a
--- /dev/null
+++ b/src/components/AccountSignerSelector/AccountSignerSelector.ts
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// child components
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { mapGetters } from 'vuex';
+import { AccountService } from '@/services/AccountService';
+
+@Component({
+ components: { FormRow },
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ accountModels: 'account/knownAccounts',
+ }),
+ },
+})
+export class AccountSignerSelectorTs extends Vue {
+ accountModels: AccountModel[];
+
+ @Prop({
+ default: 'sender',
+ })
+ label: string;
+
+ @Prop({
+ default: false,
+ })
+ noLabel: boolean;
+
+ @Prop({
+ default: false,
+ })
+ disabled: boolean;
+
+ /**
+ * Currently active account
+ */
+ public currentAccount: AccountModel;
+
+ /// region computed properties getter/setter
+ /**
+ * Value set by the parent component
+ * @type {string}
+ */
+ get chosenAccount(): string {
+ return this.currentAccount.id;
+ }
+ set chosenAccount(id: string) {
+ this.onChangeCurrentAccount(id);
+ }
+
+ /**
+ * Hook called when a current account is selected.
+ * @param id
+ */
+ public async onChangeCurrentAccount(id: string) {
+ if (!id || !id.length) {
+ return;
+ }
+
+ const account = new AccountService().getAccount(id);
+ if (!account) {
+ return;
+ }
+
+ if (!this.currentAccount || account.id !== this.currentAccount.id) {
+ await this.$store.dispatch('account/SET_CURRENT_ACCOUNT', account);
+ }
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AccountSignerSelector/AccountSignerSelector.vue b/src/components/AccountSignerSelector/AccountSignerSelector.vue
new file mode 100644
index 0000000..7898769
--- /dev/null
+++ b/src/components/AccountSignerSelector/AccountSignerSelector.vue
@@ -0,0 +1,27 @@
+
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+ {{ `${item.name} - ${item.address.slice(0, 5)}...${item.address.slice(34)}` }}
+
+
+
+
+
+
+
+
diff --git a/src/components/ActionDisplay/ActionDisplay.vue b/src/components/ActionDisplay/ActionDisplay.vue
new file mode 100644
index 0000000..e78e8e8
--- /dev/null
+++ b/src/components/ActionDisplay/ActionDisplay.vue
@@ -0,0 +1,22 @@
+
+
+
+
+ {{ $t(`transaction_descriptor_${transaction.type}`) }}
+ ({{ $t('click_to_cosign') }})
+
+
+
+
+
diff --git a/src/components/ActionDisplay/ActionDisplayTs.ts b/src/components/ActionDisplay/ActionDisplayTs.ts
new file mode 100644
index 0000000..cf65ba7
--- /dev/null
+++ b/src/components/ActionDisplay/ActionDisplayTs.ts
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { Address, Transaction, TransactionType } from 'symbol-sdk';
+// @ts-ignore
+import AddressDisplay from '@/components/AddressDisplay/AddressDisplay.vue';
+import { mapGetters } from 'vuex';
+
+@Component({
+ components: {
+ AddressDisplay,
+ },
+ computed: {
+ ...mapGetters({
+ address: 'account/currentAccountAddress',
+ }),
+ },
+})
+export class ActionDisplayTs extends Vue {
+ /**
+ * Transaction
+ * @type {Transaction}
+ */
+ @Prop({ default: null }) transaction: Transaction;
+ /**
+ * Transaction type from SDK
+ * @type {TransactionType}
+ */
+ public transactionType = TransactionType;
+
+ /**
+ * @protected
+ * @type {boolean}
+ */
+ protected address: Address;
+
+ /**
+ * Whether the transaction needs a cosignature
+ * // @TODO
+ * @protected
+ * @type {boolean}
+ */
+ protected needsCosignature: boolean = false;
+}
diff --git a/src/components/AddCosignatoryInput/AddCosignatoryInput.vue b/src/components/AddCosignatoryInput/AddCosignatoryInput.vue
new file mode 100644
index 0000000..f7813d6
--- /dev/null
+++ b/src/components/AddCosignatoryInput/AddCosignatoryInput.vue
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AddCosignatoryInput/AddCosignatoryInputTs.ts b/src/components/AddCosignatoryInput/AddCosignatoryInputTs.ts
new file mode 100644
index 0000000..0c26f8e
--- /dev/null
+++ b/src/components/AddCosignatoryInput/AddCosignatoryInputTs.ts
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { Address, NetworkType, PublicAccount, RepositoryFactory } from 'symbol-sdk';
+// internal dependencies
+import { AddressValidator, PublicKeyValidator } from '@/core/validation/validators';
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+// child components
+import { ValidationObserver, ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+// @ts-ignore
+import ButtonAdd from '@/components/ButtonAdd/ButtonAdd.vue';
+import { FilterHelpers } from '@/core/utils/FilterHelpers';
+
+@Component({
+ components: {
+ ValidationObserver,
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ ButtonAdd,
+ },
+ computed: {
+ ...mapGetters({
+ repositoryFactory: 'network/repositoryFactory',
+ networkType: 'network/networkType',
+ }),
+ },
+})
+export class AddCosignatoryInputTs extends Vue {
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /**
+ * Current peer
+ * @private
+ * @type {string}
+ */
+ private repositoryFactory: RepositoryFactory;
+
+ /**
+ * Current network type
+ * @private
+ * @type {NetworkType}
+ */
+ private networkType: NetworkType;
+
+ /**
+ * Cosignatory input (address or public key)
+ * @protected
+ * @type {string}
+ */
+ public cosignatory: string = '';
+
+ /**
+ * Handles the form submission
+ * @protected
+ * @return {void}
+ */
+ protected onAddCosignatory(): void {
+ if (AddressValidator.validate(this.cosignatory)) {
+ this.addCosignerFromAddress();
+ this.cosignatory = '';
+ return;
+ } else if (PublicKeyValidator.validate(this.cosignatory, this.networkType)) {
+ this.addCosignerFromPublicKey();
+ this.cosignatory = '';
+ return;
+ } else {
+ this.$store.dispatch('notification/ADD_ERROR', 'address_not_valid');
+ return;
+ }
+ }
+
+ /**
+ * Emits onAddCosignatory event when cosignatory is input as a public key
+ * @private
+ * @return {void}
+ */
+ private addCosignerFromPublicKey(): void {
+ if (!this.cosignatory) {
+ return;
+ }
+ const publicAccount = PublicAccount.createFromPublicKey(this.cosignatory, this.networkType);
+ this.$emit('added', publicAccount.address);
+ }
+
+ /**
+ * Emits onAddCosignatory event when cosignatory is input as an address
+ * @private
+ * @return {void}
+ */
+ private async addCosignerFromAddress() {
+ this.$emit('added', Address.createFromRawAddress(this.cosignatory));
+ }
+ /**
+ * filter tags
+ */
+ public stripTagsCosignatory() {
+ this.cosignatory = FilterHelpers.stripFilter(this.cosignatory);
+ }
+}
diff --git a/src/components/AddressDisplay/AddressDisplay.vue b/src/components/AddressDisplay/AddressDisplay.vue
new file mode 100644
index 0000000..77bc533
--- /dev/null
+++ b/src/components/AddressDisplay/AddressDisplay.vue
@@ -0,0 +1,9 @@
+
+ {{ descriptor }}
+
+
+
diff --git a/src/components/AddressDisplay/AddressDisplayTs.ts b/src/components/AddressDisplay/AddressDisplayTs.ts
new file mode 100644
index 0000000..a7f55c4
--- /dev/null
+++ b/src/components/AddressDisplay/AddressDisplayTs.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { Address, NamespaceId } from 'symbol-sdk';
+
+@Component
+export class AddressDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ address: Address | NamespaceId;
+
+ /**
+ * Action descriptor
+ * @var {string}
+ */
+ public descriptor: string = '';
+
+ /**
+ * Hook called when the component is mounted
+ * @return {void}
+ */
+ public created() {
+ // - load transaction details
+ this.loadDetails();
+ }
+
+ /**
+ * Load transaction details
+ * @return {Promise}
+ */
+ protected async loadDetails(): Promise {
+ this.descriptor = '';
+ if (!this.address) {
+ return;
+ }
+ // in case of normal transfer, display pretty address
+ if (this.address instanceof Address) {
+ const contact = await this.$store.dispatch('addressBook/RESOLVE_ADDRESS', this.address.plain());
+ this.descriptor = contact ? contact.name : this.address.pretty();
+ } else if (this.address instanceof NamespaceId) {
+ this.descriptor = this.address.toHex();
+ this.descriptor = await this.$store.dispatch('namespace/RESOLVE_NAME', this.address);
+ }
+ }
+}
diff --git a/src/components/AddressInput/AddressInput.vue b/src/components/AddressInput/AddressInput.vue
new file mode 100644
index 0000000..c6992bb
--- /dev/null
+++ b/src/components/AddressInput/AddressInput.vue
@@ -0,0 +1,83 @@
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AddressQR/AddressQR.vue b/src/components/AddressQR/AddressQR.vue
new file mode 100644
index 0000000..57d7de2
--- /dev/null
+++ b/src/components/AddressQR/AddressQR.vue
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/src/components/AddressQR/AddressQRTs.ts b/src/components/AddressQR/AddressQRTs.ts
new file mode 100644
index 0000000..f3bf65c
--- /dev/null
+++ b/src/components/AddressQR/AddressQRTs.ts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { AddressQR } from 'symbol-qr-library';
+import { Address } from 'symbol-sdk';
+import { mapGetters } from 'vuex';
+import { IContact } from 'symbol-address-book';
+// @ts-ignore
+import QRCodeDisplay from '@/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue';
+@Component({
+ components: {
+ QRCodeDisplay,
+ },
+ computed: {
+ ...mapGetters({
+ generationHash: 'network/generationHash',
+ }),
+ },
+})
+export class AddressQRTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ contact: IContact;
+
+ /**
+ * Current network's generation hash
+ * @var {string}
+ */
+ public generationHash: string;
+
+ /// region computed properties getter/setter
+ get qrCodeArgs(): AddressQR {
+ if (!this.contact) {
+ return null;
+ }
+
+ try {
+ const addressObj = Address.createFromRawAddress(this.contact.address);
+ return new AddressQR(this.contact.name, this.contact.address, addressObj.networkType, this.generationHash);
+ } catch (error) {
+ return null;
+ }
+ }
+
+ get downloadName(): string {
+ return this.contact ? `contact-qr-${this.contact.name}.png` : '';
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/Alert/Alert.vue b/src/components/Alert/Alert.vue
new file mode 100644
index 0000000..39f01e3
--- /dev/null
+++ b/src/components/Alert/Alert.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
{{ value }}
+
+
+
+
+
+
+
diff --git a/src/components/AmountDisplay/AmountDisplay.vue b/src/components/AmountDisplay/AmountDisplay.vue
new file mode 100644
index 0000000..5a7ee93
--- /dev/null
+++ b/src/components/AmountDisplay/AmountDisplay.vue
@@ -0,0 +1,39 @@
+
+
+ {{ integerPart }}
+ {{ fractionalPart }}
+ ({{ displayedTicker }})
+
+
+
+
+
+
diff --git a/src/components/AmountDisplay/AmountDisplayTs.ts b/src/components/AmountDisplay/AmountDisplayTs.ts
new file mode 100644
index 0000000..7057b41
--- /dev/null
+++ b/src/components/AmountDisplay/AmountDisplayTs.ts
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { mapGetters } from 'vuex';
+
+// configuration
+
+@Component({
+ computed: {
+ ...mapGetters({
+ networkConfiguration: 'network/networkConfiguration',
+ }),
+ },
+})
+export class AmountDisplayTs extends Vue {
+ @Prop({ default: 0 }) value: number;
+
+ @Prop({ default: undefined }) decimals: number | undefined;
+
+ @Prop({ default: false }) showTicker: false;
+
+ @Prop({ default: '' }) ticker: string;
+
+ @Prop({ default: 'normal' }) size: 'normal' | 'smaller' | 'bigger' | 'biggest';
+
+ public networkConfiguration: NetworkConfigurationModel;
+
+ /// region computed properties getter/setter
+ get integerPart(): string {
+ return this.value >= 0 ? Math.floor(this.value).toLocaleString() : '-' + Math.floor(this.value * -1).toLocaleString();
+ }
+
+ get fractionalPart(): string {
+ const absoluteValue = Math.abs(this.value);
+ const rest = absoluteValue - Math.floor(absoluteValue);
+ const decimals = this.decimals === undefined ? this.networkConfiguration.maxMosaicDivisibility || 6 : this.decimals;
+ const formatOptions = {
+ minimumFractionDigits: 0,
+ maximumFractionDigits: decimals,
+ };
+ // remove leftmost 0 and rightmost 0s
+ return rest.toLocaleString(undefined, formatOptions).replace(/^0/, '');
+ }
+
+ /**
+ * Ticker displayed in the view
+ * @readonly
+ * @type {string}
+ */
+ get displayedTicker(): string {
+ return (this.showTicker && this.ticker) || '';
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AmountInput/AmountInput.vue b/src/components/AmountInput/AmountInput.vue
new file mode 100644
index 0000000..b41ce81
--- /dev/null
+++ b/src/components/AmountInput/AmountInput.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/AmountInput/AmountInputTs.ts b/src/components/AmountInput/AmountInputTs.ts
new file mode 100644
index 0000000..495be69
--- /dev/null
+++ b/src/components/AmountInput/AmountInputTs.ts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+
+// internal dependencies
+import { createValidationRuleSet } from '@/core/validation/ValidationRuleset';
+
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+import { mapGetters } from 'vuex';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { networkConfig } from '@/config';
+import { NetworkType } from 'symbol-sdk';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ },
+ computed: {
+ ...mapGetters({
+ mosaics: 'mosaic/mosaics',
+ networkType: 'network/networkType',
+ }),
+ },
+})
+export class AmountInputTs extends Vue {
+ @Prop({ default: '' }) value: string;
+ @Prop({ default: '' }) mosaicHex: string;
+
+ /**
+ * Available mosaics models
+ */
+ public mosaics: MosaicModel[];
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules;
+
+ public networkType: NetworkType;
+
+ created() {
+ // update validation rule to reflect correct mosaic divisibility
+ const chosenMosaic = this.mosaics.find((mosaic) => this.mosaicHex === mosaic.mosaicIdHex);
+ const networkConfigurationDefaults = networkConfig[this.networkType || NetworkType.TEST_NET].networkConfigurationDefaults;
+ networkConfigurationDefaults.maxMosaicDivisibility = chosenMosaic ? chosenMosaic.divisibility : 6;
+
+ // set validation rules for this field
+ this.validationRules = createValidationRuleSet(networkConfigurationDefaults);
+ }
+
+ /// region computed properties getter/setter
+ public get relativeValue(): string {
+ return this.value;
+ }
+
+ public set relativeValue(amount: string) {
+ this.$emit('input', amount);
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/AppLogo/AppLogo.less b/src/components/AppLogo/AppLogo.less
new file mode 100644
index 0000000..03268e8
--- /dev/null
+++ b/src/components/AppLogo/AppLogo.less
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.wrap {
+ .top_window {
+ .app-logo-container {
+ display: grid;
+ position: relative;
+ float: left;
+ height: 100%;
+ text-align: center;
+ align-items: center;
+
+ img {
+ height: 0.48rem;
+ }
+ }
+ }
+}
diff --git a/src/components/AppLogo/AppLogo.vue b/src/components/AppLogo/AppLogo.vue
new file mode 100644
index 0000000..8544e07
--- /dev/null
+++ b/src/components/AppLogo/AppLogo.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/AppLogo/AppLogoTs.ts b/src/components/AppLogo/AppLogoTs.ts
new file mode 100644
index 0000000..11ec3bd
--- /dev/null
+++ b/src/components/AppLogo/AppLogoTs.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+
+// configuration
+import { appConfig } from '@/config';
+
+// import logo as an image
+// @ts-ignore
+import logo from '@/views/resources/logo-dhealth.png';
+
+@Component
+export class AppLogoTs extends Vue {
+ /**
+ * Logo image
+ * @var {any}
+ */
+ public readonly logo = logo;
+
+ /**
+ * Title of the app
+ * @var {string}
+ */
+ public readonly appTitle = appConfig.title;
+}
diff --git a/src/components/ApprovalAndRemovalInput/ApprovalAndRemovalInput.vue b/src/components/ApprovalAndRemovalInput/ApprovalAndRemovalInput.vue
new file mode 100644
index 0000000..8e4be8f
--- /dev/null
+++ b/src/components/ApprovalAndRemovalInput/ApprovalAndRemovalInput.vue
@@ -0,0 +1,25 @@
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+
+
diff --git a/src/components/ApprovalAndRemovalInput/ApprovalAndRemovalInputTs.ts b/src/components/ApprovalAndRemovalInput/ApprovalAndRemovalInputTs.ts
new file mode 100644
index 0000000..7cf2c5b
--- /dev/null
+++ b/src/components/ApprovalAndRemovalInput/ApprovalAndRemovalInputTs.ts
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { MultisigAccountInfo } from 'symbol-sdk';
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+// configuration
+import { mapGetters } from 'vuex';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ networkConfiguration: 'network/networkConfiguration',
+ }),
+ },
+})
+export class ApprovalAndRemovalInputTs extends Vue {
+ /**
+ * Value bound to the form v-model
+ * @type {number}
+ */
+ @Prop({
+ default: '',
+ })
+ value: number;
+
+ /**
+ * Type of multisig account modification operation
+ * @type {('conversion' | 'modification')}
+ */
+ @Prop({
+ default: 'conversion',
+ })
+ operation: 'conversion' | 'modification';
+
+ /**
+ * Type of field
+ * @type {('approval' | 'removal')}
+ */
+ @Prop({
+ default: 'approval',
+ })
+ type: 'approval' | 'removal';
+
+ /**
+ * Current min approval or mun removal value of the target account
+ * @type {number}
+ */
+ @Prop({
+ default: null,
+ })
+ multisig: MultisigAccountInfo;
+
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /// region computed properties getter/setter
+ /**
+ * Gets the input value from the value prop
+ * @protected
+ * @type {number}
+ */
+ protected get chosenValue(): number {
+ return this.value;
+ }
+
+ /**
+ * Emits input value change to the parent
+ * @protected
+ */
+ protected set chosenValue(amount: number) {
+ this.$emit('input', amount);
+ }
+
+ /**
+ * Form label
+ * @readonly
+ * @protected
+ * @type {string}
+ */
+ protected get label(): string {
+ return this.type === 'approval' ? 'form_label_new_min_approval' : 'form_label_new_min_removal';
+ }
+
+ protected get description(): string {
+ return this.type === 'approval' ? 'form_label_description_min_approval' : 'form_label_description_min_removal';
+ }
+
+ /**
+ * Current minApproval or minRemoval of the target account
+ * @readonly
+ * @protected
+ * @type {number}
+ */
+ protected get currentValue(): number {
+ if (!this.multisig) {
+ return 0;
+ }
+ if (this.type === 'approval') {
+ return this.multisig.minApproval;
+ }
+ return this.multisig.minRemoval;
+ }
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ protected validationRules = ValidationRuleset;
+
+ /**
+ * Available input choices
+ * @readonly
+ * @protected
+ * @type {{label: string, value: number}}
+ */
+ protected get deltaOptions(): { value: number; newDelta: number }[] {
+ // For an account conversion, the minimum delta is 1
+ const isConversion = this.operation === 'conversion';
+
+ // minimum possible delta
+ const maxCosignatoriesPerAccount = this.networkConfiguration.maxCosignatoriesPerAccount;
+ const minDelta = isConversion ? 1 : 0 - this.currentValue;
+
+ return [...Array(maxCosignatoriesPerAccount).keys()].map((index: number) => {
+ const delta = minDelta + index;
+ const newValue = this.currentValue + delta;
+ return { value: delta, newDelta: newValue };
+ });
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/ButtonAdd/ButtonAdd.less b/src/components/ButtonAdd/ButtonAdd.less
new file mode 100644
index 0000000..6c37aeb
--- /dev/null
+++ b/src/components/ButtonAdd/ButtonAdd.less
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.round-button {
+ display: flex;
+ align-items: center;
+
+ .add-button-title {
+ font-size: @normalFont;
+ padding-left: 0.1rem;
+ }
+}
diff --git a/src/components/ButtonAdd/ButtonAdd.vue b/src/components/ButtonAdd/ButtonAdd.vue
new file mode 100644
index 0000000..4668fea
--- /dev/null
+++ b/src/components/ButtonAdd/ButtonAdd.vue
@@ -0,0 +1,21 @@
+
+
+
+ {{ title }}
+
+
+
+
+
+
diff --git a/src/components/ButtonCopyToClipboard/ButtonCopyToClipboard.less b/src/components/ButtonCopyToClipboard/ButtonCopyToClipboard.less
new file mode 100644
index 0000000..7a76541
--- /dev/null
+++ b/src/components/ButtonCopyToClipboard/ButtonCopyToClipboard.less
@@ -0,0 +1,25 @@
+@import '../../views/resources/css/variables.less';
+.copy-button-container {
+ color: @purple;
+ cursor: pointer;
+}
+.copy-icon {
+ width: 0.24rem;
+ height: 0.24rem;
+ color: @purpleDark;
+ padding: 2px;
+ margin-left: 5px;
+}
+
+.ivu-tooltip {
+ background-color: #00000000;
+}
+
+.icon {
+ height: 0.22rem;
+ width: 0.22rem;
+}
+
+.font-size-zero {
+ font-size: 0;
+}
diff --git a/src/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue b/src/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue
new file mode 100644
index 0000000..3b9c4e2
--- /dev/null
+++ b/src/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
diff --git a/src/components/ButtonCopyToClipboard/ButtonCopyToClipboardTs.ts b/src/components/ButtonCopyToClipboard/ButtonCopyToClipboardTs.ts
new file mode 100644
index 0000000..20362ad
--- /dev/null
+++ b/src/components/ButtonCopyToClipboard/ButtonCopyToClipboardTs.ts
@@ -0,0 +1,24 @@
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { UIHelpers } from '@/core/utils/UIHelpers';
+import { NotificationType } from '@/core/utils/NotificationType';
+
+@Component
+export class ButtonCopyToClipboardTs extends Vue {
+ @Prop({ default: null }) value: string;
+
+ @Prop({ default: 'button' }) type: 'button' | 'icon-black' | 'icon-white' | 'icon-gray';
+
+ @Prop({ default: 'mnemonic_copy' }) readonly tooltipText!: string;
+
+ copyToClipboard() {
+ const value: any = this.value;
+ if (value) {
+ try {
+ UIHelpers.copyToClipboard(value);
+ this.$store.dispatch('notification/ADD_SUCCESS', NotificationType.COPY_SUCCESS);
+ } catch (e) {
+ this.$store.dispatch('notification/ADD_ERROR', NotificationType.COPY_FAILED);
+ }
+ }
+ }
+}
diff --git a/src/components/ButtonRefresh/ButtonRefresh.less b/src/components/ButtonRefresh/ButtonRefresh.less
new file mode 100644
index 0000000..53f80fd
--- /dev/null
+++ b/src/components/ButtonRefresh/ButtonRefresh.less
@@ -0,0 +1,8 @@
+@import '../../views/resources/css/variables.less';
+
+.button-refresh {
+ font-size: 0.27rem;
+ font-weight: 600;
+ color: @primary;
+ cursor: pointer;
+}
diff --git a/src/components/ButtonRefresh/ButtonRefresh.vue b/src/components/ButtonRefresh/ButtonRefresh.vue
new file mode 100644
index 0000000..110febb
--- /dev/null
+++ b/src/components/ButtonRefresh/ButtonRefresh.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
diff --git a/src/components/ButtonRefresh/ButtonRefreshTs.ts b/src/components/ButtonRefresh/ButtonRefreshTs.ts
new file mode 100644
index 0000000..ef0404d
--- /dev/null
+++ b/src/components/ButtonRefresh/ButtonRefreshTs.ts
@@ -0,0 +1,3 @@
+import { Vue, Component } from 'vue-property-decorator';
+@Component
+export class ButtonRefreshTs extends Vue {}
diff --git a/src/components/ButtonRemove/ButtonRemove.vue b/src/components/ButtonRemove/ButtonRemove.vue
new file mode 100644
index 0000000..f0dd8da
--- /dev/null
+++ b/src/components/ButtonRemove/ButtonRemove.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/src/components/ContactDetailPanel/ContactDetailPanel.less b/src/components/ContactDetailPanel/ContactDetailPanel.less
new file mode 100644
index 0000000..c2c4d44
--- /dev/null
+++ b/src/components/ContactDetailPanel/ContactDetailPanel.less
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.account-detail-outer-container {
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-rows: auto;
+ background-color: @white;
+ border-radius: 0.04rem;
+ overflow: hidden;
+ padding-top: 2%;
+
+ .account-detail-inner-container {
+ width: 100%;
+ padding: 0.2rem 0.4rem;
+ margin: 0;
+ display: grid;
+ grid-template-columns: 2.1rem auto;
+ grid-template-rows: auto;
+ overflow: auto;
+
+ .right-container {
+ width: 100%;
+
+ .title-row {
+ font-size: @biggerFont;
+ }
+
+ .account-details-container {
+ height: 100%;
+ display: grid;
+ }
+
+ .right-container-title {
+ font-size: @normalFont;
+ color: #222;
+ font-weight: 500;
+ }
+
+ .account-details-grid {
+ background-color: white;
+ font-size: 18px;
+ display: inline-grid;
+ font-weight: 400;
+ color: @primary;
+ grid-auto-rows: 0.5rem;
+ padding-left: 10px;
+ }
+
+ .detail-row {
+ grid-row: span 1;
+ }
+
+ .detail-double-row {
+ grid-row: span 2;
+ }
+
+ .account-detail-row-3cols {
+ display: grid;
+ grid-template-columns: 1.4rem 5rem auto;
+ }
+
+ .account-detail-row {
+ display: grid;
+ grid-template-columns: 1.4rem 5rem;
+ }
+
+ .account-detail-cosignatory {
+ display: grid;
+ grid-template-rows: auto rem;
+ }
+
+ .account-detail-row,
+ .account-detail-row-3cols {
+ font .label {
+ font-family: @symbolFontMedium;
+ font-weight: bold;
+ margin-right: 10px;
+ width: 1.4rem;
+ }
+
+ /deep/ .value {
+ font-family: @symbolFontLight;
+ text-overflow: ellipsis;
+ color: @purpleDark;
+ }
+
+ /deep/ .value {
+ }
+ }
+ }
+
+ .left-container {
+ /deep/ .qr-code-image {
+ width: 1.5rem;
+ height: 1.5rem;
+ }
+ }
+ }
+
+ .account-actions-outer-container {
+ background-color: lightgray;
+ width: 100%;
+ padding: 25px 0 0 0;
+
+ .account-actions-inner-container {
+ background-color: lightseagreen;
+ width: 100%;
+ border-radius: 0.04rem;
+ }
+ }
+}
+
+.edit-account-name {
+ margin-left: 0.18rem;
+ cursor: pointer;
+}
+
+.icon-left-button {
+ width: 0.3rem;
+ height: 0.3rem;
+ color: @purpleDark;
+ margin-right: 0.18rem;
+}
+
+.consignatory_row {
+ display: grid;
+ grid-template-columns: 0.4rem 4.6rem;
+}
diff --git a/src/components/ContactDetailPanel/ContactDetailPanel.vue b/src/components/ContactDetailPanel/ContactDetailPanel.vue
new file mode 100644
index 0000000..e075e1d
--- /dev/null
+++ b/src/components/ContactDetailPanel/ContactDetailPanel.vue
@@ -0,0 +1,113 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ContactDetailPanel/ContactDetailPanelTs.ts b/src/components/ContactDetailPanel/ContactDetailPanelTs.ts
new file mode 100644
index 0000000..c950a7a
--- /dev/null
+++ b/src/components/ContactDetailPanel/ContactDetailPanelTs.ts
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// child components
+// @ts-ignore
+import AccountNameDisplay from '@/components/AccountNameDisplay/AccountNameDisplay.vue';
+// @ts-ignore
+import AddressQR from '@/components/AddressQR/AddressQR.vue';
+// @ts-ignore
+import AccountAddressDisplay from '@/components/AccountAddressDisplay/AccountAddressDisplay.vue';
+// @ts-ignore
+import AccountActions from '@/components/AccountActions/AccountActions.vue';
+// @ts-ignore
+import FormInputEditable from '@/components/FormInputEditable/FormInputEditable.vue';
+// @ts-ignore
+import ModalConfirm from '@/views/modals/ModalConfirm/ModalConfirm.vue';
+import { AddressBook, IContact } from 'symbol-address-book';
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+import { Address } from 'symbol-sdk';
+
+@Component({
+ components: {
+ AccountNameDisplay,
+ AddressQR,
+ AccountActions,
+ AccountAddressDisplay,
+ FormInputEditable,
+ ModalConfirm,
+ },
+ computed: {
+ ...mapGetters({
+ addressBook: 'addressBook/getAddressBook',
+ selectedContact: 'addressBook/getSelectedContact',
+ }),
+ address: function () {
+ return Address.createFromRawAddress(this.selectedContact.address).pretty();
+ },
+ },
+})
+export class ContactDetailPanelTs extends Vue {
+ public addressBook: AddressBook;
+
+ public selectedContact: IContact;
+
+ public showDeleteConfirmModal: boolean = false;
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ public saveProperty(propName: string) {
+ return (newVal: string) => {
+ if (propName === 'address') {
+ const plainAddress = Address.createFromRawAddress(this.selectedContact.address).plain();
+ this.selectedContact[propName] = plainAddress;
+ this.$forceUpdate();
+ } else {
+ this.selectedContact[propName] = newVal;
+ }
+ this.$store.dispatch('addressBook/UPDATE_CONTACT', { id: this.selectedContact.id, contact: this.selectedContact });
+ };
+ }
+
+ public get showDeleteModal() {
+ return this.showDeleteConfirmModal;
+ }
+
+ public set showDeleteModal(val: boolean) {
+ this.showDeleteConfirmModal = val;
+ }
+
+ public removeContact() {
+ this.$store.dispatch('addressBook/REMOVE_CONTACT', this.selectedContact.id);
+ this.showDeleteConfirmModal = false;
+ }
+}
diff --git a/src/components/ContactSelector/ContactSelector.less b/src/components/ContactSelector/ContactSelector.less
new file mode 100644
index 0000000..9364aec
--- /dev/null
+++ b/src/components/ContactSelector/ContactSelector.less
@@ -0,0 +1,52 @@
+@import '../../views/resources/css/variables.less';
+
+.button-container {
+ display: flex;
+ align-items: center;
+}
+
+.node-selector-container {
+ padding-top: 0;
+}
+
+.network-text {
+ color: @primary;
+ font-size: @smallFont;
+ margin-right: 10px;
+}
+
+.node-list-container {
+ margin-top: 0;
+
+ .node-list-head {
+ font-size: @smallFont;
+ color: @primary;
+ font-weight: 500;
+ }
+
+ .node-list-content {
+ border: none !important;
+ border: 0.02rem solid @line;
+ height: 2.5rem;
+ padding: 0.1rem 0;
+
+ ul {
+ overflow-x: hidden;
+ overflow-y: auto;
+ height: 100%;
+ position: relative;
+ }
+
+ .list-item {
+ font-size: @smallerFont;
+ color: @grayDark;
+ padding: 0.04rem 0.22rem;
+ width: 100%;
+ overflow: hidden;
+ }
+ }
+}
+
+.contact-selector {
+ -webkit-app-region: no-drag;
+}
diff --git a/src/components/ContactSelector/ContactSelector.vue b/src/components/ContactSelector/ContactSelector.vue
new file mode 100644
index 0000000..ba9c053
--- /dev/null
+++ b/src/components/ContactSelector/ContactSelector.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
diff --git a/src/components/ContactSelector/ContactSelectorTs.ts b/src/components/ContactSelector/ContactSelectorTs.ts
new file mode 100644
index 0000000..b659dad
--- /dev/null
+++ b/src/components/ContactSelector/ContactSelectorTs.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+//@ts-ignore
+import ModalNetworkNotMatchingProfile from '@/views/modals/ModalNetworkNotMatchingProfile/ModalNetworkNotMatchingProfile.vue';
+import { IContact, AddressBook } from 'symbol-address-book';
+
+@Component({
+ components: { ModalNetworkNotMatchingProfile },
+ computed: {
+ ...mapGetters({
+ addressBook: 'addressBook/getAddressBook',
+ }),
+ },
+})
+export class ContactSelectorTs extends Vue {
+ @Prop() onContactSelect: (id: string) => {};
+
+ public poptipVisible: boolean = false;
+ public addressBook: AddressBook;
+
+ /// region computed properties getter/setter
+ get contactList(): IContact[] {
+ return this.addressBook.getAllContacts();
+ }
+
+ /// end-region computed properties getter/setter
+
+ /**
+ * Switch the currently active peer
+ * @param id
+ */
+ public selectContact(id: string) {
+ this.$emit('change', id);
+ this.poptipVisible = false;
+ }
+ onPopTipShow() {
+ this.$forceUpdate();
+ }
+}
diff --git a/src/components/ContactSelectorPanel/ContactSelectorPanel.less b/src/components/ContactSelectorPanel/ContactSelectorPanel.less
new file mode 100644
index 0000000..7646cd8
--- /dev/null
+++ b/src/components/ContactSelectorPanel/ContactSelectorPanel.less
@@ -0,0 +1,244 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.account-switch-container {
+ .account-switch-header-container {
+ display: grid;
+ grid-template-columns: 60% 40%;
+ grid-template-rows: 100%;
+
+ .account-switch-header-left-container {
+ padding: 0 0.4rem;
+ margin: 0.2rem 0;
+
+ .section-title {
+ font-weight: 600;
+ color: @purpleDark;
+ font-family: @symbolFont;
+ }
+ }
+
+ .account-switch-header-right-container {
+ text-align: right;
+ padding: 0.19rem 0.2rem 0 0;
+ .back-up {
+ }
+ }
+ }
+
+ @passiveTextColor: #73747a;
+
+ .account-switch-body-container {
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-auto-rows: 0.7rem;
+ position: relative;
+ .active-background {
+ color: @black;
+ }
+
+ .inactive-background {
+ color: @grayLight;
+ }
+
+ .account-tile {
+ margin: 0 0.24rem;
+ position: relative;
+ padding: 0.14rem 0.25rem;
+ .account-tile-inner-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-rows: 50% 50%;
+ grid-template-columns: 100%;
+ font-weight: 900;
+ overflow: hidden;
+
+ .account-tile-upper-container {
+ .account-name {
+ color: @white;
+ }
+ }
+
+ .account-tile-lower-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-template-rows: 100%;
+ grid-template-columns: 80% 20%;
+
+ .account-amount {
+ }
+
+ .account-icons {
+ .account-icon {
+ }
+ }
+ }
+ }
+ }
+ }
+
+ .account-switch-footer-container {
+ padding: 0.3rem 0.3rem;
+ display: grid;
+ grid-template-columns: 50% 50%;
+ grid-template-rows: 100%;
+ text-align: center;
+ font-size: @normalFont;
+ font-family: @symbolFont;
+ line-height: 22px;
+ color: @purpleLightest;
+
+ .add-account {
+ .ivu-icon {
+ padding-right: 3px;
+ padding-bottom: 2px;
+ vertical-align: center;
+ }
+ }
+
+ .account-switch-header-right-container {
+ img {
+ width: 18px;
+ height: 16px;
+ padding-right: 5px;
+ // margin-top: 5px;
+ vertical-align: center;
+ }
+ }
+ }
+}
+
+.mosaic_data {
+ height: 0.65rem;
+ padding: 0.15rem 0.25rem 0.15rem 0;
+ display: flex;
+ flex-direction: row;
+ justify-items: center;
+ justify-content: space-between;
+ align-content: center;
+ align-items: center;
+ border-bottom: 0.01rem solid @line;
+ position: relative;
+ color: @purpleDark;
+ font-family: @symbolFontLight;
+
+ .namege_img {
+ position: absolute;
+ display: inline-block;
+ top: 0.2rem;
+
+ .mosaicIcon {
+ display: inline-block;
+ width: 0.28rem;
+ height: 0.28rem;
+ margin-left: 0.1rem;
+ }
+ }
+
+ .img_container {
+ display: inline-block;
+ position: absolute;
+ top: 0.23rem;
+ margin-right: 0.15rem;
+
+ img {
+ display: inline-block;
+ width: 0.22rem;
+ height: 0.2rem;
+ }
+
+ img.grayed-xym-logo {
+ opacity: 0.4;
+ -webkit-filter: grayscale(100%);
+ -moz-filter: grayscale(100%);
+ -o-filter: grayscale(100%);
+ -ms-filter: grayscale(100%);
+ filter: grayscale(100%);
+ }
+ }
+
+ .mosaic_name {
+ position: relative;
+ top: 0;
+ left: 0.4rem;
+ width: 1.8rem;
+ font-size: @bigFont;
+ font-weight: 400;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+
+ .active-background {
+ color: @black;
+ }
+ }
+
+ .account-type {
+ position: relative;
+ top: 0;
+ left: 0.4rem;
+ width: 1rem;
+ font-weight: 400;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .mosaic_value {
+ margin-left: 0.5rem;
+ text-align: right;
+
+ div:first-of-type {
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @blackLight;
+ }
+
+ div:nth-of-type(2) {
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @grayDark;
+ }
+ }
+
+ .small_icon {
+ width: 0.2rem;
+ height: 0.2rem;
+ margin-bottom: 0.05rem;
+ }
+}
+
+.icon-left-button {
+ width: 0.15rem;
+ height: 0.15rem;
+ color: @purpleDark;
+}
+
+.account-selector-panel {
+ height: 100%;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-template-rows: auto 1rem;
+ grid-auto-flow: row;
+ overflow: auto;
+}
diff --git a/src/components/ContactSelectorPanel/ContactSelectorPanel.vue b/src/components/ContactSelectorPanel/ContactSelectorPanel.vue
new file mode 100644
index 0000000..ad8707b
--- /dev/null
+++ b/src/components/ContactSelectorPanel/ContactSelectorPanel.vue
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
{{ item.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ContactSelectorPanel/ContactSelectorPanelTs.ts b/src/components/ContactSelectorPanel/ContactSelectorPanelTs.ts
new file mode 100644
index 0000000..daa406d
--- /dev/null
+++ b/src/components/ContactSelectorPanel/ContactSelectorPanelTs.ts
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { ValidationProvider } from 'vee-validate';
+// internal dependencies
+import { AddressBook, IContact } from 'symbol-address-book';
+// child components
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormLabel from '@/components/FormLabel/FormLabel.vue';
+// @ts-ignore
+import ModalFormSubAccountCreation from '@/views/modals/ModalFormSubAccountCreation/ModalFormSubAccountCreation.vue';
+// @ts-ignore
+import ModalImportAddressBook from '@/views/modals/ModalImportAddressBook/ModalImportAddressBook.vue';
+// @ts-ignore
+import AmountDisplay from '@/components/AmountDisplay/AmountDisplay.vue';
+// @ts-ignore
+import ModalBackupProfile from '@/views/modals/ModalBackupProfile/ModalBackupProfile.vue';
+// @ts-ignore
+import NavigationLinks from '@/components/NavigationLinks/NavigationLinks.vue';
+// @ts-ignore
+import ModalContactCreation from '@/views/modals/ModalContactCreation/ModalContactCreation.vue';
+import { UIHelpers } from '@/core/utils/UIHelpers';
+
+@Component({
+ components: {
+ MosaicAmountDisplay,
+ ModalFormSubAccountCreation,
+ ModalImportAddressBook,
+ ErrorTooltip,
+ FormLabel,
+ ValidationProvider,
+ AmountDisplay,
+ ModalBackupProfile,
+ ModalContactCreation,
+ NavigationLinks,
+ },
+ computed: {
+ ...mapGetters({
+ addressBook: 'addressBook/getAddressBook',
+ selectedContact: 'addressBook/getSelectedContact',
+ }),
+ },
+})
+export class ContactSelectorPanelTs extends Vue {
+ /**
+ * Address book
+ * @see {Store.addressBook}
+ * @var {AddressBook}
+ */
+ public addressBook: AddressBook;
+ /**
+ * Selected contact
+ * @see {Store.addressBook}
+ * @var {IContact}
+ */
+ public selectedContact: IContact;
+
+ public hasAddAccountModal: boolean = false;
+
+ public hasImportProfileModal: boolean = false;
+
+ public get allContacts(): IContact[] {
+ return this.addressBook.getAllContacts();
+ }
+
+ public set selectedContactId(id: string) {
+ const newSelectedContact = this.addressBook.getContactById(id);
+ this.$store.commit('addressBook/setSelectedContact', newSelectedContact);
+ }
+ public get selectedContactId() {
+ return this.selectedContact.id;
+ }
+
+ public isActiveContact(contact: IContact): boolean {
+ if (!this.selectedContact) {
+ return false;
+ }
+ return this.selectedContact.id === contact.id;
+ }
+
+ public downloadAddressBook() {
+ UIHelpers.downloadBytesAsFile(this.addressBook.toJSON(), `address-book.json`, 'application/json');
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/CosignatoryModificationsDisplay/CosignatoryModificationsDisplay.vue b/src/components/CosignatoryModificationsDisplay/CosignatoryModificationsDisplay.vue
new file mode 100644
index 0000000..05e1b46
--- /dev/null
+++ b/src/components/CosignatoryModificationsDisplay/CosignatoryModificationsDisplay.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/src/components/CosignatoryModificationsDisplay/CosignatoryModificationsDisplayTs.ts b/src/components/CosignatoryModificationsDisplay/CosignatoryModificationsDisplayTs.ts
new file mode 100644
index 0000000..866aee4
--- /dev/null
+++ b/src/components/CosignatoryModificationsDisplay/CosignatoryModificationsDisplayTs.ts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { NetworkType } from 'symbol-sdk';
+
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+import { CosignatoryModifications } from '@/views/forms/FormMultisigAccountModificationTransaction/FormMultisigAccountModificationTransactionTs';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ networkType: 'network/networkType',
+ }),
+ },
+})
+export class CosignatoryModificationsDisplayTs extends Vue {
+ /**
+ * Cosignatory modifications
+ * @type {CosignatoryModifications}
+ */
+ @Prop({
+ default: {},
+ })
+ cosignatoryModifications: CosignatoryModifications;
+
+ private networkType: NetworkType;
+
+ get modifications(): {
+ address: string;
+ addOrRemove: 'add' | 'remove';
+ }[] {
+ return Object.values(this.cosignatoryModifications).map(({ addOrRemove, cosignatory }) => ({
+ address: cosignatory.pretty(),
+ addOrRemove,
+ }));
+ }
+}
diff --git a/src/components/DeleteProfileButton/DeleteProfileButton.less b/src/components/DeleteProfileButton/DeleteProfileButton.less
new file mode 100644
index 0000000..9e5300e
--- /dev/null
+++ b/src/components/DeleteProfileButton/DeleteProfileButton.less
@@ -0,0 +1,5 @@
+@import '../../views/resources/css/variables.less';
+
+button {
+ padding: 0 0.35rem;
+}
diff --git a/src/components/DeleteProfileButton/DeleteProfileButton.vue b/src/components/DeleteProfileButton/DeleteProfileButton.vue
new file mode 100644
index 0000000..139e4b7
--- /dev/null
+++ b/src/components/DeleteProfileButton/DeleteProfileButton.vue
@@ -0,0 +1,23 @@
+
+
+
+ {{ $t('delete_profile') }}
+
+
+
+
+
+
diff --git a/src/components/DeleteProfileButton/DeleteProfileButtonTs.ts b/src/components/DeleteProfileButton/DeleteProfileButtonTs.ts
new file mode 100644
index 0000000..8ccde8c
--- /dev/null
+++ b/src/components/DeleteProfileButton/DeleteProfileButtonTs.ts
@@ -0,0 +1,28 @@
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { Vue, Component } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// @ts-ignore
+import ModalConfirm from '@/views/modals/ModalConfirm/ModalConfirm.vue';
+import { ProfileService } from '@/services/ProfileService';
+
+@Component({
+ components: {
+ ModalConfirm,
+ },
+ computed: {
+ ...mapGetters({
+ currentProfile: 'profile/currentProfile',
+ }),
+ },
+})
+export class DeleteProfileButtonTs extends Vue {
+ public showConfirmationModal = false;
+ public currentProfile: ProfileModel;
+
+ private profileService: ProfileService = new ProfileService();
+
+ public async deleteProfile() {
+ this.profileService.deleteProfile(this.currentProfile.profileName);
+ this.$emit('logout');
+ }
+}
diff --git a/src/components/DisabledFormOverlay/DisabledFormOverlay.less b/src/components/DisabledFormOverlay/DisabledFormOverlay.less
new file mode 100644
index 0000000..b2c52c8
--- /dev/null
+++ b/src/components/DisabledFormOverlay/DisabledFormOverlay.less
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+.multisig_ban_container {
+ font-size: 16px !important;
+ .is_multisig {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ background-color: white;
+ opacity: 0.4;
+ z-index: 2;
+ left: 0;
+ }
+}
diff --git a/src/components/DisabledFormOverlay/DisabledFormOverlay.vue b/src/components/DisabledFormOverlay/DisabledFormOverlay.vue
new file mode 100644
index 0000000..cfa2eae
--- /dev/null
+++ b/src/components/DisabledFormOverlay/DisabledFormOverlay.vue
@@ -0,0 +1,92 @@
+
+
+
+ {{ $t(alert) }}
+
+
+
+
+
+
+
+
diff --git a/src/components/DisabledUiOverlay/DisabledUiOverlay.less b/src/components/DisabledUiOverlay/DisabledUiOverlay.less
new file mode 100644
index 0000000..1829f55
--- /dev/null
+++ b/src/components/DisabledUiOverlay/DisabledUiOverlay.less
@@ -0,0 +1,6 @@
+.disabledUiOverlay {
+ .uiDisabledMessage {
+ text-align: center;
+ font-size: 2em;
+ }
+}
diff --git a/src/components/DisabledUiOverlay/DisabledUiOverlay.vue b/src/components/DisabledUiOverlay/DisabledUiOverlay.vue
new file mode 100644
index 0000000..716130d
--- /dev/null
+++ b/src/components/DisabledUiOverlay/DisabledUiOverlay.vue
@@ -0,0 +1,25 @@
+
+
+
+
+ {{ $t(message) }}
+
+
+
+
+
+
+
diff --git a/src/components/DisabledUiOverlay/DisabledUiOverlayTs.ts b/src/components/DisabledUiOverlay/DisabledUiOverlayTs.ts
new file mode 100644
index 0000000..b465f81
--- /dev/null
+++ b/src/components/DisabledUiOverlay/DisabledUiOverlayTs.ts
@@ -0,0 +1,23 @@
+import { mapState } from 'vuex';
+import { Component, Vue } from 'vue-property-decorator';
+
+@Component({
+ computed: { ...mapState({ app: 'app' }) },
+})
+export class DisabledUiOverlayTs extends Vue {
+ app: any;
+
+ get show() {
+ return this.app.isUiDisabled;
+ }
+
+ set show(val) {
+ if (!val) {
+ this.$emit('close');
+ }
+ }
+
+ get message() {
+ return this.app.uiDisabledMessage;
+ }
+}
diff --git a/src/components/DivisibilityInput/DivisibilityInput.vue b/src/components/DivisibilityInput/DivisibilityInput.vue
new file mode 100644
index 0000000..1e76552
--- /dev/null
+++ b/src/components/DivisibilityInput/DivisibilityInput.vue
@@ -0,0 +1,25 @@
+
+
+ {{ $t('divisibility') }}:
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/DivisibilityInput/DivisibilityInputTs.ts b/src/components/DivisibilityInput/DivisibilityInputTs.ts
new file mode 100644
index 0000000..b942937
--- /dev/null
+++ b/src/components/DivisibilityInput/DivisibilityInputTs.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+})
+export class DivisibilityInputTs extends Vue {
+ @Prop({ default: '' }) value: string;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /// region computed properties getter/setter
+ public get chosenValue(): string {
+ return this.value;
+ }
+
+ public set chosenValue(amount: string) {
+ if (parseInt(amount) > 6) {
+ amount = '6';
+ }
+ if (parseInt(amount) < 0) {
+ amount = '0';
+ }
+ this.$emit('input', amount);
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/DurationInput/DurationInput.less b/src/components/DurationInput/DurationInput.less
new file mode 100644
index 0000000..8380976
--- /dev/null
+++ b/src/components/DurationInput/DurationInput.less
@@ -0,0 +1,11 @@
+.chosenValue-container {
+ position: relative;
+ height: 100%;
+ .relative-time {
+ position: absolute;
+ right: 0.6rem;
+ top: 0.05rem;
+ display: flex;
+ align-items: center;
+ }
+}
diff --git a/src/components/DurationInput/DurationInput.vue b/src/components/DurationInput/DurationInput.vue
new file mode 100644
index 0000000..d4a614f
--- /dev/null
+++ b/src/components/DurationInput/DurationInput.vue
@@ -0,0 +1,25 @@
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+
+ {{ $t('estimated_period_of_validity') }}: {{ relativeTime }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/DurationInput/DurationInputTs.ts b/src/components/DurationInput/DurationInputTs.ts
new file mode 100644
index 0000000..c32798f
--- /dev/null
+++ b/src/components/DurationInput/DurationInputTs.ts
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+import { mapGetters } from 'vuex';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ networkConfiguration: 'network/networkConfiguration',
+ }),
+ },
+})
+export class DurationInputTs extends Vue {
+ @Prop({ default: '' }) value: string;
+
+ /**
+ * Asset type
+ * @type {('mosaic' | 'namespace')}
+ */
+ @Prop({ default: 'mosaic' }) targetAsset: 'mosaic' | 'namespace';
+
+ /**
+ * Field label
+ * @type {string}
+ */
+ @Prop({ default: 'form_label_duration' }) label: string;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /**
+ * Injected network configuration.
+ */
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /**
+ * the toggle for the display of realativeTime
+ * @type boolean
+ */
+ @Prop({ default: false }) showRelativeTime: boolean;
+
+ /// region computed properties getter/setter
+ public get chosenValue(): string {
+ return this.value;
+ }
+
+ public set chosenValue(amount: string) {
+ this.$emit('input', amount);
+ }
+
+ /**
+ * @return relativeTime example: 56d 21h 18m
+ */
+ public get relativeTime() {
+ const duration = parseInt(this.value);
+ if (isNaN(duration) || 0 === duration) {
+ return this.$t('label_duration_unlimited');
+ }
+
+ return TimeHelpers.durationToRelativeTime(duration, this.networkConfiguration.blockGenerationTargetTime);
+ }
+
+ public get validationRule(): string {
+ return this.targetAsset === 'mosaic' ? this.validationRules.duration : this.validationRules.namespaceDuration;
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/ErrorTooltip/ErrorTooltip.vue b/src/components/ErrorTooltip/ErrorTooltip.vue
new file mode 100644
index 0000000..543c418
--- /dev/null
+++ b/src/components/ErrorTooltip/ErrorTooltip.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/src/components/ErrorTooltip/ErrorTooltipTs.ts b/src/components/ErrorTooltip/ErrorTooltipTs.ts
new file mode 100644
index 0000000..75a8b3e
--- /dev/null
+++ b/src/components/ErrorTooltip/ErrorTooltipTs.ts
@@ -0,0 +1,59 @@
+import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
+
+@Component
+export class ErrorTooltipTs extends Vue {
+ /**
+ * Tooltip placement
+ * @type {string}
+ */
+ @Prop({ default: 'top-end' }) placementOverride!: string;
+
+ /**
+ * Errors returned by the Validation Provider
+ * @type {string[]}
+ */
+ @Prop() errors!: string[];
+
+ /**
+ * Error message shown in the tooltip
+ * @var {string}
+ */
+ displayedError = '';
+
+ /**
+ * The string of the first error message
+ * @readonly
+ * @type {string}
+ */
+ get fieldError(): string | null {
+ if (!this.errors) {
+ return null;
+ }
+ if (!this.errors.length) {
+ return null;
+ }
+ return this.errors.shift() || null;
+ }
+
+ /**
+ * Errored state
+ * @readonly
+ * @type {boolean}
+ */
+ get errored(): boolean {
+ return this.fieldError !== null;
+ }
+
+ /**
+ * Sets the string shown in the tooltip
+ * (To avoid an ugly-looking behaviour,
+ * it must not switch to a falsy value or an empty string)
+ * @param {string} newValue
+ */
+ @Watch('fieldError', { immediate: true })
+ onFieldErrorChanged(newValue: string) {
+ if (newValue && newValue !== '') {
+ this.displayedError = newValue;
+ }
+ }
+}
diff --git a/src/components/ExplorerUrlSetter/ExplorerUrlSetter.vue b/src/components/ExplorerUrlSetter/ExplorerUrlSetter.vue
new file mode 100644
index 0000000..ecdd595
--- /dev/null
+++ b/src/components/ExplorerUrlSetter/ExplorerUrlSetter.vue
@@ -0,0 +1,55 @@
+
+
+ {{ $t('set_explorer_link') }}:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ExplorerUrlSetter/ExplorerUrlSetterTs.ts b/src/components/ExplorerUrlSetter/ExplorerUrlSetterTs.ts
new file mode 100644
index 0000000..e9c985e
--- /dev/null
+++ b/src/components/ExplorerUrlSetter/ExplorerUrlSetterTs.ts
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+
+// child components
+import { ValidationProvider, ValidationObserver } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+// configuration
+import { networkConfig } from '@/config';
+import { NetworkType } from 'symbol-sdk';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ValidationObserver,
+ ErrorTooltip,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ explorerUrl: 'app/explorerUrl',
+ networkType: 'network/networkType',
+ }),
+ },
+})
+export class ExplorerUrlSetterTs extends Vue {
+ @Prop({
+ default: '',
+ })
+ value: string;
+
+ @Prop({
+ default: true,
+ })
+ autoSubmit: boolean;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /**
+ * Explorer URL
+ * @var {string}
+ */
+ public explorerUrl: string;
+
+ public networkType: NetworkType;
+
+ /**
+ * Default explorer link list
+ * @readonly
+ * @type {string[]}
+ */
+ get defaultExplorerLinkList(): string[] {
+ // @TODO
+ return [networkConfig[this.networkType].explorerUrl];
+ }
+
+ /**
+ * Currently explorer url
+ */
+ get chosenExplorerUrl() {
+ return this.value && this.value.length ? this.value : this.explorerUrl;
+ }
+
+ /**
+ * Sets the new language
+ */
+ set chosenExplorerUrl(url: string) {
+ if (this.autoSubmit) {
+ this.$store.dispatch('app/SET_EXPLORER_URL', url);
+ }
+
+ this.$emit('input', url);
+ }
+}
diff --git a/src/components/FormInputEditable/FormInputEditable.vue b/src/components/FormInputEditable/FormInputEditable.vue
new file mode 100644
index 0000000..9245221
--- /dev/null
+++ b/src/components/FormInputEditable/FormInputEditable.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/FormInputEditable/FormInputEditableTs.ts b/src/components/FormInputEditable/FormInputEditableTs.ts
new file mode 100644
index 0000000..98c9092
--- /dev/null
+++ b/src/components/FormInputEditable/FormInputEditableTs.ts
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
+
+// child components
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormLabel from '@/components/FormLabel/FormLabel.vue';
+// @ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+// child components
+import { ValidationObserver, ValidationProvider } from 'vee-validate';
+
+@Component({
+ components: {
+ ErrorTooltip,
+ FormLabel,
+ ButtonCopyToClipboard,
+ ValidationObserver,
+ ValidationProvider,
+ },
+})
+export class FormInputEditableTs extends Vue {
+ @Prop()
+ model: any;
+
+ @Prop()
+ label: string;
+
+ @Prop()
+ value: string;
+
+ @Prop({ default: 'required' })
+ rules: string;
+
+ newValue: string;
+
+ @Prop()
+ onEdit: (v: string) => {};
+
+ editing: boolean = false;
+
+ /**
+ * Type the ValidationObserver refs
+ * @type {{
+ * observer: InstanceType
+ * }}
+ */
+ public $refs!: {
+ observer: InstanceType;
+ };
+
+ public startEditing() {
+ this.newValue = '' + (this.value ? this.value : '');
+ this.editing = true;
+ }
+
+ public finishEdition() {
+ this.editing = false;
+ this.value = '' + this.newValue;
+ this.onEdit(this.value);
+ }
+ @Watch('model', { immediate: true })
+ public cancelEdition() {
+ this.editing = false;
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/FormLabel/FormLabel.vue b/src/components/FormLabel/FormLabel.vue
new file mode 100644
index 0000000..b490a73
--- /dev/null
+++ b/src/components/FormLabel/FormLabel.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/FormRow/FormRow.less b/src/components/FormRow/FormRow.less
new file mode 100644
index 0000000..e84283f
--- /dev/null
+++ b/src/components/FormRow/FormRow.less
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+@import '../../views/resources/css/variables.less';
+.form-row {
+ width: auto;
+
+ .form-row-inner-container {
+ align-items: initial;
+
+ &.form-row-vertical {
+ .label-container {
+ .form-label-container {
+ padding: 0.08rem 0;
+ .form-label {
+ color: yellow;
+ padding-left: 0 !important;
+ }
+ }
+ }
+ .inputs-container {
+ .inputs-create-container {
+ margin: 0 0.7rem;
+ width: 92%;
+
+ .select-style {
+ padding-right: 0.08rem;
+ }
+ }
+ }
+ }
+ }
+
+ .flex-container {
+ display: flex;
+ justify-content: initial;
+ float: right;
+ }
+}
diff --git a/src/components/FormRow/FormRow.vue b/src/components/FormRow/FormRow.vue
new file mode 100644
index 0000000..dfc7a5e
--- /dev/null
+++ b/src/components/FormRow/FormRow.vue
@@ -0,0 +1,37 @@
+
+
+
+
+
+
diff --git a/src/components/FormTitle/FormTitle.less b/src/components/FormTitle/FormTitle.less
new file mode 100644
index 0000000..ce3df11
--- /dev/null
+++ b/src/components/FormTitle/FormTitle.less
@@ -0,0 +1,17 @@
+.form-title-container {
+ padding-top: 70px;
+ display: block;
+ float: left;
+ width: 100%;
+ clear: both;
+ overflow: hidden;
+ height: 1.4rem;
+ border-bottom: 0.01rem solid #eee;
+ margin-bottom: 20px;
+
+ .form-title {
+ font-size: 24px;
+ font-weight: 400;
+ color: #000;
+ }
+}
diff --git a/src/components/FormTitle/FormTitle.vue b/src/components/FormTitle/FormTitle.vue
new file mode 100644
index 0000000..2d4226d
--- /dev/null
+++ b/src/components/FormTitle/FormTitle.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/FormWrapper/FormWrapper.vue b/src/components/FormWrapper/FormWrapper.vue
new file mode 100644
index 0000000..cbb24c7
--- /dev/null
+++ b/src/components/FormWrapper/FormWrapper.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/HardwareConfirmationButton/HardwareConfirmationButton.vue b/src/components/HardwareConfirmationButton/HardwareConfirmationButton.vue
new file mode 100644
index 0000000..4b15d82
--- /dev/null
+++ b/src/components/HardwareConfirmationButton/HardwareConfirmationButton.vue
@@ -0,0 +1,13 @@
+
+
+
+ {{ $t('confirm') }}
+
+
+
+
+
diff --git a/src/components/HardwareConfirmationButton/HardwareConfirmationButtonTs.ts b/src/components/HardwareConfirmationButton/HardwareConfirmationButtonTs.ts
new file mode 100644
index 0000000..2e07520
--- /dev/null
+++ b/src/components/HardwareConfirmationButton/HardwareConfirmationButtonTs.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { Transaction, SignedTransaction, CosignatureTransaction, CosignatureSignedTransaction } from 'symbol-sdk';
+
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import TrezorConnect from '@/core/utils/TrezorConnect';
+import { TransactionSigner } from '@/services/TransactionAnnouncerService';
+import { from, Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ }),
+ },
+})
+export class HardwareConfirmationButtonTs extends Vue implements TransactionSigner {
+ /**
+ * Currently active account
+ * @see {Store.Account}
+ * @var {AccountModel}
+ */
+ public currentAccount: AccountModel;
+
+ /**
+ * Process with hardware confirmation (currently trezor only)
+ * @return {void}
+ */
+ public async processHardware() {
+ return this.$emit('success', this);
+ }
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ signCosignatureTransaction(t: CosignatureTransaction): Observable {
+ throw new Error('Not Implemented!!!');
+ }
+
+ signTransaction(stagedTx: Transaction): Observable {
+ // - sign each transaction with TrezorConnect
+ const promise: Promise = TrezorConnect.nemSignTransaction({
+ path: this.currentAccount.path,
+ transaction: stagedTx,
+ });
+ return from(promise).pipe(
+ map((result) => {
+ if (!result.success) {
+ throw new Error(result.payload.error);
+ }
+ return new SignedTransaction(
+ result.payload.data,
+ stagedTx.transactionInfo.hash,
+ stagedTx.signer.publicKey,
+ stagedTx.type,
+ stagedTx.networkType,
+ );
+ }),
+ );
+ }
+}
diff --git a/src/components/HarvestStatisticsPanel/HarvestStatisticsPanel.less b/src/components/HarvestStatisticsPanel/HarvestStatisticsPanel.less
new file mode 100644
index 0000000..5bbf8a4
--- /dev/null
+++ b/src/components/HarvestStatisticsPanel/HarvestStatisticsPanel.less
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+@import '../../views/resources/css/variables.less';
+@import '../../views/resources/css/common.less';
+
+.top_harvesting_info {
+ background-color: transparent;
+ justify-content: space-between;
+ height: 100%;
+ width: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ .number-grow-warp {
+ display: inline-block;
+ }
+
+ .top_account_info {
+ width: 100%;
+ padding-left: 0.2rem;
+ padding-right: 0.2rem;
+ display: grid;
+ grid-template-columns: repeat(3, 33%);
+ grid-template-rows: 100%;
+
+ padding-top: 8px;
+ padding-bottom: 8px;
+
+ border-radius: @borderRadius;
+ background-color: white;
+
+ > div {
+ padding: 18px 0 18px 30px;
+ position: relative;
+
+ .title {
+ margin-bottom: 18px;
+
+ .title_txt {
+ font-size: 20px;
+ line-height: 33px;
+ color: @purpleDark;
+ }
+ }
+ }
+
+ .txt_info {
+ font-size: 40px;
+ font-weight: 400;
+ width: 180px;
+ display: inline-block;
+ color: #5200c6;
+ line-height: 40px;
+
+ button.button-style {
+ padding: 0;
+ }
+ }
+
+ .txt-small {
+ font-size: @normalFont;
+ text-transform: uppercase;
+ color: @purpleLightest;
+ line-height: 40px;
+ }
+
+ .status-indicator {
+ width: 15px;
+ height: 15px;
+ border-radius: 10px;
+ }
+
+ .red {
+ background-color: red;
+ }
+
+ .green {
+ background-color: green;
+ }
+
+ .amber {
+ background-color: #ffbf00;
+ }
+
+ .level-item {
+ margin-left: 15px;
+ }
+
+ .speed {
+ width: 65px;
+ }
+
+ .speed-blocks {
+ font-size: 16px;
+ line-height: 22px;
+ color: rgba(82, 0, 198, 1);
+ opacity: 0.75;
+ text-transform: lowercase;
+ }
+ }
+}
diff --git a/src/components/HarvestStatisticsPanel/HarvestStatisticsPanel.vue b/src/components/HarvestStatisticsPanel/HarvestStatisticsPanel.vue
new file mode 100644
index 0000000..36a61c5
--- /dev/null
+++ b/src/components/HarvestStatisticsPanel/HarvestStatisticsPanel.vue
@@ -0,0 +1,63 @@
+
+
+
+
+
+ {{ $t('harvesting_status') }}
+
+
+
+
+
{{ harvestingStatusIndicator.text }}
+
+
+
+
+
+
+ {{ $t('blocks_made') }}
+
+
+
+
+
+ {{ harvestedBlockStats.totalBlockCount }}
+
+
+
+
+
+
+ {{ $t('fees_collected') }}
+
+
+
+
+
+ {{ totalFeesEarned }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/HarvestStatisticsPanel/HarvestStatisticsPanelTs.ts b/src/components/HarvestStatisticsPanel/HarvestStatisticsPanelTs.ts
new file mode 100644
index 0000000..55cb33d
--- /dev/null
+++ b/src/components/HarvestStatisticsPanel/HarvestStatisticsPanelTs.ts
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Watch } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+
+import { AccountInfo } from 'symbol-sdk';
+import { HarvestedBlockStats, HarvestingStatus } from '@/store/Harvesting';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+import { HarvestingService } from '@/services/HarvestingService';
+import { HarvestingModel } from '@/core/database/entities/HarvestingModel';
+@Component({
+ computed: {
+ ...mapGetters({
+ currentSignerAccountInfo: 'account/currentSignerAccountInfo',
+ harvestingStatus: 'harvesting/status',
+ harvestedBlockStats: 'harvesting/harvestedBlockStats',
+ isFetchingHarvestedBlockStats: 'harvesting/isFetchingHarvestedBlockStats',
+ pollingTrials: 'harvesting/pollingTrials',
+ networkCurrency: 'mosaic/networkCurrency',
+ currentSignerHarvestingModel: 'harvesting/currentSignerHarvestingModel',
+ }),
+ },
+})
+export class HarvestStatisticsPanelTs extends Vue {
+ public currentSignerAccountInfo: AccountInfo;
+ public harvestingStatus: HarvestingStatus;
+ public harvestedBlockStats: HarvestedBlockStats;
+ public isFetchingHarvestedBlockStats: boolean;
+ public networkCurrency: NetworkCurrencyModel;
+
+ private pollingTrials: number;
+ private statusPollingInterval: any;
+ private statsPollingInterval: any;
+ private currentSignerHarvestingModel: HarvestingModel;
+ created() {
+ this.refresh();
+ this.checkUnLockedAccounts();
+ this.refreshStatusBlocks();
+ }
+
+ public refresh() {
+ this.refreshHarvestingStatus();
+ this.refreshHarvestingStats();
+ }
+
+ public refreshHarvestingStats() {
+ this.$store.dispatch('harvesting/LOAD_HARVESTED_BLOCKS_STATS');
+ }
+
+ public refreshHarvestingStatus() {
+ this.$store.dispatch('harvesting/FETCH_STATUS');
+ }
+
+ public get harvestingStatusIndicator() {
+ switch (this.harvestingStatus) {
+ case HarvestingStatus.ACTIVE:
+ return { cls: 'status-indicator green', text: this.$t('harvesting_status_active') };
+ case HarvestingStatus.INACTIVE:
+ return { cls: 'status-indicator red', text: this.$t('harvesting_status_inactive') };
+ case HarvestingStatus.KEYS_LINKED:
+ return { cls: 'status-indicator amber', text: this.$t('harvesting_status_keys_linked') };
+ case HarvestingStatus.INPROGRESS_ACTIVATION:
+ return { cls: 'status-indicator amber', text: this.$t('harvesting_status_inprogress_activation') };
+ case HarvestingStatus.INPROGRESS_DEACTIVATION:
+ return { cls: 'status-indicator amber', text: this.$t('harvesting_status_inprogress_deactivation') };
+ case HarvestingStatus.FAILED:
+ return { cls: 'status-indicator red', text: this.$t('harvesting_status_failed') };
+ }
+ }
+
+ private checkUnLockedAccounts(): void {
+ Vue.nextTick(() => {
+ const harvestingService = new HarvestingService();
+ if (this.harvestingStatus !== HarvestingStatus.FAILED) {
+ this.statusPollingInterval = setInterval(() => {
+ if (this.harvestingStatus === HarvestingStatus.INPROGRESS_ACTIVATION) {
+ if (this.pollingTrials < 20 && !this.currentSignerHarvestingModel.delegatedHarvestingRequestFailed) {
+ this.refreshHarvestingStatus();
+ this.$store.dispatch('harvesting/SET_POLLING_TRIALS', this.pollingTrials + 1);
+ } else {
+ const harvestingModel = harvestingService.getHarvestingModel(this.currentSignerHarvestingModel.accountAddress);
+ harvestingService.updateDelegatedHarvestingRequestFailed(harvestingModel, true);
+ return;
+ }
+ }
+ }, 45000);
+ } else {
+ const harvestingModel = harvestingService.getHarvestingModel(this.currentSignerHarvestingModel.accountAddress);
+ harvestingService.updateDelegatedHarvestingRequestFailed(harvestingModel, true);
+ return;
+ }
+ });
+ }
+
+ private refreshStatusBlocks(): void {
+ Vue.nextTick(() => {
+ this.statsPollingInterval = setInterval(() => {
+ if (this.harvestingStatus == HarvestingStatus.ACTIVE) {
+ this.refreshHarvestingStats();
+ }
+ }, 30000);
+ });
+ }
+
+ private destroyed() {
+ clearInterval(this.statusPollingInterval);
+ clearInterval(this.statsPollingInterval);
+ }
+ public get totalFeesEarned(): string {
+ const relativeAmount = this.harvestedBlockStats.totalFeesEarned.compact() / Math.pow(10, this.networkCurrency.divisibility);
+ if (relativeAmount === 0) {
+ return '0';
+ }
+ return relativeAmount.toLocaleString(undefined, {
+ minimumFractionDigits: 1,
+ maximumFractionDigits: this.networkCurrency.divisibility,
+ });
+ }
+
+ @Watch('currentSignerAccountInfo')
+ public refreshWatcher() {
+ this.refresh();
+ }
+}
diff --git a/src/components/ImportanceScoreDisplay/ImportanceScoreDisplay.vue b/src/components/ImportanceScoreDisplay/ImportanceScoreDisplay.vue
new file mode 100644
index 0000000..799e8ae
--- /dev/null
+++ b/src/components/ImportanceScoreDisplay/ImportanceScoreDisplay.vue
@@ -0,0 +1,12 @@
+
+
+ {{ $t('importance') }}:
+ {{ score }}
+
+
+
+
diff --git a/src/components/ImportanceScoreDisplay/ImportanceScoreDisplayTs.ts b/src/components/ImportanceScoreDisplay/ImportanceScoreDisplayTs.ts
new file mode 100644
index 0000000..ab1342c
--- /dev/null
+++ b/src/components/ImportanceScoreDisplay/ImportanceScoreDisplayTs.ts
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { AccountInfo } from 'symbol-sdk';
+// internal dependencies
+import { mapGetters } from 'vuex';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ accountsInfo: 'account/accountsInfo',
+ networkCurrency: 'mosaic/networkCurrency',
+ networkConfiguration: 'network/networkConfiguration',
+ }),
+ },
+})
+export class ImportanceScoreDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ address: string;
+
+ private accountsInfo: AccountInfo[];
+ private networkCurrency: NetworkCurrencyModel;
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /// region computed properties getter/setter
+ get score(): string {
+ const accountInfo = this.accountsInfo.find((k) => k.address.plain() === this.address);
+ if (!accountInfo) {
+ return '0 %';
+ }
+
+ if (!this.networkCurrency?.divisibility || !this.networkConfiguration?.totalChainImportance) {
+ return 'N/A';
+ }
+
+ const importance = accountInfo.importance.compact();
+
+ const relativeImportance = importance > 0 ? importance / this.networkConfiguration.totalChainImportance : importance;
+
+ const divisibility = this.networkCurrency.divisibility;
+ const formatOptions: Intl.NumberFormatOptions = {
+ maximumFractionDigits: divisibility,
+ style: 'percent',
+ };
+ return relativeImportance.toLocaleString(undefined, formatOptions);
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/LanguageSelector/LanguageSelector.less b/src/components/LanguageSelector/LanguageSelector.less
new file mode 100644
index 0000000..5ce0982
--- /dev/null
+++ b/src/components/LanguageSelector/LanguageSelector.less
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.switch_language {
+ -webkit-app-region: no-drag;
+ position: relative;
+}
diff --git a/src/components/LanguageSelector/LanguageSelector.vue b/src/components/LanguageSelector/LanguageSelector.vue
new file mode 100644
index 0000000..3993ea2
--- /dev/null
+++ b/src/components/LanguageSelector/LanguageSelector.vue
@@ -0,0 +1,18 @@
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
+
diff --git a/src/components/LanguageSelector/LanguageSelectorTs.ts b/src/components/LanguageSelector/LanguageSelectorTs.ts
new file mode 100644
index 0000000..0575081
--- /dev/null
+++ b/src/components/LanguageSelector/LanguageSelectorTs.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentLanguage: 'app/language',
+ languageList: 'app/languages',
+ }),
+ },
+})
+export class LanguageSelectorTs extends Vue {
+ @Prop({
+ default: '',
+ })
+ value: string;
+
+ @Prop({
+ default: false,
+ })
+ defaultFormStyle: boolean;
+
+ @Prop({
+ default: true,
+ })
+ autoSubmit: boolean;
+
+ /**
+ * Currently active language
+ * @see {Store.AppInfo}
+ * @var {string}
+ */
+ public currentLanguage: string;
+ private language: string = '';
+ /**
+ * List of available languages
+ * @see {Store.AppInfo}
+ * @var {any[]}
+ */
+ public languageList: { value: string; label: string }[];
+
+ @Watch('language')
+ onLanguageChange() {
+ if (this.autoSubmit) {
+ this.$store.dispatch('app/SET_LANGUAGE', this.language);
+ }
+ this.$emit('input', this.language);
+ }
+ created() {
+ this.language = this.currentLanguage;
+ }
+}
diff --git a/src/components/LogoutButton/LogoutButton.less b/src/components/LogoutButton/LogoutButton.less
new file mode 100644
index 0000000..928a4d6
--- /dev/null
+++ b/src/components/LogoutButton/LogoutButton.less
@@ -0,0 +1,12 @@
+@import '../../views/resources/css/variables.less';
+
+.logout-link {
+ font-size: 0.16rem;
+ color: @purpleDark;
+ margin: 0 0.15rem;
+
+ i {
+ font-size: 0.2rem;
+ margin-right: 0.1rem;
+ }
+}
diff --git a/src/components/LogoutButton/LogoutButton.vue b/src/components/LogoutButton/LogoutButton.vue
new file mode 100644
index 0000000..c28eb93
--- /dev/null
+++ b/src/components/LogoutButton/LogoutButton.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
diff --git a/src/components/LogoutButton/LogoutButtonTs.ts b/src/components/LogoutButton/LogoutButtonTs.ts
new file mode 100644
index 0000000..29a8a5b
--- /dev/null
+++ b/src/components/LogoutButton/LogoutButtonTs.ts
@@ -0,0 +1,9 @@
+import { Vue, Component } from 'vue-property-decorator';
+
+@Component({})
+export class LogoutButtonTs extends Vue {
+ public async logout() {
+ await this.$store.dispatch('profile/LOG_OUT');
+ this.$router.push({ name: 'profiles.login' });
+ }
+}
diff --git a/src/components/LongTextDisplay/LongTextDisplay.less b/src/components/LongTextDisplay/LongTextDisplay.less
new file mode 100644
index 0000000..3de9c44
--- /dev/null
+++ b/src/components/LongTextDisplay/LongTextDisplay.less
@@ -0,0 +1,25 @@
+@import '../../views/resources/css/variables.less';
+
+.truncate-middle-ellipses-container {
+ display: inline-block;
+
+ span:first-child {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ max-width: 3rem;
+ display: inline-block;
+ vertical-align: bottom;
+ cursor: pointer;
+ }
+ span:nth-child(2) {
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ display: inline-block;
+ vertical-align: bottom;
+ direction: rtl;
+ text-align: left;
+ cursor: pointer;
+ }
+}
diff --git a/src/components/LongTextDisplay/LongTextDisplay.vue b/src/components/LongTextDisplay/LongTextDisplay.vue
new file mode 100644
index 0000000..6e2e47b
--- /dev/null
+++ b/src/components/LongTextDisplay/LongTextDisplay.vue
@@ -0,0 +1,18 @@
+
+
+
+ {{ leftPart }}
+ {{ rightPart }}
+
+
+
+
+
+
+
diff --git a/src/components/LongTextDisplay/LongTextDisplayTs.ts b/src/components/LongTextDisplay/LongTextDisplayTs.ts
new file mode 100644
index 0000000..33ef8a2
--- /dev/null
+++ b/src/components/LongTextDisplay/LongTextDisplayTs.ts
@@ -0,0 +1,24 @@
+import { Vue, Component, Prop } from 'vue-property-decorator';
+
+@Component
+export default class LongTextDisplayTs extends Vue {
+ @Prop({ default: '' }) readonly text!: string;
+
+ @Prop({ default: 10 }) readonly rightPartSize!: number;
+
+ @Prop({ default: 'Full Text' }) readonly popTipTitle!: string;
+
+ @Prop({ default: 600 }) readonly popTipWidth!: number;
+
+ public get lastCharsCount() {
+ return Math.min(this.text.length, this.rightPartSize);
+ }
+
+ public get leftPart() {
+ return this.text.substr(0, this.text.length - this.lastCharsCount);
+ }
+
+ public get rightPart() {
+ return this.text.substr(this.text.length - this.lastCharsCount, this.text.length);
+ }
+}
diff --git a/src/components/MaxFeeAndSubmit/MaxFeeAndSubmit.less b/src/components/MaxFeeAndSubmit/MaxFeeAndSubmit.less
new file mode 100644
index 0000000..42fbd47
--- /dev/null
+++ b/src/components/MaxFeeAndSubmit/MaxFeeAndSubmit.less
@@ -0,0 +1,6 @@
+.warning-fee-low {
+ color: #b98e0d;
+ i {
+ font-size: 0.18rem;
+ }
+}
diff --git a/src/components/MaxFeeAndSubmit/MaxFeeAndSubmit.vue b/src/components/MaxFeeAndSubmit/MaxFeeAndSubmit.vue
new file mode 100644
index 0000000..6fe2adb
--- /dev/null
+++ b/src/components/MaxFeeAndSubmit/MaxFeeAndSubmit.vue
@@ -0,0 +1,131 @@
+
+
+ {{ $t('fee') }}:
+
+
+
+
+
+ {{ $t(submitButtonText) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/MaxFeeSelector/MaxFeeSelector.less b/src/components/MaxFeeSelector/MaxFeeSelector.less
new file mode 100644
index 0000000..39756f7
--- /dev/null
+++ b/src/components/MaxFeeSelector/MaxFeeSelector.less
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.label-and-select {
+ display: flex;
+ align-items: center;
+}
+
+.fee-label {
+ font-weight: 500;
+ font-size: 0.18rem;
+ font-family: 'noto-sans-regular';
+ margin-right: 0.1rem;
+ color: @primary;
+ min-width: max-content;
+}
diff --git a/src/components/MaxFeeSelector/MaxFeeSelector.vue b/src/components/MaxFeeSelector/MaxFeeSelector.vue
new file mode 100644
index 0000000..7adb933
--- /dev/null
+++ b/src/components/MaxFeeSelector/MaxFeeSelector.vue
@@ -0,0 +1,39 @@
+
+
+
+
{{ $t('fee') }}:
+
+
+ {{ label }}
+
+
+
+ {{ fees.find((i) => i.maxFee == chosenMaxFee).label }}
+
+
+
+
+ {{ $t('low_fee_warning_message') }}
+
+
+ {{ $t('minimal_fee_transaction') + transactionFees.minFeeMultiplier.toString() }}
+
+
+
+
+
+
+
diff --git a/src/components/MaxFeeSelector/MaxFeeSelectorTs.ts b/src/components/MaxFeeSelector/MaxFeeSelectorTs.ts
new file mode 100644
index 0000000..bae32ce
--- /dev/null
+++ b/src/components/MaxFeeSelector/MaxFeeSelectorTs.ts
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// @ts-ignore
+import FormLabel from '@/components/FormLabel/FormLabel.vue';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+import { TransactionFees } from 'symbol-sdk';
+
+@Component({
+ components: {
+ FormLabel,
+ },
+ computed: {
+ ...mapGetters({
+ defaultFee: 'app/defaultFee',
+ networkMosaicName: 'mosaic/networkMosaicName',
+ networkCurrency: 'mosaic/networkCurrency',
+ transactionFees: 'network/transactionFees',
+ feesConfig: 'network/feesConfig',
+ }),
+ },
+ props: {
+ placement: {
+ type: String,
+ default: 'bottom-start',
+ },
+ },
+})
+export class MaxFeeSelectorTs extends Vue {
+ @Prop({
+ default: 'form-line-container',
+ })
+ public className: string;
+
+ @Prop({ default: false })
+ public displayOnly!: boolean;
+
+ public placement: string;
+
+ /**
+ * Networks currency mosaic name
+ * @var {string}
+ */
+ private networkMosaicName: string;
+ private feesConfig: {
+ slow: number;
+ slowest: number;
+ median: number;
+ fast: number;
+ };
+
+ /**
+ * Known mosaics info
+ * @var {MosaicInfo[]}
+ */
+ private networkCurrency: NetworkCurrencyModel;
+
+ public transactionFees: TransactionFees;
+ /**
+ * Default fee setting
+ * @var {number}
+ */
+ private defaultFee: number;
+
+ /**
+ * Dynamically calculated recommended fee
+ */
+ @Prop({ default: 0 }) calculatedRecommendedFee: number;
+
+ /**
+ /**
+ * Show low fee warning
+ */
+ @Prop({ default: false }) showLowFeeWarning: boolean;
+
+ @Prop({ default: false }) showFeeLabel: boolean;
+ @Prop({ default: 0 }) slowFee: number;
+ @Prop({ default: 0 }) slowestFee: number;
+ @Prop({ default: 0 }) fastFee: number;
+ @Prop({ default: 0 }) averageFee: number;
+
+ /**
+ * The fees to be displayed in the dropw down.
+ */
+ private fees: { label: string; maxFee: number; calculatedFee: number }[];
+
+ @Prop({
+ default: 1,
+ })
+ multiplier: number;
+
+ public created() {
+ this.fees = Object.entries(this.feesConfig).map((entry) => ({
+ label: this.getLabel([entry[0], entry[1] as number]),
+ maxFee: entry[1] as number,
+ calculatedFee: entry[1] as number,
+ }));
+ }
+
+ /**
+ * Returns the label based on the feesConfig property
+ * @param {[string, number]} key, value pair
+ */
+ private getLabel([key, value]: [string, number]) {
+ //SPECIAL VALUES!!!
+ if (value === this.feesConfig.median) {
+ return this.formatLabel('fee_speed_' + key, this.averageFee, this.networkMosaicName, !!this.averageFee);
+ } else if (value === this.feesConfig.fast) {
+ return this.formatLabel('fee_speed_' + key, this.fastFee, this.networkMosaicName, !!this.fastFee);
+ } else if (value === this.feesConfig.slow) {
+ return this.formatLabel('fee_speed_' + key, this.slowFee, this.networkMosaicName, !!this.slowFee);
+ } else if (value === this.feesConfig.slowest) {
+ return this.formatLabel('fee_speed_' + key, this.slowestFee, this.networkMosaicName, !!this.slowestFee);
+ } else {
+ return this.formatLabel('fee_speed_' + key, value, this.networkMosaicName);
+ }
+ }
+
+ /**
+ * Returns the formatted label
+ * @param labelKey
+ * @param fee
+ * @param mosaic
+ * @param showAmount
+ */
+ private formatLabel(labelKey: string, fee: number, mosaic: string, showAmount: boolean = true): string {
+ let label = this.$t(labelKey).toString();
+ if (showAmount) {
+ label += `: ${this.getFormattedRelative(fee)} ${mosaic}`;
+ }
+ return label;
+ }
+
+ /**
+ * Value set by the parent component's v-model
+ * @type {number}
+ */
+ @Prop({
+ default: 10,
+ })
+ value: number;
+
+ /// region computed properties getter/setter
+ /**
+ * Value set by the parent component
+ * @type {number}
+ */
+ get chosenMaxFee(): number {
+ return typeof this.value === 'number' ? this.value : this.defaultFee;
+ }
+
+ /**
+ * Emit value change
+ */
+ set chosenMaxFee(newValue: number) {
+ this.$emit('input', newValue);
+ }
+ /// end-region computed properties getter/setter
+
+ /**
+ * Convert a relative amount to absolute using mosaicInfo
+ * @param {number} price
+ * @return {number}
+ */
+ public getFormattedRelative(amount: number): string {
+ let relativeAmount: number;
+ if (this.networkCurrency === undefined) {
+ relativeAmount = amount;
+ } else {
+ relativeAmount = amount / Math.pow(10, this.networkCurrency.divisibility);
+ }
+ return relativeAmount.toLocaleString(undefined, { maximumFractionDigits: this.networkCurrency.divisibility });
+ }
+
+ /**
+ * Returns the sorted fees (including the calculated fees)
+ */
+ public get feesCalculated(): { label: string; maxFee: number }[] {
+ return this.fees
+ .map((i) => {
+ if (i.maxFee === this.feesConfig.median) {
+ return {
+ label: this.getLabel(['median', this.feesConfig.median]),
+ maxFee: i.maxFee,
+ calculatedFee: this.averageFee,
+ };
+ } else if (i.maxFee === this.feesConfig.fast) {
+ return {
+ label: this.getLabel(['fast', this.feesConfig.fast]),
+ maxFee: i.maxFee,
+ calculatedFee: this.fastFee,
+ };
+ } else if (i.maxFee === this.feesConfig.slow) {
+ return {
+ label: this.getLabel(['slow', this.feesConfig.slow]),
+ maxFee: i.maxFee,
+ calculatedFee: this.slowFee,
+ };
+ } else if (i.maxFee === this.feesConfig.slowest) {
+ return {
+ label: this.getLabel(['slowest', this.feesConfig.slowest]),
+ maxFee: i.maxFee,
+ calculatedFee: this.slowestFee,
+ };
+ } else {
+ return i;
+ }
+ })
+ .slice()
+ .sort((a, b) => a.calculatedFee - b.calculatedFee);
+ }
+}
diff --git a/src/components/MessageDisplay/MessageDisplay.vue b/src/components/MessageDisplay/MessageDisplay.vue
new file mode 100644
index 0000000..e235d9c
--- /dev/null
+++ b/src/components/MessageDisplay/MessageDisplay.vue
@@ -0,0 +1,28 @@
+
+
+
+ {{ messageDisplay }}
+
+
+ {{ $t('decrypt_message') }}
+
+
+
+
+
+
+
+
diff --git a/src/components/MessageDisplay/MessageDisplayTs.ts b/src/components/MessageDisplay/MessageDisplayTs.ts
new file mode 100644
index 0000000..5619785
--- /dev/null
+++ b/src/components/MessageDisplay/MessageDisplayTs.ts
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address, EncryptedMessage, MessageType, Account, UnresolvedAddress, Message } from 'symbol-sdk';
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// @ts-ignore
+import FormWrapper from '@/components/FormWrapper/FormWrapper.vue';
+// @ts-ignore
+import ModalFormProfileUnlock from '@/views/modals/ModalFormProfileUnlock/ModalFormProfileUnlock.vue';
+import { PublicAccount } from 'symbol-sdk';
+import { mapGetters } from 'vuex';
+import { PlainMessage } from 'symbol-sdk';
+import { NamespaceId } from 'symbol-sdk';
+import { NotificationType } from '@/core/utils/NotificationType';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+
+@Component({
+ components: {
+ FormWrapper,
+ ModalFormProfileUnlock,
+ },
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ currentRecipient: 'account/currentRecipient',
+ linkedAddress: 'namespace/linkedAddress',
+ }),
+ },
+})
+export class MessageDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ message: Message;
+ @Prop({
+ default: null,
+ })
+ incoming: boolean;
+ @Prop({
+ default: null,
+ })
+ recipient: UnresolvedAddress;
+ @Prop({
+ default: true,
+ })
+ unannounced: boolean;
+ @Prop({
+ default: null,
+ })
+ signer: PublicAccount;
+
+ private isEncrypted = false;
+ private messageDisplay = '';
+ private showUnlockAccountModal = false;
+ private decryptedMessage: PlainMessage;
+ private currentRecipient: PublicAccount;
+ private linkedAddress: Address | null;
+ private currentAccount: AccountModel;
+
+ /**
+ * Hook called when the component is mounted
+ * @return {void}
+ */
+ public created() {
+ // - load transaction details
+ this.loadDetails();
+ }
+
+ /**
+ * Load transaction details
+ * @return {Promise}
+ */
+ protected async loadDetails(): Promise {
+ this.isEncrypted = this.message.type === MessageType.EncryptedMessage;
+ if (this.isEncrypted) {
+ this.messageDisplay = this.unannounced ? `${this.message.payload} (${this.$t('encrypted_message')})` : '******';
+ } else {
+ this.messageDisplay = this.message.payload;
+ }
+ }
+
+ /**
+ * Hook called when the account has been unlocked
+ * @param {Account} account
+ * @return {boolean}
+ */
+ protected onAccountUnlocked(account: Account) {
+ this.hasAccountUnlockModal = false;
+ if (this.recipient instanceof NamespaceId) {
+ this.$store.dispatch('namespace/GET_LINKED_ADDRESS', this.recipient).then(() => {
+ if (this.linkedAddress) {
+ this.decryptMessage(account.privateKey, this.linkedAddress);
+ } else {
+ this.$store.dispatch('notification/ADD_ERROR', this.$t(NotificationType.RECIPIENT_LINKED_ADDRESS_INVALID));
+ }
+ });
+ } else {
+ this.decryptMessage(account.privateKey, this.recipient);
+ }
+ }
+
+ /**
+ * Getter for modal visability property
+ */
+ protected get hasAccountUnlockModal(): boolean {
+ return this.showUnlockAccountModal;
+ }
+
+ /**
+ * Setter for modal visability property
+ */
+ protected set hasAccountUnlockModal(f: boolean) {
+ this.showUnlockAccountModal = f;
+ }
+
+ /**
+ * Get decrypted message
+ * @param privateKey Current account private key
+ * @param recipient: recipient address.
+ */
+ private decryptMessage(privateKey: string, recipient: Address) {
+ /**
+ * If transaction recipient === current account use signer to decrypt message
+ * Otherwise use the recipient for decryption
+ * */
+
+ if (recipient.plain() === this.currentAccount.address) {
+ this.decryptedMessage = EncryptedMessage.decrypt(this.message, privateKey, this.signer);
+ this.isEncrypted = false;
+ this.messageDisplay = this.decryptedMessage.payload;
+ } else {
+ this.$store.dispatch('account/GET_RECIPIENT', this.recipient as Address).then(() => {
+ this.decryptedMessage = EncryptedMessage.decrypt(this.message, privateKey, this.currentRecipient);
+ this.isEncrypted = false;
+ this.messageDisplay = this.decryptedMessage.payload;
+ });
+ }
+ }
+}
diff --git a/src/components/MessageInput/MessageInput.less b/src/components/MessageInput/MessageInput.less
new file mode 100644
index 0000000..4dfac83
--- /dev/null
+++ b/src/components/MessageInput/MessageInput.less
@@ -0,0 +1,37 @@
+.remark {
+ margin-top: 20px;
+
+ .title {
+ position: relative;
+ bottom: 15px;
+ }
+
+ .textarea_container {
+ justify-content: center;
+ padding: 15px 20px;
+ line-height: 20px;
+
+ textarea {
+ border: none;
+ outline: none;
+ font-size: 16px;
+ }
+
+ textarea::placeholder {
+ font-size: 16px;
+ font-weight: 400;
+ }
+ }
+}
+
+/deep/.inputs-container {
+ height: auto !important;
+}
+
+.fixed-height {
+ height: 0.7rem;
+}
+
+.message-box {
+ overflow-y: auto;
+}
diff --git a/src/components/MessageInput/MessageInput.vue b/src/components/MessageInput/MessageInput.vue
new file mode 100644
index 0000000..ab4b6a0
--- /dev/null
+++ b/src/components/MessageInput/MessageInput.vue
@@ -0,0 +1,33 @@
+
+
+ {{ $t('message') }}:
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/MessageInput/MessageInputTs.ts b/src/components/MessageInput/MessageInputTs.ts
new file mode 100644
index 0000000..dced163
--- /dev/null
+++ b/src/components/MessageInput/MessageInputTs.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+// child components
+// @ts-ignore
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+})
+export class MessageInputTs extends Vue {
+ @Prop({
+ default: '',
+ })
+ value: string;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /// region computed properties getter/setter
+ get plain(): string {
+ return this.value;
+ }
+
+ set plain(msg: string) {
+ this.$emit('input', msg);
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/MnemonicDisplay/MnemonicDisplay.less b/src/components/MnemonicDisplay/MnemonicDisplay.less
new file mode 100644
index 0000000..c89defe
--- /dev/null
+++ b/src/components/MnemonicDisplay/MnemonicDisplay.less
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+.mnemonic-container {
+ padding-top: 0.05rem;
+ height: 2.6rem;
+ border: 1px solid rgba(51, 51, 51, 0.2);
+ border-radius: 0.05rem;
+ margin-bottom: 0.2rem;
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ position: relative;
+ .copy-button {
+ position: absolute;
+ bottom: 0.1rem;
+ right: 0.1rem;
+ }
+}
+.mnemonic-list {
+ padding: 0.1rem;
+
+ span {
+ display: inline-block;
+ background-color: @purpleDark;
+ padding: 0.1rem 0.2rem;
+ border-radius: 0.04rem;
+ margin: 0.05rem;
+ font-size: @smallFont;
+ color: @white;
+ }
+}
diff --git a/src/components/MnemonicDisplay/MnemonicDisplay.vue b/src/components/MnemonicDisplay/MnemonicDisplay.vue
new file mode 100644
index 0000000..7da21ed
--- /dev/null
+++ b/src/components/MnemonicDisplay/MnemonicDisplay.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
diff --git a/src/components/MnemonicDisplay/MnemonicDisplayTs.ts b/src/components/MnemonicDisplay/MnemonicDisplayTs.ts
new file mode 100644
index 0000000..e86e1e4
--- /dev/null
+++ b/src/components/MnemonicDisplay/MnemonicDisplayTs.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import draggable from 'vuedraggable';
+
+// @ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+import { Formatters } from '@/core/utils/Formatters';
+
+@Component({
+ components: { draggable, ButtonCopyToClipboard },
+})
+export class MnemonicDisplayTs extends Vue {
+ @Prop({
+ default: [],
+ })
+ words: string[];
+ public get waitingCopyString(): string {
+ return Formatters.splitArrayByDelimiter(this.words);
+ }
+}
diff --git a/src/components/MnemonicInput/MnemonicInput.less b/src/components/MnemonicInput/MnemonicInput.less
new file mode 100644
index 0000000..79a0f10
--- /dev/null
+++ b/src/components/MnemonicInput/MnemonicInput.less
@@ -0,0 +1,39 @@
+@import '../../views/resources/css/variables.less';
+
+.show-mnemonic {
+ width: 100%;
+ min-height: 2.6rem;
+ padding: 0.2rem;
+ border: 1px solid rgba(51, 51, 51, 0.2);
+ border-radius: 0.05rem;
+ margin-bottom: 0.2rem;
+ position: relative;
+
+ .input-already {
+ display: inline-block;
+ padding: 0.08rem 0.2rem;
+ background-color: @grayLight;
+ color: @purpleDark;
+ border-radius: 0.05rem;
+ margin-right: 0.15rem;
+ margin-bottom: 0.2rem;
+ text-transform: lowercase;
+ }
+
+ .mnemonic-input-container {
+ display: inline-block;
+
+ .mnemonic-input {
+ background-color: transparent;
+ outline: none;
+ max-width: 2rem;
+ border: 0;
+ width: 100%;
+ }
+ }
+ .copy-button {
+ position: absolute;
+ bottom: 0.1rem;
+ right: 0.4rem;
+ }
+}
diff --git a/src/components/MnemonicInput/MnemonicInput.vue b/src/components/MnemonicInput/MnemonicInput.vue
new file mode 100644
index 0000000..96bdc40
--- /dev/null
+++ b/src/components/MnemonicInput/MnemonicInput.vue
@@ -0,0 +1,26 @@
+
+
+
+ {{ word }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/MnemonicInput/MnemonicInputTs.ts b/src/components/MnemonicInput/MnemonicInputTs.ts
new file mode 100644
index 0000000..4db7dc2
--- /dev/null
+++ b/src/components/MnemonicInput/MnemonicInputTs.ts
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
+
+// internal dependencies
+
+// @ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+import { Formatters } from '@/core/utils/Formatters';
+@Component({
+ components: { ButtonCopyToClipboard },
+})
+export class MnemonicInputTs extends Vue {
+ /**
+ * @description: initial seed data
+ */
+ @Prop({ default: '' })
+ public seed: string;
+
+ /**
+ * @description: wordsArray
+ */
+ public wordsArray: Array = [];
+
+ /**
+ * @description: status of isEditing
+ */
+ public isEditing: boolean = false;
+
+ /**
+ * @description: isNeedPressDelTwice
+ */
+ public isNeedPressDelTwice = true;
+
+ /**
+ * @description: watch the inputform
+ */
+ public inputWord: string = '';
+
+ public get userInput(): string {
+ return this.inputWord;
+ }
+ public set userInput(input: string) {
+ // avoid cache
+ this.inputWord = input;
+ // add the limit
+ if (this.wordsArray.length >= 24) {
+ this.inputWord = '';
+ this.initInput();
+ } else {
+ // control the keyboard input rules
+ this.inputWord = input.replace(/[^a-zA-Z]/g, '');
+ // determine if the input is editing status
+ if (!this.isEditing && !!this.inputWord) {
+ this.isEditing = true;
+ }
+ }
+ }
+ public get waitingCopyString(): string {
+ return Formatters.splitArrayByDelimiter(this.wordsArray);
+ }
+
+ /**
+ * @description: add word to the wordsArray
+ */
+ addWord() {
+ if (this.inputWord.length >= 2 && this.inputWord.length <= 50) {
+ if (this.wordsArray.length < 24) {
+ this.handleWordsArray(this.inputWord);
+ this.inputWord = '';
+ this.initInput();
+ }
+ }
+ }
+
+ /**
+ * @description: delete the word
+ */
+ deleteWord() {
+ if (this.inputWord) {
+ this.isNeedPressDelTwice = true;
+ } else {
+ if (this.isEditing) {
+ if (this.isNeedPressDelTwice) {
+ this.isNeedPressDelTwice = false;
+ return;
+ }
+ this.handleWordsArray();
+ this.initInput();
+ } else {
+ this.handleWordsArray();
+ this.initInput();
+ }
+ }
+ }
+
+ /**
+ * @description: add one word or reduce one word
+ */
+ handleWordsArray(item?) {
+ if (!!item) {
+ this.wordsArray.push(item);
+ } else {
+ this.wordsArray.pop();
+ }
+ // transform to lower case
+ this.wordsArray.forEach((item: string, index) => {
+ this.wordsArray[index] = item.toLowerCase();
+ });
+ this.$emit('handle-words', this.wordsArray);
+ }
+
+ handlePaste(e: ClipboardEvent) {
+ this.handleSeed(e.clipboardData.getData('text').toString());
+ }
+
+ /**
+ * @description handles seed data changes
+ * @param seed imported/pasted seed data
+ */
+ @Watch('seed', { immediate: true })
+ private handleSeed(seed: string) {
+ if (!seed) {
+ return;
+ }
+ const pasteDataArr: Array = seed.trim().split(/\s+/g);
+ pasteDataArr.forEach((pasteData) => {
+ if (!!pasteData && this.wordsArray.length < 24) {
+ this.handleWordsArray(pasteData);
+ }
+ });
+ }
+ /**
+ * @description: init input
+ */
+ initInput() {
+ this.isNeedPressDelTwice = true;
+ this.isEditing = false;
+ }
+}
diff --git a/src/components/MnemonicVerification/MnemonicVerification.less b/src/components/MnemonicVerification/MnemonicVerification.less
new file mode 100644
index 0000000..d6320b2
--- /dev/null
+++ b/src/components/MnemonicVerification/MnemonicVerification.less
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+.mnemonic_container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: space-around;
+
+ .mnemonicWordDiv {
+ width: 100%;
+ height: 200px;
+ background: #fff;
+ border: 1px solid #cccccc;
+ padding: 10px;
+ border-radius: 8px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ overflow-y: scroll;
+
+ span {
+ font-size: 14px;
+ color: #44004e;
+ padding: 0.1rem 0.2rem;
+ background: #d3d3d3;
+ margin: 8px;
+ float: left;
+ cursor: pointer;
+ border-radius: 4px;
+
+ .ivu-tag {
+ background: transparent;
+ border: none;
+ font-size: 14px;
+ color: #44004e !important;
+ padding-left: 0px;
+ margin: 0px;
+ }
+ .ivu-tag-text {
+ color: none;
+ font-family: noto-sans-regular;
+ }
+ .ivu-icon {
+ color: #44004e !important;
+ }
+ }
+
+ .ghost {
+ border-left: 6px solid rgb(0, 183, 255);
+ box-shadow: 10px 10px 5px 01px rgba(0, 0, 0, 0.14);
+ opacity: 0.7;
+ }
+ }
+
+ .mnemonicWordDiv::-webkit-scrollbar {
+ width: 5px;
+ }
+
+ .wordDiv {
+ width: 100%;
+
+ .confirmed_word {
+ background-color: #44004e;
+ color: white;
+ }
+
+ span {
+ font-size: 16px;
+ font-weight: 400;
+ color: #44004e;
+ background: #d3d3d3;
+ padding: 8px 18px 10px;
+ border-radius: 4px;
+ margin-right: 20px;
+ margin-bottom: 20px;
+ float: left;
+ cursor: pointer;
+ }
+ }
+
+ .buttons {
+ width: 70%;
+ button {
+ height: 40px;
+ vertical-align: center;
+ }
+ }
+}
diff --git a/src/components/MnemonicVerification/MnemonicVerification.vue b/src/components/MnemonicVerification/MnemonicVerification.vue
new file mode 100644
index 0000000..c29c502
--- /dev/null
+++ b/src/components/MnemonicVerification/MnemonicVerification.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ {{ shuffledWords[index] }}
+
+
+
+
+
+
+ {{ shuffledWords[index] }}
+
+
+
+
+
+
+
+
diff --git a/src/components/MnemonicVerification/MnemonicVerificationTs.ts b/src/components/MnemonicVerification/MnemonicVerificationTs.ts
new file mode 100644
index 0000000..62133fe
--- /dev/null
+++ b/src/components/MnemonicVerification/MnemonicVerificationTs.ts
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import draggable from 'vuedraggable';
+// internal dependencies
+import { NotificationType } from '@/core/utils/NotificationType';
+
+/**
+ * Emits: success, error, canceled
+ */
+@Component({
+ components: { draggable },
+})
+export class MnemonicVerificationTs extends Vue {
+ @Prop({ default: [] }) words: string[];
+
+ /**
+ * Randomized words
+ * @var {Record}
+ */
+ public shuffledWords: Record = {};
+
+ /**
+ * Randomized words indexes
+ * @var {number[]}
+ */
+ public shuffledWordsIndexes: number[] = [];
+
+ /**
+ * Selected words indexes
+ * @var {number[]}
+ */
+ public selectedWordIndexes: number[] = [];
+
+ /**
+ * Hook called when the component is created
+ * @return {void}
+ */
+ public created() {
+ const shuffledWordsArray: string[] = [...this.words].sort((a, b) => a.localeCompare(b));
+ this.shuffledWords = shuffledWordsArray.reduce((acc, word, index) => ({ ...acc, ...{ [index]: word } }), {});
+ this.shuffledWordsIndexes = [...Array(shuffledWordsArray.length).keys()];
+ }
+
+ /**
+ * Toggle a word presence in the confirmed words
+ * @param {string} word
+ * @return {void}
+ */
+ public onWordClicked(index: number): void {
+ if (this.selectedWordIndexes.includes(index)) {
+ this.removeWord(index);
+ return;
+ }
+ this.selectedWordIndexes.push(index);
+ }
+
+ /**
+ * Add confirmed word
+ * @param {string} word
+ * @return {string[]}
+ */
+ public removeWord(index: number): void {
+ this.selectedWordIndexes = [...this.selectedWordIndexes].filter((sel) => sel !== index);
+ }
+
+ public next(): void {
+ if (this.correctWordsAreSelected()) {
+ this.$emit('success');
+ }
+ }
+
+ public correctWordsAreSelected(): boolean {
+ const origin = this.words.join(' ');
+ const rebuilt = this.selectedWordIndexes.map((i) => this.shuffledWords[i]).join(' ');
+ return origin === rebuilt;
+ }
+
+ /**
+ * Show Notification based on the entered mnemonic validity
+ */
+ private mnemonicCheckerNotification(origin: string, rebuilt: string): boolean {
+ if (!origin.startsWith(rebuilt)) {
+ const errorMsg = NotificationType.MNEMONIC_INCONSISTENCY_ERROR;
+ this.$store.dispatch('notification/ADD_WARNING', errorMsg);
+ this.$emit('error', errorMsg);
+ return false;
+ } else {
+ // watch mnemonic validity only if mnemonic input is full
+ if (this.selectedWordIndexes.length === 24) {
+ this.$store.dispatch('notification/ADD_SUCCESS', NotificationType.MNEMONIC_CORRECT);
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Watching mnemonic Words changes
+ */
+ @Watch('selectedWordIndexes')
+ onSelectedMnemonicChange() {
+ const origin = this.words.join(' ');
+ const rebuilt = this.selectedWordIndexes.map((i) => this.shuffledWords[i]).join(' ');
+ return this.mnemonicCheckerNotification(origin, rebuilt);
+ }
+}
diff --git a/src/components/MosaicAmountDisplay/MosaicAmountDisplay.less b/src/components/MosaicAmountDisplay/MosaicAmountDisplay.less
new file mode 100644
index 0000000..fee2f37
--- /dev/null
+++ b/src/components/MosaicAmountDisplay/MosaicAmountDisplay.less
@@ -0,0 +1,19 @@
+.asset {
+ .title {
+ position: relative;
+ bottom: 15px;
+ }
+
+ .type {
+ width: 190px;
+ display: inline-block;
+ }
+
+ .amount {
+ width: 300px;
+ display: inline-block;
+ margin-left: 20px;
+ color: black;
+ font-size: 24px;
+ }
+}
diff --git a/src/components/MosaicAmountDisplay/MosaicAmountDisplay.vue b/src/components/MosaicAmountDisplay/MosaicAmountDisplay.vue
new file mode 100644
index 0000000..cfc729b
--- /dev/null
+++ b/src/components/MosaicAmountDisplay/MosaicAmountDisplay.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/MosaicAmountDisplay/MosaicAmountDisplayTs.ts b/src/components/MosaicAmountDisplay/MosaicAmountDisplayTs.ts
new file mode 100644
index 0000000..1455c10
--- /dev/null
+++ b/src/components/MosaicAmountDisplay/MosaicAmountDisplayTs.ts
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { mapGetters } from 'vuex';
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { MosaicId, NamespaceId } from 'symbol-sdk';
+// internal dependencies
+// configuration
+// child components
+// @ts-ignore
+import AmountDisplay from '@/components/AmountDisplay/AmountDisplay.vue';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+@Component({
+ components: { AmountDisplay },
+ computed: {
+ ...mapGetters({
+ mosaics: 'mosaic/mosaics',
+ networkCurrency: 'mosaic/networkCurrency',
+ networkConfiguration: 'network/networkConfiguration',
+ }),
+ },
+})
+export class MosaicAmountDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ id: MosaicId | NamespaceId;
+
+ @Prop({
+ default: null,
+ })
+ relativeAmount: number;
+
+ @Prop({
+ default: null,
+ })
+ absoluteAmount: number;
+
+ @Prop({
+ default: 'green',
+ })
+ color: 'red' | 'green';
+
+ @Prop({
+ default: 'normal',
+ })
+ size: 'normal' | 'smaller' | 'bigger' | 'biggest';
+
+ @Prop({
+ default: false,
+ })
+ showTicker: false;
+
+ private mosaics: MosaicModel[];
+
+ private networkCurrency: NetworkCurrencyModel;
+
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /// region computed properties getter/setter
+
+ private useNetwork(): boolean {
+ if (!this.id) {
+ return !!this.networkCurrency;
+ }
+ if (this.networkCurrency && this.id.toHex() === this.networkCurrency.mosaicIdHex) {
+ return true;
+ }
+ if (this.networkCurrency && this.id.toHex() === this.networkCurrency.namespaceIdHex) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Mosaic divisibility from database
+ * @return {number}
+ */
+ protected get divisibility(): number {
+ if (this.useNetwork()) {
+ return this.networkCurrency.divisibility;
+ }
+ // TODO improve how to resolve the mosaic id when the known value is a namespace id.
+ // Note that if the transaction is old, the namespace id of the mosaic may have been expired!
+ const mosaic = this.mosaics.find((m) => m.mosaicIdHex === this.id.toHex());
+ return mosaic ? mosaic.divisibility : this.networkConfiguration.maxMosaicDivisibility;
+ }
+
+ public get amount(): number {
+ if (this.absoluteAmount) {
+ return this.absoluteAmount / Math.pow(10, this.divisibility);
+ } else {
+ return this.relativeAmount || 0;
+ }
+ }
+
+ public get ticker(): string {
+ if (!this.showTicker) {
+ return '';
+ }
+
+ if (this.useNetwork()) {
+ return this.networkCurrency.ticker || '';
+ }
+
+ const mosaic = this.mosaics.find((m) => m.mosaicIdHex === this.id.toHex());
+ return (mosaic && mosaic.name) || this.id.toHex();
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/MosaicAttachmentInput/MosaicAttachmentInput.vue b/src/components/MosaicAttachmentInput/MosaicAttachmentInput.vue
new file mode 100644
index 0000000..bf9741c
--- /dev/null
+++ b/src/components/MosaicAttachmentInput/MosaicAttachmentInput.vue
@@ -0,0 +1,21 @@
+
+
+
+ {{ $t('mosaic') }}:
+
+
+
+
+
+
+
+
diff --git a/src/components/MosaicAttachmentInput/MosaicAttachmentInputTs.ts b/src/components/MosaicAttachmentInput/MosaicAttachmentInputTs.ts
new file mode 100644
index 0000000..a92a10c
--- /dev/null
+++ b/src/components/MosaicAttachmentInput/MosaicAttachmentInputTs.ts
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+// child components
+import { ValidationObserver } from 'vee-validate';
+// @ts-ignore
+import MosaicSelector from '@/components/MosaicSelector/MosaicSelector.vue';
+// @ts-ignore
+import AmountInput from '@/components/AmountInput/AmountInput.vue';
+// @ts-ignore
+import ButtonRemove from '@/components/ButtonRemove/ButtonRemove.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+@Component({
+ components: {
+ ValidationObserver,
+ MosaicSelector,
+ AmountInput,
+ ButtonRemove,
+ FormRow,
+ },
+})
+export class MosaicAttachmentInputTs extends Vue {
+ /**
+ * Initial value set by the parent
+ * @type {{mosaicHex: string, amount: number}}
+ */
+ @Prop({
+ default: { mosaicHex: '', amount: 0 },
+ required: true,
+ })
+ mosaicAttachment: { mosaicHex: string; amount: string };
+
+ /**
+ * Unique Id assigned to this component
+ * @type {number}
+ */
+ @Prop({ default: 0, required: true }) uid: number;
+
+ /**
+ * Hex ids of mosaics to show in options
+ * @type {string[]}
+ */
+ @Prop({ default: [] }) mosaicHexIds: string[];
+
+ /**
+ * Whether to show absolute amounts or not
+ */
+ @Prop({ default: false }) absolute: boolean;
+
+ /**
+ * the item index in the Array
+ */
+ @Prop({ default: true }) isShowDelete: boolean;
+
+ /**
+ * whether to show the label accord to isFirstItem
+ */
+ @Prop({ default: true }) isFirstItem: boolean;
+ /**
+ * Updated value to sync with the parent formItems
+ * @protected
+ * @type {{mosaicHex: string, amount: number}}
+ */
+ protected get chosenValue(): { mosaicHex: string; amount: string } {
+ return this.mosaicAttachment;
+ }
+
+ /**
+ * Handle mosaic changes from mosaic selection fields
+ * @param {string} hex
+ */
+ public onChangeMosaic(hex: string): void {
+ Vue.set(this.chosenValue, 'mosaicHex', hex);
+ Vue.nextTick().then(() => this.emitChange());
+ }
+
+ /**
+ * Handle amount changes from mosaic selection fields
+ * @param {number} amount
+ */
+ public onChangeAmount(amount: number): void {
+ Vue.set(this.chosenValue, 'amount', amount);
+ Vue.nextTick().then(() => this.emitChange());
+ }
+
+ /**
+ * Emits input change to the parent
+ * @private
+ * @return {void}
+ */
+ private emitChange(): void {
+ this.$emit('input-changed', {
+ mosaicAttachment: this.chosenValue,
+ inputIndex: this.uid,
+ });
+ }
+
+ /**
+ * Form items
+ * @var {any}
+ */
+ public formItems = {
+ selectedMosaicHex: '',
+ relativeAmount: this.chosenValue?.amount || '0',
+ };
+
+ get selectedMosaic(): string {
+ return this.formItems.selectedMosaicHex;
+ }
+
+ set selectedMosaic(hex: string) {
+ this.formItems.selectedMosaicHex = hex;
+ }
+
+ get relativeAmount(): string {
+ return this.formItems.relativeAmount;
+ }
+
+ set relativeAmount(amount: string) {
+ this.formItems.relativeAmount = amount;
+ }
+
+ get canClickAdd(): boolean {
+ if (!this.formItems.selectedMosaicHex || undefined === this.formItems.relativeAmount) {
+ return false;
+ }
+
+ return true;
+ }
+ /// end-region computed properties getter/setter
+
+ mounted() {
+ this.emitChange();
+ }
+
+ @Watch('mosaicAttachment')
+ public onMosaicAttachmentChange(mosaicAttachment: { mosaicHex: string; amount: string }) {
+ this.relativeAmount = mosaicAttachment.amount;
+ }
+}
diff --git a/src/components/MosaicBalanceList/MosaicBalanceList.less b/src/components/MosaicBalanceList/MosaicBalanceList.less
new file mode 100644
index 0000000..94352f1
--- /dev/null
+++ b/src/components/MosaicBalanceList/MosaicBalanceList.less
@@ -0,0 +1,314 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.toggle_all_checked {
+ margin-top: 0.1rem;
+ font-size: 0.16rem;
+ height: 0.2rem;
+ width: 100%;
+ line-height: 0.2rem;
+ display: flex;
+ align-items: center;
+ padding: 0.2rem 0;
+
+ span {
+ min-width: 1.5rem;
+ display: flex;
+ align-items: center;
+ margin-right: 0.1rem;
+ cursor: pointer;
+ }
+}
+
+.false {
+ width: 0.2rem;
+ height: 0.2rem;
+ background-image: url('../../views/resources/img/monitor/mosaics/unselected.png');
+ background-repeat: no-repeat;
+ background-size: 0.2rem;
+ margin-right: 0.1rem;
+ cursor: pointer;
+}
+
+.true {
+ width: 0.2rem;
+ height: 0.2rem;
+ background-image: url('../../views/resources/img/monitor/mosaics/selected.png');
+ background-repeat: no-repeat;
+ background-size: 0.2rem;
+ margin-right: 0.1rem;
+ cursor: pointer;
+}
+
+.mosaicList {
+ display: block;
+
+ .complete_container {
+ width: 100%;
+ height: 0.8rem;
+ background-color: @white;
+ padding-top: 0.2rem;
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ z-index: 1;
+ }
+
+ .complete {
+ width: 1.5rem;
+ height: 0.44rem;
+ border-radius: 0.22rem;
+ border: 0.01rem solid @border;
+ text-align: center;
+ line-height: 0.44rem;
+ cursor: pointer;
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @purple;
+ position: absolute;
+ margin-left: 50%;
+ left: -0.75rem;
+ }
+}
+
+.mosaicList::-webkit-scrollbar {
+ display: none;
+}
+
+.asset_setting_tit {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @blackLight;
+ height: 0.2rem;
+
+ img {
+ margin-right: 0.19rem;
+ width: 0.08rem;
+ height: 0.16rem;
+ position: relative;
+ bottom: 0.02rem;
+ }
+}
+
+.searchMosaic {
+ .mosaic_data {
+ .mosaic_name {
+ left: 0.7rem;
+ }
+ }
+}
+
+.search {
+ position: absolute;
+ display: inline-block;
+ width: 0.6rem;
+ font-size: @normalFont;
+ text-align: center;
+ right: -0.6rem;
+ color: @purple;
+}
+
+.input_outter {
+ width: 2.8rem;
+ height: 0.4rem;
+ display: flex;
+ position: absolute;
+ top: 0.2rem;
+ left: 0.6rem;
+ align-items: center;
+ flex-direction: row;
+
+ img {
+ width: 0.18rem;
+ height: 0.18rem;
+ margin: 0 0.1rem 0 0.1rem;
+ }
+
+ border: 0.01rem solid @border;
+ border-radius: 0.2rem;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ input {
+ border: none;
+ width: 2.8rem;
+ }
+}
+
+.mosaic_data {
+ height: 0.65rem;
+ padding: 0.15rem 0.25rem 0.15rem 0;
+ display: flex;
+ flex-direction: row;
+ justify-items: center;
+ justify-content: space-between;
+ align-content: center;
+ align-items: center;
+ border-bottom: 0.01rem solid @line;
+ position: relative;
+
+ .namege_img {
+ position: absolute;
+ display: inline-block;
+ top: 0.2rem;
+
+ .mosaicIcon {
+ display: inline-block;
+ width: 0.28rem;
+ height: 0.28rem;
+ margin-left: 0.1rem;
+ }
+ }
+
+ .img_container {
+ display: inline-block;
+ position: absolute;
+ top: 0.23rem;
+ margin-right: 0.15rem;
+
+ img {
+ display: inline-block;
+ width: 0.22rem;
+ height: 0.2rem;
+ }
+
+ img.grayed-xym-logo {
+ opacity: 0.4;
+ -webkit-filter: grayscale(100%);
+ -moz-filter: grayscale(100%);
+ -o-filter: grayscale(100%);
+ -ms-filter: grayscale(100%);
+ filter: grayscale(100%);
+ }
+ }
+
+ .mosaic_name {
+ position: relative;
+ top: 0;
+ left: 0.4rem;
+ width: 1.8rem;
+ font-size: @normalFont;
+ font-weight: 400;
+ color: @purpleDark;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .mosaic_value {
+ margin-left: 0.5rem;
+ text-align: right;
+ color: @purpleDark;
+
+ div:first-of-type {
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @blackLight;
+ }
+
+ div:nth-of-type(2) {
+ font-size: 0.16rem;
+ font-weight: 400;
+ color: @grayDark;
+ }
+ }
+
+ .small_icon {
+ width: 0.2rem;
+ height: 0.2rem;
+ margin-bottom: 0.05rem;
+ }
+}
+
+.padding_top_0 {
+ padding-top: 0 !important;
+ height: 0.55rem !important;
+}
+
+.padding_top_0 .namege_img {
+ top: 0.1rem !important;
+}
+
+.padding_top_0 .mosaic_value {
+ padding-top: 0.1rem !important;
+ margin-left: 0.7rem;
+}
+
+/deep/.ivu-tabs-tab {
+ font-size: @bigFont !important;
+ color: @primary !important;
+ padding: 0.08rem 0.1rem !important;
+ font-weight: @bold;
+}
+
+/deep/.ivu-tabs-ink-bar {
+ background-color: transparent !important;
+ border: none !important;
+}
+
+/deep/.ivu-tabs-bar {
+ margin-bottom: 0 !important;
+ position: relative;
+ .asset_list {
+ width: 0.24rem;
+ position: absolute;
+ bottom: 0.08rem;
+ right: 0.1rem;
+ z-index: 1;
+ }
+ border: none !important;
+ border-color: transparent !important;
+}
+
+.mosaics-list-container {
+ overflow: auto;
+ /deep/.ivu-tabs {
+ height: 100%;
+ .ivu-tabs-content {
+ height: calc(100% - 0.45rem);
+ overflow-y: auto;
+ }
+ }
+}
+
+.mosaic-balance-list-tabs-container {
+ height: 100%;
+ position: relative;
+}
+
+/deep/.ivu-tabs-content {
+ display: block;
+ overflow: visible;
+ height: 100%;
+}
+
+/deep/.ivu-tabs-tabpane {
+ height: 100%;
+ position: relative;
+ overflow-y: overlay;
+ display: block !important;
+}
+
+.toggle-mosaic-display-icon {
+ height: 0.2rem;
+ width: 0.2rem;
+ margin-right: 0.13rem;
+}
diff --git a/src/components/MosaicBalanceList/MosaicBalanceList.vue b/src/components/MosaicBalanceList/MosaicBalanceList.vue
new file mode 100644
index 0000000..4046b8c
--- /dev/null
+++ b/src/components/MosaicBalanceList/MosaicBalanceList.vue
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
{{ entry.name !== '' ? entry.name : entry.id.toHex() }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ areAllMosaicsShown() ? $t('uncheck_all') : $t('select_all') }}
+
+
+
+
+
+
+
+
+
+
+ {{ entry.name }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/MosaicBalanceList/MosaicBalanceListTs.ts b/src/components/MosaicBalanceList/MosaicBalanceListTs.ts
new file mode 100644
index 0000000..c038fe6
--- /dev/null
+++ b/src/components/MosaicBalanceList/MosaicBalanceListTs.ts
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { MosaicId, NamespaceId } from 'symbol-sdk';
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// internal dependencies
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// resources
+import { dashboardImages } from '@/views/resources/Images';
+import { MosaicService } from '@/services/MosaicService';
+import { AccountMosaicConfigurationModel } from '@/core/database/entities/MosaicConfigurationModel';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+
+export interface BalanceEntry {
+ id: MosaicId;
+ name: string;
+ amount: number;
+ mosaic: MosaicModel;
+}
+
+@Component({
+ components: {
+ MosaicAmountDisplay,
+ },
+ computed: {
+ ...mapGetters({
+ accountMosaicConfigurations: 'mosaic/accountMosaicConfigurations',
+ balanceMosaics: 'mosaic/balanceMosaics',
+ networkMosaic: 'mosaic/networkMosaic',
+ currentHeight: 'network/currentHeight',
+ networkConfiguration: 'network/networkConfiguration',
+ currentAccount: 'account/currentAccount',
+ }),
+ },
+})
+export class MosaicBalanceListTs extends Vue {
+ /**
+ * Dashboard images
+ * @var {any}
+ */
+ protected dashboardImages: Record = dashboardImages;
+
+ /**
+ * Networks 1currency mosaic
+ * @var {MosaicId}
+ */
+ public networkMosaic: MosaicId;
+
+ /**
+ * Network mosaics info (all)
+ * @var {MosaicInfo[]}
+ */
+ public balanceMosaics: MosaicModel[];
+
+ /**
+ * List of mosaics that are hidden
+ * @var {string[]}
+ */
+ public accountMosaicConfigurations: AccountMosaicConfigurationModel;
+
+ /**
+ * Current account info
+ */
+ public currentAccount: AccountModel;
+ /**
+ * Whether the component is in edition mode
+ * @var {boolean}
+ */
+ public isEditionMode: boolean = false;
+
+ public currentHeight: number;
+
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /// region computed properties getter/setter
+ /**
+ * Balance entries from the currently active account's mosaics
+ * @readonly
+ * @type {BalanceEntry}
+ */
+ get balanceEntries(): BalanceEntry[] {
+ return this.balanceMosaics.map((mosaic) => {
+ return {
+ id: new MosaicId(mosaic.mosaicIdHex),
+ name: mosaic.name || mosaic.mosaicIdHex,
+ amount: mosaic.balance || 0,
+ mosaic: mosaic,
+ };
+ });
+ }
+
+ /**
+ * All balance entries except expired mosaics
+ * @readonly
+ * @type {BalanceEntry[]}
+ */
+ get allBalanceEntries(): BalanceEntry[] {
+ return this.balanceEntries.filter((entry) => {
+ // calculate expiration
+ const expiration = MosaicService.getExpiration(
+ entry.mosaic,
+ this.currentHeight,
+ this.networkConfiguration.blockGenerationTargetTime,
+ );
+ // skip if mosaic is expired
+ return expiration !== 'expired';
+ });
+ }
+
+ /**
+ * Balance entries of active and not hidden mosaics
+ * @readonly
+ * @type {BalanceEntry[]}
+ */
+ get filteredBalanceEntries(): BalanceEntry[] {
+ // filter out hidden mosaics
+ return this.allBalanceEntries.filter((entry) => {
+ return !this.isMosaicHidden(entry.id);
+ });
+ }
+
+ /// end-region computed properties getter/setter
+
+ /**
+ * Returns true when mosaic \a mosaicId is hidden
+ * @param {MosaicId} mosaicId
+ * @return {boolean}
+ */
+ public isMosaicHidden(mosaicId: MosaicId | NamespaceId): boolean {
+ const mosaicConfiguration = this.accountMosaicConfigurations[mosaicId.toHex()];
+ return mosaicConfiguration && mosaicConfiguration.hidden;
+ }
+
+ /**
+ * Returns true if no mosaic is hidden
+ * @returns {boolean}
+ */
+ public areAllMosaicsShown(): boolean {
+ return !Object.values(this.accountMosaicConfigurations).find((c) => c.hidden);
+ }
+
+ /**
+ * Toggle whether all mosaics are shown or hidden
+ * @return {void}
+ */
+ public toggleMosaicDisplay(mosaicId?: MosaicId | NamespaceId) {
+ // - clicked singular checkbox
+ if (mosaicId !== undefined) {
+ const isHidden = this.isMosaicHidden(mosaicId);
+ const action = isHidden ? 'SHOW_MOSAIC' : 'HIDE_MOSAIC';
+ return this.$store.dispatch('mosaic/' + action, { mosaicId: mosaicId, account: this.currentAccount });
+ }
+
+ // - update state
+ const action = this.areAllMosaicsShown() ? 'HIDE_MOSAIC' : 'SHOW_MOSAIC';
+ return this.balanceMosaics.forEach((mosaic) =>
+ this.$store.dispatch('mosaic/' + action, {
+ mosaicId: new MosaicId(mosaic.mosaicIdHex),
+ account: this.currentAccount,
+ }),
+ );
+ }
+}
diff --git a/src/components/MosaicSelector/MosaicSelector.less b/src/components/MosaicSelector/MosaicSelector.less
new file mode 100644
index 0000000..75ad96b
--- /dev/null
+++ b/src/components/MosaicSelector/MosaicSelector.less
@@ -0,0 +1,17 @@
+.asset {
+ .title {
+ position: relative;
+ bottom: 15px;
+ }
+
+ .type {
+ width: 190px;
+ display: inline-block;
+ }
+
+ .amount {
+ width: 300px;
+ display: inline-block;
+ margin-left: 20px;
+ }
+}
diff --git a/src/components/MosaicSelector/MosaicSelector.vue b/src/components/MosaicSelector/MosaicSelector.vue
new file mode 100644
index 0000000..8fc6f14
--- /dev/null
+++ b/src/components/MosaicSelector/MosaicSelector.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+ {{ m.name || m.mosaicIdHex }}
+
+
+
+
+
+
+
diff --git a/src/components/MosaicSelector/MosaicSelectorTs.ts b/src/components/MosaicSelector/MosaicSelectorTs.ts
new file mode 100644
index 0000000..7a12d8a
--- /dev/null
+++ b/src/components/MosaicSelector/MosaicSelectorTs.ts
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { MosaicId } from 'symbol-sdk';
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// internal dependencies
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components//ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormLabel from '@/components//FormLabel/FormLabel.vue';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormLabel,
+ },
+ computed: {
+ ...mapGetters({
+ networkMosaic: 'mosaic/networkMosaic',
+ networkMosaicName: 'mosaic/networkMosaicName',
+ balanceMosaics: 'mosaic/balanceMosaics',
+ holdMosaics: 'mosaic/holdMosaics',
+ }),
+ },
+})
+export class MosaicSelectorTs extends Vue {
+ /**
+ * Prop bound to the parent v-model
+ */
+ @Prop({ default: '' }) value: string;
+
+ /**
+ * Mosaics to display as options
+ */
+ @Prop({ default: [] }) mosaicHexIds: string[];
+
+ /**
+ * Field label hidden by default
+ */
+ @Prop({ default: null }) label: string;
+
+ /**
+ * Disable mosaic selector
+ */
+ @Prop({ default: false }) disabled: boolean;
+
+ @Prop({ default: 'networkMosaic' }) defaultMosaic: 'networkMosaic' | 'firstInList';
+ /**
+ * Networks currency mosaic
+ */
+ public networkMosaic: MosaicId;
+
+ /**
+ * Networks currency mosaic name
+ */
+ public networkMosaicName: string;
+
+ /**
+ * All the known mosaics.
+ */
+
+ public balanceMosaics: MosaicModel[];
+ public holdMosaics: MosaicModel[];
+
+ /// region computed properties getter/setter
+
+ /**
+ * Mosaics shown as options in the select
+ * @readonly
+ * @protected
+ */
+ protected get displayedMosaics(): MosaicModel[] {
+ if (this.$route.fullPath === '/aggregate/supply') {
+ return this.mosaicHexIds.map((mosaicIdHex) => this.holdMosaics.find((m) => m.mosaicIdHex === mosaicIdHex)).filter((x) => x);
+ }
+ return this.mosaicHexIds.map((mosaicIdHex) => this.balanceMosaics.find((m) => m.mosaicIdHex === mosaicIdHex)).filter((x) => x);
+ }
+
+ /**
+ * Sets the default input value
+ * @type {string}
+ */
+ public get selectedMosaic(): string {
+ return this.value;
+ }
+
+ /**
+ * Emits input value change to parent component
+ */
+ public set selectedMosaic(hex: string) {
+ this.$emit('input', hex);
+ }
+
+ /**
+ * Hook called when the layout is mounted
+ * @return {void}
+ */
+ public mounted(): void {
+ // if a value is provided, return
+ if (this.value && this.value.length > 0) {
+ return;
+ }
+
+ // else... set default value to network mosaic
+ if (this.defaultMosaic === 'networkMosaic' && this.networkMosaic) {
+ this.selectedMosaic = this.networkMosaic.toHex();
+ }
+
+ // otherwise... set default value to the first mosaic from the props
+ if (this.defaultMosaic === 'firstInList' && this.mosaicHexIds.length) {
+ this.selectedMosaic = this.mosaicHexIds[0];
+ }
+ }
+}
diff --git a/src/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplay.vue b/src/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplay.vue
new file mode 100644
index 0000000..c6356b0
--- /dev/null
+++ b/src/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplay.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+ {{ $t('message_empty_cosignatories') }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplayTs.ts b/src/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplayTs.ts
new file mode 100644
index 0000000..1554ab2
--- /dev/null
+++ b/src/components/MultisigCosignatoriesDisplay/MultisigCosignatoriesDisplayTs.ts
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { MultisigAccountInfo, Address } from 'symbol-sdk';
+
+// child components
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+// @ts-ignore
+import AddCosignatoryInput from '@/components/AddCosignatoryInput/AddCosignatoryInput.vue';
+
+// custom types
+type AddOrRemove = 'add' | 'remove';
+
+interface Modification {
+ cosignatory: Address;
+ addOrRemove: AddOrRemove;
+}
+
+type Cosignatories = { address: Address }[];
+
+@Component({
+ components: {
+ FormRow,
+ AddCosignatoryInput,
+ },
+})
+export class MultisigCosignatoriesDisplayTs extends Vue {
+ @Prop({ default: null }) multisig: MultisigAccountInfo;
+ @Prop({ default: false }) modifiable: boolean;
+ @Prop({ default: {} }) cosignatoryModifications: Record;
+ @Prop({
+ default: '',
+ })
+ currentAddress: string;
+ /**
+ * Whether the add cosignatory form input is visible
+ */
+ protected isAddingCosignatory = false;
+
+ /**
+ * Cosignatories to add
+ * @type {Cosignatories}
+ */
+ protected get addModifications(): Cosignatories {
+ return this.getFilteredModifications('add');
+ }
+
+ /**
+ * Cosignatories to remove
+ * @type {Cosignatories}
+ */
+ protected get removeModifications(): Cosignatories {
+ return this.getFilteredModifications('remove');
+ }
+
+ /**
+ * Internal helper to get filtered cosignatory modifications
+ * @param {AddOrRemove} addOrRemoveFilter
+ * @returns {Cosignatories}
+ */
+ private getFilteredModifications(addOrRemoveFilter: AddOrRemove): Cosignatories {
+ return Object.values(this.cosignatoryModifications)
+ .filter(({ addOrRemove }) => addOrRemove === addOrRemoveFilter)
+ .map(({ cosignatory }) => ({
+ address: cosignatory,
+ }));
+ }
+
+ /**
+ * The multisig account cosignatories after modifications
+ * @type {{ publicKey: string; address: string }[]}
+ */
+ protected get cosignatories(): { address: Address }[] {
+ if (!this.multisig) {
+ return [];
+ }
+
+ return this.multisig.cosignatoryAddresses
+ .filter((address) => !this.cosignatoryModifications[address.plain()])
+ .map((address) => ({ address }));
+ }
+
+ /**
+ * Hook called when a cosignatory is added
+ * @param {PublicAccount} publicAccount
+ */
+ protected onAddCosignatory(cosigAddress: Address): Promise {
+ if (!Address.isValidRawAddress(cosigAddress.plain())) {
+ this.$store.dispatch('notification/ADD_ERROR', 'warning_unknown_account');
+ return;
+ }
+ const isCosignatory = this.cosignatories.find(({ address }) => cosigAddress.plain() === address.plain());
+
+ if (isCosignatory || this.cosignatoryModifications[cosigAddress.plain()]) {
+ this.$store.dispatch('notification/ADD_WARNING', 'warning_already_a_cosignatory');
+ return;
+ }
+
+ if (cosigAddress.plain() === this.currentAddress) {
+ this.$store.dispatch('notification/ADD_WARNING', 'current_cosigner_matches_current_account');
+ return;
+ }
+
+ this.$emit('add', cosigAddress);
+ }
+
+ /**
+ * Hook called when a cosignatory is removed
+ * @param {string} publicKey
+ */
+ protected onRemoveCosignatory(address: Address): void {
+ this.$emit('remove', address);
+ }
+
+ /**
+ * Hook called when a cosignatory modification is undone
+ * @param {string} thePublicKey
+ */
+ protected onUndoModification(theAddress: Address): void {
+ this.$emit('undo', theAddress);
+ }
+}
diff --git a/src/components/NamespaceNameInput/NamespaceNameInput.vue b/src/components/NamespaceNameInput/NamespaceNameInput.vue
new file mode 100644
index 0000000..afb9fac
--- /dev/null
+++ b/src/components/NamespaceNameInput/NamespaceNameInput.vue
@@ -0,0 +1,38 @@
+
+
+ {{ $t('form_label_namespace_name') }}:
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/NamespaceNameInput/NamespaceNameInputTs.ts b/src/components/NamespaceNameInput/NamespaceNameInputTs.ts
new file mode 100644
index 0000000..be19236
--- /dev/null
+++ b/src/components/NamespaceNameInput/NamespaceNameInputTs.ts
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { NamespaceRegistrationType, NetworkType } from 'symbol-sdk';
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ networkType: 'network/networkType',
+ }),
+ },
+})
+export class NamespaceNameInputTs extends Vue {
+ @Prop({ default: null }) value: string;
+
+ @Prop({ default: NamespaceRegistrationType.RootNamespace })
+ namespaceRegistrationType: NamespaceRegistrationType;
+
+ @Prop({ default: true }) isNeedAutoFocus: boolean;
+
+ /**
+ * Current network type
+ * @var {NetworkType}
+ */
+ public networkType: NetworkType;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /// region computed properties getter/setter
+ public get chosenValue(): string {
+ return this.value;
+ }
+
+ public set chosenValue(input: string) {
+ this.$emit('input', input);
+ }
+
+ /**
+ * Validation rule
+ * @readonly
+ * @type {Record}
+ */
+ public get validationRule(): Record {
+ return this.namespaceRegistrationType === NamespaceRegistrationType.RootNamespace
+ ? this.validationRules.namespaceName
+ : this.validationRules.subNamespaceName;
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/NamespaceSelector/NamespaceSelector.vue b/src/components/NamespaceSelector/NamespaceSelector.vue
new file mode 100644
index 0000000..7088b54
--- /dev/null
+++ b/src/components/NamespaceSelector/NamespaceSelector.vue
@@ -0,0 +1,39 @@
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+ {{ getName(namespaceModel) }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/NamespaceSelector/NamespaceSelectorTs.ts b/src/components/NamespaceSelector/NamespaceSelectorTs.ts
new file mode 100644
index 0000000..44972a9
--- /dev/null
+++ b/src/components/NamespaceSelector/NamespaceSelectorTs.ts
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+import { NamespaceModel } from '@/core/database/entities/NamespaceModel';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ namespaces: 'namespace/ownedNamespaces',
+ }),
+ },
+})
+export class NamespaceSelectorTs extends Vue {
+ /**
+ * Field label
+ * @type {string}
+ */
+ @Prop({ default: '' }) label: string;
+
+ /**
+ * Value set by the parent component's v-model
+ * @type {string}
+ */
+ @Prop({ default: null }) value: string;
+
+ /**
+ * Namespaces that are not linked
+ * @type {boolean}
+ */
+ @Prop({ default: false }) disableLinked: boolean;
+
+ /**
+ * Namespaces that are linked to an alias
+ * @type {boolean}
+ */
+ @Prop({ default: false }) disableUnlinked: boolean;
+
+ /**
+ * Level 1,2 namespace
+ * @type {boolean}
+ */
+ @Prop({ default: false }) parentNamespace: boolean;
+
+ /**
+ * Level 3 namespace
+ * @type {boolean}
+ */
+ @Prop({ default: false }) nonParentNamespace: boolean;
+
+ /**
+ * Disabled namespace selector
+ */
+ @Prop({ default: false }) disabled: boolean;
+
+ /**
+ * Namespaces names
+ * @type {[h: string]: string}
+ */
+ public namespaces: NamespaceModel[];
+
+ /**
+ * Filter Namespaces
+ */
+ get filteredNamespaces() {
+ if (this.disableLinked) {
+ return this.linkableNamespaces;
+ }
+ if (this.disableUnlinked) {
+ return this.unlinkableNamespaces;
+ }
+ if (this.parentNamespace) {
+ return this.parentNamespaces;
+ }
+ if (this.nonParentNamespace) {
+ return this.nonParentNamespaces;
+ }
+ return this.allNamespaces;
+ }
+
+ /**
+ * Namespaces that are not linked
+ */
+ get linkableNamespaces() {
+ return this.namespaces.filter((n) => n.aliasType === 0);
+ }
+
+ /**
+ * Namespaces that are linked to an alias
+ */
+ get unlinkableNamespaces() {
+ return this.namespaces.filter((n) => n.aliasType !== 0);
+ }
+
+ /**
+ * Filter out of level 3 when creating a subnamespace
+ */
+ get parentNamespaces() {
+ return this.namespaces.filter((n) => n.depth !== 3);
+ }
+
+ /**
+ * Filter level 3 subnamespace
+ */
+ get nonParentNamespaces() {
+ return this.namespaces.filter((n) => n.depth === 3);
+ }
+
+ /**
+ * all namespaces
+ */
+ get allNamespaces() {
+ return this.namespaces;
+ }
+
+ /// region computed properties getter/setter
+ /**
+ * Value set by the parent component
+ * @type {string}
+ */
+ get chosenValue(): string {
+ return this.value;
+ }
+
+ /**
+ * Emit value change
+ */
+ set chosenValue(newValue: string) {
+ this.$emit('input', newValue);
+ }
+
+ /// end-region computed properties getter/setter
+ /**
+ * Helper method to read namespace name if available
+ * @param {NamespaceModel} info
+ * @return {string}
+ */
+ public getName(info: NamespaceModel): string {
+ return info.name || info.namespaceIdHex;
+ }
+
+ /**
+ * Hook called when the layout is mounted
+ * @return {void}
+ */
+ public mounted(): void {
+ // set default value to the first namespace in the list
+ if (this.filteredNamespaces.length) {
+ this.chosenValue = this.getName(this.filteredNamespaces[0]);
+ }
+ }
+}
diff --git a/src/components/NavigationLinks/NavigationLinks.less b/src/components/NavigationLinks/NavigationLinks.less
new file mode 100644
index 0000000..5306f63
--- /dev/null
+++ b/src/components/NavigationLinks/NavigationLinks.less
@@ -0,0 +1,91 @@
+@import '../../views/resources/css/variables.less';
+
+.vertical {
+ .symbol-tab-nav {
+ height: 0.75rem;
+ display: table;
+ width: 100.5%;
+
+ .nav-item {
+ padding-left: 0.3rem;
+ font-size: @normalFont;
+ font-weight: 400;
+ color: @primary;
+ cursor: pointer;
+ display: table-cell;
+ vertical-align: middle;
+
+ &.active-item {
+ color: @primary;
+ font-family: @symbolFontSemiBold;
+ }
+ }
+ &.active-item {
+ background-color: #f3f4f8;
+ }
+ }
+}
+
+.horizontal {
+ display: grid;
+ grid-template-columns: auto;
+ grid-auto-flow: column;
+ justify-items: start;
+ justify-content: start;
+ background-color: transparent;
+
+ .empty {
+ display: flex;
+ height: 100%;
+ width: 100%;
+ }
+
+ .nav-item {
+ font-size: @bigFont;
+ position: relative;
+ font-weight: 600;
+ cursor: pointer;
+ height: 0.2rem;
+ padding: 0 0.4rem;
+ margin: 0.2rem 0;
+ line-height: 0.2rem;
+ text-align: center;
+ color: @grayLight;
+ img {
+ height: 0.2rem;
+ width: 0.2rem;
+ margin-top: 0.02rem;
+ display: inline-block;
+ }
+ &.active-item {
+ color: @primary;
+ font-family: @symbolFontSemiBold;
+ }
+ &.inactive-item {
+ color: @grayLight;
+ font-family: @symbolFont;
+ font-weight: 500;
+ }
+ }
+ .border {
+ border-left: 2px solid @primary;
+ }
+
+ .active-item {
+ color: @primary;
+ font-weight: 500;
+ cursor: not-allowed !important;
+ }
+
+ .active-item:after {
+ display: block;
+ position: absolute;
+ width: 0.3rem;
+ height: 0.04rem;
+ background: unset;
+ content: '';
+ left: -0.15rem;
+ margin-left: 50%;
+ bottom: 0;
+ }
+}
diff --git a/src/components/NavigationLinks/NavigationLinks.vue b/src/components/NavigationLinks/NavigationLinks.vue
new file mode 100644
index 0000000..0e9f035
--- /dev/null
+++ b/src/components/NavigationLinks/NavigationLinks.vue
@@ -0,0 +1,26 @@
+
+
+
+
+ {{ $t(translationPrefix + item.toLowerCase()) }}
+
+
+
+
+
+
+
diff --git a/src/components/NavigationLinks/NavigationLinksTs.ts b/src/components/NavigationLinks/NavigationLinksTs.ts
new file mode 100644
index 0000000..097f1a6
--- /dev/null
+++ b/src/components/NavigationLinks/NavigationLinksTs.ts
@@ -0,0 +1,9 @@
+import { Vue, Component, Prop } from 'vue-property-decorator';
+
+@Component
+export class NavigationLinksTs extends Vue {
+ @Prop({ default: () => [] }) items: string[];
+ @Prop({ default: 0 }) currentItemIndex: number;
+ @Prop({ default: 'vertical' }) direction: string;
+ @Prop({ default: 'settings_tab_' }) translationPrefix: string;
+}
diff --git a/src/components/NavigationTabs/NavigationTabs.less b/src/components/NavigationTabs/NavigationTabs.less
new file mode 100644
index 0000000..b22cd8e
--- /dev/null
+++ b/src/components/NavigationTabs/NavigationTabs.less
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+@import '../../views/resources/css/variables.less';
+.tabs {
+ border-bottom: none;
+}
+.horizontal {
+ display: grid;
+ grid-template-columns: auto;
+ grid-auto-flow: column;
+ justify-items: start;
+ justify-content: start;
+ height: 100%;
+ width: fit-content;
+ background-color: transparent;
+
+ .tab-item {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: @bigFont;
+ position: relative;
+ font-weight: 500;
+ cursor: pointer;
+ height: 0.2rem;
+ width: auto;
+ padding: 0 0.4rem;
+ margin: 0.2rem 0;
+ line-height: 0.2rem;
+ text-align: center;
+ color: @purpleDark;
+ opacity: 0.5;
+
+ img {
+ height: 0.15rem;
+ width: 0.15rem;
+ display: inline-block;
+ }
+
+ .tab-icon {
+ margin: auto;
+ margin-right: 1em;
+ }
+ }
+ .tab-item:not(:first-child) {
+ border-left: 2px solid @primary;
+ }
+
+ .active {
+ color: @purpleDark;
+ opacity: 1;
+ font-weight: 600;
+ cursor: default !important;
+ }
+
+ .active:after {
+ display: block;
+ position: absolute;
+ width: 0.3rem;
+ height: 0.04rem;
+ background: unset;
+ content: '';
+ left: -0.15rem;
+ margin-left: 50%;
+ bottom: 0;
+ }
+}
+
+.vertical {
+ display: grid;
+ grid-template-columns: auto;
+ padding-top: 70px;
+
+ .tab-item {
+ padding-bottom: 0.35rem;
+ font-size: 18px;
+ font-weight: 400;
+ color: @grayLight;
+ cursor: pointer;
+ padding-left: 80px;
+ }
+
+ .active {
+ font-size: 18px;
+ font-weight: 700;
+ color: @primary;
+ cursor: not-allowed !important;
+ }
+}
diff --git a/src/components/NavigationTabs/NavigationTabs.vue b/src/components/NavigationTabs/NavigationTabs.vue
new file mode 100644
index 0000000..43fb28c
--- /dev/null
+++ b/src/components/NavigationTabs/NavigationTabs.vue
@@ -0,0 +1,25 @@
+
+
+
{})"
+ >
+
+
+ {{ $t(tabEntry.title) }}
+
+
+
+
+
+
+
+
diff --git a/src/components/NavigationTabs/NavigationTabsTs.ts b/src/components/NavigationTabs/NavigationTabsTs.ts
new file mode 100644
index 0000000..e323a35
--- /dev/null
+++ b/src/components/NavigationTabs/NavigationTabsTs.ts
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+// external dependencies
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { AccountModel, AccountType } from '@/core/database/entities/AccountModel';
+import { mapGetters } from 'vuex';
+// internal dependencies
+import { TabEntry } from '@/router/TabEntry';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ }),
+ },
+})
+export class NavigationTabsTs extends Vue {
+ /**
+ * Parent route name
+ * @var {string}
+ */
+ @Prop({ default: '' }) parentRouteName: string;
+ @Prop() customTabEntries: TabEntry[];
+
+ public get tabEntries(): TabEntry[] {
+ if (this.customTabEntries && this.customTabEntries.length > 0) {
+ return this.customTabEntries;
+ }
+
+ // @ts-ignore
+ const getTabEntries = this.$router.getTabEntries(this.parentRouteName);
+ if (this.isLedger) {
+ return getTabEntries.filter((entry) => {
+ return entry.title !== 'page_title_account_backup';
+ });
+ } else {
+ return getTabEntries;
+ }
+ }
+
+ public currentAccount: AccountModel;
+
+ public get isLedger(): boolean {
+ return this.currentAccount.type === AccountType.LEDGER || this.currentAccount.type === AccountType.LEDGER_OPT_IN;
+ }
+
+ @Prop({ default: 'horizontal' }) direction: 'horizontal' | 'vertical';
+}
diff --git a/src/components/NetworkNodeSelector/NetworkNodeSelector.less b/src/components/NetworkNodeSelector/NetworkNodeSelector.less
new file mode 100644
index 0000000..a35e550
--- /dev/null
+++ b/src/components/NetworkNodeSelector/NetworkNodeSelector.less
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+@import '../../views/resources/css/variables.less';
+
+/deep/.ivu-select-dropdown-list {
+ max-height: 3rem;
+}
+
+/deep/.ivu-auto-complete .ivu-icon-ios-close {
+ font-size: 0.24rem;
+}
+
+.emphasis {
+ min-height: 0.9rem;
+}
+
+.custom-node-input-container {
+ padding-right: 0.14rem;
+ display: flex;
+ gap: 0.14rem;
+ align-items: center;
+}
+
+.publickey-input-container {
+ background: #f2f2f2;
+ margin-top: 0.14rem;
+}
+
+.select-button {
+ border: none !important;
+ font-weight: bold;
+ padding: 0.04rem;
+ cursor: pointer;
+ background-color: transparent;
+ color: @purpleLightest;
+}
+.clickable-input {
+ cursor: pointer;
+}
diff --git a/src/components/NetworkNodeSelector/NetworkNodeSelector.vue b/src/components/NetworkNodeSelector/NetworkNodeSelector.vue
new file mode 100644
index 0000000..7b73391
--- /dev/null
+++ b/src/components/NetworkNodeSelector/NetworkNodeSelector.vue
@@ -0,0 +1,61 @@
+
+
+ {{ $t('node_url') }}:
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/NetworkNodeSelector/NetworkNodeSelectorTs.ts b/src/components/NetworkNodeSelector/NetworkNodeSelectorTs.ts
new file mode 100644
index 0000000..a109bec
--- /dev/null
+++ b/src/components/NetworkNodeSelector/NetworkNodeSelectorTs.ts
@@ -0,0 +1,216 @@
+// external dependencies
+import { Component, Vue, Prop, Watch } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+
+// internal dependencies
+// @ts-ignore
+import FormWrapper from '@/components/FormWrapper/FormWrapper.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+import { URLHelpers } from '@/core/utils/URLHelpers';
+import { NetworkType, NodeInfo, RepositoryFactoryHttp, RoleType } from 'symbol-sdk';
+import { NotificationType } from '@/core/utils/NotificationType';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+
+@Component({
+ components: {
+ FormWrapper,
+ FormRow,
+ },
+ computed: {
+ ...mapGetters({
+ repositoryFactory: 'network/repositoryFactory',
+ peerNodes: 'network/peerNodes',
+ networkType: 'network/networkType',
+ currentProfile: 'profile/currentProfile',
+ }),
+ },
+})
+export class NetworkNodeSelectorTs extends Vue {
+ @Prop({ default: () => [RoleType.PeerNode, RoleType.VotingNode] }) includeRoles: number[];
+
+ @Prop()
+ value: NodeModel;
+
+ @Prop({
+ default: false,
+ })
+ disabled: boolean;
+
+ @Prop({
+ default: false,
+ })
+ isAccountKeyLinked: boolean;
+ @Prop({
+ default: false,
+ })
+ isVrfKeyLinked: boolean;
+
+ @Prop({
+ default: false,
+ })
+ missingKeys: boolean;
+
+ public peerNodes: NodeInfo[];
+ public isFetchingNodeInfo = false;
+ public networkType: NetworkType;
+ /**
+ * Form items
+ */
+ protected formNodeUrl = '';
+
+ protected customNode = '';
+
+ protected formNodePublicKey = '';
+
+ public customNodeData = [];
+
+ public filteredData = [];
+
+ public showInputPublicKey = false;
+
+ public currentProfile: ProfileModel;
+
+ private hideList: boolean = false;
+ /**
+ * Checks if the given node is eligible for harvesting
+ * @protected
+ * @returns {Promise}
+ */
+ protected async fetchNodePublicKey(value) {
+ if (!value) {
+ return '';
+ }
+
+ // first check it in peer nodes
+ const peerNode = this.filteredNodes.find((p) => p.host === value);
+ if (peerNode && peerNode?.nodePublicKey) {
+ const nodeModel = new NodeModel(
+ value,
+ peerNode.friendlyName,
+ false,
+ this.networkType,
+ peerNode.publicKey,
+ peerNode.nodePublicKey,
+ );
+ Vue.set(this, 'showInputPublicKey', false);
+ this.$emit('input', nodeModel);
+ return;
+ }
+ this.isFetchingNodeInfo = true;
+ try {
+ const nodeUrl = URLHelpers.getNodeUrl(value);
+ const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
+ const nodeRepository = repositoryFactory.createNodeRepository();
+ const nodeInfo = await nodeRepository.getNodeInfo().toPromise();
+ this.formNodeUrl = value;
+ if (nodeInfo.nodePublicKey) {
+ const nodeModel = new NodeModel(
+ value,
+ nodeInfo.friendlyName,
+ false,
+ this.networkType,
+ nodeInfo.publicKey,
+ nodeInfo.nodePublicKey,
+ );
+ Vue.set(this, 'showInputPublicKey', false);
+ this.$emit('input', nodeModel);
+ if (this.isAccountKeyLinked && this.isVrfKeyLinked && this.missingKeys) {
+ this.$store.dispatch('harvesting/FETCH_STATUS', value);
+ }
+ } else {
+ Vue.set(this, 'showInputPublicKey', true);
+ }
+ } catch (error) {
+ this.$store.dispatch('notification/ADD_ERROR', NotificationType.INVALID_NODE);
+ console.log(error);
+ Vue.set(this, 'showInputPublicKey', true);
+ throw new Error('Node_connection_failed');
+ } finally {
+ this.isFetchingNodeInfo = false;
+ }
+ }
+
+ public async created() {
+ await this.$store.dispatch('network/LOAD_PEER_NODES');
+ this.customNodeData = this.filteredNodes.map((n) => n.host);
+ this.filteredData = [...this.customNodeData];
+ const currentNodeUrl = this.currentProfile.selectedNodeUrlToConnect.replace(/http:|:3000|\//g, '');
+ if (this.customNodeData.includes(currentNodeUrl) && !this.value.url) {
+ this.fetchNodePublicKey(currentNodeUrl);
+ }
+ }
+
+ @Watch('value', { immediate: true })
+ protected valueWatcher(newVal: NodeModel) {
+ if (newVal) {
+ this.formNodeUrl = newVal.url;
+ if (!this.formNodeUrl) {
+ this.formNodePublicKey = newVal.nodePublicKey;
+ }
+ if (this.formNodePublicKey) {
+ this.showInputPublicKey = !this.formNodeUrl;
+ }
+ } else {
+ this.formNodeUrl = '';
+ }
+ }
+
+ @Watch('formNodeUrl', { immediate: true })
+ protected nodeWatcher(newInput: string) {
+ this.hideList = false;
+ this.customNode = newInput;
+ if (newInput) {
+ this.filteredData = this.customNodeData.filter((n) => n.toLowerCase().startsWith(newInput.toLowerCase()));
+ }
+ if (!this.formNodeUrl) {
+ this.filteredData = this.customNodeData;
+ }
+ }
+
+ public filterUrls(value, option) {
+ return option.toUpperCase().indexOf(value.toUpperCase()) !== -1;
+ }
+
+ public onChangeFormNodePublicKey(event) {
+ const nodeModel = { nodePublicKey: event.target.value };
+ this.$emit('input', nodeModel);
+ }
+
+ public onClear() {
+ // @ts-ignore
+ this.$refs.nodeUrlInput.$el.focus();
+ this.$emit('input', { nodePublicKey: '' });
+ }
+
+ public async handleSelectCustomNode() {
+ if (this.customNode !== '') {
+ this.hideList = true;
+ await this.fetchNodePublicKey(this.customNode);
+ this.customNode = '';
+ }
+ }
+
+ protected get filteredNodes() {
+ if (this.includeRoles && this.includeRoles.length > 0) {
+ // exclude ngl nodes that doesn't support harvesting
+ return this.peerNodes.filter(
+ (node) =>
+ node.roles?.some((role) => this.isIncluded(role)) &&
+ !node.host?.includes('ap-southeast-1.testnet') &&
+ !node.host.includes('us-east-1.testnet') &&
+ !node.host.includes('eu-central-1.testnet') &&
+ node.networkIdentifier === this.networkType,
+ );
+ }
+ return this.peerNodes;
+ }
+
+ private isIncluded(role: RoleType) {
+ return this.includeRoles?.some((includedRole) => includedRole === role);
+ }
+ get nodeExistsInList() {
+ return this.filteredData.includes(this.customNode);
+ }
+}
diff --git a/src/components/NetworkStatisticsPanel/NetworkStatisticsPanel.less b/src/components/NetworkStatisticsPanel/NetworkStatisticsPanel.less
new file mode 100644
index 0000000..f658cb3
--- /dev/null
+++ b/src/components/NetworkStatisticsPanel/NetworkStatisticsPanel.less
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+@import '../../views/resources/css/variables.less';
+
+.top_network_info {
+ background-color: transparent;
+ justify-content: space-between;
+
+ .number-grow-warp {
+ display: inline-block;
+ }
+
+ .top_account_info {
+ display: grid;
+ grid-template-columns: repeat(3, 33%);
+ grid-template-rows: 100%;
+
+ padding-top: 8px;
+ padding-bottom: 8px;
+
+ border-radius: @borderRadius;
+ background-color: white;
+
+ > div {
+ padding: 18px 0 18px 30px;
+ position: relative;
+
+ .title {
+ margin-bottom: 18px;
+
+ .title_txt {
+ font-size: 20px;
+ line-height: 33px;
+ color: @purpleDark;
+ }
+ }
+ }
+
+ .txt_info {
+ font-size: 40px;
+ font-weight: 400;
+ width: 180px;
+ display: inline-block;
+ color: #5200c6;
+ line-height: 40px;
+
+ button.button-style {
+ padding: 0;
+ }
+ }
+
+ .speed {
+ width: 65px;
+ }
+
+ .speed-blocks {
+ font-size: 16px;
+ line-height: 22px;
+ color: rgba(82, 0, 198, 1);
+ opacity: 0.75;
+ text-transform: lowercase;
+ }
+ }
+}
diff --git a/src/components/NetworkStatisticsPanel/NetworkStatisticsPanel.vue b/src/components/NetworkStatisticsPanel/NetworkStatisticsPanel.vue
new file mode 100644
index 0000000..a3af520
--- /dev/null
+++ b/src/components/NetworkStatisticsPanel/NetworkStatisticsPanel.vue
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+ {{ $t('chain_height') }}
+
+
+ {{ currentHeight }}
+
+
+
+
+
+ {{ $t('transactions') }}
+
+
{{ countTransactions }}
+
+
+
+
+ {{ $t('peers_number') }}
+
+
+ {{ countNodes }}
+
+
+
+
+
+
+
+
diff --git a/src/components/NetworkStatisticsPanel/NetworkStatisticsPanelTs.ts b/src/components/NetworkStatisticsPanel/NetworkStatisticsPanelTs.ts
new file mode 100644
index 0000000..300e85f
--- /dev/null
+++ b/src/components/NetworkStatisticsPanel/NetworkStatisticsPanelTs.ts
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// configuration
+// child components
+// @ts-ignore
+// @ts-ignore
+import { officialIcons } from '@/views/resources/Images';
+
+import { AccountModel, AccountType as ProfileType } from '@/core/database/entities/AccountModel';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ networkConfiguration: 'network/networkConfiguration',
+ countTransactions: 'statistics/countTransactions',
+ countAccounts: 'statistics/countAccounts',
+ countNodes: 'statistics/countNodes',
+ currentHeight: 'network/currentHeight',
+ currentPeerInfo: 'network/currentPeerInfo',
+ }),
+ },
+})
+export class NetworkStatisticsPanelTs extends Vue {
+ /**
+ * The icons resources.
+ */
+ public officialIcons = officialIcons;
+
+ /**
+ * The current account.
+ */
+ private currentAccount: AccountModel;
+
+ /**
+ * The network configuration.
+ */
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /**
+ * Number of transactions on the network
+ */
+ public countTransactions: number;
+
+ /**
+ * Number of accounts on the network
+ */
+ public countAccounts: number;
+
+ /**
+ * Number of nodes on the network
+ */
+ public countNodes: number;
+
+ /**
+ * Current network block height
+ */
+ public currentHeight: number;
+
+ /**
+ * Currently connect peer information
+ */
+ public currentPeerInfo: NodeModel;
+
+ /**
+ * Whether harvesting wizard is currently displayed
+ */
+ protected isHarvestingWizardDisplayed = false;
+
+ /**
+ * The supported profile types for harvesting
+ */
+ protected harvestingSupportedProfileTypes: ProfileType[] = [ProfileType.SEED];
+
+ /**
+ * Whether harvesting is enabled for current account
+ */
+ protected isHarvestingEnabled = false;
+
+ /**
+ * Current network target block time
+ */
+ protected get blockGenerationTargetTime(): number {
+ return this.networkConfiguration.blockGenerationTargetTime;
+ }
+
+ public created() {
+ if (this.currentAccount) {
+ this.isHarvestingEnabled = this.harvestingSupportedProfileTypes.includes(this.currentAccount.type);
+ }
+ }
+}
diff --git a/src/components/PageNavigator/PageNavigator.less b/src/components/PageNavigator/PageNavigator.less
new file mode 100644
index 0000000..64d78bc
--- /dev/null
+++ b/src/components/PageNavigator/PageNavigator.less
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+@iconHeight: 1rem;
+@numberOfIcons: 7; // number of icons in the menu, excluding the logout button
+
+.wrap {
+ .left-navigator {
+ height: 100%;
+ width: 250px;
+ background-color: @white;
+ color: @purpleDark;
+ font-size: @normalFont;
+
+ .navigator-items-container {
+ // overflow-y: scroll;
+ overflow: hidden;
+ height: calc(100% - 200px);
+ }
+
+ .navigator-item-container {
+ width: 100%;
+ height: 70px;
+ text-align: center;
+ justify-content: center;
+ align-items: center;
+ display: flex;
+ background-color: @white;
+ cursor: pointer;
+
+ .navigator-icon-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ height: 100%;
+ width: 85px;
+ .navigator-icon {
+ width: 35px;
+ }
+ .ivu-icon {
+ color: @purpleDark;
+ }
+ }
+
+ .navigator-text-container {
+ flex: 1;
+ padding-left: 10px;
+ text-align: left;
+ }
+ }
+
+ .active {
+ background: #f3f4f8;
+ opacity: 1;
+ cursor: not-allowed;
+ border-right: 0.3em #ff00ff solid;
+ padding-right: 0.5em;
+ font-weight: bold;
+ }
+ }
+}
+
+.logo-container {
+ text-align: center;
+ width: 100%;
+ height: 100px;
+ img {
+ width: auto;
+ max-width: 100%;
+ max-height: 100px;
+ padding: 30px;
+ }
+}
+
+.network-container {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ width: 250px;
+ height: 100px;
+ text-align: center;
+ border-top: 1px solid @grayLight;
+ background-color: @white;
+}
diff --git a/src/components/PageNavigator/PageNavigator.vue b/src/components/PageNavigator/PageNavigator.vue
new file mode 100644
index 0000000..4845516
--- /dev/null
+++ b/src/components/PageNavigator/PageNavigator.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+
{{ $t(route.meta.title) }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/PageNavigator/PageNavigatorTs.ts b/src/components/PageNavigator/PageNavigatorTs.ts
new file mode 100644
index 0000000..6194fad
--- /dev/null
+++ b/src/components/PageNavigator/PageNavigatorTs.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// internal dependencies
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { Route } from 'vue-router';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentProfile: 'profile/currentProfile',
+ }),
+ },
+})
+export class PageNavigatorTs extends Vue {
+ /**
+ * Currently active profile
+ * @see {Store.Profile}
+ * @var {string}
+ */
+ public currentProfile: ProfileModel;
+
+ /**
+ * Executes action of logout
+ * @return {void}
+ */
+ public async logout() {
+ await this.$store.dispatch('profile/LOG_OUT');
+ this.$router.push({ name: 'profiles.login' });
+ }
+
+ public onPageNavigate(route: Route) {
+ const isDuplicatedRoute = this.$route.matched.map(({ path }) => path).includes(route.path);
+ !isDuplicatedRoute &&
+ this.currentProfile &&
+ this.$router.push({ name: route.name }).catch(() => {
+ /**/
+ });
+ }
+}
diff --git a/src/components/PageTitle/PageTitle.less b/src/components/PageTitle/PageTitle.less
new file mode 100644
index 0000000..f46aea8
--- /dev/null
+++ b/src/components/PageTitle/PageTitle.less
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+.label_page {
+ font-size: 18px;
+ font-weight: 400;
+ color: rgba(102, 102, 102);
+ line-height: 23px;
+ padding-top: 20px;
+
+ .page_title {
+ font-size: 20px;
+ // padding-bottom: 5px;
+ margin: 0 23px 0 15px;
+ position: relative;
+ //width: 140px;
+ }
+}
diff --git a/src/components/PageTitle/PageTitle.vue b/src/components/PageTitle/PageTitle.vue
new file mode 100644
index 0000000..6503677
--- /dev/null
+++ b/src/components/PageTitle/PageTitle.vue
@@ -0,0 +1,16 @@
+
+
+ {{ $t(title) }}
+
+ {{ $t('refresh') }}
+
+
+
+
+
+
diff --git a/src/components/PageTitle/PageTitleTs.ts b/src/components/PageTitle/PageTitleTs.ts
new file mode 100644
index 0000000..7fea208
--- /dev/null
+++ b/src/components/PageTitle/PageTitleTs.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+
+@Component
+export class PageTitleTs extends Vue {
+ @Prop({
+ default: '',
+ })
+ title: string;
+}
diff --git a/src/components/Pagination/Pagination.less b/src/components/Pagination/Pagination.less
new file mode 100644
index 0000000..a00349e
--- /dev/null
+++ b/src/components/Pagination/Pagination.less
@@ -0,0 +1,19 @@
+@import '../../views/resources/css/variables.less';
+
+/deep/.ivu-page-simple-pager {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 0;
+ input {
+ width: 0.4rem;
+ margin-bottom: 0.05rem;
+ }
+}
+
+.table-container {
+ .table-footer-container {
+ /deep/.ivu-page-item {
+ -webkit-box-shadow: none !important;
+ }
+ }
+}
diff --git a/src/components/Pagination/Pagination.vue b/src/components/Pagination/Pagination.vue
new file mode 100644
index 0000000..bf5d15e
--- /dev/null
+++ b/src/components/Pagination/Pagination.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/src/components/Pagination/PaginationTs.ts b/src/components/Pagination/PaginationTs.ts
new file mode 100644
index 0000000..f654c5c
--- /dev/null
+++ b/src/components/Pagination/PaginationTs.ts
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+
+@Component
+export default class PaginationTs extends Vue {
+ @Prop({ default: 1 }) readonly current!: number;
+ @Prop({ default: 10 }) readonly pageSize!: number;
+ @Prop({ default: false }) readonly lastPage!: boolean;
+ @Prop({ default: 'ivu-page ivu-page-simple' }) readonly simpleWrapClasses!: string;
+ @Prop({ default: 'ivu-page-prev' }) readonly prevClasses!: string;
+ @Prop({ default: 'ivu-page-simple-pager' }) readonly simplePagerClasses!: string;
+ @Prop({ default: 'ivu-page-next' }) readonly nextClasses!: string;
+
+ public targetPage: number = 0;
+
+ public prefixCls = 'ivu-page';
+
+ public mounted() {
+ this.targetPage = this.current;
+ }
+
+ public get currentPage() {
+ return this.current;
+ }
+
+ /**
+ * Class names for previous page button
+ */
+ public get prevCls() {
+ return [
+ this.prevClasses,
+ {
+ [`${this.prefixCls}-disabled`]: this.currentPage <= 1,
+ },
+ ];
+ }
+
+ /**
+ * Class names for next page button
+ */
+ public get nextCls() {
+ return [
+ this.nextClasses,
+ {
+ [`${this.prefixCls}-disabled`]: this.lastPage,
+ },
+ ];
+ }
+
+ /**
+ * Hook called when next page button is clicked
+ */
+ public next() {
+ if (this.lastPage) {
+ return;
+ }
+ this.targetPage = this.currentPage + 1;
+ this.$emit('targetPage', this.targetPage);
+ }
+
+ /**
+ * Hook called when previous page button is clicked
+ */
+ public prev() {
+ if (this.currentPage <= 1) {
+ return;
+ }
+ this.targetPage = this.currentPage - 1;
+ this.$emit('targetPage', this.targetPage);
+ }
+
+ /**
+ * Hook called when key is up
+ * @param key event
+ */
+ public keyUp(e) {
+ const key = e.keyCode;
+ const val = parseInt(e.target.value);
+ if (isNaN(val)) {
+ return;
+ }
+ if (key === 40) {
+ this.prev();
+ } else if (key === 38) {
+ this.next();
+ } else if (key === 13) {
+ this.$emit('targetPage', val);
+ }
+ }
+
+ /**
+ * Hook called when key is down
+ * Prevents the disallowed chars to be typed in
+ * @param key event
+ */
+ public keyDown(e) {
+ const key = e.keyCode;
+ const condition = (key >= 48 && key <= 57) || (key >= 96 && key <= 105) || key === 8 || key === 37 || key === 39;
+ if (!condition) {
+ e.preventDefault();
+ }
+ }
+}
diff --git a/src/components/PaidFeeDisplay/PaidFeeDisplay.vue b/src/components/PaidFeeDisplay/PaidFeeDisplay.vue
new file mode 100644
index 0000000..af403f7
--- /dev/null
+++ b/src/components/PaidFeeDisplay/PaidFeeDisplay.vue
@@ -0,0 +1,41 @@
+
+
+
+
+
+ ({{ $t('max_fee') }})
+
+
+
+
+
+
diff --git a/src/components/PaidFeeDisplay/PaidFeeDisplayTs.ts b/src/components/PaidFeeDisplay/PaidFeeDisplayTs.ts
new file mode 100644
index 0000000..5254b08
--- /dev/null
+++ b/src/components/PaidFeeDisplay/PaidFeeDisplayTs.ts
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { Transaction } from 'symbol-sdk';
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+import { BlockInfoModel } from '@/core/database/entities/BlockInfoModel';
+// configuration
+
+@Component({
+ components: { MosaicAmountDisplay },
+})
+export class PaidFeeDisplayTs extends Vue {
+ @Prop() transaction: Transaction;
+
+ public amount = 0;
+
+ public isMaxFee = false;
+
+ public isLoading = false;
+
+ public async mounted() {
+ this.amount = this.transaction.maxFee.compact();
+ this.isMaxFee = true;
+ this.isLoading = true;
+ if (this.transaction.transactionInfo && this.transaction.transactionInfo.height) {
+ try {
+ const blockInfo: BlockInfoModel = await this.$store.dispatch('block/GET_BLOCK', this.transaction.transactionInfo.height);
+ this.isLoading = false;
+ this.isMaxFee = false;
+ this.amount = blockInfo.feeMultiplier * this.transaction.size;
+ } catch (e) {
+ this.isLoading = false;
+ }
+ }
+ }
+}
diff --git a/src/components/PeerSelector/PeerSelector.less b/src/components/PeerSelector/PeerSelector.less
new file mode 100644
index 0000000..8b282f5
--- /dev/null
+++ b/src/components/PeerSelector/PeerSelector.less
@@ -0,0 +1,126 @@
+@import '../../views/resources/css/variables.less';
+
+.node-selector-container {
+ width: 7.9rem;
+ min-height: 3.5rem;
+ padding-top: 0.2rem;
+}
+
+.network-text {
+ color: @black;
+ font-size: 14px;
+}
+
+.current-node-info {
+ color: @primary;
+ font-size: @smallFont;
+
+ .ivu-row {
+ &:nth-child(1) {
+ margin-bottom: 0.1rem;
+ }
+ }
+}
+
+.current-node-header {
+ text-align: right;
+ font-weight: bold;
+}
+
+.current-node-value {
+ text-align: left;
+ padding-left: 0.5em;
+}
+
+.node-url {
+ font-size: @smallFont;
+ color: @grayDark;
+ font-weight: 500;
+}
+
+.node-list-container {
+ margin-top: 0.24rem;
+
+ .node-list-head {
+ font-size: @smallFont;
+ color: @primary;
+ font-weight: bold;
+ }
+
+ .node-list-entry {
+ font-size: @smallFont;
+ color: @primary;
+ font-weight: 500;
+ }
+
+ .node-list-content {
+ border: none !important;
+ margin-top: 0.1rem;
+ border: 0.02rem solid @line;
+ height: 2.2rem;
+ padding: 0.1rem 0;
+
+ ul {
+ overflow-x: hidden;
+ overflow-y: auto;
+ height: 100%;
+ position: relative;
+ }
+
+ .list-item {
+ font-size: @smallerFont;
+ color: @grayLight;
+ padding: 0.04rem 0.22rem;
+ width: 100%;
+ overflow: hidden;
+
+ &.active {
+ background-color: @listItemBackgroundColor;
+ }
+ }
+ }
+}
+
+.node-list-text {
+ margin: 0.08rem 0 0.25rem 0;
+ color: @tipFontColor;
+
+ .ivu-icon-ios-help-circle-outline {
+ margin-right: 0.03rem;
+ }
+}
+.endpoint-healthy,
+.endpoint-unhealthy {
+ -webkit-app-region: no-drag;
+
+ i.point {
+ display: inline-block;
+ width: 14px;
+ height: 14px;
+ border-radius: 50%;
+ }
+
+ .point {
+ vertical-align: middle;
+ margin-right: 0.08rem;
+ margin-left: 0;
+ }
+
+ .network_type_text {
+ font-size: @smallerFont;
+ vertical-align: unset;
+ color: #fff;
+ }
+}
+
+.endpoint-healthy {
+ i.point {
+ background-color: #18b566;
+ }
+}
+
+.endpoint-unhealthy {
+ i.point {
+ background-color: red;
+ }
+}
diff --git a/src/components/PeerSelector/PeerSelector.vue b/src/components/PeerSelector/PeerSelector.vue
new file mode 100644
index 0000000..cb0e579
--- /dev/null
+++ b/src/components/PeerSelector/PeerSelector.vue
@@ -0,0 +1,97 @@
+
+
+
+
+ {{ $t('node') }}
+
+
+
+
+ {{ networkTypeText }}
+
+
+
+
+
+
{{ currentPeerInfo.friendlyName }}
+
{{ currentPeerInfo.url }}
+
+
+
+
+
+
+ {{ $t('node_list') }}
+ ({{ peersList.length }})
+
+
+
+
+
+
{{ friendlyName }}
+
{{ url }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('node_list') }}
+ ({{ peersList.length }})
+
+
+
+
+
+
{{ friendlyName }}
+
{{ url }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/PeerSelector/PeerSelectorTs.ts b/src/components/PeerSelector/PeerSelectorTs.ts
new file mode 100644
index 0000000..d99f513
--- /dev/null
+++ b/src/components/PeerSelector/PeerSelectorTs.ts
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkType, RepositoryFactory } from 'symbol-sdk';
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+import { NetworkTypeHelper } from '@/core/utils/NetworkTypeHelper';
+import * as _ from 'lodash';
+//@ts-ignore
+import ModalNetworkNotMatchingProfile from '@/views/modals/ModalNetworkNotMatchingProfile/ModalNetworkNotMatchingProfile.vue';
+
+@Component({
+ components: { ModalNetworkNotMatchingProfile },
+ computed: {
+ ...mapGetters({
+ currentPeerInfo: 'network/currentPeerInfo',
+ isConnected: 'network/isConnected',
+ networkType: 'network/networkType',
+ repositoryFactory: 'network/repositoryFactory',
+ generationHash: 'network/generationHash',
+ knowNodes: 'network/knowNodes',
+ networkIsNotMatchingProfile: 'network/networkIsNotMatchingProfile',
+ }),
+ },
+})
+export class PeerSelectorTs extends Vue {
+ @Prop({ default: false }) isEmbedded: boolean;
+ /**
+ * Currently active endpoint
+ * @see {Store.Network}
+ * @var {Object}
+ */
+ public currentPeerInfo: NodeModel;
+ public networkIsNotMatchingProfile: boolean;
+ /**
+ * Whether the connection is up
+ * @see {Store.Network}
+ * @var {boolean}
+ */
+ public isConnected: boolean;
+
+ /**
+ * Current networkType
+ * @see {Store.Network}
+ * @var {NetworkType}
+ */
+ public networkType: NetworkType;
+
+ /**
+ * Current generationHash
+ * @see {Store.Network}
+ * @var {string}
+ */
+ public generationHash: string;
+
+ /**
+ * Known peers
+ * @see {Store.Network}
+ * @var {string[]}
+ */
+ public knowNodes: NodeModel[];
+
+ public repositoryFactory: RepositoryFactory;
+
+ public poptipVisible: boolean = false;
+
+ /// region computed properties getter/setter
+ get peersList(): NodeModel[] {
+ return _.sortBy(
+ this.knowNodes,
+ (a) => a.isDefault !== true,
+ (a) => a.url,
+ );
+ }
+
+ get networkTypeText(): string {
+ if (!this.isConnected) {
+ return this.$t('invalid_node').toString();
+ }
+ return !!this.networkType ? NetworkTypeHelper.getNetworkTypeLabel(this.networkType) : this.$t('loading').toString();
+ }
+
+ /// end-region computed properties getter/setter
+
+ /**
+ * Switch the currently active peer
+ * @param peer
+ */
+ public switchPeer(url: string) {
+ this.$store.dispatch('network/SET_CURRENT_PEER', url);
+ }
+ onPopTipShow() {
+ this.$forceUpdate();
+ }
+ goSettings() {
+ this.poptipVisible = false;
+ this.$store.commit('profile/toggleSettings');
+ }
+ onCloseNetworkModal() {
+ this.$store.dispatch('network/SET_NETWORK_IS_NOT_MATCHING_PROFILE', false);
+ }
+}
diff --git a/src/components/ProfileBalancesPanel/ProfileBalancesPanel.less b/src/components/ProfileBalancesPanel/ProfileBalancesPanel.less
new file mode 100644
index 0000000..6110ddf
--- /dev/null
+++ b/src/components/ProfileBalancesPanel/ProfileBalancesPanel.less
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.balances-panel-outer-container {
+ .balances-panel-container {
+ display: grid;
+ height: 100%;
+ grid-template-columns: 100%;
+ grid-template-rows: 2.4rem auto;
+ grid-row-gap: 0.3rem;
+ }
+}
+.mosaicListWrap {
+ height: 100%;
+}
+.account-info-tile {
+ background-color: @white;
+}
+
+.top_account_address.grayed {
+ background-color: @grayDark;
+}
+
+.top_account_address.purpled {
+ background-color: @primary;
+}
+
+.top_account_address {
+ width: 100%;
+ height: 2.4rem;
+ padding: 0.13rem 0.2rem 0 0.21rem;
+ position: relative;
+ background-size: cover;
+ background: linear-gradient(315.55deg, #49004e -1.68%, #5200c6 110.7%);
+ border-radius: @borderRadius;
+
+ .account_address {
+ padding-bottom: 0.15rem;
+ display: flex;
+ justify-content: space-between;
+
+ .address-label {
+ color: @white;
+ font-size: @biggerFont;
+ font-weight: 100;
+ display: inline-block;
+ }
+
+ .address {
+ color: @white;
+ font-size: @biggerFont;
+ font-weight: 100;
+ display: inline-block;
+ width: 3.6rem;
+ word-break: break-word;
+ }
+
+ img {
+ float: right;
+ width: 0.22rem;
+ height: 0.22rem;
+ }
+
+ .copy-button {
+ height: max-content;
+ margin-top: 0.34rem;
+ }
+ }
+
+ .XEM_amount {
+ margin-top: 0.29rem;
+ font-size: @biggerFont;
+ font-weight: 500;
+ color: @white;
+ }
+
+ .amount {
+ line-height: 1;
+ }
+
+ .balance-background {
+ width: 1.29rem;
+ height: 1.22rem;
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ }
+}
+
+/deep/.xym-outline {
+ -webkit-box-shadow: none !important;
+ box-shadow: none !important;
+}
+
+.bottom_account_info {
+ width: 100%;
+ padding: 0.27rem 0.18rem 0.27rem 0.28rem;
+ position: relative;
+ display: grid;
+ grid-template-rows: 100%;
+ grid-template-columns: 100%;
+ overflow-y: hidden;
+ background-color: white;
+ border-radius: @borderRadius;
+
+ .ivu-tabs-tab-active {
+ color: @primary;
+ }
+
+ .ivu-tabs-tab:hover {
+ color: @primary;
+ }
+
+ .ivu-tabs-ink-bar {
+ background-color: @purple;
+ }
+}
+
+.mosaicListWrap {
+ height: 100%;
+ display: block;
+ overflow: hidden;
+}
diff --git a/src/components/ProfileBalancesPanel/ProfileBalancesPanel.vue b/src/components/ProfileBalancesPanel/ProfileBalancesPanel.vue
new file mode 100644
index 0000000..c20ce3e
--- /dev/null
+++ b/src/components/ProfileBalancesPanel/ProfileBalancesPanel.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
{{ $t('address') }}:
+
{{ currentSignerAddress.pretty() }}
+
+
+
+
+
+
+
{{ networkCurrency.ticker }} {{ $t('balance') }}:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ProfileBalancesPanel/ProfileBalancesPanelTs.ts b/src/components/ProfileBalancesPanel/ProfileBalancesPanelTs.ts
new file mode 100644
index 0000000..ccd92bb
--- /dev/null
+++ b/src/components/ProfileBalancesPanel/ProfileBalancesPanelTs.ts
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address } from 'symbol-sdk';
+import { Component, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// child components
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import MosaicBalanceList from '@/components/MosaicBalanceList/MosaicBalanceList.vue';
+//@ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+
+@Component({
+ components: {
+ MosaicAmountDisplay,
+ MosaicBalanceList,
+ ButtonCopyToClipboard,
+ },
+ computed: {
+ ...mapGetters({
+ currentSignerAddress: 'account/currentSignerAddress',
+ balanceMosaics: 'mosaic/balanceMosaics',
+ isCosignatoryMode: 'account/isCosignatoryMode',
+ networkCurrency: 'mosaic/networkCurrency',
+ }),
+ },
+})
+export class ProfileBalancesPanelTs extends Vue {
+ /**
+ * Currently active signer
+ * @var {any}
+ */
+ public currentSignerAddress: Address;
+
+ /**
+ * Currently active account's balances
+ * @var {Mosaic[]}
+ */
+ public balanceMosaics: MosaicModel[];
+
+ /**
+ * Whether currently active account is in cosignatory mode
+ * @var {boolean}
+ */
+ public isCosignatoryMode: boolean;
+
+ /**
+ * Networks currency mosaic
+ * @var {MosaicId}
+ */
+ public networkCurrency: NetworkCurrencyModel;
+
+ public async created() {
+ this.$store.dispatch('mosaic/LOAD_MOSAICS');
+ }
+
+ public get absoluteBalance() {
+ const networkMosaicData = this.balanceMosaics.filter((m) => m.isCurrencyMosaic).find((i) => i);
+ return (networkMosaicData && networkMosaicData.balance) || 0;
+ }
+}
diff --git a/src/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButton.vue b/src/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButton.vue
new file mode 100644
index 0000000..3ae9026
--- /dev/null
+++ b/src/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButton.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ {{ $t('accounts_backup_tile_mnemonic') }}
+
+
+ {{ $t('accounts_backup_tile_mnemonic_desc') }}
+
+
+
+
+
+
+
+
diff --git a/src/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButtonTs.ts b/src/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButtonTs.ts
new file mode 100644
index 0000000..d1e59be
--- /dev/null
+++ b/src/components/ProtectedMnemonicDisplayButton/ProtectedMnemonicDisplayButtonTs.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { UIHelpers } from '@/core/utils/UIHelpers';
+// child components
+// @ts-ignore
+import ModalMnemonicDisplay from '@/views/modals/ModalMnemonicDisplay/ModalMnemonicDisplay.vue';
+
+@Component({
+ components: {
+ ModalMnemonicDisplay,
+ },
+ computed: {
+ ...mapGetters({
+ currentProfile: 'profile/currentProfile',
+ networkType: 'network/networkType',
+ generationHash: 'network/generationHash',
+ }),
+ },
+})
+export class ProtectedMnemonicDisplayButtonTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ /**
+ * UI Helpers
+ * @var {UIHelpers}
+ */
+ public uiHelpers = UIHelpers;
+
+ /**
+ * Whether currently viewing export
+ * @var {boolean}
+ */
+ public isViewingExportModal: boolean = false;
+
+ /// region computed properties getter/setter
+ public get hasMnemonicExportModal(): boolean {
+ return this.isViewingExportModal;
+ }
+
+ public set hasMnemonicExportModal(f: boolean) {
+ this.isViewingExportModal = f;
+ }
+ /// end-region computed properties getter/setter
+
+ /**
+ * Hook called when the account unlock modal must open
+ * @return {void}
+ */
+ public onClickDisplay() {
+ this.hasMnemonicExportModal = true;
+ }
+}
diff --git a/src/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButton.vue b/src/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButton.vue
new file mode 100644
index 0000000..667ef60
--- /dev/null
+++ b/src/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButton.vue
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ {{ $t('accounts_backup_tile_title') }}
+
+
+ {{ $t('accounts_backup_tile_description') }}
+
+
+
+
+
+
+
+
diff --git a/src/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButtonTs.ts b/src/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButtonTs.ts
new file mode 100644
index 0000000..db5c285
--- /dev/null
+++ b/src/components/ProtectedMnemonicQRButton/ProtectedMnemonicQRButtonTs.ts
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { UIHelpers } from '@/core/utils/UIHelpers';
+
+// child components
+// @ts-ignore
+import ModalMnemonicExport from '@/views/modals/ModalMnemonicExport/ModalMnemonicExport.vue';
+
+@Component({
+ components: {
+ ModalMnemonicExport,
+ },
+ computed: {
+ ...mapGetters({
+ currentProfile: 'profile/currentProfile',
+ networkType: 'network/networkType',
+ generationHash: 'network/generationHash',
+ }),
+ },
+})
+export class ProtectedMnemonicQRButtonTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel;
+
+ /**
+ * UI Helpers
+ * @var {UIHelpers}
+ */
+ public uiHelpers = UIHelpers;
+
+ /**
+ * Whether currently viewing export
+ * @var {boolean}
+ */
+ public isViewingExportModal: boolean = false;
+
+ /// region computed properties getter/setter
+ public get hasMnemonicExportModal(): boolean {
+ return this.isViewingExportModal;
+ }
+
+ public set hasMnemonicExportModal(f: boolean) {
+ this.isViewingExportModal = f;
+ }
+ /// end-region computed properties getter/setter
+
+ /**
+ * Hook called when the account unlock modal must open
+ * @return {void}
+ */
+ public onClickDisplay() {
+ this.hasMnemonicExportModal = true;
+ }
+}
diff --git a/src/components/ProtectedPrivateKeyDisplay/ProtectedPrivateKeyDisplay.vue b/src/components/ProtectedPrivateKeyDisplay/ProtectedPrivateKeyDisplay.vue
new file mode 100644
index 0000000..af7f3ac
--- /dev/null
+++ b/src/components/ProtectedPrivateKeyDisplay/ProtectedPrivateKeyDisplay.vue
@@ -0,0 +1,79 @@
+
+
+
+
{{ $t('private_key') }}
+
{{ plainInformation }}
+
+
+
+
+
+
+
+ {{ $t('not_linked') }}:
+
+
+
+
+ {{ $t('show_button') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/ProtectedPrivateKeyDisplay/ProtectedPrivateKeyDisplayTs.ts b/src/components/ProtectedPrivateKeyDisplay/ProtectedPrivateKeyDisplayTs.ts
new file mode 100644
index 0000000..a66bf10
--- /dev/null
+++ b/src/components/ProtectedPrivateKeyDisplay/ProtectedPrivateKeyDisplayTs.ts
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import { Account, Crypto, Password } from 'symbol-sdk';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+// child components
+// @ts-ignore
+import ModalFormProfileUnlock from '@/views/modals/ModalFormProfileUnlock/ModalFormProfileUnlock.vue';
+//@ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+const defaultCount: number = 10;
+const defaultTimerDuration: number = 1000;
+@Component({
+ components: {
+ ModalFormProfileUnlock,
+ ButtonCopyToClipboard,
+ },
+})
+export class ProtectedPrivateKeyDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ account: AccountModel | Account;
+
+ @Prop({
+ default: null,
+ })
+ encPrivateKey: string;
+
+ /**
+ * Whether account is currently being unlocked
+ * @var {boolean}
+ */
+ public isUnlockingAccount: boolean = false;
+
+ /**
+ * Whether private key is currently displayed
+ * @var {boolean}
+ */
+ public isDisplayingPrivateKey: boolean = false;
+
+ /**
+ * Plain private key information
+ * @internal
+ * @var {string}
+ */
+ private plainInformation: string = '';
+
+ /**
+ * seconds counter
+ * @internal
+ * @var {number}
+ */
+ public secondsCounter: number = defaultCount;
+
+ // Timer
+ public countInterval: any;
+ /// region computed properties getter/setter
+ public get hasPlainPrivateKey(): boolean {
+ return this.isDisplayingPrivateKey;
+ }
+
+ public set hasPlainPrivateKey(f: boolean) {
+ this.isDisplayingPrivateKey = f;
+
+ if (f === true) {
+ // "countdown" for hiding message
+ this.onStartCounter();
+ }
+ }
+
+ public get hasAccountUnlockModal(): boolean {
+ return this.isUnlockingAccount;
+ }
+
+ public set hasAccountUnlockModal(f: boolean) {
+ this.isUnlockingAccount = f;
+ }
+ /// end-region computed properties getter/setter
+
+ public reset() {
+ this.hasPlainPrivateKey = false;
+ this.secondsCounter = defaultCount;
+ this.countInterval && clearInterval(this.countInterval);
+ this.countInterval = null;
+ this.plainInformation = null;
+ }
+
+ /**
+ * Hook called when the seconds counter starts
+ * @return {void}
+ */
+ public onStartCounter() {
+ !this.countInterval &&
+ (this.countInterval = setInterval(() => {
+ this.secondsCounter--;
+ if (this.secondsCounter < 0) {
+ this.reset();
+ }
+ }, defaultTimerDuration));
+ }
+ /**
+ * Hook called when the account unlock modal must open
+ * @return {void}
+ */
+ public onClickDisplay() {
+ // don't prompt for password when an Account is povided as a prop
+ if (this.account instanceof Account) {
+ this.onAccountUnlocked(this.account);
+ return;
+ }
+
+ // prompt for password when an AccountModel is provided as a prop
+ this.hasAccountUnlockModal = true;
+ }
+
+ /**
+ * Hook called when the account has been unlocked
+ * @param {Account} account
+ * @return {boolean}
+ */
+ public onAccountUnlocked(account: Account, password?: Password): boolean {
+ this.hasPlainPrivateKey = true;
+ this.hasAccountUnlockModal = false;
+ if (this.$route.fullPath === '/delegatedHarvesting') {
+ this.plainInformation = Crypto.decrypt(this.encPrivateKey, password.value);
+ } else {
+ this.plainInformation = account.privateKey;
+ }
+ return true;
+ }
+
+ @Watch('account')
+ onAccountChange() {
+ this.reset();
+ }
+ public destroyed() {
+ this.reset();
+ }
+ public get hasPrivateKey(): boolean {
+ return !!((this.encPrivateKey && this.encPrivateKey.length > 0) || this.account);
+ }
+}
diff --git a/src/components/QRCode/ImportQRButton/ImportQRButton.less b/src/components/QRCode/ImportQRButton/ImportQRButton.less
new file mode 100644
index 0000000..eca2922
--- /dev/null
+++ b/src/components/QRCode/ImportQRButton/ImportQRButton.less
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../../views/resources/css/variables.less';
+
+.trigger-importqr {
+ color: @blackLight;
+ font-size: @normalFont !important;
+
+ span {
+ font-size: @normalFont !important;
+ }
+}
+
+.navbar-icon {
+ display: inline;
+ margin-right: 10px;
+ width: 0.15rem;
+ height: 0.15rem;
+}
diff --git a/src/components/QRCode/ImportQRButton/ImportQRButton.vue b/src/components/QRCode/ImportQRButton/ImportQRButton.vue
new file mode 100644
index 0000000..a714b4a
--- /dev/null
+++ b/src/components/QRCode/ImportQRButton/ImportQRButton.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
{{ $t('import_qr_code') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/ImportQRButton/ImportQRButtonTs.ts b/src/components/QRCode/ImportQRButton/ImportQRButtonTs.ts
new file mode 100644
index 0000000..1af235b
--- /dev/null
+++ b/src/components/QRCode/ImportQRButton/ImportQRButtonTs.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+
+import { QRCodeType } from 'symbol-qr-library';
+//@ts-ignore
+import ModalImportQR from '@/views/modals/ModalImportQR/ModalImportQR.vue';
+
+@Component({
+ components: { ModalImportQR },
+})
+export default class ImportQRButtonTs extends Vue {
+ @Prop({
+ default: [
+ QRCodeType.AddContact,
+ QRCodeType.RequestTransaction,
+ QRCodeType.SignedTransaction,
+ QRCodeType.CosignatureSignedTransaction,
+ ],
+ })
+ readonly validQrTypes!: QRCodeType[];
+
+ /**
+ * Whether Modal is visible
+ * @type boolean
+ */
+ private visible: boolean = false;
+
+ public onClick() {
+ this.visible = true;
+ }
+
+ public onClose() {
+ this.visible = false;
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/ContactQRAction/ContactQRAction.vue b/src/components/QRCode/QRCodeActions/ContactQRAction/ContactQRAction.vue
new file mode 100644
index 0000000..b386d44
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/ContactQRAction/ContactQRAction.vue
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/ContactQRAction/ContactQRActionTs.ts b/src/components/QRCode/QRCodeActions/ContactQRAction/ContactQRActionTs.ts
new file mode 100644
index 0000000..9ba4eb3
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/ContactQRAction/ContactQRActionTs.ts
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { ContactQR } from 'symbol-qr-library';
+import { Address, NetworkType } from 'symbol-sdk';
+import { QRCodeDetailItem } from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs';
+// @ts-ignore
+import TemplateQRAction from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue';
+
+@Component({
+ components: { TemplateQRAction },
+})
+export default class ContactQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: ContactQR;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ /**
+ * Get QR Code detail items
+ *
+ * @returns QRCodeDetailItem[]
+ */
+ public get detailItems(): QRCodeDetailItem[] {
+ const items: QRCodeDetailItem[] = [];
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_type').toString(),
+ this.$t('qrcode_detail_item_type_contactqr').toString(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_network_type').toString(), NetworkType[this.qrCode.networkType], true));
+
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_contact_name').toString(), this.qrCode.name, true));
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_address').toString(),
+ Address.createFromPublicKey(this.qrCode.accountPublicKey, this.qrCode.networkType).plain(),
+ true,
+ ),
+ );
+
+ return items;
+ }
+
+ public onSubmit() {
+ this.onSuccess();
+ this.$router.push({
+ name: 'dashboard.transfer',
+ params: { recipientAddress: Address.createFromPublicKey(this.qrCode.accountPublicKey, this.qrCode.networkType).plain() },
+ });
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRAction.vue b/src/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRAction.vue
new file mode 100644
index 0000000..9d95d61
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRAction.vue
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRActionTs.ts b/src/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRActionTs.ts
new file mode 100644
index 0000000..1a2ca56
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRActionTs.ts
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { CosignatureQR } from 'symbol-qr-library';
+import { NetworkType } from 'symbol-sdk';
+
+import { QRCodeDetailItem } from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs';
+// @ts-ignore
+import TemplateQRAction from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue';
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import MaxFeeSelector from '@/components/MaxFeeSelector/MaxFeeSelector.vue';
+// @ts-ignore
+import TransactionDetails from '@/components/TransactionDetails/TransactionDetails.vue';
+import { QRCode } from 'symbol-qr-library/index';
+
+@Component({
+ components: { TemplateQRAction, MosaicAmountDisplay, MaxFeeSelector, TransactionDetails },
+})
+export default class CosignatureQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: CosignatureQR;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ @Prop() readonly confirmAction?: (qrCode: QRCode) => void;
+
+ @Prop() readonly confirmText?: string;
+
+ /**
+ * Get QR Code detail items
+ *
+ * @returns QRCodeDetailItem[]
+ */
+ public get detailItems(): QRCodeDetailItem[] {
+ const items: QRCodeDetailItem[] = [];
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_type').toString(),
+ this.$t('qrcode_detail_item_type_cosignatureqr').toString(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_network_type').toString(), NetworkType[this.qrCode.networkType], true));
+
+ return items;
+ }
+
+ public onSubmit() {
+ this.onSuccess();
+ if (this.confirmAction) {
+ this.confirmAction(this.qrCode);
+ } else {
+ this.$router.push({
+ name: 'dashboard.index',
+ // @ts-ignore
+ params: { transaction: this.qrCode.transaction, action: 'transaction-details' },
+ });
+ }
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRAction.vue b/src/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRAction.vue
new file mode 100644
index 0000000..35d5130
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRAction.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
{{ slotProps.item.label }}:
+
+
+
+
+
+
+
{{ slotProps.item.value }}
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRActionTs.ts b/src/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRActionTs.ts
new file mode 100644
index 0000000..98305dc
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRActionTs.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { CosignatureSignedTransactionQR } from 'symbol-qr-library';
+import { NetworkType, CosignatureSignedTransaction, PublicAccount } from 'symbol-sdk';
+
+import { QRCodeDetailItem } from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs';
+// @ts-ignore
+import TemplateQRAction from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue';
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import MaxFeeSelector from '@/components/MaxFeeSelector/MaxFeeSelector.vue';
+import { TransactionAnnouncerService } from '@/services/TransactionAnnouncerService';
+
+@Component({
+ components: { TemplateQRAction, MosaicAmountDisplay, MaxFeeSelector },
+})
+export default class CosignatureSignedTransactionQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: CosignatureSignedTransactionQR;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ /**
+ * SignedTransaction read from QR
+ */
+ tran: CosignatureSignedTransaction;
+
+ /**
+ * Get QR Code detail items
+ *
+ * @returns QRCodeDetailItem[]
+ */
+ public get detailItems(): QRCodeDetailItem[] {
+ const items: QRCodeDetailItem[] = [];
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_type').toString(),
+ this.$t('qrcode_detail_item_type_signedqr').toString(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_network_type').toString(), NetworkType[this.qrCode.networkType], true));
+ this.tran = (this.qrCode.singedTransaction as unknown) as CosignatureSignedTransaction;
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('from').toString(),
+ PublicAccount.createFromPublicKey(this.tran.signerPublicKey, this.qrCode.networkType).address.plain(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('hash').toString(), this.tran.parentHash, true));
+ return items;
+ }
+
+ public async onSubmit() {
+ const transactionAnnouncerService = new TransactionAnnouncerService(this.$store);
+ transactionAnnouncerService.announceAggregateBondedCosignature(this.tran).subscribe((res) => {
+ if (res.success) {
+ this.$store.dispatch('notification/ADD_SUCCESS', 'success_transactions_announced');
+ } else if (res.error) {
+ this.$store.dispatch('notification/ADD_ERROR', res.error);
+ }
+ });
+ this.onSuccess();
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRAction.vue b/src/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRAction.vue
new file mode 100644
index 0000000..a18f7a8
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRAction.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRActionTs.ts b/src/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRActionTs.ts
new file mode 100644
index 0000000..6a8eac5
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRActionTs.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { MnemonicQR } from 'symbol-qr-library';
+import { NetworkType } from 'symbol-sdk';
+import { QRCodeDetailItem } from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs';
+// @ts-ignore
+import TemplateQRAction from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue';
+
+@Component({
+ components: { TemplateQRAction },
+})
+export default class MnemonicQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: MnemonicQR;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ /**
+ * Get QR Code detail items
+ *
+ * @returns QRCodeDetailItem[]
+ */
+ public get detailItems(): QRCodeDetailItem[] {
+ const items: QRCodeDetailItem[] = [];
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_type').toString(),
+ this.$t('qrcode_detail_item_type_mnemonicqr').toString(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_network_type').toString(), NetworkType[this.qrCode.networkType], true));
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_mnemonic_passphrase').toString(),
+ this.qrCode.mnemonicPlainText.split(' ').splice(3).join(' ') + ' ********', // masked for security purposes
+ true,
+ ),
+ );
+ return items;
+ }
+
+ public async onSubmit() {
+ this.$store.dispatch('temporary/SET_MNEMONIC', this.qrCode.mnemonicPlainText);
+ this.onSuccess();
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/QRCodeActions.less b/src/components/QRCode/QRCodeActions/QRCodeActions.less
new file mode 100644
index 0000000..88b49c4
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/QRCodeActions.less
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../../views/resources/css/variables.less';
+
+.preview-container {
+ display: grid;
+ grid-template-columns: 20% 80%;
+
+ .qrcode-details {
+ margin-top: 0.3rem;
+ }
+}
+.qrcode-details-row-inner {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-columns: 20% 80%;
+ grid-template-rows: 100%;
+
+ .qrcode-details-row-label {
+ text-align: right;
+ font-size: @normalFont;
+ font-weight: 500;
+ color: @grayDark;
+ text-transform: capitalize;
+ overflow: hidden;
+ word-break: break-word;
+ }
+
+ .qrcode-details-row-value {
+ font-size: @normalFont;
+ color: @secondary;
+ padding-left: 0.2rem;
+ overflow: hidden;
+ word-break: break-word;
+ display: grid;
+ align-items: center;
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/QRCodeActions.vue b/src/components/QRCode/QRCodeActions/QRCodeActions.vue
new file mode 100644
index 0000000..ce8c341
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/QRCodeActions.vue
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/QRCodeActionsTs.ts b/src/components/QRCode/QRCodeActions/QRCodeActionsTs.ts
new file mode 100644
index 0000000..158a1bd
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/QRCodeActionsTs.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { QRCode } from 'symbol-qr-library';
+
+// @ts-ignore
+import QRCodeDisplay from '@/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue';
+// @ts-ignore
+import ContactQRAction from '@/components/QRCode/QRCodeActions/ContactQRAction/ContactQRAction.vue';
+// @ts-ignore
+import MnemonicQRAction from '@/components/QRCode/QRCodeActions/MnemonicQRAction/MnemonicQRAction.vue';
+// @ts-ignore
+import TransactionQRAction from '@/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRAction.vue';
+// @ts-ignore
+import CosignatureQRAction from '@/components/QRCode/QRCodeActions/CosignatureQRAction/CosignatureQRAction.vue';
+// @ts-ignore
+import SignedTransactionQRAction from '@/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRAction.vue';
+// @ts-ignore
+import CosignatureSignedTransactionQRAction from '@/components/QRCode/QRCodeActions/CosignatureSignedTransactionQRAction/CosignatureSignedTransactionQRAction.vue';
+
+@Component({
+ components: {
+ QRCodeDisplay,
+ ContactQRAction,
+ MnemonicQRAction,
+ TransactionQRAction,
+ CosignatureQRAction,
+ SignedTransactionQRAction,
+ CosignatureSignedTransactionQRAction,
+ },
+})
+export default class QRCodeActionsTs extends Vue {
+ @Prop({ default: null }) readonly qrCode: QRCode;
+
+ @Prop({ default: true }) readonly showPreview: boolean;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ @Prop() readonly confirmAction?: (qrCode: QRCode) => void;
+
+ @Prop() readonly confirmText?: string;
+}
diff --git a/src/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRAction.vue b/src/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRAction.vue
new file mode 100644
index 0000000..4e194ec
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRAction.vue
@@ -0,0 +1,33 @@
+
+
+
+
+
+
{{ slotProps.item.label }}:
+
+
+
+
+
+
+
{{ slotProps.item.value }}
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRActionTs.ts b/src/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRActionTs.ts
new file mode 100644
index 0000000..c510533
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/SignedTransactionQRAction/SignedTransactionQRActionTs.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { SignedTransactionQR } from 'symbol-qr-library';
+import { NetworkType, Address, SignedTransaction } from 'symbol-sdk';
+
+import { QRCodeDetailItem } from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs';
+// @ts-ignore
+import TemplateQRAction from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue';
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import MaxFeeSelector from '@/components/MaxFeeSelector/MaxFeeSelector.vue';
+import { TransactionAnnouncerService } from '@/services/TransactionAnnouncerService';
+@Component({
+ components: { TemplateQRAction, MosaicAmountDisplay, MaxFeeSelector },
+})
+export default class SignedTransactionQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: SignedTransactionQR;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ /**
+ * SignedTransaction read from QR
+ */
+ tran: SignedTransaction;
+
+ /**
+ * Get QR Code detail items
+ *
+ * @returns QRCodeDetailItem[]
+ */
+ public get detailItems(): QRCodeDetailItem[] {
+ const items: QRCodeDetailItem[] = [];
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_type').toString(),
+ this.$t('qrcode_detail_item_type_signedqr').toString(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_network_type').toString(), NetworkType[this.qrCode.networkType], true));
+ this.tran = (this.qrCode.singedTransaction as unknown) as SignedTransaction;
+ items.push(new QRCodeDetailItem(this.$t('from').toString(), (this.tran.getSignerAddress() as Address).plain(), true));
+ items.push(new QRCodeDetailItem(this.$t('hash').toString(), this.tran.hash, true));
+ return items;
+ }
+
+ public async onSubmit() {
+ const transactionAnnouncerService = new TransactionAnnouncerService(this.$store);
+ transactionAnnouncerService.announce(this.tran).subscribe((res) => {
+ if (res.success) {
+ this.$store.dispatch('notification/ADD_SUCCESS', 'success_transactions_announced');
+ } else if (res.error) {
+ this.$store.dispatch('notification/ADD_ERROR', res.error);
+ }
+ });
+ this.onSuccess();
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.less b/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.less
new file mode 100644
index 0000000..6bbaf1b
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.less
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../../../views/resources/css/variables.less';
+
+.preview-container {
+ display: grid;
+ grid-template-columns: 20% 80%;
+
+ .qrcode-details {
+ margin-top: 0.3rem;
+ }
+}
+.qrcode-details-row-inner {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-columns: 20% 80%;
+ grid-template-rows: 100%;
+
+ .qrcode-details-row-label {
+ text-align: right;
+ font-size: @normalFont;
+ font-weight: 500;
+ color: @grayDark;
+ text-transform: capitalize;
+ overflow: hidden;
+ word-break: break-word;
+ }
+
+ .qrcode-details-row-value {
+ font-size: @normalFont;
+ color: @secondary;
+ padding-left: 0.2rem;
+ overflow: hidden;
+ word-break: break-word;
+ display: grid;
+ align-items: center;
+ }
+}
+
+.qrcode-action {
+ display: grid;
+ grid-template-columns: 80% 20%;
+ margin: 0.2rem 0 0.2rem 0;
+ .qrcode-action-desc {
+ //border-left: 3px solid @purpleLight;
+ display: flex;
+ align-items: center;
+ text-align: center;
+ justify-content: center;
+ span {
+ margin: 0 0.2rem 0 0;
+ font-size: 0.2rem;
+ }
+ }
+ .qrcode-action-button {
+ display: flex;
+ align-items: center;
+ text-align: center;
+ justify-content: center;
+
+ button {
+ padding: 0 0.2rem;
+ }
+ }
+}
diff --git a/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue b/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue
new file mode 100644
index 0000000..d316176
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
{{ item.label }}:
+
{{ item.value }}
+
+
+
+
+
+
+
+
+
+
+ {{ $t(actionDesc) }}
+
+
+
+ {{ $t(actionButtonText) }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs.ts b/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs.ts
new file mode 100644
index 0000000..70f6ade
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { QRCode } from 'symbol-qr-library';
+// @ts-ignore
+import QRCodeDisplay from '@/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue';
+
+@Component({
+ components: { QRCodeDisplay },
+})
+export default class TemplateQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: QRCode;
+
+ @Prop({ default: '' }) readonly actionDesc!: string;
+
+ @Prop({ default: true }) readonly showActionButton!: boolean;
+
+ @Prop({ default: 'continue' }) readonly actionButtonText!: string;
+
+ @Prop({ default: [] }) readonly detailItems!: QRCodeDetailItem[];
+
+ @Prop({ default: null }) readonly onSubmit!: () => void;
+}
+
+export class QRCodeDetailItem {
+ constructor(public label: string, public value: string, public header: boolean = false) {}
+}
diff --git a/src/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRAction.vue b/src/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRAction.vue
new file mode 100644
index 0000000..3d2c407
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRAction.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
{{ slotProps.item.label }}:
+
+
+
+
+
+
+
{{ slotProps.item.value }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRActionTs.ts b/src/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRActionTs.ts
new file mode 100644
index 0000000..a7e0001
--- /dev/null
+++ b/src/components/QRCode/QRCodeActions/TransactionQRAction/TransactionQRActionTs.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { TransactionQR } from 'symbol-qr-library';
+import { NetworkType, TransferTransaction, Address } from 'symbol-sdk';
+
+import { QRCodeDetailItem } from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRActionTs';
+// @ts-ignore
+import TemplateQRAction from '@/components/QRCode/QRCodeActions/TemplateQRAction/TemplateQRAction.vue';
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import MaxFeeSelector from '@/components/MaxFeeSelector/MaxFeeSelector.vue';
+@Component({
+ components: { TemplateQRAction, MosaicAmountDisplay, MaxFeeSelector },
+})
+export default class TransactionQRActionTs extends Vue {
+ @Prop({ default: null }) readonly qrCode!: TransactionQR;
+
+ @Prop({ default: null }) readonly onSuccess: () => void;
+
+ /**
+ * TransferTransaction read from QR
+ */
+ tran: TransferTransaction;
+
+ /**
+ * Get QR Code detail items
+ *
+ * @returns QRCodeDetailItem[]
+ */
+ public get detailItems(): QRCodeDetailItem[] {
+ const items: QRCodeDetailItem[] = [];
+ items.push(
+ new QRCodeDetailItem(
+ this.$t('qrcode_detail_item_type').toString(),
+ this.$t('qrcode_detail_item_type_transactionqr').toString(),
+ true,
+ ),
+ );
+ items.push(new QRCodeDetailItem(this.$t('qrcode_detail_item_network_type').toString(), NetworkType[this.qrCode.networkType], true));
+ this.tran = (this.qrCode.transaction as unknown) as TransferTransaction;
+ items.push(new QRCodeDetailItem(this.$t('to').toString(), (this.tran.recipientAddress as Address).plain(), true));
+ items.push(new QRCodeDetailItem(this.$t('mosaic_id').toString(), this.tran.mosaics[0].id.id.toHex(), true));
+ items.push(new QRCodeDetailItem(this.$t('amount').toString(), this.tran.mosaics[0].amount.toString(), true));
+ items.push(new QRCodeDetailItem(this.$t('message').toString(), this.tran.message.payload, true));
+ items.push(new QRCodeDetailItem(this.$t('fee').toString(), this.tran.maxFee.toString(), true));
+ return items;
+ }
+
+ public onSubmit() {
+ const tran = (this.qrCode.transaction as unknown) as TransferTransaction;
+ this.onSuccess();
+ this.$router.push({
+ name: 'dashboard.transfer',
+ // @ts-ignore
+ params: { transaction: tran, recipientAddress: (tran.recipientAddress as Address).plain() },
+ });
+ }
+}
diff --git a/src/components/QRCode/QRCodeDisplay/QRCodeDisplay.less b/src/components/QRCode/QRCodeDisplay/QRCodeDisplay.less
new file mode 100644
index 0000000..5511bb8
--- /dev/null
+++ b/src/components/QRCode/QRCodeDisplay/QRCodeDisplay.less
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+.qrcode-display {
+ font-size: 0.16rem;
+ padding: 0.05rem 0.1rem;
+ text-align: center;
+ width: 2.1rem;
+ img {
+ width: 1.9rem;
+ }
+}
+.qrcode-display-footer {
+ display: inline-block;
+}
diff --git a/src/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue b/src/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue
new file mode 100644
index 0000000..59b5972
--- /dev/null
+++ b/src/components/QRCode/QRCodeDisplay/QRCodeDisplay.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodeDisplay/QRCodeDisplayTs.ts b/src/components/QRCode/QRCodeDisplay/QRCodeDisplayTs.ts
new file mode 100644
index 0000000..5dc1d79
--- /dev/null
+++ b/src/components/QRCode/QRCodeDisplay/QRCodeDisplayTs.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { QRCode } from 'symbol-qr-library';
+import { of, Observable } from 'rxjs';
+import { PropType } from 'vue/types/options';
+import { pluck, concatMap } from 'rxjs/operators';
+import { UIHelpers } from '@/core/utils/UIHelpers';
+// resources
+// @ts-ignore
+import failureIcon from '@/views/resources/img/monitor/failure.png';
+
+@Component({
+ subscriptions() {
+ const qrCodeBase64$ = this.$watchAsObservable('qrCode', {
+ immediate: true,
+ }).pipe(
+ pluck('newValue'),
+ concatMap((args) => (args instanceof QRCode ? args.toBase64() : of(failureIcon))),
+ );
+ return { qrCodeBase64$ };
+ },
+})
+export default class QRCodeDisplayTs extends Vue {
+ @Prop({
+ default: null,
+ type: Object as PropType,
+ })
+ public qrCode: QRCode;
+
+ @Prop({
+ default: '',
+ })
+ public header: string;
+
+ @Prop({
+ default: 'symbol_wallet_qrcode.png',
+ })
+ public downloadName: string;
+
+ @Prop({
+ default: 'qr_code',
+ })
+ public alt: string;
+
+ @Prop({
+ default: false,
+ })
+ public showDownload: boolean;
+
+ /**
+ * base64 representation of qrcode
+ * @type Obervable
+ */
+ public qrCodeBase64$: Observable;
+
+ public copyAsText() {
+ UIHelpers.copyToClipboard(this.qrCode?.toJSON());
+ }
+}
diff --git a/src/components/QRCode/QRCodePassword/QRCodePassword.less b/src/components/QRCode/QRCodePassword/QRCodePassword.less
new file mode 100644
index 0000000..b6e0698
--- /dev/null
+++ b/src/components/QRCode/QRCodePassword/QRCodePassword.less
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+.qrcode-password-container {
+ .qrcode-password-info {
+ font-size: 0.18rem;
+ text-align: center;
+ margin: 0.5rem 0 0.2rem 0.2rem;
+ }
+}
diff --git a/src/components/QRCode/QRCodePassword/QRCodePassword.vue b/src/components/QRCode/QRCodePassword/QRCodePassword.vue
new file mode 100644
index 0000000..98493c6
--- /dev/null
+++ b/src/components/QRCode/QRCodePassword/QRCodePassword.vue
@@ -0,0 +1,51 @@
+
+
+
+
+ {{ $t('qrcode_password_info') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/QRCodePassword/QRCodePasswordTs.ts b/src/components/QRCode/QRCodePassword/QRCodePasswordTs.ts
new file mode 100644
index 0000000..b2defbf
--- /dev/null
+++ b/src/components/QRCode/QRCodePassword/QRCodePasswordTs.ts
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
+import { QRCodeGenerator, QRCode, QRCodeType } from 'symbol-qr-library';
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import FormWrapper from '@/components/FormWrapper/FormWrapper.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+import { CosignatureSignedTransaction, SignedTransaction, TransactionMapping } from 'symbol-sdk';
+
+@Component({
+ components: { FormWrapper, FormRow, ErrorTooltip, ValidationProvider },
+})
+export default class QRCodePasswordTs extends Vue {
+ @Prop({ default: null })
+ public qrcodeJson: string;
+
+ @Prop({ default: '' })
+ public header: string;
+
+ @Prop({ default: false })
+ public showDownload: string;
+
+ public qrCode: QRCode;
+
+ public askForPassword: boolean = false;
+
+ public formItems = {
+ password: '',
+ };
+
+ public $refs!: {
+ provider: InstanceType;
+ };
+
+ @Watch('qrcodeJson', { immediate: true })
+ public proceedIfNoPasswordNeeded() {
+ const jsonObject = JSON.parse(this.qrcodeJson);
+ if (jsonObject && (jsonObject.type == QRCodeType.ExportAccount || jsonObject.type == QRCodeType.ExportMnemonic)) {
+ this.askForPassword = true;
+ } else {
+ // no password needed, continue to generate qrcode
+ this.generateQRCode();
+ }
+ }
+
+ public generateQRCode() {
+ try {
+ const transformToSigned = (dto: any): SignedTransaction => {
+ return new SignedTransaction(dto.payload, dto.hash, dto.signerPublicKey, dto.type, dto.networkType);
+ };
+ const transformToCosignedSigned = (dto: any): CosignatureSignedTransaction => {
+ return new CosignatureSignedTransaction(dto.parentHash, dto.signature, dto.signerPublicKey);
+ };
+ this.qrCode = QRCodeGenerator.fromJSON(
+ this.qrcodeJson,
+ TransactionMapping.createFromPayload,
+ this.formItems.password,
+ transformToSigned,
+ transformToCosignedSigned,
+ );
+ this.$emit('qrCodeGenerated', this.qrCode);
+ this.askForPassword = false;
+ } catch (error) {
+ this.showError(error);
+ }
+ }
+
+ private showError(error: string) {
+ this.$refs.provider.applyResult({
+ errors: [error],
+ failedRules: {},
+ });
+ }
+}
diff --git a/src/components/QRCode/UploadQRCode/UploadQRCode.less b/src/components/QRCode/UploadQRCode/UploadQRCode.less
new file mode 100644
index 0000000..015e25d
--- /dev/null
+++ b/src/components/QRCode/UploadQRCode/UploadQRCode.less
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../../views/resources/css/variables.less';
+
+.upload-qrcode-container {
+ display: grid;
+ grid-template-columns: 70% 30%;
+ i {
+ color: @grayLight;
+ font-size: 1rem;
+ }
+
+ /deep/.ivu-upload .ivu-upload-drag {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 3rem;
+ }
+
+ /deep/.ivu-upload-drag:hover {
+ border: 0.01rem dashed @purpleLight;
+ }
+
+ .upload-qrcode-preview {
+ display: flex;
+ align-items: center;
+ text-align: center;
+ justify-content: center;
+ width: 3rem;
+ margin-bottom: 0.1rem;
+ color: @purple;
+ img {
+ width: 2rem;
+ }
+ }
+
+ .upload-qrcode-right-pane {
+ .upload-qrcode-explanation {
+ font-size: 0.2rem;
+ margin-top: 0.2rem;
+ }
+ .upload-qrcode-valid-qrcodes {
+ font-size: 0.17rem;
+ margin-top: 0.2rem;
+ ul {
+ list-style: circle inside none;
+ li.selected {
+ color: @purpleLight;
+ }
+ }
+ }
+ }
+}
diff --git a/src/components/QRCode/UploadQRCode/UploadQRCode.vue b/src/components/QRCode/UploadQRCode/UploadQRCode.vue
new file mode 100644
index 0000000..000cf99
--- /dev/null
+++ b/src/components/QRCode/UploadQRCode/UploadQRCode.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+
+
+
{{ imageFileName }}
+
+
+
+
+
{{ $t(uploadFileMessage) }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t('upload_qr_code_explanation') }}
+
+
+
+
+ {{ $t('upload_qr_code_explanation_type_contactqr') }}
+
+
+ {{ $t('upload_qr_code_explanation_type_transactionqr') }}
+
+
+ {{ $t('upload_qr_code_explanation_type_cosignatureqr') }}
+
+
+ {{ $t('upload_qr_code_explanation_type_mnemonicqr') }}
+
+
+ {{ $t('upload_qr_code_explanation_type_signedtransactionqr') }}
+
+
+ {{ $t('upload_qr_code_explanation_type_cosignaturesignedtransactionqr') }}
+
+
+ {{ $t('upload_qr_code_invalid_type_message', { type: qrType == 0 ? 'unknown' : qrType }) }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/QRCode/UploadQRCode/UploadQRCodeTs.ts b/src/components/QRCode/UploadQRCode/UploadQRCodeTs.ts
new file mode 100644
index 0000000..8748d63
--- /dev/null
+++ b/src/components/QRCode/UploadQRCode/UploadQRCodeTs.ts
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { QrcodeCapture, QrcodeDropZone, QrcodeStream } from 'vue-qrcode-reader';
+import { QRCodeType } from 'symbol-qr-library';
+
+@Component({
+ components: { QrcodeCapture, QrcodeDropZone, QrcodeStream },
+})
+export default class UploadQRCodeTs extends Vue {
+ @Prop({ default: true })
+ public uploadEnabled: boolean;
+
+ @Prop({ default: true })
+ public scanEnabled: boolean;
+
+ @Prop({ default: true })
+ readonly showExplanation: boolean;
+
+ @Prop({ default: [QRCodeType.AddContact, QRCodeType.RequestTransaction, QRCodeType.ExportObject] })
+ readonly validQrTypes!: QRCodeType[];
+
+ @Prop({ default: 'upload_file_message' })
+ readonly uploadFileMessage!: string;
+
+ /**
+ * Whether scan tab is active
+ */
+ scanActive: boolean = false;
+
+ /**
+ * Preview uploaded image data
+ */
+ image: string = null;
+
+ /**
+ * Uploaded file name
+ */
+ imageFileName = '';
+
+ /**
+ * QR Code type identified
+ */
+ qrType: number = 0;
+
+ /**
+ * Invalid qr type
+ */
+ invalidType: boolean = false;
+
+ public $refs!: {
+ qrcodeCapture: QrcodeCapture;
+ };
+
+ /**
+ * Uploaded qr image decode hook
+ *
+ * @param json
+ */
+ public onDecode(json) {
+ const jsonObj = JSON.parse(json);
+ this.qrType = jsonObj.type;
+ if (this.validQrTypes.includes(this.qrType)) {
+ this.$emit('uploadComplete', json);
+ } else {
+ this.invalidType = true;
+ }
+ }
+
+ /**
+ * Handles Tab Click(Upload/Scan)
+ * @param name of the tab clicked
+ */
+ public onTabClick(name) {
+ this.scanActive = name === 'scan';
+ }
+
+ /**
+ * Hook for handling file before upload completes
+ * It intercepts the upload process and pass the file to qrcodeCapture component
+ * @param file uploaded
+ */
+ public onBeforeUpload(file) {
+ this.reset();
+ const evt = {
+ target: {
+ files: [file],
+ },
+ };
+ this.$refs.qrcodeCapture.onChangeInput(evt); // to pass the evt to qrcode image decoder
+ this.imageFileName = file.name;
+ const fileReader = new FileReader();
+ fileReader.readAsDataURL(file);
+ fileReader.onload = (event) => {
+ // called once readAsDataURL is completed
+ this.image = event.target.result as string;
+ };
+
+ return false; //return false now since we have the file passed to qrcodeCapture component
+ }
+
+ private reset() {
+ this.invalidType = false;
+ }
+}
diff --git a/src/components/RecipientInput/RecipientInput.vue b/src/components/RecipientInput/RecipientInput.vue
new file mode 100644
index 0000000..3f41643
--- /dev/null
+++ b/src/components/RecipientInput/RecipientInput.vue
@@ -0,0 +1,35 @@
+
+
+ {{ $t('transfer_target') }}:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/RecipientInput/RecipientInputTs.ts b/src/components/RecipientInput/RecipientInputTs.ts
new file mode 100644
index 0000000..5074153
--- /dev/null
+++ b/src/components/RecipientInput/RecipientInputTs.ts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { NetworkType } from 'symbol-sdk';
+
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+// @ts-ignore
+import ContactSelector from '@/components/ContactSelector/ContactSelector.vue';
+import { AddressBook } from 'symbol-address-book/AddressBook';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ ContactSelector,
+ },
+ computed: {
+ ...mapGetters({
+ networkType: 'network/networkType',
+ addressBook: 'addressBook/getAddressBook',
+ }),
+ },
+})
+export class RecipientInputTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ value: string;
+
+ @Prop({ default: false })
+ readonly disabled!: boolean;
+
+ /**
+ * Current network type
+ * @var {NetworkType}
+ */
+ public networkType: NetworkType;
+ /**
+ * Current address book
+ * @var {AddressBook}
+ */
+ public addressBook: AddressBook;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /// region computed properties getter/setter
+ public get rawValue(): string {
+ return this.value;
+ }
+
+ public set rawValue(input: string) {
+ this.$emit('input', input);
+ }
+ /// end-region computed properties getter/setter
+
+ public onSelectContact(id: string) {
+ const contact = this.addressBook.getContactById(id);
+ if (contact) {
+ this.rawValue = contact.address;
+ }
+ }
+}
diff --git a/src/components/RemoveCosignatoryInput/RemoveCosignatoryInput.vue b/src/components/RemoveCosignatoryInput/RemoveCosignatoryInput.vue
new file mode 100644
index 0000000..44505a3
--- /dev/null
+++ b/src/components/RemoveCosignatoryInput/RemoveCosignatoryInput.vue
@@ -0,0 +1,23 @@
+
+
+ {{ $t('form_label_remove_cosignatory') }}:
+
+
+
+
+
+
+
diff --git a/src/components/RemoveCosignatoryInput/RemoveCosignatoryInputTs.ts b/src/components/RemoveCosignatoryInput/RemoveCosignatoryInputTs.ts
new file mode 100644
index 0000000..7ab631d
--- /dev/null
+++ b/src/components/RemoveCosignatoryInput/RemoveCosignatoryInputTs.ts
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { Address, NetworkType, PublicAccount } from 'symbol-sdk';
+// child components
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+// @ts-ignore
+import ButtonRemove from '@/components/ButtonRemove/ButtonRemove.vue';
+
+@Component({
+ components: {
+ FormRow,
+ ButtonRemove,
+ },
+ computed: {
+ ...mapGetters({
+ networkType: 'network/networkType',
+ }),
+ },
+})
+export class RemoveCosignatoryInputTs extends Vue {
+ /**
+ * Target account cosignatories
+ * @protected
+ * @type {PublicAccount[]}
+ */
+ @Prop({ default: [] })
+ protected cosignatories: PublicAccount[];
+
+ /**
+ * Current network type
+ * @private
+ * @type {NetworkType}
+ */
+ private networkType: NetworkType;
+
+ /**
+ * Selected cosignatory public key
+ * @protected
+ * @type {string}
+ */
+ public cosignatory: string = '';
+
+ /**
+ * Handles the form submission
+ * @protected
+ * @return {void}
+ */
+ protected onRemoveCosignatory(): void {
+ this.$emit('on-remove-cosignatory', this.cosignatory);
+ }
+
+ /**
+ * Returns a pretty address from a public key
+ * @protected
+ * @param {string} publicKey
+ * @returns {string}
+ */
+ protected getAddressFromPublicKey(publicKey: string): string {
+ return Address.createFromPublicKey(publicKey, this.networkType).pretty();
+ }
+}
diff --git a/src/components/RentalFees/RentalFee.vue b/src/components/RentalFees/RentalFee.vue
new file mode 100644
index 0000000..77be2d1
--- /dev/null
+++ b/src/components/RentalFees/RentalFee.vue
@@ -0,0 +1,18 @@
+
+
+
+ {{ $t('estimated_rental_fee') }}:
+
+
+
+
+
+
+
diff --git a/src/components/RentalFees/RentalFeeTs.ts b/src/components/RentalFees/RentalFeeTs.ts
new file mode 100644
index 0000000..2e6fad8
--- /dev/null
+++ b/src/components/RentalFees/RentalFeeTs.ts
@@ -0,0 +1,49 @@
+import { Component, Vue, Prop } from 'vue-property-decorator';
+//@ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+//@ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+//@ts-ignore
+import { mapGetters } from 'vuex';
+import { RentalFees } from 'symbol-sdk';
+export type RentalFeesType = 'mosaic' | 'root-namespace' | 'child-namespace';
+@Component({
+ components: {
+ MosaicAmountDisplay,
+ FormRow,
+ },
+ computed: mapGetters({
+ rentalEstimation: 'network/rentalFeeEstimation',
+ }),
+})
+export class RentalFeeTs extends Vue {
+ @Prop({ required: true }) rentalType: RentalFeesType;
+ @Prop() duration: number;
+ private rentalEstimation: RentalFees;
+ /**
+ * @description: return effectiveFee according to prop 'rentalType'
+ */
+ public async created() {
+ await this.$store.dispatch('network/REST_NETWORK_RENTAL_FEES');
+ }
+ get rentalFeeAmount(): number {
+ let feeAmountRaw: number = 0;
+ if (this.rentalEstimation) {
+ switch (this.rentalType) {
+ case 'mosaic':
+ feeAmountRaw = this.rentalEstimation?.effectiveMosaicRentalFee.compact();
+ break;
+ case 'root-namespace':
+ feeAmountRaw = this.rentalEstimation?.effectiveRootNamespaceRentalFeePerBlock.compact() * this.duration;
+ break;
+ case 'child-namespace':
+ feeAmountRaw = this.rentalEstimation?.effectiveChildNamespaceRentalFee.compact();
+ break;
+ default:
+ feeAmountRaw = 0;
+ }
+ return feeAmountRaw;
+ }
+ }
+}
diff --git a/src/components/RestrictionDirectionInput/RestrictionDirectionInput.less b/src/components/RestrictionDirectionInput/RestrictionDirectionInput.less
new file mode 100644
index 0000000..42fbd47
--- /dev/null
+++ b/src/components/RestrictionDirectionInput/RestrictionDirectionInput.less
@@ -0,0 +1,6 @@
+.warning-fee-low {
+ color: #b98e0d;
+ i {
+ font-size: 0.18rem;
+ }
+}
diff --git a/src/components/RestrictionDirectionInput/RestrictionDirectionInput.vue b/src/components/RestrictionDirectionInput/RestrictionDirectionInput.vue
new file mode 100644
index 0000000..4ef03e9
--- /dev/null
+++ b/src/components/RestrictionDirectionInput/RestrictionDirectionInput.vue
@@ -0,0 +1,50 @@
+
+
+ {{ $t('direction') }}:
+
+
+
+
+ {{ $t('incoming') }}
+
+
+ {{ $t('outgoing') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/RestrictionTypeInput/RestrictionTypeInput.less b/src/components/RestrictionTypeInput/RestrictionTypeInput.less
new file mode 100644
index 0000000..b31ecf6
--- /dev/null
+++ b/src/components/RestrictionTypeInput/RestrictionTypeInput.less
@@ -0,0 +1,7 @@
+/deep/.form-label-container .form-label {
+ padding-left: 0.47rem;
+}
+
+/deep/.ivu-tooltip {
+ text-transform: none;
+}
diff --git a/src/components/RestrictionTypeInput/RestrictionTypeInput.vue b/src/components/RestrictionTypeInput/RestrictionTypeInput.vue
new file mode 100644
index 0000000..c3eecf7
--- /dev/null
+++ b/src/components/RestrictionTypeInput/RestrictionTypeInput.vue
@@ -0,0 +1,55 @@
+
+
+
+
+
+ {{ $t('type') }}:
+
+
+
+
+
+ {{ $t('block') }}
+
+
+ {{ $t('allow') }}
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/Settings/Settings.less b/src/components/Settings/Settings.less
new file mode 100644
index 0000000..99ad5f0
--- /dev/null
+++ b/src/components/Settings/Settings.less
@@ -0,0 +1,13 @@
+@import '../../views/resources/css/variables.less';
+.settings-link {
+ font-size: @normalFont;
+ color: @purpleDark;
+ display: flex;
+ align-items: center;
+
+ .setting-menu-icon {
+ width: 0.2rem;
+ cursor: pointer;
+ margin-right: 10px;
+ }
+}
diff --git a/src/components/Settings/Settings.vue b/src/components/Settings/Settings.vue
new file mode 100644
index 0000000..30a4212
--- /dev/null
+++ b/src/components/Settings/Settings.vue
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/src/components/Settings/SettingsTs.ts b/src/components/Settings/SettingsTs.ts
new file mode 100644
index 0000000..6ba70bf
--- /dev/null
+++ b/src/components/Settings/SettingsTs.ts
@@ -0,0 +1,25 @@
+import { Vue, Component } from 'vue-property-decorator';
+// @ts-ignore
+import ModalSettings from '@/views/modals/ModalSettings/ModalSettings.vue';
+import { officialIcons } from '@/views/resources/Images';
+import { mapGetters } from 'vuex';
+
+@Component({
+ components: { ModalSettings },
+ computed: {
+ ...mapGetters({
+ isSettingsVisible: 'profile/isSettingsVisible',
+ }),
+ },
+})
+export class SettingsTs extends Vue {
+ public isSettingsVisible: boolean;
+
+ public toggleSettings() {
+ this.$store.commit('profile/toggleSettings');
+ }
+
+ public get settingsIcon() {
+ return officialIcons.settings;
+ }
+}
diff --git a/src/components/SignerFilter/SignerFilter.vue b/src/components/SignerFilter/SignerFilter.vue
new file mode 100644
index 0000000..0851dd8
--- /dev/null
+++ b/src/components/SignerFilter/SignerFilter.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+ {{ item.multisig ? $t('label_postfix_multisig') : '' }}
+ {{ item.label }}
+
+
+
+
+
+
+
diff --git a/src/components/SignerFilter/SignerFilterTs.ts b/src/components/SignerFilter/SignerFilterTs.ts
new file mode 100644
index 0000000..bc04899
--- /dev/null
+++ b/src/components/SignerFilter/SignerFilterTs.ts
@@ -0,0 +1,46 @@
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import { Signer } from '@/store/Account';
+import { mapGetters } from 'vuex';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentSigner: 'account/currentSigner',
+ }),
+ },
+})
+export class SignerFilterTs extends Vue {
+ @Prop({ default: [] })
+ public signers: Signer[];
+
+ /**
+ * Selected signer from the store
+ * @protected
+ * @type {string}
+ */
+ public currentSigner: Signer;
+
+ public selectedSigner: string = '';
+
+ created() {
+ if (this.signers?.length > 0) {
+ const signer: Signer[] = this.signers.filter((s) => s.address.plain() === this.currentSigner.address.plain());
+ if (signer.length) {
+ this.selectedSigner = signer[0].address.plain();
+ } else {
+ this.selectedSigner = this.signers[0].address.plain();
+ }
+ }
+ }
+ /**
+ * onAddressChange
+ */
+ public onSignerChange() {
+ this.$emit('signer-change', this.selectedSigner);
+ }
+
+ @Watch('currentSigner', { immediate: true })
+ onCurrentSignerChange() {
+ this.selectedSigner = this.currentSigner.address.plain();
+ }
+}
diff --git a/src/components/SignerSelector/SignerSelector.vue b/src/components/SignerSelector/SignerSelector.vue
new file mode 100644
index 0000000..81da7eb
--- /dev/null
+++ b/src/components/SignerSelector/SignerSelector.vue
@@ -0,0 +1,28 @@
+
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+ {{ item.label }}
+ {{ item.multisig ? $t('label_postfix_multisig') : '' }}
+
+
+
+
+
+ {{ signers[0] ? signers[0].label : '' }}
+ {{ signers[0] && signers[0].multisig ? $t('label_postfix_multisig') : '' }}
+
+
+
+
+
+
+
diff --git a/src/components/SignerSelector/SignerSelectorTs.ts b/src/components/SignerSelector/SignerSelectorTs.ts
new file mode 100644
index 0000000..120e058
--- /dev/null
+++ b/src/components/SignerSelector/SignerSelectorTs.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// child components
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+import { Signer } from '@/store/Account';
+
+@Component({
+ components: { FormRow },
+})
+export class SignerSelectorTs extends Vue {
+ /**
+ * Value set by the parent component's v-model
+ * @type {string}
+ */
+ @Prop({
+ default: '',
+ })
+ value: string;
+
+ @Prop({
+ default: () => [],
+ })
+ signers: Signer[];
+
+ @Prop({
+ default: 'sender',
+ })
+ label: string;
+
+ @Prop({
+ default: false,
+ })
+ noLabel: boolean;
+
+ @Prop({
+ default: false,
+ })
+ disabled: boolean;
+
+ /// region computed properties getter/setter
+ /**
+ * Value set by the parent component
+ * @type {string}
+ */
+ get chosenSigner(): string {
+ return this.value;
+ }
+
+ /**
+ * Emit value change
+ */
+ set chosenSigner(newValue: string) {
+ this.$emit('input', newValue);
+ }
+
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/SpinnerDots/SpinnerDots.less b/src/components/SpinnerDots/SpinnerDots.less
new file mode 100644
index 0000000..a6c5212
--- /dev/null
+++ b/src/components/SpinnerDots/SpinnerDots.less
@@ -0,0 +1,53 @@
+.spinner {
+ width: 100%;
+ text-align: center;
+}
+
+.spinner > div {
+ width: 10px;
+ height: 10px;
+ margin: 10px;
+ background-color: #ccc;
+ border-radius: 100%;
+ display: inline-block;
+ -webkit-animation: bounceDelay 1.4s infinite ease-in-out;
+ animation: bounceDelay 1.4s infinite ease-in-out;
+ /* Prevent first frame from flickering when animation starts */
+
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+}
+
+.spinner .bounce1 {
+ -webkit-animation-delay: -0.32s;
+ animation-delay: -0.32s;
+}
+
+.spinner .bounce2 {
+ -webkit-animation-delay: -0.16s;
+ animation-delay: -0.16s;
+}
+
+@-webkit-keyframes bounceDelay {
+ 0%,
+ 80%,
+ 100% {
+ -webkit-transform: scale(0);
+ }
+ 40% {
+ -webkit-transform: scale(1);
+ }
+}
+
+@keyframes bounceDelay {
+ 0%,
+ 80%,
+ 100% {
+ transform: scale(0);
+ -webkit-transform: scale(0);
+ }
+ 40% {
+ transform: scale(1);
+ -webkit-transform: scale(1);
+ }
+}
diff --git a/src/components/SpinnerDots/SpinnerDots.vue b/src/components/SpinnerDots/SpinnerDots.vue
new file mode 100644
index 0000000..cabf8c2
--- /dev/null
+++ b/src/components/SpinnerDots/SpinnerDots.vue
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/src/components/SpinnerLoading/SpinnerLoading.vue b/src/components/SpinnerLoading/SpinnerLoading.vue
new file mode 100644
index 0000000..a798663
--- /dev/null
+++ b/src/components/SpinnerLoading/SpinnerLoading.vue
@@ -0,0 +1,114 @@
+
+
+
+
+
+
diff --git a/src/components/SplitButton/SplitButton.less b/src/components/SplitButton/SplitButton.less
new file mode 100644
index 0000000..ab2cb82
--- /dev/null
+++ b/src/components/SplitButton/SplitButton.less
@@ -0,0 +1,18 @@
+.split-button-container {
+ display: flex;
+
+ .split-main-button {
+ border-radius: 0.04rem 0 0 0.04rem;
+ }
+ /deep/.ivu-dropdown-rel {
+ height: 100%;
+ button {
+ height: 100%;
+ }
+ }
+}
+.split-dropdown-button {
+ border: unset;
+ border-left: 1px solid #976dd4;
+ border-radius: 0 0.04rem 0.04rem 0;
+}
diff --git a/src/components/SplitButton/SplitButton.vue b/src/components/SplitButton/SplitButton.vue
new file mode 100644
index 0000000..feed1b8
--- /dev/null
+++ b/src/components/SplitButton/SplitButton.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
diff --git a/src/components/SplitButton/SplitButtonTs.ts b/src/components/SplitButton/SplitButtonTs.ts
new file mode 100644
index 0000000..40a5c5b
--- /dev/null
+++ b/src/components/SplitButton/SplitButtonTs.ts
@@ -0,0 +1,9 @@
+import { Vue, Component, Prop } from 'vue-property-decorator';
+
+@Component
+export default class SplitButtonTs extends Vue {
+ @Prop({ default: '' }) readonly label!: string;
+ @Prop({ default: 'button-style validation-button' }) readonly className!: string;
+ @Prop({ default: 'validation-button' }) readonly dropdownClassName!: string;
+ @Prop({ default: [] }) readonly dropdownActions!: Array<{ icon: string; label: string; action: () => void }>;
+}
diff --git a/src/components/SupplyInput/SupplyInput.vue b/src/components/SupplyInput/SupplyInput.vue
new file mode 100644
index 0000000..d282b3a
--- /dev/null
+++ b/src/components/SupplyInput/SupplyInput.vue
@@ -0,0 +1,17 @@
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/SupplyInput/SupplyInputTs.ts b/src/components/SupplyInput/SupplyInputTs.ts
new file mode 100644
index 0000000..3d66f46
--- /dev/null
+++ b/src/components/SupplyInput/SupplyInputTs.ts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue, Prop } from 'vue-property-decorator';
+
+// internal dependencies
+import { ValidationRuleset } from '@/core/validation/ValidationRuleset';
+
+// child components
+import { ValidationProvider } from 'vee-validate';
+// @ts-ignore
+import ErrorTooltip from '@/components/ErrorTooltip/ErrorTooltip.vue';
+// @ts-ignore
+import FormRow from '@/components/FormRow/FormRow.vue';
+
+@Component({
+ components: {
+ ValidationProvider,
+ ErrorTooltip,
+ FormRow,
+ },
+})
+export class SupplyInputTs extends Vue {
+ /**
+ * Value bound to parent v-model
+ * @type {string}
+ */
+ @Prop({ default: '' }) value: number;
+
+ /**
+ * Form label
+ * @type {string}
+ */
+ @Prop({ default: 'supply' }) label: string;
+
+ /**
+ * Validation rules
+ * @var {ValidationRuleset}
+ */
+ public validationRules = ValidationRuleset;
+
+ /// region computed properties getter/setter
+ public get chosenValue(): number {
+ return this.value;
+ }
+
+ public set chosenValue(amount: number) {
+ this.$emit('input', amount);
+ }
+ /// end-region computed properties getter/setter
+}
diff --git a/src/components/TableDisplay/TableAssetType.ts b/src/components/TableDisplay/TableAssetType.ts
new file mode 100644
index 0000000..205e7a8
--- /dev/null
+++ b/src/components/TableDisplay/TableAssetType.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export enum TableAssetType {
+ Mosaic = 'mosaic',
+ Namespace = 'namespace',
+ Metadata = 'metadata',
+ AccountRestrictions = 'accountRestrictions',
+}
diff --git a/src/components/TableDisplay/TableDisplay.less b/src/components/TableDisplay/TableDisplay.less
new file mode 100644
index 0000000..533c990
--- /dev/null
+++ b/src/components/TableDisplay/TableDisplay.less
@@ -0,0 +1,367 @@
+@import '../../views/resources/css/variables.less';
+.mosaic-columns {
+ grid-template-columns: 14% 10% repeat(2, 14%) 12% repeat(4, 8%) 4%;
+ grid-template-rows: 100%;
+}
+
+.namespace-columns {
+ grid-template-columns: 15% 15% 10% 15% 10% 25% 10%;
+ .name-header,
+ .name-cell {
+ text-align: left;
+ }
+ .expiration-header,
+ .expiration-cell {
+ text-align: left;
+ }
+ .expired-header,
+ .expired-cell {
+ text-align: center;
+ }
+ .aliasIdentifier-header,
+ .aliasIdentifier-cell {
+ text-align: center;
+ }
+ .aliasType-header,
+ .aliasType-cell {
+ text-align: center;
+ }
+}
+
+.metadata-columns {
+ grid-template-columns: 20% 15% 15% 25% 10% 15%;
+ .targetAddress-header,
+ .targetAddress-cell {
+ text-align: left;
+ }
+ .targetID-header,
+ .targetID-cell {
+ text-align: left;
+ }
+ .targetType-header,
+ .targetType-cell {
+ text-align: left;
+ }
+ .scopedMetadataKey-header,
+ .scopedMetadataKey-cell {
+ text-align: left;
+ }
+ .status-header,
+ .status-cell {
+ text-align: left;
+ }
+ .changeTimes-header,
+ .changeTimes-cell {
+ text-align: left;
+ }
+}
+
+.hexId-header {
+ text-align: left;
+}
+
+.supply-header,
+.balance-header,
+.expiration-header {
+ text-align: left;
+}
+
+.name-header {
+ text-align: left;
+}
+
+.divisibility-header {
+ text-align: center;
+}
+
+.transferable-header {
+ text-align: center;
+ white-space: nowrap;
+}
+
+.supplyMutable-header {
+ text-align: center;
+ white-space: nowrap;
+}
+
+.restrictable-header {
+ text-align: center;
+ white-space: nowrap;
+}
+
+.hexId-cell {
+ text-align: left;
+}
+
+.name-cell {
+ text-align: left;
+}
+
+.supply-cell,
+.balance-cell,
+.expiration-cell {
+ text-align: left;
+}
+
+.divisibility-cell {
+ text-align: center;
+}
+
+.transferable-cell {
+ text-align: center;
+}
+
+.supplyMutable-cell {
+ text-align: center;
+}
+
+.restrictable-cell {
+ text-align: center;
+}
+
+.table-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-rows: 0.8rem 0.35rem auto 0.6rem;
+ grid-template-columns: 100%;
+ font-size: 0.16rem;
+ overflow-y: auto;
+
+ .upper-section-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-rows: 100%;
+ grid-template-columns: 100%;
+
+ .table-title-container {
+ padding-left: 0.2rem;
+ padding-top: 0.1rem;
+ position: relative;
+ .section-title {
+ font-size: 1.125em;
+ font-weight: 500;
+ color: @blackLight;
+ }
+ .user-operation {
+ display: flex;
+ justify-content: flex-end;
+ position: absolute;
+ right: 0.5rem;
+ bottom: 0.3rem;
+ color: @primary;
+ align-items: center;
+
+ .add-metadata-button {
+ margin-right: 0.3rem;
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ user-select: none;
+ cursor: pointer;
+ .add-icon {
+ padding: 3px 5px 0px 4px;
+ }
+ }
+
+ .table-filter-item-container {
+ font-size: 0.16rem;
+ margin-right: 0.2rem;
+
+ span {
+ margin-left: 0.1rem;
+ }
+ }
+
+ /deep/.ivu-select {
+ .ivu-select-selection {
+ font-size: @normalFont;
+ background-color: @grayLightest !important;
+ border: none !important;
+ box-shadow: none !important;
+ color: @primary;
+ :hover {
+ border: none;
+ box-shadow: none;
+ }
+ .ivu-select-prefix {
+ color: @purpleDark;
+ }
+ .ivu-select-selected-value {
+ padding-right: 0.35rem !important;
+ }
+ }
+
+ .ivu-select-visible {
+ .ivu-select-selection {
+ color: @white !important;
+ background-color: @purpleDark;
+ border: 0.01rem solid @purpleDark;
+ }
+
+ .ivu-icon-ios-arrow-down::before {
+ color: @white !important;
+ }
+
+ .ivu-select-prefix {
+ color: @white;
+ }
+ }
+ .ivu-select-group-title {
+ font-size: @smallerFont !important;
+ }
+
+ .ivu-select-item {
+ font-size: @smallFont !important;
+ }
+ }
+ /deep/ .ivu-select-dropdown {
+ background-color: @grayLightest;
+
+ .ivu-select-item-selected {
+ color: @primary;
+ background-color: @grayLightest;
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+ }
+ /deep/ .ivu-select-item:hover {
+ background-color: @white !important;
+ }
+ }
+
+ /deep/ .ivu-select-dropdown {
+ background-color: @grayLightest !important;
+
+ .ivu-select-item-selected {
+ color: @primary !important;
+ background-color: @grayLightest !important;
+ }
+
+ .ivu-select-item-selected:hover {
+ background-color: @grayLightest !important;
+ }
+ }
+
+ /deep/ .ivu-select-item:hover {
+ background-color: @white !important;
+ }
+
+ .table-actions-container {
+ text-align: right;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-auto-rows: 50%;
+ cursor: pointer;
+ }
+ }
+
+ .table-header-container {
+ display: grid;
+ width: 100%;
+ text-align: right;
+ color: @purpleDark;
+ background-color: @white;
+ font-size: @normalFont;
+ font-family: @symbolFontMedium;
+
+ .table-header-item {
+ padding: 0 0.1rem;
+ line-height: 0.35rem;
+ font-weight: 300;
+ cursor: pointer;
+
+ .header-label {
+ }
+
+ .sort-icon {
+ }
+ }
+ }
+
+ .table-body-container {
+ text-align: right;
+ overflow-y: auto;
+ overflow-x: hidden;
+ position: relative;
+ font-family: @symbolFontLight;
+ font-size: @normalFont;
+ color: @purpleDark;
+ .table-rows-outer-container {
+ width: 100%;
+ max-height: 100%;
+ overflow-y: auto;
+ .table-rows-container {
+ width: 100%;
+ height: 100%;
+ display: grid;
+ grid-auto-rows: 0.6rem;
+ grid-template-columns: 100%;
+ }
+ }
+
+ .no-data-inner-container {
+ display: grid;
+ grid-auto-rows: 0.6rem;
+ grid-template-columns: 100%;
+
+ > div {
+ border-bottom: 1px solid @line;
+ }
+ }
+ }
+
+ .table-footer-container {
+ text-align: right;
+ padding-top: 0.1rem;
+ padding-right: 0.7rem;
+
+ .page {
+ display: inline-block;
+ vertical-align: middle;
+ }
+
+ /deep/.ivu-page-item {
+ width: 30px;
+ min-width: 30px;
+ height: 30px;
+ border: none;
+ box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.16);
+ color: @grayDark;
+ -webkit-box-shadow: none !important;
+ }
+
+ /deep/.ivu-page-item-active a,
+ /deep/.ivu-page-item-active:hover a {
+ color: @primary !important;
+ }
+
+ /deep/.ivu-page-prev,
+ /deep/.ivu-page-next {
+ border: none !important;
+ }
+ }
+}
+.animation-rotate {
+ animation: auto-rotate infinite linear 1s;
+}
+@keyframes auto-rotate {
+ from {
+ transform: rotateZ(0);
+ }
+ to {
+ transform: rotateZ(360deg);
+ }
+}
+
+.padding-bottom {
+ padding-bottom: 0.7rem;
+}
diff --git a/src/components/TableDisplay/TableDisplay.vue b/src/components/TableDisplay/TableDisplay.vue
new file mode 100644
index 0000000..4bcf75b
--- /dev/null
+++ b/src/components/TableDisplay/TableDisplay.vue
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+ {{ $t('show_expired_mosaics') }}
+ {{ $t('show_expired_namespaces') }}
+
+
+
+
+
+
+
+
+
+
+ {{ $t(label) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TableDisplay/TableDisplayTs.ts b/src/components/TableDisplay/TableDisplayTs.ts
new file mode 100644
index 0000000..136d473
--- /dev/null
+++ b/src/components/TableDisplay/TableDisplayTs.ts
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { Address, AliasAction, MosaicId, NamespaceId } from 'symbol-sdk';
+// internal dependencies
+import {
+ AssetTableService,
+ FilteringTypes,
+ SortingDirections,
+ TableField,
+ TableFilteringOptions,
+ TableSortingOptions,
+} from '@/services/AssetTableService/AssetTableService';
+import { MosaicTableService } from '@/services/AssetTableService/MosaicTableService';
+import { NamespaceTableService } from '@/services/AssetTableService/NamespaceTableService';
+import { MetadataTableService } from '@/services/AssetTableService/MetadataTableService';
+// table asset types
+import { TableAssetType } from './TableAssetType';
+// child components
+// @ts-ignore
+import TableRow from '@/components/TableRow/TableRow.vue';
+// @ts-ignore
+import ButtonAdd from '@/components/ButtonAdd/ButtonAdd';
+// @ts-ignore
+import ButtonRefresh from '@/components/ButtonRefresh/ButtonRefresh';
+// @ts-ignore
+import ModalFormWrap from '@/views/modals/ModalFormWrap/ModalFormWrap.vue';
+// @ts-ignore
+import FormAliasTransaction from '@/views/forms/FormAliasTransaction/FormAliasTransaction.vue';
+// @ts-ignore
+import FormExtendNamespaceDurationTransaction from '@/views/forms/FormExtendNamespaceDurationTransaction/FormExtendNamespaceDurationTransaction.vue';
+// @ts-ignore
+import FormMosaicSupplyChangeTransaction from '@/views/forms/FormMosaicSupplyChangeTransaction/FormMosaicSupplyChangeTransaction.vue';
+// @ts-ignore
+import ModalMetadataDisplay from '@/views/modals/ModalMetadataDisplay/ModalMetadataDisplay.vue';
+import { NamespaceModel } from '@/core/database/entities/NamespaceModel';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { Signer } from '@/store/Account';
+// @ts-ignore
+import SignerFilter from '@/components/SignerFilter/SignerFilter.vue';
+import { MetadataModel } from '@/core/database/entities/MetadataModel';
+// @ts-ignore
+import ModalMetadataUpdate from '@/views/modals/ModalMetadataUpdate/ModalMetadataUpdate.vue';
+import { PageInfo } from '@/store/Transaction';
+@Component({
+ components: {
+ TableRow,
+ ModalFormWrap,
+ FormAliasTransaction,
+ FormExtendNamespaceDurationTransaction,
+ FormMosaicSupplyChangeTransaction,
+ ModalMetadataDisplay,
+ SignerFilter,
+ ButtonAdd,
+ ModalMetadataUpdate,
+ ButtonRefresh,
+ },
+ computed: {
+ ...mapGetters({
+ currentHeight: 'network/currentHeight',
+ currentAccount: 'account/currentAccount',
+ holdMosaics: 'mosaic/holdMosaics',
+ ownedNamespaces: 'namespace/ownedNamespaces',
+ currentConfirmedPage: 'namespace/currentConfirmedPage',
+ attachedMetadataList: 'metadata/accountMetadataList',
+ networkConfiguration: 'network/networkConfiguration',
+ signers: 'account/signers',
+ isFetchingNamespaces: 'namespace/isFetchingNamespaces',
+ isFetchingMosaics: 'mosaic/isFetchingMosaics',
+ isFetchingMetadata: 'metadata/isFetchingMetadata',
+ }),
+ },
+})
+export class TableDisplayTs extends Vue {
+ /**
+ * Type of assets shown in the table
+ * @type {string}
+ */
+ @Prop({
+ default: TableAssetType.Mosaic,
+ })
+ assetType: TableAssetType;
+
+ @Prop({ default: 'pagination' })
+ public paginationType!: 'pagination' | 'scroll';
+
+ /**
+ * Current account owned mosaics
+ * @protected
+ * @type {MosaicModel[]}
+ */
+ private holdMosaics: MosaicModel[];
+
+ /**
+ * Current account owned namespaces
+ * @protected
+ * @type {NamespaceModel[]}
+ */
+ private ownedNamespaces: NamespaceModel[];
+
+ /**
+ * Current account attached metadata list
+ * @protected
+ * @type {MetadataModel[]}
+ */
+ private attachedMetadataList: MetadataModel[];
+
+ /**
+ * target mosaic or namespace metadata view
+ * @type {MetadataModel[]}
+ */
+ protected targetedMetadataList: MetadataModel[];
+
+ private currentAccount: AccountModel;
+
+ private currentHeight: number;
+
+ private networkConfiguration: NetworkConfigurationModel;
+
+ /**
+ * current signers
+ */
+ public signers: Signer[];
+
+ public isFetchingNamespaces: boolean;
+
+ public isFetchingMosaics: boolean;
+
+ public isFetchingMetadata: boolean;
+
+ /**
+ * Current confirmed page info
+ * @var {PageInfo}
+ */
+ public currentConfirmedPage: PageInfo;
+
+ /**
+ * Loading state of the data to be shown in the table
+ * @type {boolean}
+ */
+ public get isLoading() {
+ switch (this.assetType) {
+ case TableAssetType.Namespace:
+ return this.isFetchingNamespaces;
+ case TableAssetType.Metadata:
+ return this.isFetchingMetadata;
+ default:
+ return this.isFetchingMosaics;
+ }
+ }
+
+ /**
+ * Hook called when the signer selector has changed
+ * @protected
+ */
+ protected onSignerSelectorChange(address: string): void {
+ // clear previous account transactions
+ if (address) {
+ this.$store.dispatch('account/SET_CURRENT_SIGNER', {
+ address: Address.createFromRawAddress(address),
+ reset: true,
+ unsubscribeWS: false,
+ });
+ }
+ }
+
+ /**
+ * Current table sorting state
+ * @var {TableSortingOptions}
+ */
+ public sortedBy: TableSortingOptions = {
+ fieldName: undefined,
+ direction: undefined,
+ };
+
+ /**
+ * Current table filtering state
+ * @var {TableFilteringOptions}
+ */
+ public filteredBy: TableFilteringOptions = {
+ fieldName: undefined,
+ filteringType: undefined,
+ };
+
+ /**
+ * Pagination page size
+ * @type {number}
+ */
+ public pageSize: number = 10;
+
+ /**
+ * Pagination page number
+ * @type {number}
+ */
+ public currentPage: number = 1;
+
+ public nodata = [...new Array(this.pageSize).keys()];
+
+ protected get ownedAssetHexIds(): string[] {
+ return this.assetType === 'namespace'
+ ? this.ownedNamespaces.map(({ namespaceIdHex }) => namespaceIdHex)
+ : this.holdMosaics
+ .filter(({ ownerRawPlain }) => ownerRawPlain === this.currentAccount.address)
+ .map(({ mosaicIdHex }) => mosaicIdHex);
+ }
+
+ /**
+ * Modal forms visibility states
+ * @protected
+ * @type {{
+ * aliasTransaction: boolean
+ * extendNamespaceDuration: boolean
+ * mosaicSupplyChangeTransaction: boolean
+ * }}
+ */
+ protected modalFormsVisibility: {
+ aliasTransaction: boolean;
+ extendNamespaceDurationTransaction: boolean;
+ mosaicSupplyChangeTransaction: boolean;
+ } = {
+ aliasTransaction: false,
+ extendNamespaceDurationTransaction: false,
+ mosaicSupplyChangeTransaction: false,
+ };
+
+ /**
+ * Action forms props
+ * @protected
+ * @type {({
+ * namespaceId: NamespaceId
+ * aliasTarget: MosaicId | Address
+ * aliasAction: AliasAction
+ * mosaicId: MosaicId
+ * })}
+ */
+ protected modalFormsProps: {
+ namespaceId: NamespaceId;
+ aliasTarget: MosaicId | Address;
+ aliasAction: AliasAction;
+ mosaicId: MosaicId;
+ } = {
+ namespaceId: null,
+ aliasTarget: null,
+ aliasAction: null,
+ mosaicId: null,
+ };
+
+ // Alias forms props
+
+ /**
+ * Instantiate the table service around {assetType}
+ * @return {AssetTableService}
+ */
+ protected getService(): AssetTableService {
+ switch (this.assetType) {
+ case TableAssetType.Mosaic:
+ return new MosaicTableService(this.currentHeight, this.holdMosaics, this.networkConfiguration);
+
+ case TableAssetType.Namespace:
+ return new NamespaceTableService(this.currentHeight, this.ownedNamespaces, this.networkConfiguration);
+
+ case TableAssetType.Metadata:
+ return new MetadataTableService(this.currentHeight, this.attachedMetadataList, this.networkConfiguration);
+
+ default:
+ throw new Error(`Asset type '${this.assetType}' does not exist in TableDisplay.`);
+ }
+ }
+
+ /// region getters and setters
+ /**
+ * Non-filtered table data
+ * @var {TableRowValues[]}
+ */
+ private get tableRows(): any[] {
+ return this.getService().getTableRows();
+ }
+
+ /**
+ * Values displayed in the table
+ * @readonly
+ * @return {TableRowValues[]}
+ */
+ get displayedValues(): any[] {
+ return this.getService().sort(this.getService().filter(this.tableRows, this.filteredBy), this.sortedBy);
+ }
+
+ /**
+ * Header fields displayed in the table
+ * @readonly
+ * @return {TableField[]}
+ */
+ get tableFields(): TableField[] {
+ return this.getService().getTableFields();
+ }
+
+ /**
+ * Get current page rows
+ * @readonly
+ * @return {TableRowValues[]}
+ */
+ get currentPageRows(): any[] {
+ return this.paginationType === 'pagination'
+ ? this.displayedValues.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
+ : this.displayedValues;
+ }
+
+ /**
+ * getter and setter for the showExpired button
+ *
+ */
+ get showExpired(): boolean {
+ return this.filteredBy.fieldName === 'expiration' && this.filteredBy.filteringType === 'show';
+ }
+
+ set showExpired(newVal: boolean) {
+ this.setFilteredBy('expiration');
+ }
+
+ /**
+ * Alias form modal title
+ * @type {string}
+ * @protected
+ */
+ protected get aliasModalTitle(): string {
+ return this.modalFormsProps.aliasAction === AliasAction.Link ? 'modal_title_link_alias' : 'modal_title_unlink_alias';
+ }
+
+ /// end-region getters and setters
+
+ /**
+ * Hook called when the component is created
+ * @return {void}
+ */
+ public async created(): Promise {
+ // refresh owned assets
+ this.refresh();
+ // initialize sorting and filtering
+ this.setDefaultFiltering();
+ // await this.refresh()
+ this.setDefaultSorting();
+ }
+
+ /**
+ * Refreshes the owned assets
+ * @returns {void}
+ */
+ private async refresh(): Promise {
+ switch (this.assetType) {
+ case TableAssetType.Mosaic:
+ await this.$store.dispatch('mosaic/LOAD_MOSAICS');
+ break;
+
+ case TableAssetType.Namespace:
+ await this.$store.dispatch('namespace/LOAD_NAMESPACES');
+ break;
+
+ case TableAssetType.Metadata:
+ await this.$store.dispatch('metadata/LOAD_METADATA_LIST');
+ break;
+ }
+ }
+
+ /**
+ * Sets the default filtering state
+ */
+ public setDefaultFiltering(): void {
+ const defaultFilteringType: FilteringTypes = 'hide';
+ const defaultFilteringFieldName: string = 'expiration';
+
+ Vue.set(this, 'filteredBy', {
+ fieldName: defaultFilteringFieldName,
+ filteringType: defaultFilteringType,
+ });
+ }
+
+ /**
+ * Sets the default sorting state and trigger it
+ */
+ public setDefaultSorting(): void {
+ const defaultSort = 'asc';
+ const defaultField = 'namespace' === this.assetType ? 'name' : 'hexId';
+
+ Vue.set(this, 'sortedBy', {
+ fieldName: defaultField,
+ direction: defaultSort,
+ });
+
+ this.setSortedBy(defaultField);
+ }
+
+ /**
+ * Triggers table filtering by setting its filtering options
+ * @param {TableFieldNames} fieldName
+ */
+ public setFilteredBy(fieldName: string): void {
+ const filteredBy = { ...this.filteredBy };
+ const filteringType: FilteringTypes = filteredBy.fieldName === fieldName && filteredBy.filteringType === 'show' ? 'hide' : 'show';
+
+ this.filteredBy = { fieldName, filteringType };
+ }
+
+ /**
+ * Sorts the table data
+ * @param {TableFieldNames} fieldName
+ */
+ public setSortedBy(fieldName: string): void {
+ const sortedBy = { ...this.sortedBy };
+ const direction: SortingDirections = sortedBy.fieldName === fieldName && sortedBy.direction === 'asc' ? 'desc' : 'asc';
+
+ Vue.set(this, 'sortedBy', { fieldName, direction });
+ }
+
+ /**
+ * Handle pagination page change
+ * @param {number} page
+ */
+ public handlePageChange(page: number): void {
+ this.currentPage = page;
+ }
+
+ /**
+ * Triggers the alias form modal
+ * @protected
+ * @param {Record} rowValues
+ * @return {void}
+ */
+ protected showAliasForm(rowValues: Record): void {
+ // populate asset form modal props if asset is a mosaic
+ if (this.assetType === 'mosaic') {
+ this.modalFormsProps.namespaceId = rowValues.name !== 'N/A' ? new NamespaceId(rowValues.name) : null;
+ this.modalFormsProps.aliasTarget = new MosaicId(rowValues.hexId);
+ this.modalFormsProps.aliasAction = rowValues.name !== 'N/A' ? AliasAction.Unlink : AliasAction.Link;
+ }
+
+ /**
+ * Helper function to instantiate the alias target if any
+ * @param {string} aliasTarget
+ * @param {('address' | 'mosaic')} aliasType
+ * @returns {(MosaicId | Address)}
+ */
+ const getInstantiatedAlias = (aliasType: string, aliasTarget: string): MosaicId | Address => {
+ if (aliasType === 'mosaic') {
+ return new MosaicId(aliasTarget);
+ }
+ return Address.createFromRawAddress(aliasTarget);
+ };
+
+ // populate asset form modal props if asset is a namespace
+ if (this.assetType === 'namespace') {
+ (this.modalFormsProps.namespaceId = new NamespaceId(rowValues.name)),
+ (this.modalFormsProps.aliasTarget =
+ rowValues.aliasIdentifier === 'N/A'
+ ? null
+ : rowValues.aliasIdentifier
+ ? getInstantiatedAlias(rowValues.aliasType, rowValues.aliasIdentifier)
+ : null);
+ this.modalFormsProps.aliasAction = rowValues.aliasIdentifier === 'N/A' ? AliasAction.Link : AliasAction.Unlink;
+ }
+
+ // show the alias form modal
+ Vue.set(this.modalFormsVisibility, 'aliasTransaction', true);
+ }
+
+ /**
+ * Triggers the extend namespace duration form modal
+ * @protected
+ * @param {Record} rowValues
+ * @return {void}
+ */
+ protected showExtendNamespaceDurationForm(rowValues: Record): void {
+ this.modalFormsProps.namespaceId = new NamespaceId(rowValues.name);
+ Vue.set(this.modalFormsVisibility, 'extendNamespaceDurationTransaction', true);
+ }
+
+ /**
+ * Triggers the modify mosaic supply form modal
+ * @protected
+ * @param {Record} rowValues
+ * @return {void}
+ */
+ protected showModifyMosaicSupplyForm(rowValues: Record): void {
+ this.modalFormsProps.mosaicId = new MosaicId(rowValues.hexId);
+ Vue.set(this.modalFormsVisibility, 'mosaicSupplyChangeTransaction', true);
+ }
+
+ protected showMetadataValue(metadataList: MetadataModel[]) {
+ this.targetedMetadataList = metadataList;
+ Vue.set(this.modalFormsVisibility, 'targetedMetadataValue', true);
+ }
+
+ /**
+ * Closes a modal
+ * @protected
+ * @param {string} modalIdentifier
+ * @return {void}
+ */
+ protected closeModal(modalIdentifier: string): void {
+ Vue.set(this.modalFormsVisibility, modalIdentifier, false);
+ }
+
+ /**
+ * avoid multiple clicks
+ * @protected
+ * @param {string}
+ * @return {void}
+ */
+ public isRefreshing: boolean = false;
+
+ public loadMore() {
+ if (this.currentConfirmedPage && !this.currentConfirmedPage.isLastPage) {
+ if (this.assetType === TableAssetType.Namespace) {
+ this.$store.dispatch('namespace/LOAD_NAMESPACES', { pageSize: this.pageSize, pageNumber: ++this.currentPage });
+ }
+ }
+ }
+
+ protected async onRefresh() {
+ if (!this.isRefreshing) {
+ this.isRefreshing = true;
+ try {
+ await this.refresh();
+ } catch (e) {
+ console.log('Cannot refresh', e);
+ }
+ this.isRefreshing = false;
+ }
+ }
+ /**
+ * open edit metadata modal
+ */
+ protected showModalUpdateMetadata(metadataList: MetadataModel[]) {
+ this.targetedMetadataList = metadataList;
+ Vue.set(this.modalFormsVisibility, 'targetValue', true);
+ }
+
+ /**
+ * Watching if refreshed triggered
+ * @param newVal
+ */
+ @Watch('currentConfirmedPage')
+ public watchRefresh(newVal: PageInfo) {
+ // if page refresh is triggered then reset page info
+ if (newVal && newVal.pageNumber === 1) {
+ this.currentPage = 1;
+ }
+ }
+
+ /**
+ * Whether infinite scroll is currently disabled
+ */
+ protected get infiniteScrollDisabled() {
+ return this.paginationType !== 'scroll' || this.isLoading;
+ }
+
+ /**
+ * Whether it is currently fetching more transactions from repository
+ */
+ protected get isFetchingMore(): boolean {
+ return this.isLoading && this.currentConfirmedPage && this.currentConfirmedPage.pageNumber > 1;
+ }
+}
diff --git a/src/components/TableRow/TableRow.less b/src/components/TableRow/TableRow.less
new file mode 100644
index 0000000..313da87
--- /dev/null
+++ b/src/components/TableRow/TableRow.less
@@ -0,0 +1,67 @@
+@import '../../views/resources/css/variables.less';
+
+.table-row-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-auto-flow: column;
+ border-bottom: 1px solid @line;
+ grid-auto-rows: 0.6rem;
+
+ &:hover {
+ background-color: @accentPinkLight;
+ cursor: pointer;
+ }
+ .metadataList-cell {
+ display: none;
+ }
+}
+.namespace-columns,
+.mosaic-columns {
+ .table-cell > div {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+}
+.mosaic-columns ::v-deep {
+ .normal {
+ font-size: 0.16rem;
+ }
+ .integer-part {
+ opacity: 1;
+ }
+}
+.table-cell {
+ padding: 0.2rem 0.1rem 0 0.1rem;
+}
+
+.balance-cell {
+ padding-top: 0.16rem;
+}
+
+.amount-display {
+ text-align: right;
+}
+
+.edit-icon-cell {
+ text-align: center;
+ cursor: pointer;
+ line-height: 0.6rem;
+
+ .edit-icon {
+ font-size: 0.25rem;
+ }
+}
+
+.asset-action-section {
+ text-align: left;
+ p {
+ font-size: @normalFont;
+ }
+}
+
+.metadata-icon {
+ width: 25px;
+ padding: 2px;
+}
diff --git a/src/components/TableRow/TableRow.vue b/src/components/TableRow/TableRow.vue
new file mode 100644
index 0000000..25c6a06
--- /dev/null
+++ b/src/components/TableRow/TableRow.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $t(aliasActionLabel) }}
+
+
+
+
+
+ {{ $t('action_label_extend_duration') }}
+
+
+
+
+
+ {{ $t('action_label_modify_supply') }}
+
+
+
+
+
+ {{ $t('view_metadata') }}
+
+
+
+
+
+ {{ $t('edit_metadata') }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TableRow/TableRowTs.ts b/src/components/TableRow/TableRowTs.ts
new file mode 100644
index 0000000..35eb6c7
--- /dev/null
+++ b/src/components/TableRow/TableRowTs.ts
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+
+// child components
+// @ts-ignore
+import TableRow from '@/components/TableRow/TableRow.vue';
+// @ts-ignore
+import AmountDisplay from '@/components/AmountDisplay/AmountDisplay.vue';
+import { TableAssetType } from '@/components/TableDisplay/TableAssetType';
+
+@Component({
+ components: {
+ TableRow,
+ AmountDisplay,
+ },
+})
+export class TableRowTs extends Vue {
+ /**
+ * Type of assets shown in the table
+ * @type {string}
+ */
+ @Prop({ default: 'mosaic' }) assetType: string;
+
+ /**
+ * Type of assets shown in the table
+ * @type {any}
+ */
+ @Prop({ default: {} }) rowValues: any;
+
+ /**
+ * Owned assets hex ids
+ * @type {string[]}
+ */
+ @Prop({ default: [] }) ownedAssetHexIds: string[];
+
+ /**
+ * Show remove button
+ * @type {boolean}
+ */
+ @Prop({ default: false }) showRemove: boolean;
+
+ /**
+ * Whether the row is a namespace
+ * @readonly
+ * @protected
+ * @type {boolean}
+ */
+ protected get isNamespace(): boolean {
+ return Object.keys(this.rowValues).indexOf('aliasType') > -1;
+ }
+
+ /**
+ * Whether the row is a root namespace
+ * @readonly
+ * @protected
+ * @type {boolean}
+ */
+ protected get isRootNamespace(): boolean {
+ if (!this.isNamespace) {
+ return false;
+ }
+ return this.rowValues.name.indexOf('.') === -1;
+ }
+
+ /**
+ * Whether the row is an asset that has available actions
+ * @readonly
+ * @protected
+ * @type {boolean}
+ */
+ protected get hasAvailableActions(): boolean {
+ if (this.assetType === TableAssetType.AccountRestrictions) {
+ return false;
+ }
+ if (this.rowValues.expiration === 'expired') {
+ return false;
+ }
+ return this.ownedAssetHexIds.findIndex((hexId) => hexId === this.rowValues.hexId) > -1;
+ }
+
+ /**
+ * Whether the mosaic is active and supply mutable
+ * @readonly
+ * @protected
+ * @type {boolean}
+ */
+ protected get isSupplyMutableMosaic(): boolean {
+ if (Object.keys(this.rowValues).indexOf('supply') === -1) {
+ return false;
+ }
+ if (!this.rowValues.supplyMutable) {
+ return false;
+ }
+ return this.rowValues.expiration !== 'expired';
+ }
+
+ protected get hasMetadata(): boolean {
+ return this.rowValues.metadataList && this.rowValues.metadataList.length;
+ }
+
+ /**
+ * Whether link or unlink should be the alias form button label
+ * @protected
+ * @returns {string}
+ */
+ protected get aliasActionLabel(): string {
+ if (this.isNamespace) {
+ if (this.rowValues.aliasType === 'N/A') {
+ return 'action_label_alias_link';
+ }
+ return 'action_label_alias_unlink';
+ }
+ if (this.rowValues.name === 'N/A') {
+ return 'action_label_alias_link';
+ }
+ return 'action_label_alias_unlink';
+ }
+
+ /** Returns only visible values of a row */
+ protected get visibleRowValues() {
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const { hiddenData, ...visible } = this.rowValues;
+ if (this.$route.fullPath === '/mosaicList') {
+ visible.supply = (visible.supply.replace(/\D/g, '') / Math.pow(10, visible.divisibility))
+ .toString()
+ .replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+ }
+ return visible;
+ }
+}
diff --git a/src/components/TransactionDetails/DetailView.vue b/src/components/TransactionDetails/DetailView.vue
new file mode 100644
index 0000000..31e6483
--- /dev/null
+++ b/src/components/TransactionDetails/DetailView.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TransactionDetails/TransactionDetailRow/TransactionDetailRow.vue b/src/components/TransactionDetails/TransactionDetailRow/TransactionDetailRow.vue
new file mode 100644
index 0000000..3d9cdbf
--- /dev/null
+++ b/src/components/TransactionDetails/TransactionDetailRow/TransactionDetailRow.vue
@@ -0,0 +1,81 @@
+
+
+
+ {{ $t(label) }}:
+
+
+
+
+
+
+
+
diff --git a/src/components/TransactionDetails/TransactionDetails.less b/src/components/TransactionDetails/TransactionDetails.less
new file mode 100644
index 0000000..1aa2179
--- /dev/null
+++ b/src/components/TransactionDetails/TransactionDetails.less
@@ -0,0 +1,67 @@
+@import '../../views/resources/css/variables.less';
+
+.transaction-details-main-container {
+ margin-left: 0.5rem;
+ margin-right: 0.2rem;
+}
+
+.transaction-details-detail-section-title-container {
+ width: 100%;
+ height: 0.4rem;
+ margin-top: 0.2rem;
+
+ .transaction-details-detail-section-title {
+ font-size: @bigFont;
+ color: @primary;
+ font-weight: @bold;
+ }
+}
+
+.transaction-details-outer-container {
+ padding: 0 !important;
+ max-height: 4rem;
+ height: 100%;
+ position: relative;
+ display: block;
+}
+
+.transaction-details-item-inner-container {
+ margin-bottom: 0.2rem;
+}
+
+.transaction-details-item-container {
+ margin-bottom: 0.3rem;
+}
+
+.transaction-row-inner-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-columns: 17% 83%;
+ margin-top: 5px;
+ margin-bottom: 5px;
+
+ .transaction-details-row-label-container {
+ text-align: left;
+ font-size: @normalFont;
+ font-family: @symbolFontMedium;
+ font-weight: 500;
+ color: @primary;
+ text-transform: capitalize;
+ overflow: hidden;
+ word-break: break-word;
+ }
+
+ .transaction-details-row-value-container {
+ font-size: @normalFont;
+ color: @purpleDark;
+ font-family: @symbolFontLight;
+ overflow: hidden;
+ word-break: break-word;
+ align-items: center;
+ }
+}
+
+hr {
+ margin-bottom: 0.2rem;
+}
diff --git a/src/components/TransactionDetails/TransactionDetails.vue b/src/components/TransactionDetails/TransactionDetails.vue
new file mode 100644
index 0000000..ca9bd83
--- /dev/null
+++ b/src/components/TransactionDetails/TransactionDetails.vue
@@ -0,0 +1,29 @@
+
+
+
+
+
+ {{ $t('transaction_details') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TransactionDetails/TransactionDetailsTs.ts b/src/components/TransactionDetails/TransactionDetailsTs.ts
new file mode 100644
index 0000000..0b3a582
--- /dev/null
+++ b/src/components/TransactionDetails/TransactionDetailsTs.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import { AggregateTransaction, Transaction } from 'symbol-sdk';
+
+// child components
+// @ts-ignore
+import DetailView from './DetailView.vue';
+// @ts-ignore
+import TransactionDetailsHeader from '@/components/TransactionDetailsHeader/TransactionDetailsHeader.vue';
+import { TransactionViewFactory } from '@/core/transactions/TransactionViewFactory';
+import { TransactionView } from '@/core/transactions/TransactionView';
+
+//@ts-ignore
+@Component({
+ components: { DetailView, TransactionDetailsHeader },
+})
+export class TransactionDetailsTs extends Vue {
+ /**
+ * Transaction to render
+ * @type {Transaction}
+ */
+ @Prop({ default: null }) transaction: Transaction;
+
+ /**
+ * Set if the transaction type is aggregate
+ * @var {AggregateTransaction}
+ */
+ aggregateTransaction: AggregateTransaction = null;
+
+ public get views(): TransactionView[] {
+ if (!this.transaction) {
+ return [];
+ }
+
+ if (this.aggregateTransaction) {
+ return [this.getView(this.aggregateTransaction), ...this.aggregateTransaction.innerTransactions.map((tx) => this.getView(tx))];
+ }
+ return [this.getView(this.transaction)];
+ }
+
+ @Watch('transaction', { immediate: true })
+ public async refreshAggregateTransaction() {
+ if (this.transaction instanceof AggregateTransaction) {
+ if ((this.transaction as AggregateTransaction).innerTransactions?.length > 0) {
+ this.aggregateTransaction = this.transaction as AggregateTransaction;
+ } else if (!!this.transaction.transactionInfo) {
+ this.aggregateTransaction = await this.$store.dispatch('transaction/LOAD_TRANSACTION_DETAILS', {
+ group: TransactionView.getTransactionStatus(this.transaction),
+ transactionHash: this.transaction.transactionInfo?.hash,
+ });
+ }
+ }
+ }
+
+ private getView(transaction: Transaction): TransactionView {
+ return TransactionViewFactory.getView(this.$store, transaction);
+ }
+}
diff --git a/src/components/TransactionDetailsHeader/TransactionDetailsHeader.less b/src/components/TransactionDetailsHeader/TransactionDetailsHeader.less
new file mode 100644
index 0000000..b21cd21
--- /dev/null
+++ b/src/components/TransactionDetailsHeader/TransactionDetailsHeader.less
@@ -0,0 +1,35 @@
+.transaction-header-container {
+ position: relative;
+ font-size: 20px;
+
+ .qr-image {
+ position: absolute;
+ top: 0;
+ right: 40px;
+ width: 170px;
+ height: 170px;
+ }
+
+ .top-transaction-item {
+ padding-top: 10px;
+ }
+
+ .transaction-height,
+ .transaction-type {
+ display: inline-block;
+ width: 400px;
+ }
+
+ .bolder {
+ font-weight: bolder;
+ }
+
+ a {
+ color: #515a6e;
+ }
+
+ .transaction-deadline {
+ width: 400px;
+ display: inline-block;
+ }
+}
diff --git a/src/components/TransactionDetailsHeader/TransactionDetailsHeader.vue b/src/components/TransactionDetailsHeader/TransactionDetailsHeader.vue
new file mode 100644
index 0000000..c6da2c5
--- /dev/null
+++ b/src/components/TransactionDetailsHeader/TransactionDetailsHeader.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/src/components/TransactionDetailsHeader/TransactionDetailsHeaderTs.ts b/src/components/TransactionDetailsHeader/TransactionDetailsHeaderTs.ts
new file mode 100644
index 0000000..a293607
--- /dev/null
+++ b/src/components/TransactionDetailsHeader/TransactionDetailsHeaderTs.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Prop, Vue } from 'vue-property-decorator';
+// @ts-ignore
+import TransactionDetailRow from '@/components/TransactionDetails/TransactionDetailRow/TransactionDetailRow.vue';
+import { TransactionView } from '@/core/transactions/TransactionView';
+import { Transaction } from 'symbol-sdk';
+
+@Component({
+ components: {
+ TransactionDetailRow,
+ },
+})
+export class TransactionDetailsHeaderTs extends Vue {
+ @Prop({
+ default: null,
+ })
+ view: TransactionView;
+}
diff --git a/src/components/TransactionList/TransactionList.less b/src/components/TransactionList/TransactionList.less
new file mode 100644
index 0000000..b4d3f9b
--- /dev/null
+++ b/src/components/TransactionList/TransactionList.less
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.transaction-list-tabs {
+ display: block;
+ position: relative;
+ zoom: 1;
+ width: 100%;
+ height: 100%;
+
+ .ivu-tabs-bar {
+ border: 0;
+ margin-bottom: 0.2rem;
+ }
+
+ .ivu-tabs-content {
+ width: 100%;
+ height: 100%;
+ }
+
+ .ivu-tabs-tabpane {
+ display: block !important;
+ height: 100%;
+ padding-left: 0.2rem;
+ }
+
+ .ivu-tabs-tab {
+ font-size: @smallFont;
+ font-family: @symbolFont;
+ color: @grayDark;
+ font-weight: @bolder;
+ font-size: 0.24rem;
+ margin-top: 0.15rem;
+ margin-left: 0.31rem;
+ }
+
+ .ivu-tabs-tab:hover {
+ opacity: 0.6;
+ }
+
+ .ivu-tabs-tab:active,
+ .ivu-tabs-tab:hover {
+ color: @secondary;
+ }
+
+ .ivu-tabs-tab-active {
+ color: @secondary;
+ }
+
+ .ivu-tabs-ink-bar {
+ display: none;
+ }
+}
+
+.transaction-list-outer-container {
+ background-color: @white;
+ position: relative;
+ height: 100%;
+
+ .transaction-list-tabs-container {
+ width: 100%;
+ height: 100%;
+ display: block;
+ }
+
+ .transaction-list-pagination-container {
+ font-size: @normalFont;
+ text-align: right;
+ width: 100%;
+ display: block;
+ .download-transaction {
+ margin-top: 0.08rem;
+ margin-left: 0.3rem;
+ text-transform: uppercase;
+ color: @purpleLightest;
+ }
+ .ivu-page-item {
+ min-width: 0.31rem;
+ height: 0.3rem;
+ border: none;
+ background: @white;
+ box-shadow: 0 0 0.06rem @boxShadow;
+ color: @grayDark;
+ user-select: none;
+ border: 0.01rem solid @border;
+ transition: all 0.2s ease-in-out;
+ }
+
+ .ivu-page-item-active a,
+ .ivu-page-item-active:hover a {
+ color: @primary !important;
+ }
+
+ .ivu-icon {
+ border: none;
+ }
+
+ span {
+ vertical-align: middle;
+ }
+ .page_total {
+ padding-right: 0.1rem;
+ }
+ .page_content {
+ display: inline-block;
+ vertical-align: middle;
+ padding: 0.1rem 0.45rem;
+ }
+ }
+}
+
+.transaction-list-container {
+ float: left;
+ width: 100%;
+ background-color: @white;
+ padding: 0.05rem 0.31rem;
+ height: 100%;
+
+ .click-to-cosign {
+ color: red !important;
+ font-size: 0.16rem !important;
+ font-weight: 600 !important;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+
+ .inner_transaction_title {
+ width: 2rem !important;
+ }
+
+ .refresh_btn {
+ font-size: 0.16rem;
+ display: block;
+ padding: 0.02rem 0.12rem;
+ line-height: 0.3rem;
+ border-radius: 0.14rem;
+ color: @primary;
+ z-index: 1;
+ }
+}
+.transaction-list-filters-container {
+ position: absolute;
+ right: 0.2rem;
+ top: -0.7rem;
+}
diff --git a/src/components/TransactionList/TransactionList.vue b/src/components/TransactionList/TransactionList.vue
new file mode 100644
index 0000000..9542e1a
--- /dev/null
+++ b/src/components/TransactionList/TransactionList.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
diff --git a/src/components/TransactionList/TransactionListFilters/TransactionListFilters.less b/src/components/TransactionList/TransactionListFilters/TransactionListFilters.less
new file mode 100644
index 0000000..f8e1c6c
--- /dev/null
+++ b/src/components/TransactionList/TransactionListFilters/TransactionListFilters.less
@@ -0,0 +1,139 @@
+@import '../../../views/resources/css/variables.less';
+
+.transaction-list-filters-container {
+ display: flex;
+ justify-content: flex-end;
+ padding: 0.15rem 0;
+
+ .transaction-list-filter-container {
+ margin-right: 0.2rem;
+ min-width: 2rem;
+ color: @white !important;
+
+ /deep/.ivu-select {
+ .ivu-select-selection {
+ font-size: @normalFont;
+ border: none !important;
+ box-shadow: none !important;
+
+ &:hover {
+ color: @primary;
+
+ .ivu-icon-ios-arrow-down {
+ color: @primary !important;
+ }
+ .ivu-icon-ios-arrow-down::before {
+ color: @primary !important;
+ }
+ .ivu-select-prefix {
+ color: @white;
+ }
+ }
+
+ & {
+ background-color: @grayLightest;
+ color: @primary;
+ }
+
+ .ivu-icon-ios-arrow-down {
+ color: @primary !important;
+ }
+
+ .ivu-select-prefix {
+ color: @purpleDark;
+ }
+ }
+
+ .ivu-select-visible {
+ .ivu-select-selection {
+ color: @white !important;
+ background-color: @purpleDark;
+ border: 0.01rem solid @purpleDark;
+ box-shadow: none;
+ }
+
+ .ivu-icon-ios-arrow-down::before {
+ color: @white !important;
+ }
+
+ .ivu-select-prefix {
+ color: @white;
+ }
+ }
+
+ .ivu-select-dropdown {
+ padding: 0 !important;
+ .ivu-select-dropdown-list {
+ .ivu-select-large {
+ }
+
+ .ivu-select-item-selected {
+ color: @primary;
+ background-color: @grayLightest;
+ }
+ }
+
+ background-color: @grayLightest;
+ }
+
+ .ivu-select-group-title {
+ font-size: @smallerFont !important;
+ color: @grayDark;
+ }
+
+ .ivu-select-item {
+ font-size: @smallFont !important;
+ color: @grayDark;
+ }
+
+ .ivu-select-item:hover {
+ background-color: @white;
+ }
+ }
+ }
+ .button-refresh-container {
+ margin-right: 0.2rem;
+ display: flex;
+ align-items: center;
+ }
+ .button-download-container {
+ margin-right: 0.2rem;
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+
+ .button-download {
+ font-size: 0.23rem;
+ color: @primary;
+ }
+ }
+}
+
+.transaction-list-search-container {
+ margin-right: 0.2rem;
+ background-color: @grayLightest;
+ border: none;
+ border-radius: @buttonBorderRadius;
+ padding-left: 0.1rem;
+ padding-right: 0.1rem;
+ display: flex;
+ align-items: center;
+
+ .transaction-list-search-input {
+ border: none;
+ height: 100%;
+ flex-grow: 1;
+ }
+
+ .ivu-icon {
+ font-size: 24px;
+ color: @primary;
+ }
+}
+
+::placeholder {
+ /* Chrome, Firefox, Opera, Safari 10.1+ */
+ font-size: @normalFont;
+ color: @primary;
+ opacity: 10;
+}
diff --git a/src/components/TransactionList/TransactionListFilters/TransactionListFilters.vue b/src/components/TransactionList/TransactionListFilters/TransactionListFilters.vue
new file mode 100644
index 0000000..4d31cbe
--- /dev/null
+++ b/src/components/TransactionList/TransactionListFilters/TransactionListFilters.vue
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
diff --git a/src/components/TransactionList/TransactionListFilters/TransactionListFiltersTs.ts b/src/components/TransactionList/TransactionListFilters/TransactionListFiltersTs.ts
new file mode 100644
index 0000000..dce262f
--- /dev/null
+++ b/src/components/TransactionList/TransactionListFilters/TransactionListFiltersTs.ts
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { mapGetters } from 'vuex';
+import { Component, Vue } from 'vue-property-decorator';
+// child components
+// @ts-ignore
+import SignerFilter from '@/components/SignerFilter/SignerFilter.vue';
+// @ts-ignore
+import TransactionStatusFilter from '@/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.vue';
+//@ts-ignore
+import ButtonRefresh from '@/components/ButtonRefresh/ButtonRefresh.vue';
+import { Signer } from '@/store/Account';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { Address } from 'symbol-sdk';
+
+@Component({
+ components: { SignerFilter, TransactionStatusFilter, ButtonRefresh },
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ signers: 'account/signers',
+ }),
+ },
+})
+export class TransactionListFiltersTs extends Vue {
+ /**
+ * Currently active account
+ * @var {AccountModel}
+ */
+ protected currentAccount: AccountModel;
+
+ /**
+ * current signers
+ */
+ public signers: Signer[];
+
+ /**
+ * Hook called when the signer selector has changed
+ * @protected
+ */
+ protected onSignerSelectorChange(address: string): void {
+ // clear previous account transactions
+ if (address) {
+ this.$store.dispatch('account/SET_CURRENT_SIGNER', {
+ address: Address.createFromRawAddress(address),
+ reset: true,
+ unsubscribeWS: false,
+ });
+ }
+ }
+
+ public refresh() {
+ this.$store.dispatch('transaction/LOAD_TRANSACTIONS');
+ }
+
+ public downloadTransactions() {
+ this.$emit('downloadTransactions');
+ }
+
+ /**
+ * Hook called before the component is destroyed
+ */
+ beforeDestroy(): void {
+ // reset the selected signer if it is not the current account
+ if (this.currentAccount) {
+ this.onSignerSelectorChange(this.currentAccount.address);
+ }
+ }
+}
diff --git a/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.less b/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.less
new file mode 100644
index 0000000..f11bfd9
--- /dev/null
+++ b/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.less
@@ -0,0 +1,88 @@
+@import '../../../../views/resources/css/variables.less';
+
+.transactions-filter {
+ position: relative;
+ color: @primary;
+}
+
+.filter-button {
+ position: relative;
+ box-shadow: unset;
+ border: unset;
+ background: @grayLightest;
+ border-radius: 3.4px;
+ padding: 0.07rem 0.12rem;
+ font-size: @smallFont;
+ cursor: pointer;
+}
+
+.filter-button-arrow {
+ position: absolute;
+ top: 45%;
+ right: 0.12rem;
+ line-height: 1;
+ transform: translateY(-50%) rotate(135deg);
+ font-size: 0.14rem;
+ color: #808695;
+ width: 0.07rem;
+ height: 0.07rem;
+ border-top: 1px solid @primary;
+ border-right: 1px solid @primary;
+ transition: all 0.2s ease-in-out;
+ display: inline-block;
+ font-family: Ionicons;
+ speak: none;
+ font-style: normal;
+ font-weight: 400;
+ font-variant: normal;
+ text-transform: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ vertical-align: -0.125em;
+ text-align: center;
+}
+
+.arrow-up {
+ top: 55%;
+ transform: translateY(-50%) rotate(315deg);
+ display: inline-block;
+}
+
+.filter-options-container {
+ position: absolute;
+ top: calc(@smallerFont + 0.14rem);
+ width: 100%;
+ background: @grayLightest;
+ font-size: @smallFont;
+ z-index: 1061 !important;
+ padding: 0.14rem 0;
+
+ &__option {
+ margin-bottom: 0.07rem;
+ padding: 0 0.15rem;
+ }
+
+ &__divider {
+ width: 100%;
+ height: 1px;
+ background: @grayLight;
+ margin: 0.14rem 0 0.07rem 0;
+ }
+}
+
+/deep/ .ivu-checkbox {
+ .ivu-checkbox-inner {
+ background: white;
+ box-shadow: 0 0.02rem 0.04rem rgba(37, 46, 55, 0.0774148);
+ }
+}
+
+/deep/ .ivu-checkbox-checked {
+ border-radius: 0.02rem;
+ background: @primary !important;
+
+ .ivu-checkbox-inner {
+ background: transparent;
+ }
+}
diff --git a/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.vue b/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.vue
new file mode 100644
index 0000000..d53fb33
--- /dev/null
+++ b/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilter.vue
@@ -0,0 +1,39 @@
+
+
+
+
+
+ onChange(transactionFilterOptions.confirmed, value)" />
+ Confirmed
+
+
+ onChange(transactionFilterOptions.unconfirmed, value)" />
+ Unconfirmed
+
+
+ onChange(transactionFilterOptions.partial, value)" />
+ Partial
+
+
+
+ onChange(transactionFilterOptions.sent, value)" />
+ Sent
+
+
+ onChange(transactionFilterOptions.received, value)" />
+ Received
+
+
+
+
+
+
diff --git a/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilterTs.ts b/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilterTs.ts
new file mode 100644
index 0000000..9d1c8e8
--- /dev/null
+++ b/src/components/TransactionList/TransactionListFilters/TransactionStatusFilter/TransactionStatusFilterTs.ts
@@ -0,0 +1,50 @@
+import { Component, Vue, Watch } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { Signer } from '@/store/Account';
+import { FilterOption, TransactionFilterOptions } from '@/store/Transaction';
+import { Checkbox } from 'view-design';
+
+@Component({
+ computed: {
+ ...mapGetters({
+ currentSigner: 'account/currentSigner',
+ }),
+ },
+ components: {
+ Checkbox,
+ },
+})
+export class TransactionStatusFilterTs extends Vue {
+ public currentSigner: Signer;
+ public isSelectionShown: boolean = false;
+ public transactionFilterOptions = TransactionFilterOptions;
+
+ public onChange(key, value): void {
+ this.$store.commit('transaction/filterTransactions', {
+ filterOption: new FilterOption(key, value),
+ currentSignerAddress: this.currentSigner.address.plain(),
+ });
+ }
+
+ /**
+ * Toggles selection options block.
+ */
+ public toggleSelection(): void {
+ this.isSelectionShown = !this.isSelectionShown;
+ }
+
+ /**
+ * Closes selection options block.
+ */
+ public closeSelection(): void {
+ this.isSelectionShown = false;
+ }
+
+ @Watch('currentSigner')
+ onCurrentSignerChange() {
+ this.$store.commit('transaction/filterTransactions', {
+ filterOption: null,
+ currentSignerAddress: this.currentSigner.address.plain(),
+ });
+ }
+}
diff --git a/src/components/TransactionList/TransactionListHeader/TransactionListHeader.less b/src/components/TransactionList/TransactionListHeader/TransactionListHeader.less
new file mode 100644
index 0000000..7c5ee4c
--- /dev/null
+++ b/src/components/TransactionList/TransactionListHeader/TransactionListHeader.less
@@ -0,0 +1,48 @@
+@import '../../../views/resources/css/variables.less';
+
+.transaction-header-container {
+ display: grid;
+ padding-top: 0.1rem;
+ padding-left: 3%;
+ width: 100%;
+ grid-template-rows: 100%;
+ font-size: @normalFont;
+ text-align: left;
+ background-color: white;
+ font-family: @symbolFontMedium !important;
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ border-bottom: 0.01rem solid @line;
+
+ .address-header {
+ text-align: left;
+ line-height: 0.35rem;
+ margin-left: 0.5em;
+ }
+
+ .amount-header {
+ text-align: center;
+ line-height: 0.35rem;
+ }
+
+ .confirmation-header {
+ text-align: center;
+ line-height: 0.35rem;
+ }
+
+ .hash-header {
+ text-align: left;
+ line-height: 0.35rem;
+ }
+
+ span {
+ font-size: @normalFont;
+ color: @purpleDark;
+ font-weight: normal;
+ }
+
+ .account {
+ padding-left: 0.7rem;
+ }
+}
diff --git a/src/components/TransactionList/TransactionListHeader/TransactionListHeader.vue b/src/components/TransactionList/TransactionListHeader/TransactionListHeader.vue
new file mode 100644
index 0000000..a849493
--- /dev/null
+++ b/src/components/TransactionList/TransactionListHeader/TransactionListHeader.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/src/components/TransactionList/TransactionListTs.ts b/src/components/TransactionList/TransactionListTs.ts
new file mode 100644
index 0000000..29575e7
--- /dev/null
+++ b/src/components/TransactionList/TransactionListTs.ts
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { mapGetters } from 'vuex';
+import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
+import { AggregateTransaction, Convert, MosaicId, Transaction } from 'symbol-sdk';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+// child components
+// @ts-ignore
+import ModalTransactionCosignature from '@/views/modals/ModalTransactionCosignature/ModalTransactionCosignature.vue';
+// @ts-ignore
+import ModalTransactionDetails from '@/views/modals/ModalTransactionDetails/ModalTransactionDetails.vue';
+// @ts-ignore
+import PageTitle from '@/components/PageTitle/PageTitle.vue';
+// @ts-ignore
+import TransactionListFilters from '@/components/TransactionList/TransactionListFilters/TransactionListFilters.vue';
+// @ts-ignore
+import TransactionTable from '@/components/TransactionList/TransactionTable/TransactionTable.vue';
+// @ts-ignore
+import ModalTransactionExport from '@/views/modals/ModalTransactionExport/ModalTransactionExport.vue';
+import { PageInfo } from '@/store/Transaction';
+// @ts-ignore
+import Pagination from '@/components/Pagination/Pagination.vue';
+import { TransactionAnnouncerService } from '@/services/TransactionAnnouncerService';
+
+@Component({
+ components: {
+ ModalTransactionCosignature,
+ ModalTransactionDetails,
+ PageTitle,
+ TransactionListFilters,
+ TransactionTable,
+ ModalTransactionExport,
+ Pagination,
+ },
+ computed: {
+ ...mapGetters({
+ currentAccount: 'account/currentAccount',
+ networkMosaic: 'mosaic/networkMosaic',
+ filteredTransactions: 'transaction/filteredTransactions',
+ generationHash: 'network/generationHash',
+ currentConfirmedPage: 'transaction/currentConfirmedPage',
+ }),
+ },
+})
+export class TransactionListTs extends Vue {
+ @Prop({
+ default: '',
+ })
+ address: string;
+
+ /**
+ * Number of txs visible in each page
+ */
+ @Prop({
+ default: 10,
+ })
+ pageSize: number;
+
+ @Prop({
+ default: 'pagination',
+ })
+ paginationType: 'pagination' | 'scroll';
+
+ /**
+ * Number of txs to be loaded from repository in each request
+ */
+ @Prop({
+ default: 20,
+ })
+ requestPageSize: number;
+
+ /**
+ * Currently active account
+ * @see {Store.Account}
+ * @var {AccountModel}
+ */
+ public currentAccount: AccountModel;
+
+ /**
+ * Network mosaic id
+ * @see {Store.Mosaic}
+ * @var {MosaicId}
+ */
+ public networkMosaic: MosaicId;
+
+ /**
+ * List of filtered transactions (per-request)
+ */
+ public filteredTransactions: Transaction[];
+
+ /**
+ * The current page number
+ * @var {number}
+ */
+ public currentPage: number = 1;
+
+ /**
+ * Active transaction (in-modal)
+ * @var {Transaction}
+ */
+ public activeTransaction: Transaction = null;
+
+ /**
+ * Active bonded transaction (in-modal)
+ * @var {AggregateTransaction}
+ */
+ public activePartialTransaction: AggregateTransaction = null;
+
+ /**
+ * Whether the detail modal box is open
+ * @var {boolean}
+ */
+ public isDisplayingDetails: boolean = false;
+
+ /**
+ * Whether the cosignature modal box is open
+ * @var {boolean}
+ */
+ public isAwaitingCosignature: boolean = false;
+
+ /**
+ * Current generationHash
+ * @see {Store.Network}
+ * @var {string}
+ */
+ public generationHash: string;
+
+ /**
+ * Whether currently viewing export
+ * @var {boolean}
+ */
+ public isViewingExportModal: boolean = false;
+
+ /**
+ * Current confirmed page info
+ * @see {Transaction.PageInfo}
+ * @var {PageInfo}
+ */
+ public currentConfirmedPage: PageInfo;
+
+ public timeIntervals: any[] = [];
+
+ public getEmptyMessage() {
+ return 'no_data_transactions';
+ }
+
+ /// region computed properties getter/setter
+ public get countPages(): number {
+ if (!this.filteredTransactions) {
+ return 0;
+ }
+ return Math.ceil([...this.filteredTransactions].length / this.pageSize);
+ }
+
+ public get totalCountItems(): number {
+ return this.filteredTransactions.length;
+ }
+
+ private checkUnspentHashLocks(): void {
+ Vue.nextTick(() => {
+ this.timeIntervals.push(
+ setInterval(async () => {
+ try {
+ await new TransactionAnnouncerService(this.$store).sendUnspentHashLockPairs();
+ } catch (e) {
+ console.log(`Error trying to send unspent hash locks: ${e.toString()}`);
+ }
+ }, 10000),
+ );
+ });
+ }
+
+ /**
+ * Returns the transactions of the current page
+ * from the getter that matches the provided tab name.
+ * Undefined means the list is being loaded.
+ * @returns {Transaction[]}
+ */
+ public getCurrentPageTransactions(): Transaction[] {
+ // get current tab transactions
+ const transactions = this.filteredTransactions;
+ // get pagination params
+ const start = (this.currentPage - 1) * this.pageSize;
+ const end = this.currentPage * this.pageSize;
+ // slice and return
+ return [...transactions].slice(start, end);
+ }
+
+ /**
+ * Returns the transctions
+ * If the pagination type is (infinite) scroll then returns all
+ * If the pagination type is pagination(paginated) then returns the current page txs
+ *
+ * @return {Transaction[]}
+ */
+ public getTransactions(): Transaction[] {
+ return this.paginationType === 'pagination' ? this.getCurrentPageTransactions() : this.filteredTransactions;
+ }
+
+ public get hasDetailModal(): boolean {
+ return this.isDisplayingDetails;
+ }
+
+ public set hasDetailModal(f: boolean) {
+ this.isDisplayingDetails = f;
+ }
+
+ public get hasCosignatureModal(): boolean {
+ return this.isAwaitingCosignature;
+ }
+
+ public set hasCosignatureModal(f: boolean) {
+ this.isAwaitingCosignature = f;
+ }
+
+ public get aggregateTransactionHash() {
+ if (!this.activePartialTransaction.transactionInfo) {
+ return Transaction.createTransactionHash(
+ this.activePartialTransaction.serialize(),
+ Array.from(Convert.hexToUint8(this.generationHash)),
+ );
+ }
+ return this.activePartialTransaction.transactionInfo.hash;
+ }
+
+ /// end-region computed properties getter/setter
+ created() {
+ this.timeIntervals = [];
+ this.checkUnspentHashLocks();
+ if (this.$route.params.transaction) {
+ // @ts-ignore
+ this.activePartialTransaction = this.$route.params.transaction as AggregateTransaction;
+ this.hasCosignatureModal = true;
+ }
+ }
+
+ /**
+ * Refresh transaction list
+ * @return {void}
+ */
+ /* public async getTransactionListByOption(filter: TransactionGroupState) {
+ this.selectedOption = filter
+ } */
+
+ /**
+ * Hook called when a transaction is clicked
+ * @param {Transaction} transaction
+ */
+ public onClickTransaction(transaction: Transaction | AggregateTransaction) {
+ if (transaction.hasMissingSignatures()) {
+ this.activePartialTransaction = transaction as AggregateTransaction;
+ this.hasCosignatureModal = true;
+ } else {
+ this.activeTransaction = transaction;
+ this.hasDetailModal = true;
+ }
+ }
+
+ public onCloseDetailModal() {
+ this.hasDetailModal = false;
+ this.activeTransaction = undefined;
+ }
+
+ public onCloseCosignatureModal() {
+ this.hasCosignatureModal = false;
+ this.activePartialTransaction = undefined;
+ this.$router.push({ name: 'dashboard.index' });
+ }
+
+ /**
+ * Hook called at each page change
+ */
+ public onPageChange(page: number): void {
+ if (page === this.countPages) {
+ this.loadMore();
+ } else if (page > this.countPages) {
+ page = this.countPages;
+ } else if (page < 1) {
+ page = 1;
+ }
+ this.currentPage = page;
+ }
+
+ /**
+ * Loads next page of transactions from repository
+ */
+ public loadMore() {
+ if (!this.currentConfirmedPage.isLastPage) {
+ this.$store.dispatch('transaction/LOAD_TRANSACTIONS', {
+ pageNumber: ++this.currentConfirmedPage.pageNumber,
+ pageSize: this.requestPageSize,
+ });
+ }
+ }
+
+ /**
+ * Whether currently viewed page is the last page retrieved from repository
+ */
+ public get isLastPage(): boolean {
+ return this.currentConfirmedPage.isLastPage && this.currentPage * this.pageSize >= this.totalCountItems;
+ }
+
+ /**
+ * Watching if refreshed triggered
+ * @param newVal
+ */
+ @Watch('currentConfirmedPage')
+ public watchRefresh(newVal: PageInfo) {
+ // if page refresh is triggered then reset page info
+ if (newVal.pageNumber === 1) {
+ this.currentPage = 1;
+ }
+ }
+
+ public get hasTransactionExportModal(): boolean {
+ return this.isViewingExportModal;
+ }
+
+ public set hasTransactionExportModal(f: boolean) {
+ this.isViewingExportModal = f;
+ }
+
+ public downloadTransactions() {
+ this.hasTransactionExportModal = true;
+ }
+}
diff --git a/src/components/TransactionList/TransactionRow/TransactionRow.vue b/src/components/TransactionList/TransactionRow/TransactionRow.vue
new file mode 100644
index 0000000..38fde37
--- /dev/null
+++ b/src/components/TransactionList/TransactionRow/TransactionRow.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ N/A
+
+
+
+
+ {{ getHeight() }}
+
+
+
+
+
+
+
+ {{ date }}
+
+
+
+
+
+
diff --git a/src/components/TransactionList/TransactionRow/TransactionRowTs.ts b/src/components/TransactionList/TransactionRow/TransactionRowTs.ts
new file mode 100644
index 0000000..bdd0fb8
--- /dev/null
+++ b/src/components/TransactionList/TransactionRow/TransactionRowTs.ts
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { mapGetters } from 'vuex';
+import { MosaicId, NamespaceId, Transaction, TransactionType, TransferTransaction } from 'symbol-sdk';
+// internal dependencies
+import { Formatters } from '@/core/utils/Formatters';
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+// child components
+// @ts-ignore
+import MosaicAmountDisplay from '@/components/MosaicAmountDisplay/MosaicAmountDisplay.vue';
+// @ts-ignore
+import ActionDisplay from '@/components/ActionDisplay/ActionDisplay.vue';
+// resources
+import { dashboardImages, officialIcons, transactionTypeToIcon } from '@/views/resources/Images';
+import { TransactionViewFactory } from '@/core/transactions/TransactionViewFactory';
+import { TransactionView } from '@/core/transactions/TransactionView';
+import { TransactionStatus } from '@/core/transactions/TransactionStatus';
+import { NetworkConfigurationModel } from '../../../core/database/entities/NetworkConfigurationModel';
+import { DateTimeFormatter } from '@js-joda/core';
+
+@Component({
+ components: {
+ ActionDisplay,
+ MosaicAmountDisplay,
+ },
+ computed: mapGetters({
+ networkMosaic: 'mosaic/networkMosaic',
+ explorerBaseUrl: 'app/explorerUrl',
+ networkConfiguration: 'network/networkConfiguration',
+ }),
+})
+export class TransactionRowTs extends Vue {
+ @Prop({ default: [] })
+ public transaction: Transaction;
+
+ protected networkConfiguration: NetworkConfigurationModel;
+
+ /**
+ * Explorer base path
+ */
+ protected explorerBaseUrl: string;
+
+ /**
+ * Network mosaic id
+ * @private
+ */
+ protected networkMosaic: MosaicId;
+
+ /**
+ * Transaction type from SDK
+ */
+ private transactionType = TransactionType;
+
+ /**
+ * Formatters
+ */
+ public formatters: Formatters = Formatters;
+
+ /**
+ * Time helpers
+ */
+ protected timeHelpers: TimeHelpers = TimeHelpers;
+
+ /// region computed properties getter/setter
+ public get view(): TransactionView {
+ return TransactionViewFactory.getView(this.$store, this.transaction);
+ }
+
+ /// end-region computed properties getter/setter
+
+ /**
+ * Get icon per-transaction
+ * @return an icon.
+ */
+ public getIcon() {
+ if (this.transaction.isConfirmed()) {
+ // - read per-transaction-type details@
+ const view = this.view;
+
+ // - transfers have specific incoming/outgoing icons
+ if (view.transaction.type === this.transactionType.TRANSFER) {
+ return view.isIncoming ? officialIcons.incoming : officialIcons.outgoing;
+ }
+
+ // - otherwise use per-type icon
+ return transactionTypeToIcon[view.transaction.type];
+ } else {
+ return this.getTransactionStatusIcon();
+ }
+ }
+ public getTransactionStatusIcon(): string {
+ return dashboardImages.dashboardUnconfirmed;
+ }
+ /**
+ * Returns true if \a transaction is an incoming transaction
+ */
+ public isIncomingTransaction(): boolean {
+ return this.view.isIncoming;
+ }
+
+ /**
+ * Returns the amount to be shown. The first mosaic or the paid fee.
+ */
+ public getAmount(): number {
+ if (this.transaction.type === TransactionType.TRANSFER) {
+ // We may prefer XYM over other mosaic if XYM is 2nd+
+ const transferTransaction = this.transaction as TransferTransaction;
+ const amount = (transferTransaction.mosaics.length && transferTransaction.mosaics[0].amount.compact()) || 0;
+ if (!this.isIncomingTransaction()) {
+ return -amount;
+ }
+ return amount;
+ }
+ return undefined;
+ }
+
+ /**
+ * Returns the color of the balance
+ */
+ public getAmountColor(): string {
+ // https://github.com/nemfoundation/nem2-desktop-account/issues/879
+ if (this.transaction.type === TransactionType.TRANSFER) {
+ return this.isIncomingTransaction() ? 'green' : 'red';
+ }
+ return undefined;
+ }
+
+ /**
+ * Returns the mosaic id of the balance or undefined for the network.
+ */
+ public getAmountMosaicId(): MosaicId | NamespaceId | undefined {
+ if (this.transaction.type === TransactionType.TRANSFER) {
+ // We may prefer XYM over other mosaic if XYM is 2nd+
+ const transferTransaction = this.transaction as TransferTransaction;
+ return (transferTransaction.mosaics.length && transferTransaction.mosaics[0].id) || undefined;
+ }
+ return undefined;
+ }
+
+ /**
+ * Should he ticker be shown in the amount column
+ */
+ public isAmountShowTicker(): boolean {
+ // if (this.transaction.type === TransactionType.TRANSFER) {
+ // const transferTransaction = this.transaction as TransferTransaction
+ // return !!transferTransaction.mosaics.length
+ // }
+ // return true
+ return false;
+ }
+
+ /**
+ * Returns the transaction height or number of confirmations
+ */
+ public getHeight(): string {
+ const transactionStatus = TransactionView.getTransactionStatus(this.transaction);
+ if (transactionStatus == TransactionStatus.confirmed) {
+ return this.view.info?.height.compact().toString();
+ } else {
+ return this.$t(`transaction_status_${transactionStatus}`).toString();
+ }
+ }
+
+ /**
+ * Returns the explorer url
+ */
+ public get explorerUrl() {
+ return this.explorerBaseUrl.replace(/\/+$/, '') + '/transactions/' + this.transaction.transactionInfo.hash;
+ }
+
+ public get deadline() {
+ return this.transaction.deadline
+ .toLocalDateTime(this.networkConfiguration.epochAdjustment)
+ .format(DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss'));
+ }
+ public get date() {
+ return this.transaction.deadline
+ .toLocalDateTime(this.networkConfiguration.epochAdjustment)
+ .minusHours(2)
+ .format(DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss'));
+ }
+}
diff --git a/src/components/TransactionList/TransactionTable/TransactionTable.less b/src/components/TransactionList/TransactionTable/TransactionTable.less
new file mode 100644
index 0000000..7740981
--- /dev/null
+++ b/src/components/TransactionList/TransactionTable/TransactionTable.less
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../../views/resources/css/variables.less';
+
+@headerHeight: 0.45rem;
+@rowHeight: 0.75rem;
+@maxDisplayedRow: 6;
+
+.transaction-tab-inner-container {
+ display: block;
+ position: relative;
+}
+
+.transaction-table-container {
+ display: grid;
+ width: 100%;
+ height: 100%;
+ grid-template-columns: 100%;
+ grid-template-rows: @headerHeight calc(100% - @headerHeight);
+ overflow-y: auto;
+
+ .transaction-table-columns {
+ grid-template-columns: 4% 45% 15% 17% 19%;
+ }
+
+ .transaction-row-columns {
+ grid-template-columns: 4% 45% 15% 17% 19%;
+ }
+
+ .transaction-rows-outer-container {
+ display: block;
+ position: relative;
+ width: 100%;
+ max-height: 100%;
+ }
+
+ .transaction-rows-inner-container {
+ display: grid;
+ grid-auto-rows: @rowHeight;
+ width: 100%;
+ position: relative;
+ }
+
+ .transaction-row-container:hover {
+ background: @accentPinkLight;
+ }
+
+ /deep/.transaction-row-container {
+ font-size: @normalFont;
+ display: grid;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ color: @purpleDark;
+ font-family: @symbolFontLight;
+ cursor: pointer;
+ border-bottom: 0.01rem solid @line;
+ padding-left: 3%;
+
+ > div {
+ margin: auto 0;
+ }
+
+ .icon-cell {
+ position: relative;
+ width: 100%;
+ display: flex;
+
+ .icon-cell-image {
+ color: @purpleDark;
+ width: 0.2rem;
+ height: 0.2rem;
+ margin: auto;
+ display: block;
+ position: relative;
+ }
+ }
+
+ .address-cell {
+ width: 100%;
+ overflow: hidden;
+ margin-left: 0.5em;
+ }
+
+ .amount-cell {
+ text-align: center;
+ font-family: @symbolFont;
+ }
+
+ .confirmation-cell {
+ text-align: center;
+ }
+
+ .hash-cell {
+ text-align: left;
+ overflow: hidden;
+ display: grid;
+ grid-template-columns: 100%;
+ grid-template-rows: repeat(2, 50%);
+
+ .hash-cell-transaction-hash {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+ }
+ }
+}
diff --git a/src/components/TransactionList/TransactionTable/TransactionTable.vue b/src/components/TransactionList/TransactionTable/TransactionTable.vue
new file mode 100644
index 0000000..c8dd912
--- /dev/null
+++ b/src/components/TransactionList/TransactionTable/TransactionTable.vue
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
diff --git a/src/components/TransactionList/TransactionTable/TransactionTableTs.ts b/src/components/TransactionList/TransactionTable/TransactionTableTs.ts
new file mode 100644
index 0000000..f3535c8
--- /dev/null
+++ b/src/components/TransactionList/TransactionTable/TransactionTableTs.ts
@@ -0,0 +1,64 @@
+// external dependenies
+import { Component, Prop, Vue } from 'vue-property-decorator';
+import { Transaction } from 'symbol-sdk';
+import { mapGetters } from 'vuex';
+// child components
+// @ts-ignore
+import TransactionRow from '@/components/TransactionList/TransactionRow/TransactionRow.vue';
+// @ts-ignore
+import TransactionListHeader from '@/components/TransactionList/TransactionListHeader/TransactionListHeader.vue';
+import { PageInfo } from '@/store/Transaction';
+
+@Component({
+ components: {
+ TransactionRow,
+ TransactionListHeader,
+ },
+ computed: mapGetters({
+ isFetchingTransactions: 'transaction/isFetchingTransactions',
+ currentConfirmedPage: 'transaction/currentConfirmedPage',
+ }),
+})
+export class TransactionTableTs extends Vue {
+ @Prop({ default: [] })
+ public transactions: Transaction[];
+
+ @Prop({ default: 'no_data_transactions' })
+ public emptyMessage: string;
+
+ @Prop({ default: null })
+ public loadMore: () => void;
+
+ @Prop({ default: 'pagination' })
+ public paginationType!: 'pagination' | 'scroll';
+
+ public nodata = [...Array(10).keys()];
+
+ /**
+ * Whether transactios are currently being fetched
+ * @protected
+ * @type {boolean}
+ */
+ protected isFetchingTransactions: boolean;
+
+ /**
+ * Current confirmed page info
+ * @see {Transaction.PageInfo}
+ * @var {PageInfo}
+ */
+ public currentConfirmedPage: PageInfo;
+
+ /**
+ * Whether infinite scroll is currently disabled
+ */
+ protected get infiniteScrollDisabled() {
+ return this.paginationType !== 'scroll' || this.isFetchingTransactions;
+ }
+
+ /**
+ * Whether it is currently fetching more transactions from repository
+ */
+ protected get isFetchingMoreTransctions(): boolean {
+ return this.isFetchingTransactions && this.currentConfirmedPage.pageNumber > 1;
+ }
+}
diff --git a/src/components/TransactionListOptions/TransactionListOptions.vue b/src/components/TransactionListOptions/TransactionListOptions.vue
new file mode 100644
index 0000000..5984835
--- /dev/null
+++ b/src/components/TransactionListOptions/TransactionListOptions.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
+ {{ $t('see_transactions_other_account') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TransactionTypeSelector/TransactionTypeSelector.less b/src/components/TransactionTypeSelector/TransactionTypeSelector.less
new file mode 100644
index 0000000..aac40a6
--- /dev/null
+++ b/src/components/TransactionTypeSelector/TransactionTypeSelector.less
@@ -0,0 +1 @@
+@import '../../views/resources/css/variables.less';
diff --git a/src/components/TransactionTypeSelector/TransactionTypeSelector.vue b/src/components/TransactionTypeSelector/TransactionTypeSelector.vue
new file mode 100644
index 0000000..4012a8c
--- /dev/null
+++ b/src/components/TransactionTypeSelector/TransactionTypeSelector.vue
@@ -0,0 +1,19 @@
+
+
+
+
+ {{ $t(`transaction_descriptor_${value}`) }}
+
+
+
+
+
+
+
+
diff --git a/src/components/TransactionTypeSelector/TransactionTypeSelectorTs.ts b/src/components/TransactionTypeSelector/TransactionTypeSelectorTs.ts
new file mode 100644
index 0000000..e5cb219
--- /dev/null
+++ b/src/components/TransactionTypeSelector/TransactionTypeSelectorTs.ts
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */ 1;
+import { TransactionType } from 'symbol-sdk';
+import { Component, Prop, Vue } from 'vue-property-decorator';
+
+@Component
+export default class TransactionTypeSelectorTs extends Vue {
+ /**
+ * Value set by the parent component's v-model
+ * @type {string}
+ */
+ @Prop({ default: null }) value: string;
+
+ @Prop({ default: false }) readonly disabled!: boolean;
+
+ /// region computed properties getter/setter
+ /**
+ * Value set by the parent component
+ * @type {string}
+ */
+ get chosenValue(): string {
+ return this.value;
+ }
+
+ /**
+ * Emit value change
+ */
+ set chosenValue(newValue: string) {
+ this.$emit('input', newValue);
+ }
+
+ /**
+ * Returns sorted TransactionType list
+ */
+ public get transactionTypeList() {
+ return Object.entries(TransactionType)
+ .filter((e) => !(parseInt(e[0]) >= 0) && e[0] !== 'RESERVED' && e[1] !== TransactionType.ACCOUNT_OPERATION_RESTRICTION)
+ .sort((e1, e2) => e1[0].localeCompare(e2[0]));
+ }
+}
diff --git a/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplay.less b/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplay.less
new file mode 100644
index 0000000..f579087
--- /dev/null
+++ b/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplay.less
@@ -0,0 +1,29 @@
+@import '../../../views/resources/css/variables.less';
+
+.transaction-uri-container {
+ overflow-wrap: break-word;
+
+ /deep/.copy-button-container {
+ margin-left: 0.1rem;
+ display: inline-block;
+
+ .ivu-tooltip {
+ width: unset;
+ height: unset;
+
+ .ivu-tooltip-rel {
+ width: unset;
+ height: unset;
+ }
+ }
+
+ .icon {
+ width: 0.14rem;
+ height: 0.14rem;
+ }
+ }
+
+ .info-icon {
+ margin-right: 0.1rem;
+ }
+}
diff --git a/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplay.vue b/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplay.vue
new file mode 100644
index 0000000..a670d49
--- /dev/null
+++ b/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplay.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplayTs.ts b/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplayTs.ts
new file mode 100644
index 0000000..3a651fc
--- /dev/null
+++ b/src/components/TransactionUri/TransactionUriDisplay/TransactionUriDisplayTs.ts
@@ -0,0 +1,20 @@
+import { Transaction, TransactionMapping } from 'symbol-sdk';
+import { Vue, Component, Prop } from 'vue-property-decorator';
+
+import { TransactionURI } from 'symbol-uri-scheme';
+// @ts-ignore
+import ButtonCopyToClipboard from '@/components/ButtonCopyToClipboard/ButtonCopyToClipboard.vue';
+
+// @ts-ignore
+import LongTextDisplay from '@/components/LongTextDisplay/LongTextDisplay.vue';
+
+@Component({
+ components: { ButtonCopyToClipboard, LongTextDisplay },
+})
+export default class TransactionUriDisplayTs extends Vue {
+ @Prop({ default: null }) readonly transaction?: Transaction;
+
+ public get transactionURI() {
+ return new TransactionURI(this.transaction?.serialize(), TransactionMapping.createFromPayload).build();
+ }
+}
diff --git a/src/components/UploadAddressBook/UploadAddressBook.less b/src/components/UploadAddressBook/UploadAddressBook.less
new file mode 100644
index 0000000..bd3e8b8
--- /dev/null
+++ b/src/components/UploadAddressBook/UploadAddressBook.less
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+@import '../../views/resources/css/variables.less';
+
+.upload-qrcode-container {
+ display: grid;
+ grid-template-columns: 70% 30%;
+ i {
+ color: @grayLight;
+ font-size: 1rem;
+ }
+
+ /deep/.ivu-upload .ivu-upload-drag {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 3rem;
+ }
+
+ /deep/.ivu-upload-drag:hover {
+ border: 0.01rem dashed @purpleLight;
+ }
+
+ .upload-qrcode-preview {
+ display: flex;
+ align-items: center;
+ text-align: center;
+ justify-content: center;
+ width: 3rem;
+ margin-bottom: 0.1rem;
+ color: @purple;
+ img {
+ width: 2rem;
+ }
+ }
+
+ .upload-qrcode-right-pane {
+ .upload-qrcode-explanation {
+ font-size: 0.2rem;
+ margin-top: 0.2rem;
+ margin-left: 0.2rem;
+ }
+ .upload-error {
+ color: @redDark;
+ font-size: 0.2rem;
+ margin-top: 0.2rem;
+ margin-left: 0.2rem;
+ }
+ .upload-qrcode-button {
+ margin-top: 0.4rem;
+ text-align: center;
+ }
+ }
+}
diff --git a/src/components/UploadAddressBook/UploadAddressBook.vue b/src/components/UploadAddressBook/UploadAddressBook.vue
new file mode 100644
index 0000000..eeede57
--- /dev/null
+++ b/src/components/UploadAddressBook/UploadAddressBook.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
{{ $t(uploadFileMessage) }}
+
+
+
+
+
+ {{ $t('upload_address_book_explanation') }}
+
+
+ {{ $t('invalid_address_book') }}
+
+
+
+ {{ $t('import_address_book') }}
+
+
+
+
+
+
+
+
+
diff --git a/src/components/UploadAddressBook/UploadAddressBookTs.ts b/src/components/UploadAddressBook/UploadAddressBookTs.ts
new file mode 100644
index 0000000..f0e9e0c
--- /dev/null
+++ b/src/components/UploadAddressBook/UploadAddressBookTs.ts
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Vue, Component, Prop } from 'vue-property-decorator';
+import { AddressBook } from 'symbol-address-book';
+
+@Component({
+ components: {},
+})
+export default class UploadAddressBookTs extends Vue {
+ @Prop({ default: true })
+ public uploadEnabled: boolean;
+
+ @Prop({ default: true })
+ readonly showExplanation: boolean;
+
+ @Prop({ default: 'upload_file_message' })
+ readonly uploadFileMessage!: string;
+
+ /**
+ * Preview uploaded addressBook
+ */
+ addressBook: AddressBook = null;
+
+ /**
+ * Error uploading
+ */
+ showError: boolean = false;
+
+ /**
+ * Uploaded file name
+ */
+ fileName = '';
+
+ /**
+ * Hook for handling file before upload completes
+ * @param file uploaded
+ */
+ public onBeforeUpload(file) {
+ this.fileName = file.name;
+ const fileReader = new FileReader();
+ fileReader.readAsText(file);
+ fileReader.onload = (event) => {
+ // called once readAsDataURL is completed
+ const jsonData = event.target.result as string;
+ try {
+ this.addressBook = AddressBook.fromJSON(jsonData);
+ this.showError = false;
+ } catch (e) {
+ this.showError = true;
+ }
+ };
+
+ return false; //return false now since we have the file passed to qrcodeCapture component
+ }
+
+ /**
+ * Import address book handler
+ */
+ public async importAddressBook() {
+ this.$store.commit('addressBook/setAddressBook', this.addressBook);
+ await this.$store.dispatch('addressBook/SAVE_ADDRESS_BOOK');
+ this.$emit('uploadComplete');
+ }
+}
diff --git a/src/components/WindowControls/WindowControls.less b/src/components/WindowControls/WindowControls.less
new file mode 100644
index 0000000..94d53d3
--- /dev/null
+++ b/src/components/WindowControls/WindowControls.less
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+.window_controller {
+ display: none;
+ width: 100%;
+ height: 20px;
+
+ div {
+ float: right;
+ margin-right: 30px;
+ margin-top: 5px;
+ }
+
+ span {
+ -webkit-app-region: no-drag;
+ display: inline-block;
+ margin-left: 20px;
+ width: 15px;
+ height: 15px;
+ background-size: contain;
+ background-repeat: no-repeat;
+ }
+
+ span:first-of-type {
+ background-image: url('../../views/resources/img/window/windowMin.png');
+ }
+
+ span:nth-of-type(2) {
+ background-image: url('../../views/resources/img/window/windowMax.png');
+ }
+
+ span:nth-of-type(3) {
+ background-image: url('../../views/resources/img/window/windowClose.png');
+ }
+}
diff --git a/src/components/WindowControls/WindowControls.vue b/src/components/WindowControls/WindowControls.vue
new file mode 100644
index 0000000..0d86571
--- /dev/null
+++ b/src/components/WindowControls/WindowControls.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/src/components/WindowControls/WindowControlsTs.ts b/src/components/WindowControls/WindowControlsTs.ts
new file mode 100644
index 0000000..79adae3
--- /dev/null
+++ b/src/components/WindowControls/WindowControlsTs.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Component, Vue } from 'vue-property-decorator';
+
+// internal dependencies
+import { Electron } from '@/core/utils/Electron';
+
+@Component
+export class WindowControlsTs extends Vue {
+ /**
+ * Electron helpers
+ * @var {Electron}
+ */
+ public electronHelpers = Electron;
+}
diff --git a/src/config/AppConfig.ts b/src/config/AppConfig.ts
new file mode 100644
index 0000000..44d602d
--- /dev/null
+++ b/src/config/AppConfig.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export interface LanguageConfig {
+ label: string;
+ value: string;
+}
+
+export interface AppConfig {
+ languages: LanguageConfig[];
+ articlesFeedUrl: string;
+ constants: {
+ EVENTS_THROTTLING_TIME: number;
+ MAX_REMOTE_ACCOUNT_CHECKS: number;
+ SEED_ACCOUNT_NAME_PREFIX: string;
+ ANNOUNCE_TRANSACTION_TIMEOUT: number;
+ MAX_LISTENER_RECONNECT_TRIES: number;
+ MAX_PASSWORD_LENGTH: number;
+ MIN_PASSWORD_LENGTH: number;
+ DECIMAL_SEPARATOR: string;
+ };
+ title: string;
+ marketServerUrl: string;
+}
+
+const defaultAppConfig: AppConfig = {
+ title: 'dHealth Wallet',
+ constants: {
+ EVENTS_THROTTLING_TIME: 6000,
+ MAX_LISTENER_RECONNECT_TRIES: 20,
+ MAX_PASSWORD_LENGTH: 64,
+ MAX_REMOTE_ACCOUNT_CHECKS: 10,
+ MIN_PASSWORD_LENGTH: 8,
+ SEED_ACCOUNT_NAME_PREFIX: 'Identity-',
+ ANNOUNCE_TRANSACTION_TIMEOUT: 240000,
+ DECIMAL_SEPARATOR: Number('1.1').toLocaleString().substring(1, 2),
+ },
+ languages: [
+ { value: 'en-US', label: 'English' },
+ { value: 'zh-CN', label: '中文' },
+ { value: 'ja-JP', label: '日本語' },
+ ],
+ marketServerUrl: 'http://app.nemcn.io',
+ articlesFeedUrl: 'https://dhealth.network/feed',
+};
+const resolvedAppConfig: AppConfig = window['appConfig'] || defaultAppConfig;
+console.log('appConfig resolved!', resolvedAppConfig);
+export const appConfig = resolvedAppConfig;
diff --git a/src/config/FeesConfig.ts b/src/config/FeesConfig.ts
new file mode 100644
index 0000000..068bdae
--- /dev/null
+++ b/src/config/FeesConfig.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export interface FeesConfig {
+ median: number;
+ free: number;
+ slow: number;
+ slowest: number;
+ fast: number;
+}
+
+const defaultFeesConfig: FeesConfig = {
+ median: 10,
+ free: 0,
+ slow: 5,
+ slowest: 1,
+ fast: 20,
+};
+
+const resolvedFeesConfig: FeesConfig = window['feesConfig'] || defaultFeesConfig;
+console.log('feesConfig resolved!', resolvedFeesConfig);
+export const feesConfig = resolvedFeesConfig;
diff --git a/src/config/NetworkConfig.ts b/src/config/NetworkConfig.ts
new file mode 100644
index 0000000..2d0ec33
--- /dev/null
+++ b/src/config/NetworkConfig.ts
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ * Copyright 2021-present [Using Blockchain Ltd](https://using-blockchain.org), All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export interface NodeConfig {
+ roles: number;
+ friendlyName: string;
+ url: string;
+}
+
+export interface NetworkConfigurationDefaults {
+ maxTransactionsPerAggregate: number;
+ maxMosaicDuration: number;
+ lockedFundsPerAggregate: string;
+ maxNamespaceDuration: number;
+ maxCosignatoriesPerAccount: number;
+ maxMosaicAtomicUnits: number;
+ blockGenerationTargetTime: number;
+ currencyMosaicId: string;
+ namespaceGracePeriodDuration: number;
+ harvestingMosaicId: string;
+ minNamespaceDuration: number;
+ maxCosignedAccountsPerAccount: number;
+ maxNamespaceDepth: number;
+ defaultDynamicFeeMultiplier: number;
+ maxMosaicDivisibility: number;
+ maxMessageSize: number;
+ epochAdjustment: number;
+ totalChainImportance: number;
+ generationHash: string;
+}
+
+export interface NetworkConfig {
+ networkName: string;
+ faucetUrl: string;
+ nodes: NodeConfig[];
+ defaultNetworkType: number;
+ explorerUrl: string;
+ networkConfigurationDefaults: NetworkConfigurationDefaults;
+}
+
+export const defaultTestnetNetworkConfig: NetworkConfig = {
+ networkName: 'dHealth Test Network',
+ explorerUrl: 'https://explorer.dhealth.dev/',
+ faucetUrl: 'https://faucet.dhealth.dev/',
+ defaultNetworkType: 152,
+ networkConfigurationDefaults: {
+ maxMosaicDivisibility: 6,
+ namespaceGracePeriodDuration: 1051200, // 365d
+ lockedFundsPerAggregate: '10000000',
+ maxCosignatoriesPerAccount: 25,
+ blockGenerationTargetTime: 30,
+ maxNamespaceDepth: 3,
+ maxMosaicDuration: 10512000, // 3650d
+ minNamespaceDuration: 10512000, // 3650d
+ maxNamespaceDuration: 10512000, // 3650d
+ maxTransactionsPerAggregate: 100,
+ maxCosignedAccountsPerAccount: 25,
+ maxMessageSize: 1024,
+ maxMosaicAtomicUnits: 9000000000000000,
+ currencyMosaicId: '5A4935C1D66E6AC4',
+ harvestingMosaicId: '5A4935C1D66E6AC4',
+ defaultDynamicFeeMultiplier: 100,
+ epochAdjustment: 1616978397,
+ totalChainImportance: 1000000000000000,
+ generationHash: 'F1DE7701FF17DA20904565FA9753690A9990D3B00730A241FFFB7F60C2B5D638',
+ },
+ nodes: [
+ { friendlyName: 'dhealth-dual-01', roles: 7, url: 'https://dual-01.dhealth.dev:3001' },
+ { friendlyName: 'dhealth-dual-02', roles: 7, url: 'https://dual-02.dhealth.dev:3001' },
+ { friendlyName: 'dhealth-api-01', roles: 2, url: 'https://api-01.dhealth.dev:3001' },
+ { friendlyName: 'dhealth-api-02', roles: 2, url: 'https://api-02.dhealth.dev:3001' },
+ ],
+};
+
+export const defaultMainnetNetworkConfig: NetworkConfig = {
+ networkName: 'dHealth Public Network',
+ explorerUrl: 'http://explorer.dhealth.cloud/',
+ faucetUrl: 'http://faucet.dhealth.cloud/',
+ defaultNetworkType: 104,
+ networkConfigurationDefaults: {
+ maxMosaicDivisibility: 6,
+ namespaceGracePeriodDuration: 1051200, // 365d
+ lockedFundsPerAggregate: '10000000',
+ maxCosignatoriesPerAccount: 25,
+ blockGenerationTargetTime: 30,
+ maxNamespaceDepth: 3,
+ maxMosaicDuration: 10512000, // 3650d
+ minNamespaceDuration: 10512000, // 3650d
+ maxNamespaceDuration: 10512000, // 3650d
+ maxTransactionsPerAggregate: 100,
+ maxCosignedAccountsPerAccount: 25,
+ maxMessageSize: 1024,
+ maxMosaicAtomicUnits: 9000000000000000,
+ currencyMosaicId: '39E0C49FA322A459',
+ harvestingMosaicId: '39E0C49FA322A459',
+ defaultDynamicFeeMultiplier: 100,
+ epochAdjustment: 1616978397,
+ totalChainImportance: 1000000000000000,
+ generationHash: 'ED5761EA890A096C50D3F50B7C2F0CCB4B84AFC9EA870F381E84DDE36D04EF16',
+ },
+ nodes: [
+ { friendlyName: 'dhealth-dual-01', roles: 7, url: 'http://dual-01.dhealth.cloud:3000' },
+ { friendlyName: 'dhealth-dual-02', roles: 7, url: 'http://dual-02.dhealth.cloud:3000' },
+ { friendlyName: 'dhealth-dual-03', roles: 7, url: 'http://dual-03.dhealth.cloud:3000' },
+ { friendlyName: 'dhealth-api-01', roles: 2, url: 'http://api-01.dhealth.cloud:3000' },
+ { friendlyName: 'dhealth-api-02', roles: 2, url: 'http://api-02.dhealth.cloud:3000' },
+ ],
+};
+
+const defaultNetworkConfig: Record = {
+ 152: defaultTestnetNetworkConfig,
+ 104: defaultMainnetNetworkConfig,
+};
+
+const resolvedNetworkConfig: NetworkConfig = window['networkConfig'] || defaultNetworkConfig;
+console.log('networkConfig resolved!', resolvedNetworkConfig);
+export const networkConfig = resolvedNetworkConfig;
diff --git a/src/config/index.ts b/src/config/index.ts
new file mode 100644
index 0000000..81f5f13
--- /dev/null
+++ b/src/config/index.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export * from './AppConfig';
+export * from './FeesConfig';
+export * from './NetworkConfig';
diff --git a/src/core/database/backends/INetworkBasedStorage.ts b/src/core/database/backends/INetworkBasedStorage.ts
new file mode 100644
index 0000000..bb4ff98
--- /dev/null
+++ b/src/core/database/backends/INetworkBasedStorage.ts
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+/**
+ * Storage
+ */
+export interface INetworkBasedStorage {
+ /**
+ * it gets the stored value for the specific generation hash.
+ *
+ * @param generationHash the generation hash
+ * @return the stored value for the provided network hash or undefined
+ */
+ get(generationHash: string): E | undefined;
+
+ /**
+ * It gets the latest stored entry according to the timestamp.
+ * @return the entry if available.
+ */
+ getLatest(): E | undefined;
+
+ /**
+ * Stores the value for the provided generation hash.
+ *
+ * @param generationHash the generation hash
+ * @param value to be stored
+ */
+ set(generationHash: string, value: E): void;
+
+ /**
+ * Deletes the stored value for the given generation hash
+ * @param generationHash the generation hash.
+ */
+ remove(generationHash: string): void;
+}
diff --git a/src/core/database/backends/IStorage.ts b/src/core/database/backends/IStorage.ts
new file mode 100644
index 0000000..f5b88ba
--- /dev/null
+++ b/src/core/database/backends/IStorage.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+/**
+ * Generic interface for simple stored objects.
+ */
+export interface IStorage {
+ /**
+ * @return the stored value or undefined
+ */
+ get(): E | undefined;
+
+ /**
+ * Stores the provided value.
+ * @param value to be stored
+ */
+ set(value: E): void;
+
+ /**
+ * Deletes the stored value.
+ */
+ remove(): void;
+}
diff --git a/src/core/database/backends/IStorageBackend.ts b/src/core/database/backends/IStorageBackend.ts
new file mode 100644
index 0000000..83ce48b
--- /dev/null
+++ b/src/core/database/backends/IStorageBackend.ts
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+export interface IStorageBackend {
+ /**
+ * The number of available entries
+ * @var {number}
+ */
+ length: number;
+
+ /**
+ * Getter for value with \a key
+ * @param {string} key
+ * @return {string|null}
+ */
+ getItem(key: string): string | null;
+
+ /**
+ * Setter for \a key with \a value
+ * @param {string} key
+ * @param {any} value
+ */
+ setItem(key: string, value: string): void;
+
+ /**
+ * Deletes the value for the given key
+ * @param {string} key
+ */
+ removeItem(key: string): void;
+}
diff --git a/src/core/database/backends/LocalStorageBackend.ts b/src/core/database/backends/LocalStorageBackend.ts
new file mode 100644
index 0000000..82dff7e
--- /dev/null
+++ b/src/core/database/backends/LocalStorageBackend.ts
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { IStorageBackend } from './IStorageBackend';
+
+export class LocalStorageBackend implements IStorageBackend {
+ /**
+ * The number of available entries
+ * @var {number}
+ */
+ public get length(): number {
+ return !!localStorage ? localStorage.length : 0;
+ }
+
+ /**
+ * Returns true if localStorage backend is available
+ * @return {boolean}
+ */
+ public isAvailable(): boolean {
+ return !!localStorage;
+ }
+
+ /**
+ * Getter for value with \a key
+ * @param {string} key
+ * @return {any}
+ */
+ public getItem(key: string): string | undefined {
+ return localStorage.getItem(key);
+ }
+
+ /**
+ * Setter for \a key with \a value
+ * @param {string} key
+ * @param {any} value
+ */
+ public setItem(key: string, value: string): void {
+ localStorage.setItem(key, value);
+ }
+
+ /**
+ * Deletes the value for the given key
+ * @param {string} key
+ */
+ public removeItem(key: string): void {
+ localStorage.removeItem(key);
+ }
+}
diff --git a/src/core/database/backends/NetworkBasedObjectStorage.ts b/src/core/database/backends/NetworkBasedObjectStorage.ts
new file mode 100644
index 0000000..c87cb73
--- /dev/null
+++ b/src/core/database/backends/NetworkBasedObjectStorage.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkBasedEntryModel, NetworkBasedModel } from '@/core/database/entities/NetworkBasedModel';
+import { IStorage } from '@/core/database/backends/IStorage';
+
+/**
+ * A storage save the data per generation hash
+ */
+export class NetworkBasedObjectStorage {
+ /**
+ * @param delegate the delegate that will store the data that stores the generation model.
+ */
+ public constructor(private readonly delegate: IStorage>) {}
+
+ /**
+ * it gets the stored value for the specific generation hash.
+ *
+ * @param generationHash the generation hash
+ * @return the stored value for the provided network hash or undefined
+ */
+ public get(generationHash: string): E | undefined {
+ if (!generationHash) {
+ return undefined;
+ }
+ const map = this.delegate.get() || {};
+ return (map[generationHash] && map[generationHash].data) || undefined;
+ }
+
+ /**
+ * It gets the latest stored entry according to the timestamp.
+ * @return the entry if available.
+ */
+ public getLatest(): E | undefined {
+ const map = this.delegate.get() || {};
+ const latest = Object.values(map).reduce(
+ (prev, current) => (prev && prev.timestamp > current.timestamp ? prev : current),
+ undefined,
+ );
+ return (latest && latest.data) || undefined;
+ }
+
+ /**
+ * Stores the value for the provided generation hash.
+ *
+ * @param generationHash the generation hash
+ * @param value to be stored
+ */
+ public set(generationHash: string, value: E): void {
+ if (!generationHash) {
+ throw Error('Generation hash must be provided!');
+ }
+ const map = this.delegate.get() || {};
+ map[generationHash] = new NetworkBasedEntryModel(generationHash, value);
+ this.delegate.set(map);
+ }
+
+ /**
+ * Deletes the stored value for the given generation hash
+ * @param generationHash the generation hash.
+ */
+ public remove(generationHash: string): void {
+ const map = this.delegate.get() || {};
+ delete map[generationHash];
+ this.delegate.set(map);
+ }
+}
diff --git a/src/core/database/backends/ObjectStorageBackend.ts b/src/core/database/backends/ObjectStorageBackend.ts
new file mode 100644
index 0000000..fe0f038
--- /dev/null
+++ b/src/core/database/backends/ObjectStorageBackend.ts
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { IStorageBackend } from './IStorageBackend';
+
+export class ObjectStorageBackend implements IStorageBackend {
+ /**
+ * Construct an object storage backend
+ * @param backend
+ */
+ public constructor(protected readonly backend: Record = {}) {}
+
+ /**
+ * The number of available entries
+ * @var {number}
+ */
+ public get length(): number {
+ return Object.keys(this.backend).length;
+ }
+
+ /**
+ * Always returns true for "backend as an object"
+ * @return {boolean}
+ */
+ public isAvailable(): boolean {
+ return true;
+ }
+
+ /**
+ * Getter for value with \a key
+ * @param {string} key
+ * @return {any}
+ */
+ public getItem(key: string): string | null {
+ if (!this.backend || !this.backend[key]) {
+ return null;
+ }
+
+ return this.backend[key];
+ }
+
+ /**
+ * Setter for \a key with \a value
+ * @param {string} key
+ * @param {any} value
+ */
+ public setItem(key: string, value: string): void {
+ this.backend[key] = value;
+ }
+
+ /**
+ * Deletes the value for the given key
+ * @param {string} key
+ */
+ public removeItem(key: string): void {
+ delete this.backend[key];
+ }
+}
diff --git a/src/core/database/backends/SimpleObjectStorage.ts b/src/core/database/backends/SimpleObjectStorage.ts
new file mode 100644
index 0000000..9999d7e
--- /dev/null
+++ b/src/core/database/backends/SimpleObjectStorage.ts
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Convert, Crypto, SHA3Hasher } from 'symbol-sdk';
+
+// internal dependencies
+import { IStorageBackend } from '@/core/database/backends/IStorageBackend';
+import { LocalStorageBackend } from '@/core/database/backends/LocalStorageBackend';
+import { ObjectStorageBackend } from '@/core/database/backends/ObjectStorageBackend';
+import { IStorage } from '@/core/database/backends/IStorage';
+
+/**
+ * A super simple object storage that keeps one object in a local storage table.
+ *
+ * This object is generic, you can type it with the class of object that it's going to be stored.
+ * The object could be a simple object, an array or a Map/Record with key->value.
+ *
+ */
+export class SimpleObjectStorage implements IStorage {
+ /**
+ * The Storage backend, if localStorage is not available the storage will be in memory.
+ */
+
+ public constructor(
+ private readonly storageKey: string,
+ private readonly storageBackend: IStorageBackend = !!localStorage ? new LocalStorageBackend() : new ObjectStorageBackend(),
+ ) {}
+
+ /**
+ * @return the stored value or undefined
+ */
+ public get(): E | undefined {
+ const item = this.storageBackend.getItem(this.storageKey);
+ return item ? JSON.parse(item) : undefined;
+ }
+
+ /**
+ * Stores the provided value.
+ * @param value to be stored
+ */
+ public set(value: E): void {
+ this.storageBackend.setItem(this.storageKey, JSON.stringify(value));
+ }
+
+ /**
+ * Deletes the stored value.
+ */
+ public remove(): void {
+ this.storageBackend.removeItem(this.storageKey);
+ }
+
+ /**
+ * Helper that generates an identifier base on the object value
+ *
+ * @param object the object used feed the generator.
+ */
+ public static generateIdentifier(object: object | undefined = undefined): string {
+ const raw = {
+ ...{
+ time: new Date().valueOf(),
+ seed: Crypto.randomBytes(8),
+ },
+ ...(object || {}),
+ };
+ // to-json
+ const json = JSON.stringify(raw);
+ const hasher = SHA3Hasher.createHasher(64);
+ hasher.reset();
+ hasher.update(Convert.utf8ToHex(json));
+
+ const hash = new Uint8Array(64);
+ hasher.finalize(hash);
+ return Convert.uint8ToHex(hash).substr(0, 16);
+ }
+}
diff --git a/src/core/database/backends/VersionedNetworkBasedObjectStorage.ts b/src/core/database/backends/VersionedNetworkBasedObjectStorage.ts
new file mode 100644
index 0000000..4dbde57
--- /dev/null
+++ b/src/core/database/backends/VersionedNetworkBasedObjectStorage.ts
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { INetworkBasedStorage } from '@/core/database/backends/INetworkBasedStorage';
+import { NetworkBasedObjectStorage } from '@/core/database/backends/NetworkBasedObjectStorage';
+import { Migration, VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { NetworkBasedModel } from '@/core/database/entities/NetworkBasedModel';
+
+/**
+ * A storage that wraps the stored model with a {version: n, data:T} object and it handles the migration from old
+ * version to new versions.
+ *
+ */
+export class VersionedNetworkBasedObjectStorage extends NetworkBasedObjectStorage implements INetworkBasedStorage {
+ constructor(storageKey: string, migrations: Migration[] = []) {
+ super(
+ new VersionedObjectStorage>({
+ storageKey: storageKey,
+ migrations: migrations,
+ }),
+ );
+ }
+}
diff --git a/src/core/database/backends/VersionedObjectStorage.ts b/src/core/database/backends/VersionedObjectStorage.ts
new file mode 100644
index 0000000..a7fb893
--- /dev/null
+++ b/src/core/database/backends/VersionedObjectStorage.ts
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { IStorage } from '@/core/database/backends/IStorage';
+import { VersionedModel } from '@/core/database/entities/VersionedModel';
+import { SimpleObjectStorage } from '@/core/database/backends/SimpleObjectStorage';
+
+/**
+ * The operation to migrate the data.
+ */
+export interface Migration {
+ readonly description: string;
+
+ migrate(from: any): any;
+}
+
+/**
+ * A storage that wraps the stored model with a {version: n, data:T} object and it handles the migration from old
+ * version to new versions.
+ *
+ */
+export class VersionedObjectStorage implements IStorage {
+ private readonly delegate: IStorage>;
+
+ private readonly currentVersion: number;
+
+ constructor({
+ delegate,
+ storageKey,
+ migrations = [],
+ }: {
+ delegate?: IStorage>;
+ storageKey?: string;
+ migrations?: Migration[];
+ }) {
+ if (!delegate && !storageKey) {
+ throw new Error('delegate or storage key must be provided!');
+ }
+ this.delegate = delegate || new SimpleObjectStorage>(storageKey);
+ this.currentVersion = migrations.length + 1;
+ const versioned = this.delegate.get();
+ if (!versioned || versioned.version == this.currentVersion) {
+ return;
+ }
+ if (versioned.version > this.currentVersion) {
+ throw new Error(`Current data version is ${versioned.version} but higher version is ${this.currentVersion}`);
+ }
+ const value = migrations.slice(versioned.version - 1).reduce((toMigrateData, migration) => {
+ if (toMigrateData === undefined) {
+ console.log(`data to migrate is undefined, ignoring migration ${migration.description}`);
+ return undefined;
+ }
+ console.log(`Applying migration ${migration.description}`);
+ return migration.migrate(toMigrateData);
+ }, versioned.data);
+ if (value === undefined) {
+ this.remove();
+ } else {
+ this.set(value);
+ }
+ }
+
+ get(): E | undefined {
+ const versioned = this.delegate.get();
+ return (versioned && versioned.data) || undefined;
+ }
+
+ remove(): void {
+ this.delegate.remove();
+ }
+
+ set(value: E): void {
+ this.delegate.set(new VersionedModel(this.currentVersion, value));
+ }
+
+ getVersion(): E | number {
+ const versioned = this.delegate.get();
+ return (versioned && versioned.version) || undefined;
+ }
+}
diff --git a/src/core/database/entities/AccountModel.ts b/src/core/database/entities/AccountModel.ts
new file mode 100644
index 0000000..f6e20a2
--- /dev/null
+++ b/src/core/database/entities/AccountModel.ts
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { Address, PublicAccount } from 'symbol-sdk';
+
+export class AccountType {
+ public static readonly SEED: number = 1;
+ public static readonly PRIVATE_KEY = 2;
+ public static readonly KEYSTORE = 3;
+ public static readonly TREZOR = 4;
+ public static readonly LEDGER = 5;
+ public static readonly OPT_IN = 6;
+ public static readonly LEDGER_OPT_IN = 7;
+
+ public static fromDescriptor(descriptor: string) {
+ switch (descriptor) {
+ default:
+ case 'Ks':
+ return AccountType.KEYSTORE;
+ case 'Pk':
+ return AccountType.PRIVATE_KEY;
+ case 'Seed':
+ return AccountType.SEED;
+ case 'Trezor':
+ return AccountType.TREZOR;
+ case 'Ledger':
+ return AccountType.LEDGER;
+ case 'OptIn':
+ return AccountType.OPT_IN;
+ case 'Ledger-OptIn':
+ return AccountType.LEDGER_OPT_IN;
+ }
+ }
+}
+
+/**
+ * Stored POJO that holds user provided account information.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ */
+export class AccountModel {
+ public readonly id: string;
+ public readonly name: string;
+ public readonly profileName: string;
+ public readonly node: string;
+ public readonly type: number;
+ public readonly address: string;
+ public readonly publicKey: string;
+ public readonly encryptedPrivateKey: string;
+ public readonly path: string;
+ public readonly isMultisig: boolean;
+ public readonly encRemoteAccountPrivateKey?: string;
+
+ /**
+ * Permits to return specific field's mapped object instances
+ * @return any
+ */
+ public static getObjects(model: AccountModel): { address: Address; publicAccount: PublicAccount } {
+ const address = Address.createFromRawAddress(model.address);
+ const publicAccount = PublicAccount.createFromPublicKey(model.publicKey, address.networkType);
+ return { address, publicAccount };
+ }
+}
diff --git a/src/core/database/entities/BlockInfoModel.ts b/src/core/database/entities/BlockInfoModel.ts
new file mode 100644
index 0000000..84f3b62
--- /dev/null
+++ b/src/core/database/entities/BlockInfoModel.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { BlockInfo } from 'symbol-sdk';
+
+export class BlockInfoModel {
+ public readonly height: string;
+ public readonly feeMultiplier: number;
+ public readonly blockTransactionsHash: string;
+ public readonly blockReceiptsHash: string;
+ public readonly stateHash: string;
+ public readonly generationHash: string;
+ constructor(blockInfo: BlockInfo) {
+ this.height = blockInfo.height.toString();
+ this.feeMultiplier = blockInfo.feeMultiplier;
+ this.blockTransactionsHash = blockInfo.blockTransactionsHash;
+ this.blockReceiptsHash = blockInfo.blockReceiptsHash;
+ this.stateHash = blockInfo.stateHash;
+ this.generationHash = blockInfo.generationHash;
+ }
+}
diff --git a/src/core/database/entities/HarvestingModel.ts b/src/core/database/entities/HarvestingModel.ts
new file mode 100644
index 0000000..8f70760
--- /dev/null
+++ b/src/core/database/entities/HarvestingModel.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NodeModel } from './NodeModel';
+
+export class HarvestingModel {
+ public readonly accountAddress: string;
+ public readonly isPersistentDelReqSent?: boolean;
+ public readonly selectedHarvestingNode?: NodeModel;
+ public readonly encRemotePrivateKey?: string;
+ public readonly encVrfPrivateKey?: string;
+ public readonly delegatedHarvestingRequestFailed?: boolean;
+}
diff --git a/src/core/database/entities/HashLockAggregatePairModel.ts b/src/core/database/entities/HashLockAggregatePairModel.ts
new file mode 100644
index 0000000..93571e8
--- /dev/null
+++ b/src/core/database/entities/HashLockAggregatePairModel.ts
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkType, TransactionType } from 'symbol-sdk';
+
+/**
+ * HashLock Aggregate Pair to hold unspent HashLocks information
+ *
+ */
+export class HashLockAggregatePairModel {
+ public readonly profileName: string;
+ public readonly hashLockHash: string;
+ public readonly aggregateTransactionDTO: {
+ payload: string;
+ hash: string;
+ signerPublicKey: string;
+ type: TransactionType;
+ networkType: NetworkType;
+ };
+}
diff --git a/src/core/database/entities/MetadataModel.ts b/src/core/database/entities/MetadataModel.ts
new file mode 100644
index 0000000..81b1e24
--- /dev/null
+++ b/src/core/database/entities/MetadataModel.ts
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { Formatters } from '@/core/utils/Formatters';
+import { Convert, Metadata, MetadataType } from 'symbol-sdk';
+
+/**
+ * Stored POJO that holds mosaic information.
+ *
+ * The stored data is cached from rest.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ *
+ */
+export class MetadataModel {
+ public readonly metadataId: string;
+ public readonly sourceAddress: string;
+ public readonly targetAddress: string;
+ public readonly scopedMetadataKey: string;
+ public readonly metadataType: MetadataType;
+ public readonly value: string;
+ public readonly targetId?: string | undefined;
+
+ constructor(metadata: Metadata) {
+ this.metadataId = metadata.id;
+ this.sourceAddress = metadata.metadataEntry.sourceAddress.plain();
+ this.metadataType = metadata.metadataEntry.metadataType;
+ this.scopedMetadataKey = metadata.metadataEntry.scopedMetadataKey.toHex();
+ this.targetAddress = metadata.metadataEntry.targetAddress.plain();
+ this.targetId = metadata.metadataEntry.targetId?.toHex();
+ this.value = metadata.metadataEntry.value;
+ if (Convert.isHexString(metadata.metadataEntry.value)) {
+ this.value = Formatters.hexToUtf8(metadata.metadataEntry.value);
+ } else {
+ this.value = metadata.metadataEntry.value;
+ }
+ }
+}
diff --git a/src/core/database/entities/MosaicConfigurationModel.ts b/src/core/database/entities/MosaicConfigurationModel.ts
new file mode 100644
index 0000000..e7f9396
--- /dev/null
+++ b/src/core/database/entities/MosaicConfigurationModel.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+/**
+ * POJO that stores user provided configuration for mosaics.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ */
+export class MosaicConfigurationModel {
+ constructor(public readonly hidden: boolean = false) {}
+}
+export type AccountMosaicConfigurationModel = Record;
diff --git a/src/core/database/entities/MosaicModel.ts b/src/core/database/entities/MosaicModel.ts
new file mode 100644
index 0000000..8cf237d
--- /dev/null
+++ b/src/core/database/entities/MosaicModel.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { MosaicInfo } from 'symbol-sdk';
+import { MetadataModel } from './MetadataModel';
+
+/**
+ * Stored POJO that holds mosaic information.
+ *
+ * The stored data is cached from rest.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ *
+ */
+export class MosaicModel {
+ public readonly mosaicIdHex: string;
+ public readonly divisibility: number;
+ public readonly transferable: boolean;
+ public readonly supplyMutable: boolean;
+ public readonly restrictable: boolean;
+ public readonly duration: number;
+ public readonly height: number;
+ public readonly supply: number;
+ public metadataList: MetadataModel[] = [];
+
+ constructor(
+ public readonly addressRawPlain: string,
+ public readonly ownerRawPlain: string,
+ public readonly name: string | undefined,
+ public readonly isCurrencyMosaic: boolean,
+ public readonly balance: number | undefined,
+ mosaicInfo: MosaicInfo,
+ ) {
+ this.mosaicIdHex = mosaicInfo.id.toHex();
+ this.divisibility = mosaicInfo.divisibility;
+ this.transferable = mosaicInfo.isTransferable();
+ this.supplyMutable = mosaicInfo.isSupplyMutable();
+ this.restrictable = mosaicInfo.isRestrictable();
+ this.duration = mosaicInfo.duration.compact();
+ this.height = mosaicInfo.startHeight.compact();
+ this.supply = mosaicInfo.supply.compact();
+ }
+}
diff --git a/src/core/database/entities/NamespaceModel.ts b/src/core/database/entities/NamespaceModel.ts
new file mode 100644
index 0000000..58ec2c0
--- /dev/null
+++ b/src/core/database/entities/NamespaceModel.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NamespaceInfo } from 'symbol-sdk';
+import { MetadataModel } from './MetadataModel';
+
+/**
+ * Stored POJO that holds namespace information.
+ *
+ * The stored data is cached from rest.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be
+ * fined.
+ *
+ */
+export class NamespaceModel {
+ public readonly namespaceIdHex: string;
+ public readonly name: string;
+ public readonly isRoot: boolean;
+ public readonly ownerAddressRawPlain: string | undefined;
+ public readonly aliasType: number;
+ public readonly aliasTargetAddressRawPlain: string | undefined;
+ public readonly aliasTargetMosaicIdHex: string | undefined;
+ public readonly parentNamespaceIdHex: string | undefined;
+ public readonly startHeight: number;
+ public readonly endHeight: number;
+ public readonly depth: number;
+ public metadataList: MetadataModel[];
+
+ constructor(namespaceInfo: NamespaceInfo, name: string, metadataList: MetadataModel[] = []) {
+ this.namespaceIdHex = namespaceInfo.id.toHex();
+ this.name = name;
+ this.isRoot = namespaceInfo.isRoot();
+ this.aliasType = namespaceInfo.alias.type;
+ this.ownerAddressRawPlain = namespaceInfo.ownerAddress.plain();
+ this.aliasTargetAddressRawPlain =
+ (namespaceInfo.alias && namespaceInfo.alias.address && namespaceInfo.alias.address.plain()) || undefined;
+ this.aliasTargetMosaicIdHex =
+ (namespaceInfo.alias && namespaceInfo.alias.mosaicId && namespaceInfo.alias.mosaicId.toHex()) || undefined;
+ this.parentNamespaceIdHex = this.isRoot ? undefined : namespaceInfo.parentNamespaceId().toHex();
+ this.startHeight = namespaceInfo.startHeight.compact();
+ this.endHeight = namespaceInfo.endHeight.compact();
+ this.depth = namespaceInfo.depth;
+ this.metadataList = metadataList;
+ }
+}
diff --git a/src/core/database/entities/NetworkBasedModel.ts b/src/core/database/entities/NetworkBasedModel.ts
new file mode 100644
index 0000000..f7fbac3
--- /dev/null
+++ b/src/core/database/entities/NetworkBasedModel.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+/**
+ * A model that store some generic value based on the generation hash.
+ */
+export type NetworkBasedModel = Record>;
+
+export class NetworkBasedEntryModel {
+ public readonly timestamp = Date.now();
+
+ constructor(public readonly generationHash: string, public readonly data: E) {}
+}
diff --git a/src/core/database/entities/NetworkConfigurationModel.ts b/src/core/database/entities/NetworkConfigurationModel.ts
new file mode 100644
index 0000000..f8eea0e
--- /dev/null
+++ b/src/core/database/entities/NetworkConfigurationModel.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing software
+ * distributed under the License is distributed on an AS IS BASIS
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export class NetworkConfigurationModel {
+ public readonly epochAdjustment: number;
+ public readonly maxMosaicDivisibility: number;
+ public readonly namespaceGracePeriodDuration: number;
+ public readonly lockedFundsPerAggregate: string;
+ public readonly maxCosignatoriesPerAccount: number;
+ public readonly blockGenerationTargetTime: number;
+ public readonly maxNamespaceDepth: number;
+ public readonly maxMosaicDuration: number;
+ public readonly minNamespaceDuration: number;
+ public readonly maxNamespaceDuration: number;
+ public readonly maxTransactionsPerAggregate: number;
+ public readonly maxCosignedAccountsPerAccount: number;
+ public readonly maxMessageSize: number;
+ public readonly maxMosaicAtomicUnits: number;
+ public readonly currencyMosaicId: string;
+ public readonly harvestingMosaicId: string;
+ public readonly defaultDynamicFeeMultiplier: number;
+ public readonly totalChainImportance: number;
+}
diff --git a/src/core/database/entities/NetworkCurrenciesModel.ts b/src/core/database/entities/NetworkCurrenciesModel.ts
new file mode 100644
index 0000000..045943b
--- /dev/null
+++ b/src/core/database/entities/NetworkCurrenciesModel.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+
+export class NetworkCurrenciesModel {
+ constructor(public networkCurrency: NetworkCurrencyModel, public harvestCurrency: NetworkCurrencyModel) {}
+}
diff --git a/src/core/database/entities/NetworkCurrencyModel.ts b/src/core/database/entities/NetworkCurrencyModel.ts
new file mode 100644
index 0000000..eaa6f27
--- /dev/null
+++ b/src/core/database/entities/NetworkCurrencyModel.ts
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+/**
+ * Stored POJO that holds network currency information.
+ *
+ * The stored data is cached from rest.
+ *
+ */
+export class NetworkCurrencyModel {
+ constructor(
+ /**
+ * Mosaic id of this currency. This value is optional if the user only wants to provide the
+ * mosaic id. This value will be set if it's loaded by rest.
+ */
+ public readonly mosaicIdHex: string | undefined,
+ /**
+ * The Namespace id of this currency. This value is option if the user only wants to provide the
+ * namespace id. This value will be set if it's loaded by rest.
+ */
+ public readonly namespaceIdHex: string | undefined,
+ /**
+ * The Namespace id of this currency. This value is option if the user only wants to provide the
+ * namespace id. This value will be set if it's loaded by rest.
+ */
+ public readonly namespaceIdFullname: string | undefined,
+ /**
+ * Divisibility of this currency, required to create Mosaic from relative amounts.
+ */
+ public readonly divisibility: number,
+ /**
+ * Is this currency transferable.
+ */
+ public readonly transferable: boolean,
+ /**
+ * Is this currency supply mutable.
+ */
+ public readonly supplyMutable: boolean,
+ /**
+ * Is this currency restrictable.
+ */
+ public readonly restrictable: boolean,
+ /**
+ * The ticket name like XYM when namespace fullname is symbol.xym
+ */
+ public readonly ticker: string | undefined,
+ ) {}
+}
diff --git a/src/core/database/entities/NetworkModel.ts b/src/core/database/entities/NetworkModel.ts
new file mode 100644
index 0000000..f3acd6b
--- /dev/null
+++ b/src/core/database/entities/NetworkModel.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkType, NodeInfo, TransactionFees } from 'symbol-sdk';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+/**
+ * Stored POJO that holds network information.
+ *
+ * The stored data is cached from rest.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ *
+ */
+export class NetworkModel {
+ constructor(
+ public readonly url: string,
+ public readonly networkType: NetworkType,
+ public readonly networkName: string,
+ public readonly generationHash: string,
+ public readonly networkConfiguration: NetworkConfigurationModel,
+ public readonly transactionFees: TransactionFees,
+ public readonly nodeInfo: NodeInfo,
+ ) {}
+}
diff --git a/src/core/database/entities/NodeModel.ts b/src/core/database/entities/NodeModel.ts
new file mode 100644
index 0000000..54491a9
--- /dev/null
+++ b/src/core/database/entities/NodeModel.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkType } from 'symbol-sdk';
+
+/**
+ * Stored POJO that holds node information.
+ *
+ * The stored data is cached from rest.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ *
+ */
+export class NodeModel {
+ constructor(
+ public readonly url: string,
+ public readonly friendlyName: string,
+ public readonly isDefault: boolean,
+ public readonly networkType: NetworkType,
+ public readonly publicKey?: string,
+ public nodePublicKey?: string,
+ ) {}
+}
diff --git a/src/core/database/entities/ProfileModel.ts b/src/core/database/entities/ProfileModel.ts
new file mode 100644
index 0000000..9720e35
--- /dev/null
+++ b/src/core/database/entities/ProfileModel.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkType } from 'symbol-sdk';
+
+/**
+ * Stored POJO that holds profile information.
+ *
+ * The stored data is cached from rest.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ *
+ */
+export class ProfileModel {
+ public readonly profileName: string;
+ public readonly generationHash: string;
+ public readonly hint: string;
+ public readonly networkType: NetworkType;
+ public readonly password: string;
+ public readonly seed: string;
+ public readonly accounts: string[];
+ public readonly termsAndConditionsApproved: boolean;
+ public readonly selectedNodeUrlToConnect: string;
+}
diff --git a/src/core/database/entities/SettingsModel.ts b/src/core/database/entities/SettingsModel.ts
new file mode 100644
index 0000000..749764d
--- /dev/null
+++ b/src/core/database/entities/SettingsModel.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+/**
+ * POJO that stores user provided general application settings.
+ *
+ * The object is serialized and deserialized to/from JSON. no method or complex attributes can be fined.
+ */
+export class SettingsModel {
+ constructor(
+ public readonly profileName: string,
+ public readonly language: string,
+ public readonly defaultFee: number,
+ public readonly defaultAccount: string,
+ public readonly explorerUrl: string,
+ ) {}
+}
diff --git a/src/core/database/entities/VersionedModel.ts b/src/core/database/entities/VersionedModel.ts
new file mode 100644
index 0000000..bfdbd58
--- /dev/null
+++ b/src/core/database/entities/VersionedModel.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export class VersionedModel {
+ constructor(public readonly version: number, public readonly data: T) {}
+}
diff --git a/src/core/database/storage/AccountModelStorage.ts b/src/core/database/storage/AccountModelStorage.ts
new file mode 100644
index 0000000..190f947
--- /dev/null
+++ b/src/core/database/storage/AccountModelStorage.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+
+export class AccountModelStorage extends VersionedObjectStorage> {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new AccountModelStorage();
+
+ private constructor() {
+ super({
+ storageKey: 'accounts',
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for accounts',
+ migrate: () => undefined,
+ },
+ // {
+ // description: 'Update accounts for 0.9.6.3 network (address changes)',
+ // migrate: (from: any) => {
+ // // update all pre-0.9.6.x profiles
+ // const profiles = Object.keys(from);
+
+ // const modified: any = from;
+ // profiles.map((name: string) => {
+ // modified[name] = {
+ // ...modified[name],
+ // // re-generating address from public key (0.9.6.x changes in addresses format)
+ // address: Address.createFromPublicKey(modified[name].publicKey, modified[name].networkType).plain(),
+ // };
+ // });
+
+ // return modified;
+ // },
+ // },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/AddressBookModelStorage.ts b/src/core/database/storage/AddressBookModelStorage.ts
new file mode 100644
index 0000000..d073e09
--- /dev/null
+++ b/src/core/database/storage/AddressBookModelStorage.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+
+/**
+ * Stored cache for the known block infos.
+ */
+export class AddressBookModelStorage extends VersionedObjectStorage> {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new AddressBookModelStorage();
+
+ private constructor() {
+ super({
+ storageKey: 'addressBookPerProfile',
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for addressBookPerProfile',
+ migrate: () => undefined,
+ },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/BlockInfoModelStorage.ts b/src/core/database/storage/BlockInfoModelStorage.ts
new file mode 100644
index 0000000..0770bad
--- /dev/null
+++ b/src/core/database/storage/BlockInfoModelStorage.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedNetworkBasedObjectStorage } from '@/core/database/backends/VersionedNetworkBasedObjectStorage';
+import { BlockInfoModel } from '@/core/database/entities/BlockInfoModel';
+
+/**
+ * Stored cache for the known block infos.
+ */
+export class BlockInfoModelStorage extends VersionedNetworkBasedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new BlockInfoModelStorage();
+
+ private constructor() {
+ super('blockCache', [
+ {
+ description: 'dHealth Wallet Table Reset for blockCache',
+ migrate: () => undefined,
+ },
+ ]);
+ }
+}
diff --git a/src/core/database/storage/HarvestingModelStorage.ts b/src/core/database/storage/HarvestingModelStorage.ts
new file mode 100644
index 0000000..a19f229
--- /dev/null
+++ b/src/core/database/storage/HarvestingModelStorage.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '../backends/VersionedObjectStorage';
+import { HarvestingModel } from '../entities/HarvestingModel';
+
+export class HarvestingModelStorage extends VersionedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new HarvestingModelStorage();
+
+ private constructor() {
+ super({
+ storageKey: 'harvestingModels',
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for harvestingModels',
+ migrate: () => undefined,
+ },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/HashLockAggregatePairModelStorage.ts b/src/core/database/storage/HashLockAggregatePairModelStorage.ts
new file mode 100644
index 0000000..85f226d
--- /dev/null
+++ b/src/core/database/storage/HashLockAggregatePairModelStorage.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { HashLockAggregatePairModel } from '@/core/database/entities/HashLockAggregatePairModel';
+
+/**
+ * Stored cache for the known block infos.
+ */
+export class HashLockAggregatePairModelStorage extends VersionedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new HashLockAggregatePairModelStorage();
+
+ private constructor() {
+ super({
+ storageKey: 'hashLockAggregatePairs',
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for hashLockAggregatePairs',
+ migrate: () => undefined,
+ },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/MetadataModelStorage.ts b/src/core/database/storage/MetadataModelStorage.ts
new file mode 100644
index 0000000..4111b2a
--- /dev/null
+++ b/src/core/database/storage/MetadataModelStorage.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedNetworkBasedObjectStorage } from '@/core/database/backends/VersionedNetworkBasedObjectStorage';
+import { MetadataModel } from '@/core/database/entities/MetadataModel';
+
+export class MetadataModelStorage extends VersionedNetworkBasedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new MetadataModelStorage();
+
+ private constructor() {
+ super('metadataCache', [
+ {
+ description: 'dHealth Wallet Table Reset for metadataCache',
+ migrate: () => undefined,
+ },
+ ]);
+ }
+}
diff --git a/src/core/database/storage/MosaicConfigurationModelStorage.ts b/src/core/database/storage/MosaicConfigurationModelStorage.ts
new file mode 100644
index 0000000..8b1066d
--- /dev/null
+++ b/src/core/database/storage/MosaicConfigurationModelStorage.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { AccountMosaicConfigurationModel } from '@/core/database/entities/MosaicConfigurationModel';
+export class MosaicConfigurationModelStorage extends VersionedObjectStorage> {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new MosaicConfigurationModelStorage();
+
+ private constructor() {
+ super({
+ storageKey: 'mosaicConfiguration',
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for mosaicConfiguration',
+ migrate: () => undefined,
+ },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/MosaicModelStorage.ts b/src/core/database/storage/MosaicModelStorage.ts
new file mode 100644
index 0000000..f23a612
--- /dev/null
+++ b/src/core/database/storage/MosaicModelStorage.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedNetworkBasedObjectStorage } from '@/core/database/backends/VersionedNetworkBasedObjectStorage';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+
+export class MosaicModelStorage extends VersionedNetworkBasedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new MosaicModelStorage();
+
+ private constructor() {
+ super('mosaicCache', [
+ {
+ description: 'dHealth Wallet Table Reset for mosaicCache',
+ migrate: () => undefined,
+ },
+ ]);
+ }
+}
diff --git a/src/core/database/storage/NamespaceModelStorage.ts b/src/core/database/storage/NamespaceModelStorage.ts
new file mode 100644
index 0000000..7c514cb
--- /dev/null
+++ b/src/core/database/storage/NamespaceModelStorage.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedNetworkBasedObjectStorage } from '@/core/database/backends/VersionedNetworkBasedObjectStorage';
+import { NamespaceModel } from '@/core/database/entities/NamespaceModel';
+
+export class NamespaceModelStorage extends VersionedNetworkBasedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new NamespaceModelStorage();
+
+ private constructor() {
+ super('namespaceCache', [
+ {
+ description: 'dHealth Wallet Table Reset for namespaceCache',
+ migrate: () => undefined,
+ },
+ ]);
+ }
+}
diff --git a/src/core/database/storage/NetworkCurrenciesModelStorage.ts b/src/core/database/storage/NetworkCurrenciesModelStorage.ts
new file mode 100644
index 0000000..a36f05f
--- /dev/null
+++ b/src/core/database/storage/NetworkCurrenciesModelStorage.ts
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkCurrenciesModel } from '@/core/database/entities/NetworkCurrenciesModel';
+import { VersionedNetworkBasedObjectStorage } from '@/core/database/backends/VersionedNetworkBasedObjectStorage';
+
+export class NetworkCurrenciesModelStorage extends VersionedNetworkBasedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new NetworkCurrenciesModelStorage();
+
+ private constructor() {
+ super('networkCurrencyCache', [
+ {
+ description: 'dHealth Wallet Table Reset for networkCurrencyCache',
+ migrate: () => undefined,
+ },
+ // {
+ // description: 'Reset networkCurrencyCache for 0.9.6.3 network (id changes)',
+ // migrate: () => {
+ // const xymMosaic96x = new NetworkCurrencyModel(
+ // '5E62990DCAC5BE8A',
+ // 'E74B99BA41F4AFEE',
+ // 'symbol.xym',
+ // 6,
+ // true,
+ // false,
+ // false,
+ // 'XYM',
+ // );
+ // // reset table for new cache
+ // return new NetworkCurrenciesModel(xymMosaic96x, xymMosaic96x);
+ // },
+ // },
+ ]);
+ }
+}
diff --git a/src/core/database/storage/NetworkModelStorage.ts b/src/core/database/storage/NetworkModelStorage.ts
new file mode 100644
index 0000000..c978e0c
--- /dev/null
+++ b/src/core/database/storage/NetworkModelStorage.ts
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ * Copyright 2021-present [Using Blockchain Ltd](https://using-blockchain.org), All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { VersionedNetworkBasedObjectStorage } from '@/core/database/backends/VersionedNetworkBasedObjectStorage';
+import { NetworkModel } from '@/core/database/entities/NetworkModel';
+
+export class NetworkModelStorage extends VersionedNetworkBasedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new NetworkModelStorage();
+
+ private constructor() {
+ super('networkCache', [
+ {
+ description: 'dHealth Wallet Table Reset for networkCache',
+ migrate: () => undefined,
+ },
+ ]);
+ }
+}
diff --git a/src/core/database/storage/NodeModelStorage.ts b/src/core/database/storage/NodeModelStorage.ts
new file mode 100644
index 0000000..cdc3184
--- /dev/null
+++ b/src/core/database/storage/NodeModelStorage.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+import { SimpleObjectStorage } from '@/core/database/backends/SimpleObjectStorage';
+import { VersionedModel } from '@/core/database/entities/VersionedModel';
+
+export class NodeModelStorage extends VersionedObjectStorage {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new NodeModelStorage();
+
+ public constructor(delegate = new SimpleObjectStorage>('node')) {
+ super({
+ delegate: delegate,
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for node',
+ migrate: () => undefined,
+ },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/ProfileModelStorage.ts b/src/core/database/storage/ProfileModelStorage.ts
new file mode 100644
index 0000000..52e72ca
--- /dev/null
+++ b/src/core/database/storage/ProfileModelStorage.ts
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { SimpleObjectStorage } from '@/core/database/backends/SimpleObjectStorage';
+import { VersionedModel } from '@/core/database/entities/VersionedModel';
+
+export class ProfileModelStorage extends VersionedObjectStorage> {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new ProfileModelStorage();
+
+ public constructor(delegate = new SimpleObjectStorage>>('profiles')) {
+ super({
+ delegate: delegate,
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for profiles',
+ migrate: () => undefined,
+ },
+ // {
+ // description: 'Update profiles for 0.9.6.3 network (generation hash)',
+ // migrate: (from: any) => {
+ // // update all pre-0.9.6.x profiles
+ // const profiles = Object.keys(from);
+
+ // const modified: any = from;
+ // profiles.map((name: string) => {
+ // modified[name] = {
+ // ...modified[name],
+ // generationHash: '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B',
+ // };
+ // });
+
+ // return modified;
+ // },
+ // },
+ ],
+ });
+ }
+}
diff --git a/src/core/database/storage/SettingsModelStorage.ts b/src/core/database/storage/SettingsModelStorage.ts
new file mode 100644
index 0000000..be18896
--- /dev/null
+++ b/src/core/database/storage/SettingsModelStorage.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { VersionedObjectStorage } from '@/core/database/backends/VersionedObjectStorage';
+import { SettingsModel } from '@/core/database/entities/SettingsModel';
+
+export class SettingsModelStorage extends VersionedObjectStorage> {
+ /**
+ * Singleton instance as we want to run the migration just once
+ */
+ public static INSTANCE = new SettingsModelStorage();
+
+ private constructor() {
+ super({
+ storageKey: 'settings',
+ migrations: [
+ {
+ description: 'dHealth Wallet Table Reset for settings',
+ migrate: () => undefined,
+ },
+ // {
+ // description: 'Update settings for 0.9.6.3 network (address changes)',
+ // migrate: (from: any) => {
+ // // update all pre-0.9.6.x settings
+ // const profiles = Object.keys(from);
+
+ // const modified: any = from;
+ // profiles.map((name: string) => {
+ // modified[name] = {
+ // ...modified[name],
+ // explorerUrl: networkConfig[NetworkType.TEST_NET].explorerUrl,
+ // };
+ // });
+
+ // return modified;
+ // },
+ // },
+ ],
+ });
+ }
+}
diff --git a/src/core/transactions/BroadcastResult.ts b/src/core/transactions/BroadcastResult.ts
new file mode 100644
index 0000000..4437f39
--- /dev/null
+++ b/src/core/transactions/BroadcastResult.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { CosignatureSignedTransaction, SignedTransaction, Transaction } from 'symbol-sdk';
+
+export class BroadcastResult {
+ /**
+ * Create a transaction broadcast result instance
+ *
+ * @param {SignedTransaction} transaction
+ * @param {boolean} success
+ * @param {string} error
+ */
+ constructor(
+ /**
+ * The transaction that was announced
+ * @var {SignedTransaction}
+ */
+ public readonly signedTransaction: SignedTransaction | CosignatureSignedTransaction,
+
+ /**
+ * The transaction that returned.
+ * @var {SignedTransaction}
+ */
+ public readonly transaction: Transaction | undefined,
+ /**
+ * Whether broadcasting was successfull
+ * @var {boolean}
+ **/
+ public readonly success: boolean,
+ /**
+ * Error message (optional)
+ * @var {string}
+ **/
+ public readonly error?: string,
+ ) {}
+}
diff --git a/src/core/transactions/TransactionDetailItem.ts b/src/core/transactions/TransactionDetailItem.ts
new file mode 100644
index 0000000..955e3f0
--- /dev/null
+++ b/src/core/transactions/TransactionDetailItem.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export interface TransactionDetailItem {
+ readonly key: string;
+ readonly value: any;
+ readonly isMosaic?: boolean;
+ readonly isAddress?: boolean;
+ readonly isPaidFee?: boolean;
+ readonly isMessage?: boolean;
+}
diff --git a/src/core/transactions/TransactionStatus.ts b/src/core/transactions/TransactionStatus.ts
new file mode 100644
index 0000000..709a389
--- /dev/null
+++ b/src/core/transactions/TransactionStatus.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export enum TransactionStatus {
+ confirmed = 'confirmed',
+ unconfirmed = 'unconfirmed',
+ partial = 'partial',
+}
diff --git a/src/core/transactions/TransactionView.ts b/src/core/transactions/TransactionView.ts
new file mode 100644
index 0000000..731a770
--- /dev/null
+++ b/src/core/transactions/TransactionView.ts
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Store } from 'vuex';
+import { AggregateTransactionInfo, Transaction, TransactionInfo } from 'symbol-sdk';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import i18n from '@/language';
+import { TransactionStatus } from '@/core/transactions/TransactionStatus';
+import { NetworkConfigurationModel } from '../database/entities/NetworkConfigurationModel';
+
+export abstract class TransactionView {
+ /**
+ * Vuex store instance
+ * @var {Store}
+ */
+ protected readonly $store: Store;
+
+ /**
+ * The transaction header info
+ * @var {TransactionInfo}
+ */
+ public readonly info: TransactionInfo | AggregateTransactionInfo | undefined;
+
+ /**
+ * The transaction body
+ * @var {Transaction}
+ */
+ public readonly transaction: T;
+
+ /**
+ * The header items for the view.
+ */
+ public readonly headerItems: TransactionDetailItem[];
+
+ /**
+ * The the details items for the view.
+ */
+ public readonly detailItems: TransactionDetailItem[];
+
+ /**
+ * Catapult-server nemesis block generation epoch adjustment
+ */
+ public readonly epochAdjustment: number;
+
+ /**
+ * Construct a transaction view around \a store
+ * @param {Store} store
+ */
+ public constructor(store: Store, transaction: T) {
+ this.$store = store;
+ this.epochAdjustment = (this.$store.getters['network/networkConfiguration'] as NetworkConfigurationModel).epochAdjustment;
+ this.transaction = transaction;
+ this.info = transaction.transactionInfo || undefined;
+ this.headerItems = this.resolveHeaderItems();
+ this.detailItems = this.resolveDetailItems();
+ }
+
+ /**
+ * Is the transaction incoming?
+ */
+ public get isIncoming(): boolean {
+ return false;
+ }
+
+ /**
+ * Returns the status of the transaction
+ * @param transaction the transaction.
+ */
+ public static getTransactionStatus(transaction: Transaction): TransactionStatus {
+ if (transaction.isConfirmed()) {
+ return TransactionStatus.confirmed;
+ } else {
+ return TransactionView.isPartial(transaction) ? TransactionStatus.partial : TransactionStatus.unconfirmed;
+ }
+ }
+
+ /**
+ * @description: transaction.transactionInfo.merkleComponentHash==='00000...' -> status of this transaction is Partial
+ * @param {Transaction}
+ * @return: boolean
+ */
+
+ public static isPartial(transaction: Transaction): boolean {
+ return (
+ transaction.transactionInfo &&
+ transaction.transactionInfo.merkleComponentHash &&
+ parseInt(transaction.transactionInfo.merkleComponentHash) === 0
+ );
+ }
+ /**
+ * It returns a list that that it easy to render when displaying TransactionDetailRow components.
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [];
+ }
+ /**
+ * Displayed items
+ * @see {Store.Mosaic}
+ * @type {({ key: string, value: string | boolean, | Mosaic }[])}
+ */
+ protected resolveHeaderItems(): TransactionDetailItem[] {
+ return [
+ {
+ key: 'transaction_type',
+ value: `${i18n.t(`transaction_descriptor_${this.transaction.type}`)}`,
+ },
+ {
+ key: 'status',
+ value: i18n.t(`transaction_status_${TransactionView.getTransactionStatus(this.transaction)}`),
+ },
+ {
+ key: 'hash',
+ value: (this.info && this.info.hash) || undefined,
+ },
+ this.getFeeDetailItem(),
+ {
+ key: 'block_height',
+ value: this.info && this.info.height && this.info.height.compact() ? this.info.height.compact().toString() : undefined,
+ },
+ {
+ key: 'deadline',
+ value: `${this.transaction.deadline
+ .toLocalDateTime(this.epochAdjustment)
+ .toLocalDate()} ${this.transaction.deadline.toLocalDateTime(this.epochAdjustment).toLocalTime()}`,
+ },
+ {
+ key: 'signature',
+ value: this.transaction.signature,
+ },
+ {
+ key: 'signer_public_key',
+ value: (this.transaction.signer && this.transaction.signer.publicKey) || undefined,
+ },
+ ].filter((pair) => pair.value);
+ }
+
+ protected getFeeDetailItem(): TransactionDetailItem {
+ if (this.transaction.isConfirmed()) {
+ return {
+ key: 'paid_fee',
+ value: this.transaction,
+ isPaidFee: true,
+ };
+ } else {
+ return {
+ key: 'max_fee',
+ value: {
+ amount: this.transaction.maxFee.compact() || 0,
+ color: 'red',
+ },
+ isMosaic: true,
+ };
+ }
+ }
+}
diff --git a/src/core/transactions/TransactionViewFactory.ts b/src/core/transactions/TransactionViewFactory.ts
new file mode 100644
index 0000000..635cdef
--- /dev/null
+++ b/src/core/transactions/TransactionViewFactory.ts
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import {
+ AddressAliasTransaction,
+ HashLockTransaction,
+ MosaicAliasTransaction,
+ MosaicDefinitionTransaction,
+ MosaicSupplyChangeTransaction,
+ MultisigAccountModificationTransaction,
+ NamespaceRegistrationTransaction,
+ Transaction,
+ TransactionType,
+ TransferTransaction,
+ AccountKeyLinkTransaction,
+ VotingKeyLinkTransaction,
+ VrfKeyLinkTransaction,
+ NodeKeyLinkTransaction,
+ AccountMetadataTransaction,
+ MosaicMetadataTransaction,
+ NamespaceMetadataTransaction,
+ AccountAddressRestrictionTransaction,
+ AccountMosaicRestrictionTransaction,
+ AccountOperationRestrictionTransaction,
+} from 'symbol-sdk';
+import { ViewUnknownTransaction } from '@/core/transactions/ViewUnknownTransaction';
+import { ViewHashLockTransaction } from '@/core/transactions/ViewHashLockTransaction';
+import { ViewMultisigAccountModificationTransaction } from '@/core/transactions/ViewMultisigAccountModificationTransaction';
+import { ViewMosaicDefinitionTransaction } from '@/core/transactions/ViewMosaicDefinitionTransaction';
+import { ViewMosaicSupplyChangeTransaction } from '@/core/transactions/ViewMosaicSupplyChangeTransaction';
+import { ViewNamespaceRegistrationTransaction } from '@/core/transactions/ViewNamespaceRegistrationTransaction';
+import { ViewTransferTransaction } from '@/core/transactions/ViewTransferTransaction';
+import { ViewAliasTransaction } from '@/core/transactions/ViewAliasTransaction';
+import { ViewAccountKeyLinkTransaction } from '@/core/transactions/ViewAccountKeyLinkTransaction';
+import { Store } from 'vuex';
+import { TransactionView } from '@/core/transactions/TransactionView';
+import { ViewVotingKeyLinkTransaction } from '@/core/transactions/ViewVotingKeyLinkTransaction';
+import { ViewVrfKeyLinkTransaction } from '@/core/transactions/ViewVrfKeyLinkTransaction';
+import { ViewNodeKeyLinkTransaction } from './ViewNodeKeyLinkTransaction';
+import { ViewAccountMetadataTransaction } from '@/core/transactions/ViewAccountMetadataTransaction';
+import { ViewNamespaceMetadataTransaction } from '@/core/transactions/ViewNamespaceMetadataTransaction';
+import { ViewMosaicMetadataTransaction } from '@/core/transactions/ViewMosaicMetadataTransaction';
+import { ViewAccountAddressRestrictionTransaction } from './ViewAccountAddressRestrictionTransaction';
+import { ViewAccountMosaicRestrictionTransaction } from './ViewAccountMosaicRestrictionTransaction';
+import { ViewAccountOperationRestrictionTransaction } from './ViewAccountOperationRestrictionTransaction';
+
+/**
+ * Transaction view factory.
+ */
+export class TransactionViewFactory {
+ /**
+ * It creates the view for the given transaction.
+ *
+ * @param $store the vue store.
+ * @param transaction the transaction.
+ */
+ public static getView($store: Store, transaction: Transaction): TransactionView {
+ switch (transaction.type) {
+ /// region XXX views for transaction types not yet implemented
+ case TransactionType.AGGREGATE_BONDED:
+ case TransactionType.AGGREGATE_COMPLETE:
+ case TransactionType.MOSAIC_ADDRESS_RESTRICTION:
+ case TransactionType.MOSAIC_GLOBAL_RESTRICTION:
+ case TransactionType.SECRET_LOCK:
+ case TransactionType.SECRET_PROOF:
+ return new ViewUnknownTransaction($store, transaction);
+ /// end-region XXX views for transaction types not yet implemented
+ case TransactionType.ACCOUNT_ADDRESS_RESTRICTION:
+ return new ViewAccountAddressRestrictionTransaction($store, transaction as AccountAddressRestrictionTransaction);
+ case TransactionType.ACCOUNT_MOSAIC_RESTRICTION:
+ return new ViewAccountMosaicRestrictionTransaction($store, transaction as AccountMosaicRestrictionTransaction);
+ case TransactionType.ACCOUNT_OPERATION_RESTRICTION:
+ return new ViewAccountOperationRestrictionTransaction($store, transaction as AccountOperationRestrictionTransaction);
+ case TransactionType.ACCOUNT_METADATA:
+ return new ViewAccountMetadataTransaction($store, transaction as AccountMetadataTransaction);
+ case TransactionType.MOSAIC_METADATA:
+ return new ViewMosaicMetadataTransaction($store, transaction as MosaicMetadataTransaction);
+ case TransactionType.NAMESPACE_METADATA:
+ return new ViewNamespaceMetadataTransaction($store, transaction as NamespaceMetadataTransaction);
+ case TransactionType.HASH_LOCK:
+ return new ViewHashLockTransaction($store, transaction as HashLockTransaction);
+ case TransactionType.MULTISIG_ACCOUNT_MODIFICATION:
+ return new ViewMultisigAccountModificationTransaction($store, transaction as MultisigAccountModificationTransaction);
+ case TransactionType.VRF_KEY_LINK:
+ return new ViewVrfKeyLinkTransaction($store, transaction as VrfKeyLinkTransaction);
+ case TransactionType.NODE_KEY_LINK:
+ return new ViewNodeKeyLinkTransaction($store, transaction as NodeKeyLinkTransaction);
+ case TransactionType.VOTING_KEY_LINK:
+ return new ViewVotingKeyLinkTransaction($store, transaction as VotingKeyLinkTransaction);
+ case TransactionType.MOSAIC_DEFINITION:
+ return new ViewMosaicDefinitionTransaction($store, transaction as MosaicDefinitionTransaction);
+ case TransactionType.MOSAIC_SUPPLY_CHANGE:
+ return new ViewMosaicSupplyChangeTransaction($store, transaction as MosaicSupplyChangeTransaction);
+ case TransactionType.NAMESPACE_REGISTRATION:
+ return new ViewNamespaceRegistrationTransaction($store, transaction as NamespaceRegistrationTransaction);
+ case TransactionType.TRANSFER:
+ return new ViewTransferTransaction($store, transaction as TransferTransaction);
+ case TransactionType.MOSAIC_ALIAS:
+ return new ViewAliasTransaction($store, transaction as MosaicAliasTransaction);
+ case TransactionType.ADDRESS_ALIAS:
+ return new ViewAliasTransaction($store, transaction as AddressAliasTransaction);
+ case TransactionType.ACCOUNT_KEY_LINK:
+ return new ViewAccountKeyLinkTransaction($store, transaction as AccountKeyLinkTransaction);
+ default:
+ throw new Error(`View not implemented for transaction type '${transaction.type}'`);
+ }
+ }
+}
diff --git a/src/core/transactions/ViewAccountAddressRestrictionTransaction.ts b/src/core/transactions/ViewAccountAddressRestrictionTransaction.ts
new file mode 100644
index 0000000..701136d
--- /dev/null
+++ b/src/core/transactions/ViewAccountAddressRestrictionTransaction.ts
@@ -0,0 +1,55 @@
+/**
+ *
+ * Copyright 2020 for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { AccountAddressRestrictionTransaction, Address, AddressRestrictionFlag } from 'symbol-sdk';
+
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+
+export class ViewAccountAddressRestrictionTransaction extends TransactionView {
+ /**
+ * Displayed sender
+ * @var {string}
+ */
+ private get sender(): string {
+ if (this.transaction.signer) {
+ return this.transaction.signer.address.pretty();
+ }
+ const currentSignerAddress = this.$store.getters['account/currentSignerAddress'];
+ return currentSignerAddress ? currentSignerAddress.pretty() : '';
+ }
+
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ { key: 'sender', value: this.sender },
+ // @ts-ignore
+ {
+ key: 'Restriction Additions',
+ value: this.transaction.restrictionAdditions.map((a) => (a instanceof Address ? a.pretty() : a.fullName)).join('\n') || '-',
+ },
+ {
+ key: 'Restriction Deletions',
+ value: this.transaction.restrictionDeletions.map((a) => (a instanceof Address ? a.pretty() : a.fullName)).join('\n') || '-',
+ },
+ { key: 'Restriction Flag', value: AddressRestrictionFlag[this.transaction.restrictionFlags] },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewAccountKeyLinkTransaction.ts b/src/core/transactions/ViewAccountKeyLinkTransaction.ts
new file mode 100644
index 0000000..c263195
--- /dev/null
+++ b/src/core/transactions/ViewAccountKeyLinkTransaction.ts
@@ -0,0 +1,36 @@
+/**
+ *
+ * Copyright 2020 Grégory Saive for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { AccountKeyLinkTransaction, LinkAction } from 'symbol-sdk';
+
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import i18n from '@/language';
+
+// eslint-disable-next-line max-len
+export class ViewAccountKeyLinkTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ { key: 'link_action', value: this.transaction.linkAction == LinkAction.Link ? i18n.t('link') : i18n.t('unlink') },
+ { key: 'linked_account_public_key', value: this.transaction.linkedPublicKey },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewAccountMetadataTransaction.ts b/src/core/transactions/ViewAccountMetadataTransaction.ts
new file mode 100644
index 0000000..0bbba48
--- /dev/null
+++ b/src/core/transactions/ViewAccountMetadataTransaction.ts
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2020 for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { AccountMetadataTransaction } from 'symbol-sdk';
+
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { Formatters } from '../utils/Formatters';
+
+// eslint-disable-next-line max-len
+export class ViewAccountMetadataTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const metadataValue = Formatters.hexToUtf8(this.transaction.value);
+ return [
+ { key: 'sender', value: this.transaction.signer.address.pretty() },
+ // @ts-ignore
+ { key: 'target', value: this.transaction.targetAddress.pretty() },
+ { key: 'scopedMetadataKey', value: this.transaction.scopedMetadataKey.toHex() },
+ { key: 'value', value: metadataValue },
+ { key: 'valueSizeDelta', value: this.transaction.valueSizeDelta },
+ { key: 'scopedMetadataKey', value: this.transaction.scopedMetadataKey.toString() },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewAccountMosaicRestrictionTransaction.ts b/src/core/transactions/ViewAccountMosaicRestrictionTransaction.ts
new file mode 100644
index 0000000..73958c0
--- /dev/null
+++ b/src/core/transactions/ViewAccountMosaicRestrictionTransaction.ts
@@ -0,0 +1,54 @@
+/**
+ *
+ * Copyright 2020 for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { AccountMosaicRestrictionTransaction, MosaicId, MosaicRestrictionFlag } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+
+export class ViewAccountMosaicRestrictionTransaction extends TransactionView {
+ /**
+ * Displayed sender
+ * @var {string}
+ */
+ private get sender(): string {
+ if (this.transaction.signer) {
+ return this.transaction.signer.address.pretty();
+ }
+ const currentSignerAddress = this.$store.getters['account/currentSignerAddress'];
+ return currentSignerAddress ? currentSignerAddress.pretty() : '';
+ }
+
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ { key: 'sender', value: this.sender },
+ // @ts-ignore
+ {
+ key: 'Restriction Additions',
+ value: this.transaction.restrictionAdditions.map((a) => (a instanceof MosaicId ? a.toHex() : a.fullName)).join('\n') || '-',
+ },
+ {
+ key: 'Restriction Deletions',
+ value: this.transaction.restrictionDeletions.map((a) => (a instanceof MosaicId ? a.toHex() : a.fullName)).join('\n') || '-',
+ },
+ { key: 'Restriction Flag', value: MosaicRestrictionFlag[this.transaction.restrictionFlags] },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewAccountOperationRestrictionTransaction.ts b/src/core/transactions/ViewAccountOperationRestrictionTransaction.ts
new file mode 100644
index 0000000..99ced3c
--- /dev/null
+++ b/src/core/transactions/ViewAccountOperationRestrictionTransaction.ts
@@ -0,0 +1,55 @@
+/**
+ *
+ * Copyright 2020 for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import i18n from '@/language';
+import { AccountOperationRestrictionTransaction, OperationRestrictionFlag } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+
+export class ViewAccountOperationRestrictionTransaction extends TransactionView {
+ /**
+ * Displayed sender
+ * @var {string}
+ */
+ private get sender(): string {
+ if (this.transaction.signer) {
+ return this.transaction.signer.address.pretty();
+ }
+ const currentSignerAddress = this.$store.getters['account/currentSignerAddress'];
+ return currentSignerAddress ? currentSignerAddress.pretty() : '';
+ }
+
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ { key: 'sender', value: this.sender },
+ // @ts-ignore
+ {
+ key: 'Restriction Additions',
+ value: this.transaction.restrictionAdditions.map((tt) => i18n.t(`transaction_descriptor_${tt}`)).join('\n') || '-',
+ },
+ {
+ key: 'Restriction Deletions',
+ value: this.transaction.restrictionDeletions.map((tt) => i18n.t(`transaction_descriptor_${tt}`)).join('\n') || '-',
+ },
+ { key: 'Restriction Flag', value: OperationRestrictionFlag[this.transaction.restrictionFlags] },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewAliasTransaction.ts b/src/core/transactions/ViewAliasTransaction.ts
new file mode 100644
index 0000000..be801b0
--- /dev/null
+++ b/src/core/transactions/ViewAliasTransaction.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address, AddressAliasTransaction, AliasAction, MosaicAliasTransaction, MosaicId, NamespaceId } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+
+/// end-region custom types
+
+export class ViewAliasTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const transaction = this.transaction;
+ const namespaceId: NamespaceId = transaction.namespaceId;
+ let aliasTarget: Address | MosaicId;
+ if (transaction instanceof AddressAliasTransaction) {
+ aliasTarget = transaction.address;
+ }
+ if (transaction instanceof MosaicAliasTransaction) {
+ aliasTarget = transaction.mosaicId;
+ }
+ const displayName = namespaceId.fullName ? `${namespaceId.fullName} (${namespaceId.toHex()})` : namespaceId.toHex();
+ const targetKey = aliasTarget instanceof Address ? 'address' : 'mosaic';
+ const targetValue = aliasTarget instanceof Address ? aliasTarget.pretty() : aliasTarget.toHex();
+ const aliasAction = this.transaction.aliasAction;
+ return [
+ { key: 'namespace', value: displayName },
+ {
+ key: 'action',
+ value: aliasAction === AliasAction.Link ? 'Link' : 'Unlink',
+ },
+ { key: targetKey, value: targetValue },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewHashLockTransaction.ts b/src/core/transactions/ViewHashLockTransaction.ts
new file mode 100644
index 0000000..a19fc49
--- /dev/null
+++ b/src/core/transactions/ViewHashLockTransaction.ts
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { HashLockTransaction } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { AttachedMosaic } from '@/services/MosaicService';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+
+// eslint-disable-next-line max-len
+export class ViewHashLockTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const attachedMosaic: AttachedMosaic = {
+ id: this.transaction.mosaic.id,
+ mosaicHex: this.transaction.mosaic.id.toHex(),
+ amount: this.transaction.mosaic.amount.compact(),
+ };
+ return [
+ {
+ key: `locked_mosaic`,
+ value: attachedMosaic,
+ isMosaic: true,
+ },
+ { key: 'duration', value: this.transaction.duration.compact() },
+ {
+ key: 'inner_transaction_hash',
+ value: this.transaction.hash,
+ },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewMosaicDefinitionTransaction.ts b/src/core/transactions/ViewMosaicDefinitionTransaction.ts
new file mode 100644
index 0000000..f67b9bf
--- /dev/null
+++ b/src/core/transactions/ViewMosaicDefinitionTransaction.ts
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { MosaicDefinitionTransaction, MosaicFlags, MosaicId } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+
+export class ViewMosaicDefinitionTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const mosaicId: MosaicId = this.transaction.mosaicId;
+ const divisibility: number = this.transaction.divisibility;
+ const mosaicFlags: MosaicFlags = this.transaction.flags;
+ const duration = this.transaction.duration.toString();
+ const networkConfiguration: NetworkConfigurationModel = this.$store.getters['network/networkConfiguration'];
+ const blockGenerationTargetTime = networkConfiguration.blockGenerationTargetTime;
+ return [
+ { key: 'mosaic_id', value: mosaicId.toHex() },
+ {
+ key: 'table_header_divisibility',
+ value: `${divisibility}`,
+ },
+ {
+ key: 'duration',
+ value: duration === '0' ? 'unlimited' : TimeHelpers.durationToRelativeTime(parseInt(duration), blockGenerationTargetTime),
+ },
+ {
+ key: 'table_header_transferable',
+ value: mosaicFlags.transferable,
+ },
+ {
+ key: 'table_header_supply_mutable',
+ value: mosaicFlags.supplyMutable,
+ },
+ {
+ key: 'table_header_restrictable',
+ value: mosaicFlags.restrictable,
+ },
+ {
+ key: 'estimated_rental_fee',
+ value: {
+ amount: this.$store.getters['network/rentalFeeEstimation'].effectiveMosaicRentalFee.compact(),
+ color: 'red',
+ },
+ isMosaic: true,
+ },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewMosaicMetadataTransaction.ts b/src/core/transactions/ViewMosaicMetadataTransaction.ts
new file mode 100644
index 0000000..16c565c
--- /dev/null
+++ b/src/core/transactions/ViewMosaicMetadataTransaction.ts
@@ -0,0 +1,42 @@
+/**
+ *
+ * Copyright 2020 for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { MosaicMetadataTransaction } from 'symbol-sdk';
+
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { Formatters } from '../utils/Formatters';
+
+// eslint-disable-next-line max-len
+export class ViewMosaicMetadataTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const metadataValue = Formatters.hexToUtf8(this.transaction.value);
+ return [
+ { key: 'sender', value: this.transaction.signer.address.pretty() },
+ // @ts-ignore
+ { key: 'target', value: this.transaction.targetAddress.pretty() },
+ { key: 'mosaic', value: this.transaction.targetMosaicId.toHex() },
+ { key: 'scopedMetadataKey', value: this.transaction.scopedMetadataKey.toHex() },
+ { key: 'value', value: metadataValue },
+ { key: 'valueSizeDelta', value: this.transaction.valueSizeDelta },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewMosaicSupplyChangeTransaction.ts b/src/core/transactions/ViewMosaicSupplyChangeTransaction.ts
new file mode 100644
index 0000000..e71d9bf
--- /dev/null
+++ b/src/core/transactions/ViewMosaicSupplyChangeTransaction.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { MosaicSupplyChangeAction, MosaicSupplyChangeTransaction } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import i18n from '@/language';
+
+export class ViewMosaicSupplyChangeTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const mosaicId = this.transaction.mosaicId;
+ const action = this.transaction.action;
+ const delta = this.transaction.delta;
+
+ return [
+ { key: 'mosaic_id', value: mosaicId.toHex() },
+ {
+ key: 'direction',
+ value: `${i18n.t(action === MosaicSupplyChangeAction.Increase ? 'Increase' : 'Decrease')}`,
+ },
+ {
+ key: 'delta',
+ value: delta.compact().toLocaleString(),
+ },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewMultisigAccountModificationTransaction.ts b/src/core/transactions/ViewMultisigAccountModificationTransaction.ts
new file mode 100644
index 0000000..9328d3e
--- /dev/null
+++ b/src/core/transactions/ViewMultisigAccountModificationTransaction.ts
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Address, MultisigAccountModificationTransaction } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import i18n from '@/language';
+
+// eslint-disable-next-line max-len
+export class ViewMultisigAccountModificationTransaction extends TransactionView {
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ // get data from view values
+ const minApprovalDelta = this.transaction.minApprovalDelta;
+ const minRemovalDelta = this.transaction.minRemovalDelta;
+ const addressAdditions = this.transaction.addressAdditions;
+ const addressDeletions = this.transaction.addressDeletions;
+
+ // push approval and removal deltas to view items
+ const items = [
+ { key: 'minApprovalDelta', value: `${minApprovalDelta}` },
+ { key: 'minRemovalDelta', value: `${minRemovalDelta}` },
+ ];
+
+ // render views for public key additions and deletions
+ const additions = addressAdditions.map((address, index, self) => {
+ return {
+ key: `${i18n.t('public_key_addition')} (${index + 1}/${self.length})`,
+ value: (address as Address).pretty(),
+ };
+ });
+
+ const deletions = addressDeletions.map((address, index, self) => {
+ return {
+ key: `${i18n.t('public_key_deletion')} (${index + 1}/${self.length})`,
+ value: (address as Address).pretty(),
+ };
+ });
+
+ return [...items, ...additions, ...deletions];
+ }
+}
diff --git a/src/core/transactions/ViewNamespaceMetadataTransaction.ts b/src/core/transactions/ViewNamespaceMetadataTransaction.ts
new file mode 100644
index 0000000..47d3b4a
--- /dev/null
+++ b/src/core/transactions/ViewNamespaceMetadataTransaction.ts
@@ -0,0 +1,41 @@
+/**
+ *
+ * Copyright 2020 for NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { NamespaceMetadataTransaction } from 'symbol-sdk';
+
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { Formatters } from '../utils/Formatters';
+// eslint-disable-next-line max-len
+export class ViewNamespaceMetadataTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const metadataValue = Formatters.hexToUtf8(this.transaction.value);
+ return [
+ { key: 'sender', value: this.transaction.signer.address.pretty() },
+ // @ts-ignore
+ { key: 'target', value: this.transaction.targetAddress.pretty() },
+ { key: 'namespace', value: this.transaction.targetNamespaceId.toHex() },
+ { key: 'scopedMetadataKey', value: this.transaction.scopedMetadataKey.toHex() },
+ { key: 'value', value: metadataValue },
+ { key: 'valueSizeDelta', value: this.transaction.valueSizeDelta },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewNamespaceRegistrationTransaction.ts b/src/core/transactions/ViewNamespaceRegistrationTransaction.ts
new file mode 100644
index 0000000..b1e03e3
--- /dev/null
+++ b/src/core/transactions/ViewNamespaceRegistrationTransaction.ts
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NamespaceRegistrationTransaction, NamespaceRegistrationType } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { NamespaceModel } from '@/core/database/entities/NamespaceModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+
+export class ViewNamespaceRegistrationTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const transaction = this.transaction;
+ let rootNamespaceName: string;
+ let subNamespaceName: string;
+ if (NamespaceRegistrationType.RootNamespace === transaction.registrationType) {
+ rootNamespaceName = transaction.namespaceName;
+ } else {
+ subNamespaceName = transaction.namespaceName;
+ // - try to identify root namespace by id
+ const parentId = transaction.parentId;
+ const namespaces: NamespaceModel[] = this.$store.getters['namespace/ownedNamespaces'];
+ const parent = namespaces.find((n) => n.namespaceIdHex === parentId.toHex() && n.name);
+ if (parent) {
+ rootNamespaceName = parent.name;
+ }
+ }
+ const registrationType = transaction.registrationType;
+ const duration = transaction.duration;
+ const networkConfiguration: NetworkConfigurationModel = this.$store.getters['network/networkConfiguration'];
+ const blockGenerationTargetTime = networkConfiguration.blockGenerationTargetTime;
+ if (registrationType === NamespaceRegistrationType.RootNamespace) {
+ return [
+ { key: 'namespace_name', value: rootNamespaceName },
+ {
+ key: 'duration',
+ value: TimeHelpers.durationToRelativeTime(parseInt(duration.toString()), blockGenerationTargetTime),
+ },
+ {
+ key: 'estimated_rental_fee',
+ value: {
+ amount:
+ this.$store.getters['network/rentalFeeEstimation'].effectiveRootNamespaceRentalFeePerBlock.compact() *
+ this.transaction['duration'].compact(),
+ color: 'red',
+ },
+ isMosaic: true,
+ },
+ ];
+ }
+
+ return [
+ { key: 'namespace_name', value: subNamespaceName },
+ {
+ key: 'parent_namespace',
+ value: rootNamespaceName,
+ },
+ {
+ key: 'estimated_rental_fee',
+ value: {
+ amount: this.$store.getters['network/rentalFeeEstimation'].effectiveChildNamespaceRentalFee.compact(),
+ color: 'red',
+ },
+ isMosaic: true,
+ },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewNodeKeyLinkTransaction.ts b/src/core/transactions/ViewNodeKeyLinkTransaction.ts
new file mode 100644
index 0000000..a6a4276
--- /dev/null
+++ b/src/core/transactions/ViewNodeKeyLinkTransaction.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020-present NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { LinkAction, NodeKeyLinkTransaction } from 'symbol-sdk';
+import { TransactionView } from './TransactionView';
+import i18n from '@/language';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+
+export class ViewNodeKeyLinkTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ { key: 'link_action', value: this.transaction.linkAction == LinkAction.Link ? i18n.t('link') : i18n.t('unlink') },
+ { key: 'linked_node_public_key', value: this.transaction.linkedPublicKey },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewTransferTransaction.ts b/src/core/transactions/ViewTransferTransaction.ts
new file mode 100644
index 0000000..4d93029
--- /dev/null
+++ b/src/core/transactions/ViewTransferTransaction.ts
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NamespaceId, PublicAccount, TransactionType, TransferTransaction } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+import { AttachedMosaic } from '@/services/MosaicService';
+import i18n from '@/language';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+import { MosaicService } from '@/services/MosaicService';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+
+export class ViewTransferTransaction extends TransactionView {
+ public get isIncoming() {
+ const currentSignerAddress = this.$store.getters['account/currentSignerAddress'];
+ if (this.transaction.type === TransactionType.TRANSFER && this.transaction.recipientAddress instanceof NamespaceId) {
+ const linkedAddress = this.$store.getters['namespace/linkedAddress'];
+ if (!linkedAddress) {
+ this.checkLinkedAddress(this.transaction.recipientAddress);
+ return false;
+ }
+ if (currentSignerAddress.equals(linkedAddress)) {
+ return true;
+ }
+ }
+ return this.transaction.recipientAddress && currentSignerAddress && this.transaction.recipientAddress.equals(currentSignerAddress);
+ }
+
+ private async checkLinkedAddress(recipientNamespaceId) {
+ return await this.$store.dispatch('namespace/GET_LINKED_ADDRESS', recipientNamespaceId);
+ }
+
+ /**
+ * Displayed sender
+ * @var {string}
+ */
+ private get sender(): string {
+ if (this.transaction.signer) {
+ return this.transaction.signer.address.pretty();
+ }
+ const currentSignerAddress = this.$store.getters['account/currentSignerAddress'];
+ return currentSignerAddress ? currentSignerAddress.pretty() : '';
+ }
+
+ /**
+ * get available mosaics to check if any of them is expired
+ * @var {MosaicModel[]}
+ */
+ private get availableMosaics(): MosaicModel[] {
+ const currentHeight = this.$store.getters['network/currentHeight'];
+ const networkConfiguration = this.$store.getters['network/networkConfiguration'];
+ const holdMosaics = this.$store.getters['mosaic/holdMosaics'];
+ return holdMosaics.filter((entry) => {
+ const expiration = MosaicService.getExpiration(entry, currentHeight, networkConfiguration.blockGenerationTargetTime);
+ return expiration !== 'expired';
+ });
+ }
+
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ const transaction = this.transaction;
+ const attachedMosaics = transaction.mosaics.map((transactionMosaic) => {
+ return {
+ id: transactionMosaic.id,
+ mosaicHex: transactionMosaic.id.toHex(),
+ amount: transactionMosaic.amount.compact(),
+ } as AttachedMosaic;
+ });
+ const message = this.transaction.message;
+ const incoming = this.isIncoming;
+ const mosaicItems = attachedMosaics.map((mosaic, index, self) => {
+ const color = incoming ? 'green' : 'red';
+ const mosaicLabel = i18n.t('mosaic');
+ // check if mosaic not expired yet
+ return this.availableMosaics.some((entry) => entry.mosaicIdHex == mosaic.mosaicHex)
+ ? {
+ key: `${mosaicLabel} (${index + 1}/${self.length})`,
+ value: { ...mosaic, color },
+ isMosaic: true,
+ }
+ : {
+ key: `${mosaicLabel} (${index + 1}/${self.length}) ${i18n.t('mosaic_expired')}`,
+ value: { ...mosaic, color },
+ isMosaic: true,
+ };
+ });
+
+ return [
+ { key: 'sender', value: this.sender },
+ { key: 'transfer_target', value: this.transaction.recipientAddress, isAddress: true },
+ ...mosaicItems,
+ {
+ key: 'message',
+ value: {
+ message: message,
+ incoming: this.isIncoming,
+ recipient: this.transaction.recipientAddress,
+ unannounced: this.transaction.isUnannounced(),
+ signer: this.transaction.signer
+ ? PublicAccount.createFromPublicKey(this.transaction.signer.publicKey, this.transaction.networkType)
+ : null,
+ },
+ isMessage: true,
+ },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewUnknownTransaction.ts b/src/core/transactions/ViewUnknownTransaction.ts
new file mode 100644
index 0000000..f8f4f05
--- /dev/null
+++ b/src/core/transactions/ViewUnknownTransaction.ts
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Transaction } from 'symbol-sdk';
+// internal dependencies
+import { TransactionView } from './TransactionView';
+
+export class ViewUnknownTransaction extends TransactionView {}
diff --git a/src/core/transactions/ViewVotingKeyLinkTransaction.ts b/src/core/transactions/ViewVotingKeyLinkTransaction.ts
new file mode 100644
index 0000000..9aadafe
--- /dev/null
+++ b/src/core/transactions/ViewVotingKeyLinkTransaction.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020-present NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { VotingKeyLinkTransaction, Address, LinkAction } from 'symbol-sdk';
+import { TransactionView } from './TransactionView';
+import i18n from '@/language';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+
+export class ViewVotingKeyLinkTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ {
+ key: 'linked_account_address',
+ value: Address.createFromPublicKey(this.transaction.linkedPublicKey, this.transaction.networkType).plain(),
+ },
+ { key: 'link_action', value: this.transaction.linkAction == LinkAction.Link ? i18n.t('link') : i18n.t('unlink') },
+ { key: 'linked_public_key', value: this.transaction.linkedPublicKey },
+ { key: 'start_finalization_epoch', value: this.transaction.startEpoch },
+ { key: 'end_finalization_epoch', value: this.transaction.endEpoch },
+ ];
+ }
+}
diff --git a/src/core/transactions/ViewVrfKeyLinkTransaction.ts b/src/core/transactions/ViewVrfKeyLinkTransaction.ts
new file mode 100644
index 0000000..071f106
--- /dev/null
+++ b/src/core/transactions/ViewVrfKeyLinkTransaction.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020-present NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { VrfKeyLinkTransaction, LinkAction } from 'symbol-sdk';
+import { TransactionView } from './TransactionView';
+import i18n from '@/language';
+import { TransactionDetailItem } from '@/core/transactions/TransactionDetailItem';
+
+export class ViewVrfKeyLinkTransaction extends TransactionView {
+ /**
+ * Displayed items
+ */
+ protected resolveDetailItems(): TransactionDetailItem[] {
+ return [
+ { key: 'link_action', value: this.transaction.linkAction == LinkAction.Link ? i18n.t('link') : i18n.t('unlink') },
+ { key: 'linked_vrf_public_key', value: this.transaction.linkedPublicKey },
+ ];
+ }
+}
diff --git a/src/core/utils/CSVHelpers.ts b/src/core/utils/CSVHelpers.ts
new file mode 100644
index 0000000..bd277b3
--- /dev/null
+++ b/src/core/utils/CSVHelpers.ts
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Parser } from 'json2csv';
+import FileSaver from 'file-saver';
+import store from '@/store/index.ts';
+import { TransactionViewFactory } from '@/core/transactions/TransactionViewFactory';
+import { TransactionView } from '@/core/transactions/TransactionView';
+import { AggregateTransaction, Transaction, TransactionType } from 'symbol-sdk';
+import * as _ from 'lodash';
+
+export class CSVHelpers {
+ protected static views: TransactionView[] = [];
+ private static transactionsArray = [];
+
+ /**
+ * returns object of a parsed aggregate transaction
+ * @param transaction aggregate transaction
+ * returns new array with parsed aggregate transaction objects
+ */
+ private static constructAggregateTransactionsObject(transaction: AggregateTransaction) {
+ let merged = {};
+ const result = {};
+ this.views = [
+ TransactionViewFactory.getView(store, transaction),
+ ...transaction.innerTransactions.map((tx) => TransactionViewFactory.getView(store, tx)),
+ ];
+ this.views.forEach((value) => {
+ let mergedRow = {};
+ mergedRow = value.headerItems.concat(value.detailItems);
+ merged = _.defaults(merged, mergedRow);
+ });
+
+ const mergedArray = Object.entries(merged);
+ for (let i = 0; i < mergedArray.length; i++) {
+ if (mergedArray[i][1]['key'] == 'paid_fee') {
+ result[mergedArray[i][1]['key']] = mergedArray[i][1]['value'].maxFee.compact().toString();
+ } else if (mergedArray[i][1]['key'] == 'transfer_target') {
+ result[mergedArray[i]['key']] = mergedArray[i][1]['value'].address;
+ } else if (mergedArray[i][1]['key'] == 'block_height') {
+ result[mergedArray[i]['key']] = mergedArray[i][1]['value'].replace('#', '');
+ } else {
+ result[mergedArray[i][1]['key']] = mergedArray[i][1]['value'];
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Constructs transaction object
+ * @param transaction a transaction
+ * returns object of a parsed transaction
+ */
+ private static constructTransactionsObject(transaction: Transaction) {
+ this.views = [TransactionViewFactory.getView(store, transaction)];
+ const result = {};
+ const value = this.views[0].headerItems.concat(this.views[0].detailItems);
+ for (let i = 0; i < value.length; i++) {
+ if (value[i].key == 'paid_fee') {
+ result[value[i].key] = value[i].value.maxFee.compact().toString();
+ } else if (value[i].key == 'transfer_target') {
+ result[value[i].key] = value[i].value.address;
+ } else if (value[i].key.startsWith('Mosaic')) {
+ result[value[i].key] = value[i].value.amount + ' (' + value[i].value.mosaicHex + ')';
+ } else {
+ result[value[i].key] = value[i].value;
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Export to csv file
+ * @param data array of parssed transactions
+ * returns new array with parsed transaction objects
+ */
+
+ private static prepareTransactions(data: []): any[] {
+ this.transactionsArray = [];
+ data.forEach((transaction) => {
+ let result = {};
+ if (transaction['type'] == TransactionType.AGGREGATE_BONDED || transaction['type'] == TransactionType.AGGREGATE_COMPLETE) {
+ result = this.constructAggregateTransactionsObject(transaction);
+ } else {
+ result = this.constructTransactionsObject(transaction);
+ }
+ this.transactionsArray.push(result);
+ });
+ return this.transactionsArray;
+ }
+
+ /**
+ * Export to csv file
+ * @param data The json data
+ * @param filename Prefix the name of the CSV file
+ */
+ public static exportCSV(data: any, filename: string) {
+ const json2csvParser = new Parser();
+ const parsedTransactions = this.prepareTransactions(data);
+ const csvData = json2csvParser.parse(parsedTransactions);
+ const blob = new Blob(['\uFEFF' + csvData], { type: 'text/plain;charset=utf-8;' });
+ const exportFilename = `${filename}-${Date.now()}.csv`;
+ return FileSaver.saveAs(blob, exportFilename);
+ }
+}
diff --git a/src/core/utils/CommonHelpers.ts b/src/core/utils/CommonHelpers.ts
new file mode 100644
index 0000000..37abf0f
--- /dev/null
+++ b/src/core/utils/CommonHelpers.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export class CommonHelpers {
+ /**
+ * Helper method to sleep for ms miliseconds
+ * @param {string} text
+ * @return {boolean}
+ */
+ public static sleep(ms: number): Promise {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve();
+ }, ms);
+ });
+ }
+
+ /**
+ * Helper method to retry opening websocket n times asynchronously
+ */
+ public static async retryNTimes(listener, trials: number, interval: number) {
+ if (trials < 1) {
+ throw new Error('could not connect');
+ }
+ let attemptCount = 0;
+ while (!listener.isOpen()) {
+ try {
+ return await listener.open();
+ } catch (error) {
+ if (++attemptCount >= trials) {
+ throw error;
+ }
+ }
+ await this.sleep(interval);
+ }
+ }
+}
diff --git a/src/core/utils/Electron.ts b/src/core/utils/Electron.ts
new file mode 100644
index 0000000..f904f5d
--- /dev/null
+++ b/src/core/utils/Electron.ts
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { StorageHelpers } from './StorageHelpers';
+
+export class Electron {
+ /**
+ * Holds whether the app is maximized
+ * @var {boolean}
+ */
+ public static isMaximized: boolean = false;
+
+ public static openFile = (fn) => {
+ const electron = window['electron'];
+ electron['dialog'].showOpenDialog(
+ {
+ properties: ['openFile', 'openDirectory'],
+ },
+ (files) => {
+ if (files) {
+ fn(files);
+ }
+ },
+ );
+ };
+
+ public static saveFile = (name, extensions, fn) => {
+ const electron = window['electron'];
+ const options = {
+ title: 'Save File',
+ filters: [{ name: name, extensions: [extensions] }],
+ };
+ electron['dialog'].showSaveDialog(options, (filename) => {
+ fn(filename);
+ });
+ };
+
+ public static checkInstall = () => {
+ const fs = window['node_fs'];
+ if (fs) {
+ const root = fs.readdirSync('./');
+ const isInstall = root.every((fileName) => {
+ return fileName !== 'installed.config';
+ });
+ if (isInstall) {
+ window.localStorage.clear();
+ fs.writeFileSync('./installed.config', 'installed');
+ }
+ }
+ };
+
+ public static resetFontSize = () => {
+ if (window['electron']) {
+ const localZoom = StorageHelpers.sessionRead('zoomFactor') || 1;
+ const devInnerWidth = 1689;
+ const winWidth = window.innerWidth * Number(localZoom);
+ let zoomFactor = winWidth / devInnerWidth;
+ if (winWidth > devInnerWidth && winWidth < 1920) {
+ zoomFactor = 1;
+ } else if (winWidth >= 1920) {
+ zoomFactor = winWidth / 1920;
+ }
+ StorageHelpers.sessionSave('zoomFactor', zoomFactor);
+ window['electron'].webFrame.setZoomFactor(zoomFactor);
+ }
+ };
+
+ public static windowSizeChange = () => {
+ if (window['electron']) {
+ const electron = window['electron'];
+ const mainWindow = electron.remote.getCurrentWindow();
+ mainWindow.on('resize', () => {
+ Electron.resetFontSize();
+ });
+ }
+ };
+
+ public static minWindow = () => {
+ if (window['electron']) {
+ Electron.isMaximized = false;
+ const ipcRenderer = window['electron']['ipcRenderer'];
+ ipcRenderer.send('app', 'min');
+ }
+ };
+
+ public static maxWindow = () => {
+ if (window['electron']) {
+ Electron.isMaximized = true;
+ const ipcRenderer = window['electron']['ipcRenderer'];
+ ipcRenderer.send('app', 'max');
+ }
+ };
+
+ public static closeWindow = () => {
+ if (window['electron']) {
+ const ipcRenderer = window['electron']['ipcRenderer'];
+ ipcRenderer.send('app', 'quit');
+ }
+ };
+
+ public static unMaximize = () => {
+ if (window['electron']) {
+ Electron.isMaximized = false;
+ const ipcRenderer = window['electron']['ipcRenderer'];
+ ipcRenderer.send('app', 'unMaximize');
+ }
+ };
+
+ public static htmlRem = () => {
+ const docEl = document.documentElement,
+ resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
+ recalc = function () {
+ const clientWidth = docEl.clientWidth;
+ if (!clientWidth) {
+ return;
+ }
+ docEl.style.fontSize = `${10 * (clientWidth / 192)}px`;
+ };
+ if (!document.addEventListener) {
+ return;
+ }
+ window.addEventListener(resizeEvt, recalc, false);
+ document.addEventListener('DOMContentLoaded', recalc, false);
+ };
+}
diff --git a/src/core/utils/FilterHelpers.ts b/src/core/utils/FilterHelpers.ts
new file mode 100644
index 0000000..2ca8c36
--- /dev/null
+++ b/src/core/utils/FilterHelpers.ts
@@ -0,0 +1,48 @@
+/**
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export class FilterHelpers {
+ /**
+ * replace all tags
+ * @param inputStr
+ */
+ public static stripFilter(inputStr: string, allowed: string = '') {
+ // making sure the allowed arg is a string containing only tags in lowercase ()
+ allowed = (((allowed || '') + '').toLowerCase().match(/<[a-z][a-z0-9]*>/g) || []).join('');
+
+ const tags = /<\/?([a-z0-9]*)\b[^>]*>?/gi;
+ const commentsAndPhpTags = /|<\?(?:php)?[\s\S]*?\?>/gi;
+
+ // removes tha '<' char at the end of the string to replicate PHP's behaviour
+ let after = inputStr;
+ after = after.substring(after.length - 1) === '<' ? after.substring(0, after.length - 1) : after;
+
+ // recursively remove tags to ensure that the returned string doesn't contain
+ // forbidden tags after previous passes (e.g. '< switch/>')
+ let before;
+ do {
+ before = after;
+ after = before.replace(commentsAndPhpTags, '').replace(tags, function ($0, $1) {
+ return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
+ });
+
+ // return once no more tags are removed
+ if (before === after) {
+ return after;
+ }
+ } while (before !== after);
+ }
+}
diff --git a/src/core/utils/Formatters.ts b/src/core/utils/Formatters.ts
new file mode 100644
index 0000000..b0b07a0
--- /dev/null
+++ b/src/core/utils/Formatters.ts
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address } from 'symbol-sdk';
+import { decode } from 'utf8';
+
+export class Formatters {
+ public static formatNumber = (number: number): string => {
+ if (number <= 1) {
+ return `${number}`;
+ }
+ if (number === Number(number.toFixed(0))) {
+ return number.toLocaleString('en-US', { minimumFractionDigits: 0 });
+ }
+
+ const stringOfNumber = `${number}`;
+ const minimumFractionDigits = stringOfNumber.length - stringOfNumber.indexOf('.') - 1;
+ return number.toLocaleString('en-US', { minimumFractionDigits });
+ };
+
+ public static formatAddress = function (address: string): string {
+ if (!address) {
+ return;
+ }
+ return Address.createFromRawAddress(address).pretty();
+ };
+
+ public static miniAddress = (address: Address): string => {
+ const string = address.pretty();
+ return `${string.substring(0, 13).toUpperCase()}***${string.substring(28).toUpperCase()}`;
+ };
+
+ public static miniHash = (hash: string): string => {
+ return `${hash.substring(0, 18).toLowerCase()}***${hash.substring(42).toLowerCase()}`;
+ };
+
+ public static tinyHash = (hash: string): string => {
+ return `${hash.substring(0, 6).toLowerCase()}***${hash.substring(58).toLowerCase()}`;
+ };
+
+ public static formatDate = (timestamp) => {
+ const now = new Date(Number(timestamp));
+ const year = now.getFullYear();
+ let month = `${now.getMonth() + 1}`;
+ month = Number(month) < 10 ? `0${month}` : month;
+ let date = `${now.getDate()}`;
+ date = Number(date) < 10 ? `0${date}` : date;
+ let hour = `${now.getHours()}`;
+ hour = Number(hour) < 10 ? `0${hour}` : hour;
+ let minute = `${now.getMinutes()}`;
+ minute = Number(minute) < 10 ? `0${minute}` : minute;
+ let second = `${now.getSeconds()}`;
+ second = Number(second) < 10 ? `0${second}` : second;
+ return `${year}-${month}-${date} ${hour}:${minute}:${second}`;
+ };
+
+ public static hexToUtf8(hex: string): string {
+ let str = '';
+ for (let i = 0; i < hex.length; i += 2) {
+ str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
+ }
+ try {
+ return decode(str);
+ } catch (e) {
+ return str;
+ }
+ }
+
+ public static configurationNumberAsString(value: string | undefined): string {
+ return value ? value.replace(/'/g, '') : '0';
+ }
+
+ public static configurationStringAsString(value: string | undefined): string {
+ return value ? value.replace(/'/g, '').substring(2) : '';
+ }
+
+ public static configurationNumberAsNumber(value: string | undefined): number {
+ return parseInt(this.configurationNumberAsString(value));
+ }
+ public static splitArrayByDelimiter(arr: Array, delimiter?: string) {
+ delimiter = delimiter ? delimiter : ' ';
+ if (!Array.isArray(arr)) {
+ throw Error(`${arr} is not an Array`);
+ }
+ if (arr.some((e) => typeof e !== 'string')) {
+ throw Error(`Type of the element in ${arr} should be string`);
+ }
+ return arr.join(delimiter);
+ }
+}
diff --git a/src/core/utils/Ledger.ts b/src/core/utils/Ledger.ts
new file mode 100644
index 0000000..e431f71
--- /dev/null
+++ b/src/core/utils/Ledger.ts
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import * as BIPPath from 'bip32-path';
+// configuration
+import { Transaction, SignedTransaction, Convert, CosignatureSignedTransaction, AggregateTransaction } from 'symbol-sdk';
+
+const SUPPORT_VERSION = { LEDGER_MAJOR_VERSION: '1', LEDGER_MINOR_VERSION: '0', LEDGER_PATCH_VERSION: '0' };
+const CLA_FIELD = 0xe0;
+
+/**
+ * Symbol's API
+ *
+ * @example
+ * import { SymbolLedger } from '@/core/utils/Ledger'
+ * const sym = new SymbolLedger();
+ "44'/4343'/account'/change/accountIndex"
+ */
+
+export class SymbolLedger {
+ transport: any;
+
+ constructor(transport: any, scrambleKey: string) {
+ this.transport = transport;
+ transport.decorateAppAPIMethods(
+ this,
+ ['isAppSupported', 'getAccount', 'signTransaction', 'signCosignatureTransaction'],
+ scrambleKey,
+ );
+ }
+ /**
+ * Return true if app version is above the supported Symbol app version
+ * @return {boolean}
+ */
+ public async isAppSupported() {
+ const appVersion = await this.getAppVersion();
+ if (appVersion.majorVersion > SUPPORT_VERSION.LEDGER_MAJOR_VERSION) {
+ return true;
+ } else if (appVersion.majorVersion == SUPPORT_VERSION.LEDGER_MAJOR_VERSION) {
+ if (appVersion.minorVersion > SUPPORT_VERSION.LEDGER_MINOR_VERSION) {
+ return true;
+ } else if (appVersion.minorVersion == SUPPORT_VERSION.LEDGER_MINOR_VERSION) {
+ if (appVersion.patchVersion < SUPPORT_VERSION.LEDGER_PATCH_VERSION) {
+ return false;
+ } else {
+ return true;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Get Symbol app version on Ledger device
+
+ * @return an object contain major, minor, patch version of the Symbol app on Ledger device
+ */
+ private async getAppVersion() {
+ // APDU fields configuration
+ const apdu = {
+ cla: 0xe0,
+ ins: 0x06,
+ p1: 0x00,
+ p2: 0x00,
+ data: Buffer.alloc(1, 0x00, 'hex'),
+ };
+ // Response from Ledger
+ const response = await this.transport.send(apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.data);
+ const result = {
+ majorVersion: '',
+ minorVersion: '',
+ patchVersion: '',
+ };
+ result.majorVersion = response[1];
+ result.minorVersion = response[2];
+ result.patchVersion = response[3];
+ return result;
+ }
+
+ /**
+ * get Symbol's address for a given BIP 44 path from the Ledger
+ *
+ * @param path a path in BIP 44 format
+ * @param display optionally enable or not the display
+ * @param chainCode optionally enable or not the chainCode request
+ * @param isOptinSymbolWallet if Opt-in Symbol wallet uses curve Secp256K1 else uses curve Ed25519
+ * @return an object with a publicKey and (optionally) chainCode
+ */
+ async getAccount(path: string, networkType: number, display: boolean, chainCode: boolean, isOptinLedgerWallet: boolean) {
+ const GET_ACCOUNT_INS_FIELD = 0x02;
+
+ const bipPath = BIPPath.fromString(path).toPathArray();
+ const curveMask = isOptinLedgerWallet ? 0x40 : 0x80;
+
+ // APDU fields configuration
+ const apdu = {
+ cla: CLA_FIELD,
+ ins: GET_ACCOUNT_INS_FIELD,
+ p1: display ? 0x01 : 0x00,
+ p2: curveMask | (chainCode ? 0x01 : 0x00),
+ data: Buffer.alloc(1 + bipPath.length * 4 + 1),
+ };
+
+ apdu.data.writeInt8(bipPath.length, 0);
+ bipPath.forEach((segment, index) => {
+ apdu.data.writeUInt32BE(segment, 1 + index * 4);
+ });
+ apdu.data.writeUInt8(networkType, 1 + bipPath.length * 4);
+
+ // Response from Ledger
+ const response = await this.transport.send(apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.data);
+ const result = {
+ publicKey: '',
+ };
+
+ const publicKeyLength = response[0];
+ if (publicKeyLength !== 32) {
+ throw { statusCode: 27264 };
+ }
+ result.publicKey = response.slice(1, 1 + publicKeyLength).toString('hex');
+ return result;
+ }
+
+ /**
+ * sign a Symbol transaction by account on Ledger at given BIP 44 path
+ *
+ * @param path a path in BIP 44 format
+ * @param transaction a transaction needs to be signed
+ * @param networkGenerationHash the network generation hash of block 1
+ * @param signerPublicKey the public key of signer
+ * @param isOptinSymbolWallet if Opt-in Symbol wallet uses curve Secp256K1 else uses curve Ed25519
+ * @return a signed Transaction which is signed by account at path on Ledger
+ */
+ public async signTransaction(
+ path: string,
+ transaction: any,
+ networkGenerationHash: string,
+ signerPublicKey: string,
+ isOptinLedgerWallet: boolean,
+ ) {
+ const rawPayload = transaction.serialize();
+ const signingBytes = networkGenerationHash + rawPayload.slice(216);
+ const rawTx = Buffer.from(signingBytes, 'hex');
+ const response = await this.ledgerMessageHandler(path, rawTx, false, isOptinLedgerWallet);
+ // Response from Ledger
+ const h = response.toString('hex');
+ const signature = h.slice(0, 128);
+ const payload = rawPayload.slice(0, 16) + signature + signerPublicKey + rawPayload.slice(16 + 128 + 64, rawPayload.length);
+ const generationHashBytes = Array.from(Convert.hexToUint8(networkGenerationHash));
+ const transactionHash = Transaction.createTransactionHash(payload, generationHashBytes);
+ const signedTransaction = new SignedTransaction(
+ payload,
+ transactionHash,
+ signerPublicKey,
+ transaction.type,
+ transaction.networkType,
+ );
+ return signedTransaction;
+ }
+
+ /**
+ * sign a Symbol Cosignature transaction with a given BIP 44 path
+ *
+ * @param path a path in BIP 44 format
+ * @param cosignatureTransaction a cosinature transaction needs to be signed
+ * @param signerPublicKey the public key of signer
+ * @param isOptinSymbolWallet if Opt-in Symbol wallet uses curve Secp256K1 else uses curve Ed25519
+ * @return a Signed Cosignature Transaction which is signed by account at path on Ledger
+ */
+ public async signCosignatureTransaction(
+ path: string,
+ cosignatureTransaction: AggregateTransaction,
+ signerPublicKey: string,
+ isOptinSymbolWallet: boolean,
+ ) {
+ const rawPayload = cosignatureTransaction.serialize();
+ const signingBytes = cosignatureTransaction.transactionInfo.hash + rawPayload.slice(216);
+ const rawTx = Buffer.from(signingBytes, 'hex');
+ const response = await this.ledgerMessageHandler(path, rawTx, false, isOptinSymbolWallet);
+ // Response from Ledger
+ const h = response.toString('hex');
+ const signature = h.slice(0, 128);
+ const cosignatureSignedTransaction = new CosignatureSignedTransaction(
+ cosignatureTransaction.transactionInfo.hash,
+ signature,
+ signerPublicKey,
+ );
+ return cosignatureSignedTransaction;
+ }
+
+ /**
+ * handle sending and receiving packages between Ledger and Wallet
+ * @param path a path in BIP 44 format
+ * @param rawTx a raw payload transaction hex string
+ * @param chainCode optionally enable or not the chainCode request
+ * @param isOptinSymbolWallet if Opt-in Symbol wallet uses curve Secp256K1 else uses curve Ed25519
+ * @returns respond package from Ledger
+ */
+ private async ledgerMessageHandler(path: string, rawTx: Buffer, chainCode: boolean, isOptinSymbolWallet: boolean) {
+ const TX_INS_FIELD = 0x04;
+ const MAX_CHUNK_SIZE = 255;
+ const CONTINUE_SENDING = '0x9000';
+
+ const curveMask = isOptinSymbolWallet ? 0x40 : 0x80;
+ const bipPath = BIPPath.fromString(path).toPathArray();
+ const apduArray = [];
+ let offset = 0;
+
+ while (offset !== rawTx.length) {
+ const maxChunkSize = offset === 0 ? MAX_CHUNK_SIZE - 1 - bipPath.length * 4 : MAX_CHUNK_SIZE;
+ const chunkSize = offset + maxChunkSize > rawTx.length ? rawTx.length - offset : maxChunkSize;
+ // APDU fields configuration
+ const apdu = {
+ cla: CLA_FIELD,
+ ins: TX_INS_FIELD,
+ p1: offset === 0 ? (chunkSize < maxChunkSize ? 0x00 : 0x80) : chunkSize < maxChunkSize ? 0x01 : 0x81,
+ p2: curveMask | (chainCode ? 0x01 : 0x00),
+ data: offset === 0 ? Buffer.alloc(1 + bipPath.length * 4 + chunkSize) : Buffer.alloc(chunkSize),
+ };
+
+ if (offset === 0) {
+ apdu.data.writeInt8(bipPath.length, 0);
+ bipPath.forEach((segment, index) => {
+ apdu.data.writeUInt32BE(segment, 1 + index * 4);
+ });
+ rawTx.copy(apdu.data, 1 + bipPath.length * 4, offset, offset + chunkSize);
+ } else {
+ rawTx.copy(apdu.data, 0, offset, offset + chunkSize);
+ }
+ apduArray.push(apdu);
+ offset += chunkSize;
+ }
+ let response = Buffer.alloc(0);
+ for (const apdu of apduArray) {
+ response = await this.transport.send(apdu.cla, apdu.ins, apdu.p1, apdu.p2, apdu.data);
+ }
+
+ if (response.toString() != CONTINUE_SENDING) {
+ return response;
+ }
+ }
+}
diff --git a/src/core/utils/LogLevels.ts b/src/core/utils/LogLevels.ts
new file mode 100644
index 0000000..26af6d9
--- /dev/null
+++ b/src/core/utils/LogLevels.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+export enum LogLevels {
+ INFO = 1,
+ DEBUG = 2,
+ WARNING = 3,
+ ERROR = 4,
+}
diff --git a/src/core/utils/NetworkConfigurationHelpers.ts b/src/core/utils/NetworkConfigurationHelpers.ts
new file mode 100644
index 0000000..ecde6ca
--- /dev/null
+++ b/src/core/utils/NetworkConfigurationHelpers.ts
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkConfiguration, NetworkType } from 'symbol-sdk';
+import { Formatters } from '@/core/utils/Formatters';
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+
+import { networkConfig } from '@/config';
+
+/**
+ * Helper class that retrieves properties from the SDK's NetworkConfiguration object when
+ * available.
+ *
+ * This helper:
+ * - It enumerates the network configuration properties the wallet uses
+ * - It handles possible problems when the network configuration coming from the server is
+ * incomplete.
+ * - It defines common defaults when properties from unknown
+ * - It parses configuration values to a format the wallet understands
+ */
+export class NetworkConfigurationHelpers {
+ /**
+ * This are the absolute defaults if the network is down and the configuration hasn't been cached
+ * in the local storage.
+ */
+ private static defaults = networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults;
+
+ public static maxMosaicDivisibility(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.mosaic &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.plugins.mosaic.maxMosaicDivisibility)) ||
+ defaultValue ||
+ this.defaults.maxMosaicDivisibility
+ );
+ }
+
+ public static maxNamespaceDepth(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.namespace &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.plugins.namespace.maxNamespaceDepth)) ||
+ defaultValue ||
+ this.defaults.maxNamespaceDepth
+ );
+ }
+
+ public static namespaceGracePeriodDuration(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.namespace &&
+ TimeHelpers.durationStringToSeconds(networkConfiguration.plugins.namespace.namespaceGracePeriodDuration)) ||
+ defaultValue ||
+ this.defaults.namespaceGracePeriodDuration
+ );
+ }
+
+ public static maxCosignatoriesPerAccount(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.multisig &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.plugins.multisig.maxCosignatoriesPerAccount)) ||
+ defaultValue ||
+ this.defaults.maxCosignatoriesPerAccount
+ );
+ }
+
+ public static blockGenerationTargetTime(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.chain &&
+ TimeHelpers.durationStringToSeconds(networkConfiguration.chain.blockGenerationTargetTime)) ||
+ defaultValue ||
+ this.defaults.blockGenerationTargetTime
+ );
+ }
+
+ public static lockedFundsPerAggregate(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: string | undefined = undefined,
+ ): string {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.lockhash &&
+ Formatters.configurationNumberAsString(networkConfiguration.plugins.lockhash.lockedFundsPerAggregate)) ||
+ defaultValue ||
+ this.defaults.lockedFundsPerAggregate
+ );
+ }
+
+ public static maxMosaicDuration(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.mosaic &&
+ TimeHelpers.durationStringToSeconds(networkConfiguration.plugins.mosaic.maxMosaicDuration)) ||
+ defaultValue ||
+ this.defaults.maxMosaicDuration
+ );
+ }
+
+ public static epochAdjustment(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.mosaic &&
+ TimeHelpers.durationStringToSeconds(networkConfiguration.network.epochAdjustment)) ||
+ defaultValue ||
+ this.defaults.epochAdjustment
+ );
+ }
+
+ public static minNamespaceDuration(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.namespace &&
+ TimeHelpers.durationStringToSeconds(networkConfiguration.plugins.namespace.minNamespaceDuration)) ||
+ defaultValue ||
+ this.defaults.minNamespaceDuration
+ );
+ }
+
+ public static maxNamespaceDuration(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.namespace &&
+ TimeHelpers.durationStringToSeconds(networkConfiguration.plugins.namespace.maxNamespaceDuration)) ||
+ defaultValue ||
+ this.defaults.maxNamespaceDuration
+ );
+ }
+
+ public static maxTransactionsPerAggregate(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.aggregate &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.plugins.aggregate.maxTransactionsPerAggregate)) ||
+ defaultValue ||
+ this.defaults.maxTransactionsPerAggregate
+ );
+ }
+
+ public static maxCosignedAccountsPerAccount(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.multisig &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.plugins.multisig.maxCosignedAccountsPerAccount)) ||
+ defaultValue ||
+ this.defaults.maxCosignedAccountsPerAccount
+ );
+ }
+
+ public static maxMessageSize(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.plugins &&
+ networkConfiguration.plugins.transfer &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.plugins.transfer.maxMessageSize)) ||
+ defaultValue ||
+ this.defaults.maxMessageSize
+ );
+ }
+
+ public static maxMosaicAtomicUnits(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.chain &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.chain.maxMosaicAtomicUnits)) ||
+ defaultValue ||
+ this.defaults.maxMosaicAtomicUnits
+ );
+ }
+
+ public static currencyMosaicId(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: string | undefined = undefined,
+ ): string {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.chain &&
+ Formatters.configurationStringAsString(networkConfiguration.chain.currencyMosaicId)) ||
+ defaultValue ||
+ this.defaults.currencyMosaicId
+ );
+ }
+
+ public static harvestingMosaicId(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: string | undefined = undefined,
+ ): string {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.chain &&
+ Formatters.configurationStringAsString(networkConfiguration.chain.harvestingMosaicId)) ||
+ defaultValue ||
+ this.defaults.harvestingMosaicId
+ );
+ }
+
+ public static defaultDynamicFeeMultiplier(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration &&
+ networkConfiguration.chain &&
+ Formatters.configurationNumberAsNumber(networkConfiguration.chain.defaultDynamicFeeMultiplier)) ||
+ defaultValue ||
+ this.defaults.defaultDynamicFeeMultiplier
+ );
+ }
+
+ public static totalChainImportance(
+ networkConfiguration: NetworkConfiguration | undefined,
+ defaultValue: number | undefined = undefined,
+ ): number {
+ return (
+ (networkConfiguration?.chain && Formatters.configurationNumberAsNumber(networkConfiguration.chain.totalChainImportance)) ||
+ defaultValue ||
+ this.defaults.totalChainImportance
+ );
+ }
+}
diff --git a/src/core/utils/NetworkTypeHelper.ts b/src/core/utils/NetworkTypeHelper.ts
new file mode 100644
index 0000000..fc54e61
--- /dev/null
+++ b/src/core/utils/NetworkTypeHelper.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+/// region custom types
+import { NetworkType } from 'symbol-sdk';
+import { networkConfig } from '@/config';
+
+type NetworkNodeEntry = { value: NetworkType; label: string };
+
+export class NetworkTypeHelper {
+ /**
+ * Network types with their names
+ */
+ public static networkTypeList: NetworkNodeEntry[] = [
+ { value: NetworkType.MAIN_NET, label: networkConfig[NetworkType.MAIN_NET].networkName },
+ { value: NetworkType.TEST_NET, label: networkConfig[NetworkType.TEST_NET].networkName },
+ ];
+
+ /**
+ * Getter for network type label
+ * @param {NetworkType} networkType
+ * @return {string}
+ */
+ public static getNetworkTypeLabel(networkType: NetworkType): string {
+ const findType = NetworkTypeHelper.networkTypeList.find((n) => n.value === networkType);
+ if (findType === undefined) {
+ return '';
+ }
+ return findType.label;
+ }
+}
diff --git a/src/core/utils/NotificationType.ts b/src/core/utils/NotificationType.ts
new file mode 100644
index 0000000..7cc1b31
--- /dev/null
+++ b/src/core/utils/NotificationType.ts
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+export enum NotificationType {
+ PROFILE_NAME_EXISTS_ERROR = 'profile_name_already_exists',
+ PROFILE_NAME_INPUT_ERROR = 'profile_name_error',
+ ADDRESS_ALIAS_NOT_EXIST_ERROR = 'address_alias_not_exist',
+ ADDRESS_FORMAT_ERROR = 'address_format_error',
+ ADDRESS_INVALID = 'address_invalid',
+ ADDRESS_UNKNOWN = 'address_unknown',
+ ADDRESS_UNKNOWN_BY_NETWORK = 'address_unknown_by_network',
+ ALIAS_NAME_FORMAT_ERROR = 'alias_name_format_error',
+ AMOUNT_LESS_THAN_0_ERROR = 'amount_can_not_be_less_than_0',
+ CLICK_TO_LOAD = 'click_to_load',
+ CO_SIGNER_NULL_ERROR = 'co_signers_amount_less_than_0',
+ COPY_SUCCESS = 'successful_copy',
+ COSIGNATURE_ADDED = 'cosignature_added',
+ DIVISIBILITY_INVALID = 'divisibility_invalid',
+ DIVISIBILITY_LESS_THAN_0_ERROR = 'divisibility_can_not_less_than_0',
+ DIVISIBILITY_MORE_THAN_6_ERROR = 'divisibility_can_not_more_than_6',
+ DURATION_LESS_THAN_0_ERROR = 'duration_can_not_less_than_0',
+ DURATION_MORE_THAN_1_YEARS_ERROR = 'duration_can_not_more_than_1_years',
+ DURATION_MORE_THAN_10_YEARS_ERROR = 'duration_can_not_more_than_10_years',
+ DURATION_VALUE_LESS_THAN_1_ERROR = 'the_value_of_duration_cannot_be_less_than_1',
+ ERROR_PEER_UNREACHABLE = 'error_peer_unreachable',
+ ERROR_ACCOUNT_NAME_ALREADY_EXISTS = 'error_account_name_already_exists',
+ ERROR_DELETE_ALL_PEERS = 'error_delete_all_peers',
+ ENCRYPTED_MESSAGE_EMPTY_ERROR = 'encrypted_message_empty_error',
+ FEE_LESS_THAN_0_ERROR = 'fee_can_not_be_less_than_0',
+ HD_ACCOUNT_PATH_ERROR = 'hd_account_path_error',
+ ILLEGAL_MIN_APPROVAL_ERROR = 'min_approval_amount_illegal',
+ ILLEGAL_MIN_REMOVAL_ERROR = 'min_removal_amount_illegal',
+ ILLEGAL_PUBLIC_KEY_ERROR = 'illegal_publicKey',
+ ILLEGAL_publicKey_ERROR = 'illegal_public_key_error',
+ INCONSISTENT_PASSWORD_ERROR = 'create_lock_check_pw_remind',
+ INPUT_EMPTY_ERROR = 'any_information_cannot_be_empty',
+ IMPORT_EMPTY_ACCOUNT_LIST = 'address_list_cannot_be_empty',
+ INVALID_NAMESPACE_OR_MOSAIC_ID = 'invalid_namespace_or_mosaic_id',
+ KEYSTORE_DECRYPTION_FAILED = 'keystore_decryption_failed',
+ LOADING = 'loading',
+ MAX_APPROVAL_MORE_THAN_10_ERROR = 'max_approval_amount_more_than_10',
+ MAX_REMOVAL_MORE_THAN_10_ERROR = 'max_removal_amount_more_than_10',
+ TOO_MANY_SEED_ACCOUNTS_ERROR = 'error_too_many_seed_accounts',
+ MIN_APPROVAL_LESS_THAN_0_ERROR = 'min_approval_amount_less_than_0',
+ MIN_REMOVAL_LESS_THAN_0_ERROR = 'min_removal_amount_less_than_0',
+ MNEMONIC_GENERATION_ERROR = 'mnemonic_generation_error',
+ MNEMONIC_INCONSISTENCY_ERROR = 'mnemonic_inconsistency',
+ MNEMONIC_CORRECT = 'mnemonic_correct',
+ MOSAIC_ALIAS_NOT_EXIST_ERROR = 'mosaic_alias_not_exist',
+ MOSAIC_HEX_FORMAT_ERROR = 'mosaic_hex_format_error',
+ MOSAIC_LIST_NULL_ERROR = 'the_mosaic_to_be_sent_is_empty',
+ MOSAIC_NAME_NULL_ERROR = 'mosaic_name_can_not_be_null',
+ MOSAIC_NOT_SET = 'mosaic_not_set',
+ MULTISIG_ACCOUNTS_NO_TX = 'multisig_accounts_can_not_send_a_transaction_by_themselves',
+ NAMESPACE_FORMAT_ERROR = 'namespace_can_only_contain_numbers_letters_and_other',
+ NAMESPACE_MAX_DURATION = 'The duration can not exceed 2102400 blocks (365 days)',
+ NAMESPACE_NULL_ERROR = 'namespace_cannot_be_a_null_or_empty_string',
+ NAMESPACE_STARTING_ERROR = 'namespace_must_start_with_a_letter',
+ NAMESPACE_USE_BANNED_WORD_ERROR = 'namespace_cannot_use_forbidden_words',
+ NETWORK_TYPE_INVALID = 'network_type_invalid',
+ NEW_AGGREGATE_BONDED = 'notification_new_aggregate_bonded',
+ NEW_CONFIRMED_TRANSACTION = 'notification_new_transaction_confirmed',
+ NEW_COSIGNATURE = 'notification_new_cosignature',
+ NEW_UNCONFIRMED_TRANSACTION = 'notification_new_unconfirmed_transaction',
+ NO_MNEMONIC_INFO = 'no_mnemonic',
+ NO_NETWORK_CURRENCY = 'no_network_currency_alert',
+ NODE_ALL_DELETED = 'all_nodes_cannot_be_deleted',
+ NODE_CONNECTION_ERROR = 'node_connection_failed',
+ NODE_CONNECTION_SUCCEEDED = 'node_connection_succeeded',
+ NODE_EXISTS_ERROR = 'node_exists_error',
+ NODE_NULL_ERROR = 'point_null_error',
+ NOTES_SHOULD_NOT_EXCEED_25_CHARACTER = 'notes_should_not_exceed_25_character',
+ OPERATION_FAILED_ERROR = 'operation_failed',
+ OPERATION_SUCCESS = 'successful_operation',
+ PASSWORD_CREATE_ERROR = 'create_lock_pw_remind',
+ PASSWORD_HIT_SETTING_ERROR = 'create_lock_pw_txt_remind',
+ PASSWORD_IS_INVALID_ERROR = 'password_is_invalid',
+ PASSWORDS_NOT_MATCHING = 'passwords_not_matching',
+ PLEASE_ENTER_A_CORRECT_NUMBER = 'please_enter_a_correct_number',
+ PLEASE_ENTER_MNEMONIC_INFO = 'please_enter_a_mnemonic_to_ensure_that_the_mnemonic_is_correct',
+ PLEASE_SET_ACCOUNT_PASSWORD_INFO = 'please_set_your_account_password',
+ PRIVATE_KEY_INVALID_ERROR = 'private_key_invalid_error',
+ PUBLIC_KEY_INVALID = 'public_key_invalid',
+ QR_GENERATION_ERROR = 'qr_code_generation_failed',
+ REFRESH_TOO_FAST_WARNING = 'refresh_too_fast_warning',
+ REMOTE_ACCOUNT_NOT_FOUND = 'Cannot find your remote account, please try to unlink it and create a new one',
+ REMOTE_PUBLIC_KEY_MISSING = 'remote_public_key_missing_error',
+ RECIPIENT_LINKED_ADDRESS_INVALID = 'recipient_linked_address_invalid',
+ RECIPIENT_PUBLIC_KEY_INVALID_ERROR = 'recipient_public_key_invalid_error',
+ ROOT_NAMESPACE_TOO_LONG_ERROR = 'the_root_namespace_cannot_be_longer_than_16',
+ SEED_ACCOUNT_OVERFLOW_ERROR = 'seed_account_can_not_be_more_than_10',
+ SET_DEFAULT_EXPLORER = 'set_default_explorer',
+ SUB_NAMESPACE_LENGTH_LONGER_THAN_64_ERROR = 'the_sub_namespace_cannot_be_longer_than_16',
+ SUCCESS_ACCOUNT_UNLOCKED = 'success_account_unlocked',
+ SUCCESS_PASSWORD_CHANGED = 'success_password_changed',
+ SUCCESS_SETTINGS_UPDATED = 'success_settings_updated',
+ SUPPLY_LESS_THAN_0_ERROR = 'supply_can_not_less_than_0',
+ UPDATE_SUCCESS = 'update_completed',
+ USER_ABORTED_TX_CONFIRMATION = 'user_aborted_transaction_confirmation',
+ VALUE_TOO_BIG = 'value_too_big',
+ ACCOUNT_NAME_INPUT_ERROR = 'account_name_input_error',
+ WRONG_PASSWORD_ERROR = 'password_error',
+ WRONG_WALLET_NAME_ERROR = 'wrong_wallet_name_error',
+ COPY_FAILED = 'copy_failed',
+ INVALID_NODE = 'invalid_node',
+ WS_CONNECTION_FAILED = 'ws_connection_failed',
+}
diff --git a/src/core/utils/ObservableHelpers.ts b/src/core/utils/ObservableHelpers.ts
new file mode 100644
index 0000000..285f595
--- /dev/null
+++ b/src/core/utils/ObservableHelpers.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { EMPTY, merge, MonoTypeOperatorFunction, of, throwError } from 'rxjs';
+import { catchError } from 'rxjs/operators';
+
+/**
+ * Custom observable pipe style operations.
+ */
+export class ObservableHelpers {
+ /**
+ * This pipe operation concatenates the default values first when provided on top what the
+ * current observable resolves. if the defaultValue is provided and the current observable fails,
+ * the error is logged and ignored. If default is not provided, the error is propagated.
+ *
+ * The idea is that clients will get a cached version of the data first, then the data will be
+ * upgraded when returned simulating a faster response.
+ *
+ * This observable may send one extra data to the observable.
+ *
+ * @param defaultValue the default value to be piped first before the observable.
+ */
+ public static defaultFirst(defaultValue: T | undefined): MonoTypeOperatorFunction {
+ return (observable) =>
+ merge(
+ defaultValue ? of(defaultValue) : EMPTY,
+ observable.pipe(
+ catchError((e) => {
+ if (defaultValue) {
+ return EMPTY;
+ } else {
+ return throwError(e);
+ }
+ }),
+ ),
+ );
+ }
+
+ /**
+ * This pipe operation appends the default data to the observable if this one fails.
+ *
+ * If the default data is not provided, the observable error is propagated. If the observable
+ * succeeds, the default value is ignored.
+ *
+ * The idea is that if the response cannot be obtained from rest, the cached data will be used.
+ *
+ * @param defaultValue the default value to be provided if the current observable fails.
+ */
+
+ public static defaultLast(defaultValue: T | undefined = undefined): MonoTypeOperatorFunction {
+ return (observable) =>
+ observable.pipe(
+ catchError((e) => {
+ if (defaultValue) {
+ return of(defaultValue);
+ } else {
+ return throwError(e);
+ }
+ }),
+ );
+ }
+}
diff --git a/src/core/utils/RESTDispatcher.ts b/src/core/utils/RESTDispatcher.ts
new file mode 100644
index 0000000..e71ee09
--- /dev/null
+++ b/src/core/utils/RESTDispatcher.ts
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export class RESTDispatcher {
+ /**
+ *
+ */
+ protected dispatch: (action: string, payload?: any, options?: any) => void;
+
+ /**
+ *
+ */
+ protected actions: {
+ action: string;
+ payload?: any;
+ options?: any;
+ await: boolean;
+ }[] = [];
+
+ /**
+ *
+ * @param dispatchFn
+ */
+ public constructor(dispatchFn: (action: string, payload?: any, options?: any) => void) {
+ this.dispatch = dispatchFn;
+ }
+
+ /**
+ *
+ * @param action
+ * @param payload
+ * @param options
+ * @param isBlocking
+ */
+ public add(action: string, payload?: any, options?: any, shouldAwait: boolean = false) {
+ this.actions.push({
+ action,
+ payload: payload,
+ options: options,
+ await: shouldAwait,
+ });
+ }
+
+ /**
+ * Lazy store action dispatcher. This will make sure
+ * that dispatching actions does not flood REST with
+ * too many requests.
+ */
+ public throttle_dispatch() {
+ // - wrap actions execution in delayed promises
+ const promises: Promise[] = [];
+ this.actions.map((action, index: number) => {
+ // - every second value, delay 1000ms
+ const delay = index + (1 % 2) === 0 ? 1000 : 0;
+
+ // - configure promises to include delay
+ promises.push(
+ new Promise((resolve, reject) => {
+ return setTimeout(() => {
+ try {
+ const obs = this.dispatch(action.action, action.payload, action.options);
+ return resolve(obs);
+ } catch (e) {
+ return reject(e);
+ }
+ }, delay);
+ }),
+ );
+ });
+
+ return new Promise((resolve) => resolve(Promise.all(promises)));
+ }
+}
diff --git a/src/core/utils/ScopedMetadataKeysHelpers.ts b/src/core/utils/ScopedMetadataKeysHelpers.ts
new file mode 100644
index 0000000..603e01e
--- /dev/null
+++ b/src/core/utils/ScopedMetadataKeysHelpers.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { StorageHelpers } from './StorageHelpers';
+
+export const SCOPED_METADATA_STORE_KEY: string = 'SCOPED_METADATA_STORE_KEY';
+export const MAX_STORE_LENGTH = 5;
+
+export class ScopedMetadataKeysHelpers {
+ /**
+ * Stored Metadata key array
+ * @returns {string[]}
+ */
+ public static loadScopedMetadataKeys(): string[] {
+ let keys = [];
+ try {
+ keys = JSON.parse(StorageHelpers.sessionRead(SCOPED_METADATA_STORE_KEY) || '[]');
+ } catch (e) {
+ console.log(e);
+ }
+
+ return keys;
+ }
+
+ public static storeKey = (key) => {
+ let keys = ScopedMetadataKeysHelpers.loadScopedMetadataKeys();
+ if (keys.length >= MAX_STORE_LENGTH) {
+ keys.pop();
+ } else if (keys.includes(key)) {
+ keys = keys.filter((item) => item !== key);
+ keys.unshift(key);
+ } else {
+ keys.unshift(key);
+ }
+
+ StorageHelpers.sessionSave(SCOPED_METADATA_STORE_KEY, JSON.stringify(keys));
+ };
+}
diff --git a/src/core/utils/StorageHelpers.ts b/src/core/utils/StorageHelpers.ts
new file mode 100644
index 0000000..09e07b0
--- /dev/null
+++ b/src/core/utils/StorageHelpers.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+export class StorageHelpers {
+ public static sessionSave = (key, value) => {
+ sessionStorage.setItem(key, value);
+ };
+
+ public static sessionRead = (key) => {
+ return sessionStorage.getItem(key) || '';
+ };
+
+ public static cleanSession = () => {
+ sessionStorage.clear();
+ };
+}
diff --git a/src/core/utils/TimeHelpers.ts b/src/core/utils/TimeHelpers.ts
new file mode 100644
index 0000000..9e2e5a8
--- /dev/null
+++ b/src/core/utils/TimeHelpers.ts
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { DtoMapping } from 'symbol-sdk';
+
+export class TimeHelpers {
+ public static addZero = function (number: number): string {
+ return number < 10 ? `0${number}` : `${number}`;
+ };
+
+ public static formatTimestamp = (timestamp: number): string => {
+ const d = new Date(timestamp);
+ const date = `${TimeHelpers.addZero(d.getFullYear())}-${TimeHelpers.addZero(d.getMonth() + 1)}-${TimeHelpers.addZero(
+ d.getDate(),
+ )} `;
+ const time = ` ${TimeHelpers.addZero(d.getHours())}:${TimeHelpers.addZero(d.getMinutes())}:${TimeHelpers.addZero(d.getSeconds())}`;
+ return date + time;
+ };
+
+ public static formatSeconds = function (second: number): string {
+ if (!second && second !== 0) {
+ return '';
+ }
+ let d = 0,
+ h = 0,
+ m = 0;
+
+ if (second > 86400) {
+ d = Math.floor(second / 86400);
+ second = second % 86400;
+ }
+ if (second > 3600) {
+ h = Math.floor(second / 3600);
+ second = second % 3600;
+ }
+ if (second > 60) {
+ m = Math.floor(second / 60);
+ second = second % 60;
+ }
+ let result = '';
+ // seconds less than 60s
+ if (second > 0 && m == 0 && h == 0 && d == 0) {
+ result = `${second} s ${result}`;
+ }
+ if (m > 0 || h > 0 || d > 0) {
+ result = `${m} m ${result}`;
+ }
+ if (h > 0 || d > 0) {
+ result = `${h} h ${result}`;
+ }
+ if (d > 0) {
+ result = `${d} d ${result}`;
+ }
+
+ return result;
+ };
+
+ /**
+ * Transforms a number of blocks into a relative time
+ * eg. 15 blocks => 1s
+ * @param duration in block number
+ */
+ public static durationToRelativeTime = (durationInBlocks: number, blockGenerationTargetTime: number): string => {
+ try {
+ const isDurationNegative = durationInBlocks < 0;
+ const absoluteDuration = isDurationNegative ? durationInBlocks * -1 : durationInBlocks;
+ const relativeTime = TimeHelpers.formatSeconds(absoluteDuration * blockGenerationTargetTime);
+ const prefix = isDurationNegative ? '- ' : '';
+ return `${prefix}${relativeTime}`;
+ } catch (error) {
+ console.error('durationToRelativeTime -> error', error);
+ return '';
+ }
+ };
+
+ public static durationStringToSeconds(str: string): number {
+ return Math.floor(this.durationStringToMilliseconds(str) / 1000);
+ }
+
+ public static durationStringToMilliseconds(value: string): number {
+ let str = value;
+ let total = 0;
+ const milliSeconds = str.match(/(\d+)\s*ms/);
+ if (milliSeconds) {
+ str = str.replace(milliSeconds[0], '');
+ total += parseInt(milliSeconds[1]);
+ }
+ const days = str.match(/(\d+)\s*d/);
+ if (days) {
+ str = str.replace(days[0], '');
+ total += parseInt(days[1]) * 24 * 60 * 60 * 1000;
+ }
+ const hours = str.match(/(\d+)\s*h/);
+ if (hours) {
+ str = str.replace(hours[0], '');
+ total += parseInt(hours[1]) * 60 * 60 * 1000;
+ }
+ const minutes = str.match(/(\d+)\s*m/);
+ if (minutes) {
+ str = str.replace(minutes[0], '');
+ total += parseInt(minutes[1]) * 60 * 1000;
+ }
+ const seconds = str.match(/(\d+)\s*s/);
+ if (seconds) {
+ str = str.replace(seconds[0], '');
+ total += parseInt(seconds[1]) * 1000;
+ }
+ return total;
+ }
+
+ public static durationStringToMillisecondsSDK(value: string): number {
+ return DtoMapping.parseServerDuration(value).toMillis();
+ }
+
+ public static formatDate = (timestamp) => {
+ const now = new Date(Number(timestamp));
+ const year = now.getFullYear();
+ let month = `${now.getMonth() + 1}`;
+ month = Number(month) < 10 ? `0${month}` : month;
+ let date = `${now.getDate()}`;
+ date = Number(date) < 10 ? `0${date}` : date;
+ let hour = `${now.getHours()}`;
+ hour = Number(hour) < 10 ? `0${hour}` : hour;
+ let minute = `${now.getMinutes()}`;
+ minute = Number(minute) < 10 ? `0${minute}` : minute;
+ let second = `${now.getSeconds()}`;
+ second = Number(second) < 10 ? `0${second}` : second;
+ return `${year}-${month}-${date} ${hour}:${minute}:${second}`;
+ };
+
+ public static getCurrentMonthFirst = function (date: Date): Date {
+ date.setDate(1);
+ return date;
+ };
+
+ public static getCurrentMonthLast = function (date: Date): Date {
+ let currentMonth = date.getMonth();
+ const nextMonth = ++currentMonth;
+ const nextMonthFirstDay = new Date(date.getFullYear(), nextMonth, 1);
+ return new Date(Number(nextMonthFirstDay));
+ };
+}
diff --git a/src/core/utils/TrezorConnect.ts b/src/core/utils/TrezorConnect.ts
new file mode 100644
index 0000000..3267b08
--- /dev/null
+++ b/src/core/utils/TrezorConnect.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import TrezorConnect from 'trezor-connect';
+
+// TODO: figure out who wants to be the first point of contact for trezor
+// https://github.com/trezor/connect/blob/develop/docs/index.md#trezor-connect-manifest
+TrezorConnect.manifest({
+ email: 'chris@crunchycloud.io',
+ appUrl: 'http://localhost:8080',
+});
+
+export default TrezorConnect;
diff --git a/src/core/utils/UIHelpers.ts b/src/core/utils/UIHelpers.ts
new file mode 100644
index 0000000..f164eb8
--- /dev/null
+++ b/src/core/utils/UIHelpers.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export class UIHelpers {
+ /**
+ * Helper method to copy text to clipboard
+ * @param {string} text
+ * @return {boolean}
+ */
+ public static copyToClipboard(text: string): boolean {
+ try {
+ // create ghost element
+ const input = document.createElement('input');
+ input.setAttribute('readonly', 'readonly');
+ input.setAttribute('value', text);
+ document.body.appendChild(input);
+
+ // use DOM commands
+ input.select();
+ document.execCommand('copy');
+
+ // flush
+ document.body.removeChild(input);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ /**
+ * Helper method to download byte array as a file
+ *
+ * @param {Uint8Array | string} bytes Byte array to be downloaded as a file
+ * @param {string} fileName
+ * @param {string} fileMimeType
+ * @return {Observable}
+ */
+ public static downloadBytesAsFile(bytes: Uint8Array | string, fileName: string, fileMimeType: string): Promise {
+ return new Promise((resolve) => {
+ const blob = new Blob([bytes], {
+ type: fileMimeType,
+ });
+ const url = window.URL.createObjectURL(blob);
+
+ // - create link ()
+ const a = document.createElement('a');
+ const event = new MouseEvent('click');
+ a.download = fileName;
+ a.href = url;
+ // - start download
+ a.dispatchEvent(event);
+ resolve(true);
+ });
+ }
+}
diff --git a/src/core/utils/URLHelpers.ts b/src/core/utils/URLHelpers.ts
new file mode 100644
index 0000000..0ca80cb
--- /dev/null
+++ b/src/core/utils/URLHelpers.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { UrlValidator } from '../validation/validators';
+import { URLInfo } from '@/core/utils/URLInfo';
+
+export class URLHelpers {
+ public static formatUrl = (rawUrl: string): URLInfo => {
+ if (!UrlValidator.validate(rawUrl)) {
+ throw new Error(`Invalid URL: ${rawUrl}`);
+ }
+ const url = new URL(rawUrl);
+ return new URLInfo(url.protocol, url.hostname, url.port, rawUrl);
+ };
+
+ public static httpToWsUrl = (url: string) => {
+ if (UrlValidator.validate(url)) {
+ return url.replace('http', 'ws');
+ }
+ };
+
+ /**
+ * Get full node url and add missing pieces
+ * @param {string} fromUrl
+ * @return {string}
+ */
+ public static getNodeUrl(fromUrl: string): string {
+ let fixedUrl = -1 === fromUrl.indexOf('://') ? 'http://' + fromUrl : fromUrl;
+
+ fixedUrl = !fixedUrl.match(/https?:\/\/[^:]+:([0-9]+)\/?$/)
+ ? fixedUrl + ':3000' // default adds :3000
+ : fixedUrl;
+
+ const url = URLHelpers.formatUrl(fixedUrl);
+ return url.protocol + '//' + url.hostname + (url.port ? ':' + url.port : ':3000');
+ }
+}
diff --git a/src/core/utils/URLInfo.ts b/src/core/utils/URLInfo.ts
new file mode 100644
index 0000000..85056ca
--- /dev/null
+++ b/src/core/utils/URLInfo.ts
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+export class URLInfo {
+ constructor(public readonly protocol, public readonly hostname, public readonly port: string, public readonly url: string) {}
+}
diff --git a/src/core/utils/WebClient.ts b/src/core/utils/WebClient.ts
new file mode 100644
index 0000000..a6c0563
--- /dev/null
+++ b/src/core/utils/WebClient.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import request from 'request';
+
+export class WebClient {
+ public static async request(content: string, options: request.Options) {
+ const contentBuf = new Buffer(content);
+ if (!options.headers) {
+ options.headers = {};
+ }
+ options.headers['Content-Length'] = contentBuf.byteLength;
+
+ return WebClient.httpRequest(contentBuf, options);
+ }
+
+ private static async httpRequest(content: Buffer, options: request.Options) {
+ let isCalled = false;
+ return new Promise((resolve, reject) => {
+ const req = request(options, (err, res, body) => {
+ if (isCalled) {
+ return console.error(null, 'Multiple requests');
+ }
+ isCalled = true;
+ if (err) {
+ reject(err);
+ }
+ resolve(body);
+ });
+ req.write(content);
+ req.end();
+ });
+ }
+}
diff --git a/src/core/validation/CustomValidationRules.ts b/src/core/validation/CustomValidationRules.ts
new file mode 100644
index 0000000..122d93e
--- /dev/null
+++ b/src/core/validation/CustomValidationRules.ts
@@ -0,0 +1,206 @@
+// external dependencies
+import { extend } from 'vee-validate';
+import i18n from '@/language';
+import { Account, Address, NetworkType, Password, NamespaceId } from 'symbol-sdk';
+// internal dependencies
+import { ProfileService } from '@/services/ProfileService';
+import { NotificationType } from '@/core/utils/NotificationType';
+import { AppStore } from '@/app/AppStore';
+// configuration
+import { networkConfig, appConfig } from '@/config';
+import {
+ AddressValidator,
+ AliasValidator,
+ MaxDecimalsValidator,
+ MaxMessageValidator,
+ PublicKeyValidator,
+ UrlValidator,
+} from './validators';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { AccountService } from '@/services/AccountService';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { Values } from 'vue-i18n';
+import { PositiveDecimalNumberValidator } from './validators/PositiveDecimalNumberValidator';
+
+// TODO CustomValidationRules needs to be created when the network configuration is resolved, UI
+// needs to use the resolved CustomValidationRules
+// ATM rules are using the hardcoded file
+const currentNetwork: NetworkConfigurationModel = networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults;
+const { MIN_PASSWORD_LENGTH, DECIMAL_SEPARATOR } = appConfig.constants;
+
+export class CustomValidationRules {
+ /**
+ * Registers custom validation rules
+ * @static
+ */
+ public static register(): void {
+ extend('address', {
+ validate: (value) => {
+ return AddressValidator.validate(value);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.ADDRESS_INVALID, values)}`,
+ });
+
+ extend('maxDecimals', {
+ validate: (value, args: any) => {
+ const { maxDecimalNumber } = args;
+ return MaxDecimalsValidator.validate(value, maxDecimalNumber);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('max_decimal_number_error', values)}`,
+ params: ['maxDecimalNumber'],
+ });
+
+ extend('maxMessage', {
+ validate: (value, args: any) => {
+ const { maxMessageNumber } = args;
+ return MaxMessageValidator.validate(value, maxMessageNumber);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('max_message_length_error', values)}`,
+ params: ['maxMessageNumber'],
+ });
+
+ extend('positiveDecimal', {
+ validate: (value) => PositiveDecimalNumberValidator.validate(value),
+ message: () => i18n.t('positive_decimal_error', { decimalSeparator: DECIMAL_SEPARATOR }).toString(),
+ });
+
+ extend('addressOrAlias', {
+ validate: async (value) => {
+ const isValidAddress = AddressValidator.validate(value);
+ const isValidAlias = AliasValidator.validate(value);
+ if (isValidAddress) {
+ return true;
+ }
+ if (isValidAlias) {
+ await AppStore.dispatch('namespace/GET_LINKED_ADDRESS', new NamespaceId(value));
+ return !!AppStore.getters['namespace/linkedAddress'];
+ }
+ return false;
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('error_incorrect_field', values)}`,
+ });
+
+ extend('addressOrAliasNetworkType', {
+ validate: (value, args: any) => {
+ const { networkType } = args;
+ if (!AddressValidator.validate(value)) {
+ return true;
+ }
+ return Address.createFromRawAddress(value).networkType == networkType;
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.NETWORK_TYPE_INVALID, values)}`,
+ params: ['networkType'],
+ });
+
+ extend('url', {
+ validate: (value) => {
+ return UrlValidator.validate(value);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('error_incorrect_url', values)}`,
+ });
+
+ extend('confirmPassword', {
+ validate(value, args: any) {
+ const { target } = args;
+ return value === target;
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.PASSWORDS_NOT_MATCHING, values)}`,
+ params: ['target'],
+ });
+
+ extend('newAccountName', {
+ validate(value) {
+ const currentProfile = new ProfileService().getProfileByName(value);
+ return !(currentProfile && currentProfile.accounts.length > 0);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.PROFILE_NAME_EXISTS_ERROR, values)}`,
+ });
+
+ extend('profilePassword', {
+ validate(value) {
+ if (!value || value.length < 8) {
+ return false;
+ }
+
+ const currentProfile: ProfileModel = AppStore.getters['profile/currentProfile'];
+ const currentHash = currentProfile.password;
+ const inputHash = ProfileService.getPasswordHash(new Password(value));
+ return inputHash === currentHash;
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.WRONG_PASSWORD_ERROR, values)}`,
+ });
+
+ extend('profileAccountName', {
+ validate(value) {
+ const accountService = new AccountService();
+
+ // - fetch current profile accounts
+ const currentProfile: ProfileModel = AppStore.getters['profile/currentProfile'];
+ const knownAccounts = Object.values(accountService.getKnownAccounts(currentProfile.accounts));
+ return undefined === knownAccounts.find((w) => value === w.name);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.ERROR_ACCOUNT_NAME_ALREADY_EXISTS, values)}`,
+ });
+
+ extend('privateKey', {
+ validate(value) {
+ try {
+ Account.createFromPrivateKey(value, NetworkType.MIJIN_TEST);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t(NotificationType.PROFILE_NAME_EXISTS_ERROR, values)}`,
+ });
+
+ extend('addressOrPublicKey', {
+ validate: (value) => {
+ const isValidAddress = AddressValidator.validate(value);
+ const currentProfile: ProfileModel = AppStore.getters['profile/currentProfile'];
+ const isValidPublicKey = PublicKeyValidator.validate(value, currentProfile.networkType);
+ if (isValidAddress || isValidPublicKey) {
+ return true;
+ }
+ return false;
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('error_incorrect_field', values)}`,
+ });
+
+ extend('maxNamespaceDuration', {
+ validate: (value) => {
+ return value <= currentNetwork.maxNamespaceDuration;
+ },
+ message: (_fieldName: string, values: Values) => {
+ return `${i18n.t('error_incorrect_field', { ...values, maxValue: currentNetwork.maxNamespaceDuration })}`;
+ },
+ });
+
+ extend('passwordRegex', {
+ validate: (value) => {
+ return new RegExp(`(?=.*[0-9])(?=.*[a-zA-Z])(.{${MIN_PASSWORD_LENGTH},})$`).test(value);
+ },
+ message: `${i18n.t('error_new_password_format')}`,
+ });
+
+ extend('in', {
+ validate: (value, array: string[]) => {
+ if (!array) {
+ return false;
+ }
+ return array.includes(value);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('error_not_exist', values)}`,
+ });
+
+ extend('profileExists', {
+ validate: (value, profileNames: string[]) => {
+ if (!profileNames) {
+ return false;
+ }
+ return profileNames.includes(value);
+ },
+ message: (_fieldName: string, values: Values) => `${i18n.t('error_profile_does_not_exist', values)}`,
+ });
+ }
+}
diff --git a/src/core/validation/ErrorMessages.ts b/src/core/validation/ErrorMessages.ts
new file mode 100644
index 0000000..7d18347
--- /dev/null
+++ b/src/core/validation/ErrorMessages.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { configure } from 'vee-validate';
+import i18n from '@/language';
+
+export class ErrorMessages {
+ /**
+ * Loads error messages
+ * @static
+ */
+ public static load() {
+ return new ErrorMessages().loadStandardValidationRulesMessages();
+ }
+
+ /**
+ * Maps translation messages passed to i18n
+ * to the validation rules shipped with vee-validate
+ * @private
+ */
+ private loadStandardValidationRulesMessages() {
+ configure({
+ // @ts-ignore
+ defaultMessage: (_, values) => i18n.t(`validation.${values._rule_}`, values),
+ });
+ }
+}
diff --git a/src/core/validation/InitializeVeeValidate.ts b/src/core/validation/InitializeVeeValidate.ts
new file mode 100644
index 0000000..90feb06
--- /dev/null
+++ b/src/core/validation/InitializeVeeValidate.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { StandardValidationRules } from '@/core/validation/StandardValidationRules';
+
+export class VeeValidateSetup {
+ /**
+ * Initialize Vee Validate custom settings
+ * @static
+ */
+ public static initialize() {
+ const setup = new VeeValidateSetup();
+ setup.registerValidationRules();
+ }
+
+ private registerValidationRules() {
+ StandardValidationRules.register();
+ }
+}
diff --git a/src/core/validation/StandardValidationRules.ts b/src/core/validation/StandardValidationRules.ts
new file mode 100644
index 0000000..083a743
--- /dev/null
+++ b/src/core/validation/StandardValidationRules.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { extend } from 'vee-validate';
+import { digits, excluded, integer, is, is_not, max_value, max, min_value, min, regex, required } from 'vee-validate/dist/rules';
+
+export class StandardValidationRules {
+ /**
+ * Registers validation rules shipped with vee-validate
+ * @static
+ */
+ public static register() {
+ extend('digits', digits);
+ extend('excluded', excluded);
+ extend('integer', integer);
+ extend('is', is);
+ extend('is_not', is_not);
+ extend('max_value', max_value);
+ extend('max', max);
+ extend('min_value', min_value);
+ extend('min', min);
+ extend('regex', regex);
+ extend('required', required);
+ }
+}
diff --git a/src/core/validation/ValidationRuleset.ts b/src/core/validation/ValidationRuleset.ts
new file mode 100644
index 0000000..d413ca4
--- /dev/null
+++ b/src/core/validation/ValidationRuleset.ts
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// configuration
+import { appConfig } from '@/config';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+import { networkConfig } from '@/config';
+import { NetworkType } from 'symbol-sdk';
+
+const { MIN_PASSWORD_LENGTH } = appConfig.constants;
+
+export const createValidationRuleSet = ({
+ maxMessageSize,
+ maxMosaicAtomicUnits,
+ maxMosaicDivisibility,
+ maxMosaicDuration,
+ minNamespaceDuration,
+}: NetworkConfigurationModel) => {
+ return {
+ address: 'required|address|addressNetworkType:currentProfile',
+ profilePassword: 'required|profilePassword',
+ addressOrAlias: 'required|addressOrAlias|addressOrAliasNetworkType:currentProfile',
+ amount: `positiveDecimal|maxDecimals:${maxMosaicDivisibility}`,
+ confirmPassword: 'required|confirmPassword:@newPassword',
+ divisibility: 'required|min_value:0|max_value:6|integer',
+ duration: `required|min_value:0|max_value:${maxMosaicDuration}`,
+ generationHash: 'required|min:64|max:64',
+ mosaicId: 'required|mosaicId',
+ message: `maxMessage:${maxMessageSize}`,
+ namespaceDuration: `required|min_value:${
+ minNamespaceDuration / networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults.blockGenerationTargetTime
+ }|maxNamespaceDuration`,
+ namespaceName: {
+ required: true,
+ regex: '^[a-z0-9]{1}[a-z0-9-_]{0,63}$',
+ },
+ subNamespaceName: {
+ required: true,
+ regex: '^[a-z0-9]{1}[a-z0-9-_]{0,63}$',
+ },
+ password: `required|min:${MIN_PASSWORD_LENGTH}|passwordRegex`,
+ previousPassword: 'required|confirmLock:cipher',
+ privateKey: 'min:64|max:64|privateKey',
+ recipientPublicKey: 'required|publicKey',
+ supply: `required|integer|min_value: 1|max_value:${maxMosaicAtomicUnits}`,
+ url: 'required|url',
+ newAccountName: 'required|newAccountName',
+ profileAccountName: 'required|profileAccountName',
+ addressOrPublicKey: 'addressOrPublicKey',
+ email: {
+ regex: '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$',
+ },
+ contactName: {
+ required: true,
+ regex: '^(?!\\s*$).+',
+ },
+ };
+};
+
+// TODO ValidationRuleset needs to be created when the network configuration is resolved, UI needs
+// to use the resolved ValidationResulset ATM rules are using the hardocded ones
+export const ValidationRuleset = createValidationRuleSet(networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults);
diff --git a/src/core/validation/VeeValidateSetup.ts b/src/core/validation/VeeValidateSetup.ts
new file mode 100644
index 0000000..90c7cd4
--- /dev/null
+++ b/src/core/validation/VeeValidateSetup.ts
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { StandardValidationRules } from '@/core/validation/StandardValidationRules';
+import { CustomValidationRules } from '@/core/validation/CustomValidationRules';
+import { ErrorMessages } from '@/core/validation/ErrorMessages';
+
+export class VeeValidateSetup {
+ /**
+ * Initialize Vee Validate custom settings
+ * @static
+ */
+ public static initialize() {
+ const setup = new VeeValidateSetup();
+ setup.registerValidationRules();
+ setup.loadErrorMessages();
+ }
+
+ /**
+ * Registers validation rules
+ * @private
+ */
+ private registerValidationRules() {
+ StandardValidationRules.register();
+ CustomValidationRules.register();
+ }
+
+ /**
+ * Loads error messages
+ * @private
+ */
+ private loadErrorMessages() {
+ ErrorMessages.load();
+ }
+}
diff --git a/src/core/validation/validators/AddressValidator.ts b/src/core/validation/validators/AddressValidator.ts
new file mode 100644
index 0000000..02ca0ab
--- /dev/null
+++ b/src/core/validation/validators/AddressValidator.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address } from 'symbol-sdk';
+
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class AddressValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any): boolean {
+ try {
+ Address.createFromRawAddress(value);
+ return true;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/src/core/validation/validators/AliasValidator.ts b/src/core/validation/validators/AliasValidator.ts
new file mode 100644
index 0000000..ddff4f6
--- /dev/null
+++ b/src/core/validation/validators/AliasValidator.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NamespaceId } from 'symbol-sdk';
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class AliasValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any): boolean {
+ try {
+ new NamespaceId(value);
+ return value;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/src/core/validation/validators/DerivationPathValidator.ts b/src/core/validation/validators/DerivationPathValidator.ts
new file mode 100644
index 0000000..a915002
--- /dev/null
+++ b/src/core/validation/validators/DerivationPathValidator.ts
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+import { NetworkType } from 'symbol-sdk';
+
+@staticImplements()
+export class DerivationPathValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {string} value
+ * @param {NetworkType} networkType
+ * @returns {({valid: boolean|string})}
+ */
+ public static validate(value: any, networkType: NetworkType): boolean {
+ if (networkType === NetworkType.MAIN_NET) {
+ if (value.match(/^m\/44'\/4343'\/[0-9]+'\/[0-9]+'\/[0-9]+'/)) {
+ return value;
+ }
+ } else {
+ if (value.match(/^m\/44'\/1'\/[0-9]+'\/[0-9]+'\/[0-9]+'/)) {
+ return value;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/core/validation/validators/MaxDecimalsValidator.ts b/src/core/validation/validators/MaxDecimalsValidator.ts
new file mode 100644
index 0000000..8fde110
--- /dev/null
+++ b/src/core/validation/validators/MaxDecimalsValidator.ts
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Validator, staticImplements } from './Validator';
+import { appConfig } from '@/config';
+const { DECIMAL_SEPARATOR } = appConfig.constants;
+
+@staticImplements()
+export class MaxDecimalsValidator {
+ /**
+ * Validates the max number of decimals in a number
+ * @static
+ * @param {*} value
+ * @param {number} maxDecimalNumber
+ * @returns {boolean}
+ */
+ public static validate(value: any, maxDecimalNumber: number): boolean {
+ if (Math.floor(value) == value) {
+ return true;
+ }
+ const split: string[] = value.toString().split(DECIMAL_SEPARATOR);
+
+ if (split.length <= 1) {
+ return true;
+ }
+
+ if (split.length !== 2) {
+ return false;
+ }
+
+ const decimalNumber = split[1].length || 0;
+ return decimalNumber <= maxDecimalNumber;
+ }
+}
diff --git a/src/core/validation/validators/MaxMessageValidator.ts b/src/core/validation/validators/MaxMessageValidator.ts
new file mode 100644
index 0000000..bdc70c5
--- /dev/null
+++ b/src/core/validation/validators/MaxMessageValidator.ts
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class MaxMessageValidator {
+ /**
+ * Validates the max bytes of message
+ * @static
+ * @param {*} value
+ * @param {number} maxMessageNumber
+ * @returns {boolean}
+ */
+ public static validate(value: any, maxMessageNumber: number): boolean {
+ const bytes: number = new TextEncoder().encode(value).length;
+ return bytes < maxMessageNumber;
+ }
+}
diff --git a/src/core/validation/validators/MosaicIdValidator.ts b/src/core/validation/validators/MosaicIdValidator.ts
new file mode 100644
index 0000000..c791d11
--- /dev/null
+++ b/src/core/validation/validators/MosaicIdValidator.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { MosaicId } from 'symbol-sdk';
+
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class MosaicIdValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any): boolean {
+ try {
+ new MosaicId(value);
+ return value;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/src/core/validation/validators/NamespaceIdValidator.ts b/src/core/validation/validators/NamespaceIdValidator.ts
new file mode 100644
index 0000000..58b9321
--- /dev/null
+++ b/src/core/validation/validators/NamespaceIdValidator.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NamespaceId } from 'symbol-sdk';
+
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class NamespaceIdValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any): boolean {
+ try {
+ new NamespaceId(value);
+ return true;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/src/core/validation/validators/PositiveDecimalNumberValidator.ts b/src/core/validation/validators/PositiveDecimalNumberValidator.ts
new file mode 100644
index 0000000..983e6a4
--- /dev/null
+++ b/src/core/validation/validators/PositiveDecimalNumberValidator.ts
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Validator, staticImplements } from './Validator';
+import { appConfig } from '@/config';
+const { DECIMAL_SEPARATOR } = appConfig.constants;
+
+@staticImplements()
+export class PositiveDecimalNumberValidator {
+ private static regex = new RegExp(`^\\s*\\d+(\\${DECIMAL_SEPARATOR}\\d*)?\\s*$`);
+
+ /**
+ * Validates the value is a valid decimal number
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any): boolean {
+ return this.regex.test(value.toString());
+ }
+}
diff --git a/src/core/validation/validators/PrivateKeyValidator.ts b/src/core/validation/validators/PrivateKeyValidator.ts
new file mode 100644
index 0000000..d6dad0e
--- /dev/null
+++ b/src/core/validation/validators/PrivateKeyValidator.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkType, Account } from 'symbol-sdk';
+
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class PrivateKeyValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any, networkType?: NetworkType): boolean {
+ try {
+ Account.createFromPrivateKey(value, networkType);
+ return true;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/src/core/validation/validators/PublicKeyValidator.ts b/src/core/validation/validators/PublicKeyValidator.ts
new file mode 100644
index 0000000..49a49ba
--- /dev/null
+++ b/src/core/validation/validators/PublicKeyValidator.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { NetworkType, PublicAccount } from 'symbol-sdk';
+
+// internal dependencies
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class PublicKeyValidator {
+ /**
+ * Executes the validator
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: any, networkType?: NetworkType): boolean {
+ try {
+ PublicAccount.createFromPublicKey(value, networkType);
+ return value;
+ } catch (error) {
+ return false;
+ }
+ }
+}
diff --git a/src/core/validation/validators/UrlValidator.ts b/src/core/validation/validators/UrlValidator.ts
new file mode 100644
index 0000000..4d61d5b
--- /dev/null
+++ b/src/core/validation/validators/UrlValidator.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Validator, staticImplements } from './Validator';
+
+@staticImplements()
+export class UrlValidator {
+ /**
+ * Validates an URL
+ * @static
+ * @param {*} value
+ * @returns {boolean}
+ */
+ public static validate(value: string): boolean {
+ const regStr =
+ '^' + // position at start
+ '(https?:\\/\\/)?' + //protocol
+ '((([a-zA-Z\\d]{1,}([-\\.]{1}[a-zA-Z\\d]{1,})*\\.[a-zA-Z]+)' + // domain name
+ '|((\\d{1,3}\\.){3}\\d{1,3}))' + // ip(v4) address
+ '(\\:\\d+)?)' + // port
+ '|localhost\\:\\d+'; // localhost:8080
+ const pattern = new RegExp(regStr, 'i');
+ return pattern.test(value);
+ }
+}
diff --git a/src/core/validation/validators/Validator.ts b/src/core/validation/validators/Validator.ts
new file mode 100644
index 0000000..1dd578d
--- /dev/null
+++ b/src/core/validation/validators/Validator.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+/**
+ * Validator interface
+ * @interface Validator
+ */
+export interface Validator {
+ new (): void;
+ /**
+ * Validates a value
+ * @param {*} value
+ * @param {*} [args]
+ * @returns {boolean}
+ */
+ validate(value: any, args?: any): boolean;
+}
+
+/**
+ * Decorator that enables typing classes with static methods
+ */
+export function staticImplements() {
+ return (constructor: U) => {
+ constructor;
+ };
+}
diff --git a/src/core/validation/validators/index.ts b/src/core/validation/validators/index.ts
new file mode 100644
index 0000000..9a373c7
--- /dev/null
+++ b/src/core/validation/validators/index.ts
@@ -0,0 +1,11 @@
+export * from './AddressValidator';
+export * from './AliasValidator';
+export * from './DerivationPathValidator';
+export * from './MaxDecimalsValidator';
+export * from './MaxMessageValidator';
+export * from './MosaicIdValidator';
+export * from './NamespaceIdValidator';
+export * from './PublicKeyValidator';
+export * from './PrivateKeyValidator';
+export * from './UrlValidator';
+export * from './Validator';
diff --git a/src/directives/clickOutside.ts b/src/directives/clickOutside.ts
new file mode 100644
index 0000000..0730bc8
--- /dev/null
+++ b/src/directives/clickOutside.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { DirectiveBinding } from 'vue/types/options';
+import { VNode } from 'vue';
+
+let clickOutsideEvent: EventListener;
+
+const clickOutsideDirective = {
+ bind: function (el: HTMLElement, binding: DirectiveBinding, vnode: VNode) {
+ clickOutsideEvent = function (event: Event): void {
+ if (el === event.target || el.contains(event.target as Node)) {
+ return;
+ }
+
+ if (vnode.context) {
+ vnode.context[binding.expression](event);
+ }
+ };
+
+ document.body.addEventListener('click', clickOutsideEvent);
+ },
+ unbind: function (): void {
+ document.body.removeEventListener('click', clickOutsideEvent);
+ },
+};
+
+export default clickOutsideDirective;
diff --git a/src/documents/terms.json b/src/documents/terms.json
new file mode 100644
index 0000000..15b6c6b
--- /dev/null
+++ b/src/documents/terms.json
@@ -0,0 +1,3 @@
+{
+ "base64": "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bWFsL0NBIDE+Pg0KZW5kb2JqDQo5IDAgb2JqDQo8PC9UeXBlL0ZvbnQvU3VidHlwZS9UcnVlVHlwZS9OYW1lL0YyL0Jhc2VGb250L0FyaWFsLUJvbGRNVC9FbmNvZGluZy9XaW5BbnNpRW5jb2RpbmcvRm9udERlc2NyaXB0b3IgMTAgMCBSL0ZpcnN0Q2hhciAzMi9MYXN0Q2hhciAxMjEvV2lkdGhzIDcwNCAwIFI+Pg0KZW5kb2JqDQoxMCAwIG9iag0KPDwvVHlwZS9Gb250RGVzY3JpcHRvci9Gb250TmFtZS9BcmlhbC1Cb2xkTVQvRmxhZ3MgMzIvSXRhbGljQW5nbGUgMC9Bc2NlbnQgOTA1L0Rlc2NlbnQgLTIxMC9DYXBIZWlnaHQgNzI4L0F2Z1dpZHRoIDQ3OS9NYXhXaWR0aCAyNjI4L0ZvbnRXZWlnaHQgNzAwL1hIZWlnaHQgMjUwL0xlYWRpbmcgMzMvU3RlbVYgNDcvRm9udEJCb3hbIC02MjggLTIxMCAyMDAwIDcyOF0gPj4NCmVuZG9iag0KMTEgMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1R5cGUwL0Jhc2VGb250L0FyaWFsLUJvbGRNVC9FbmNvZGluZy9JZGVudGl0eS1IL0Rlc2NlbmRhbnRGb250cyAxMiAwIFIvVG9Vbmljb2RlIDcwMSAwIFI+Pg0KZW5kb2JqDQoxMiAwIG9iag0KWyAxMyAwIFJdIA0KZW5kb2JqDQoxMyAwIG9iag0KPDwvQmFzZUZvbnQvQXJpYWwtQm9sZE1UL1N1YnR5cGUvQ0lERm9udFR5cGUyL1R5cGUvRm9udC9DSURUb0dJRE1hcC9JZGVudGl0eS9EVyAxMDAwL0NJRFN5c3RlbUluZm8gMTQgMCBSL0ZvbnREZXNjcmlwdG9yIDE1IDAgUi9XIDcwMyAwIFI+Pg0KZW5kb2JqDQoxNCAwIG9iag0KPDwvT3JkZXJpbmcoSWRlbnRpdHkpIC9SZWdpc3RyeShBZG9iZSkgL1N1cHBsZW1lbnQgMD4+DQplbmRvYmoNCjE1IDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0FyaWFsLUJvbGRNVC9GbGFncyAzMi9JdGFsaWNBbmdsZSAwL0FzY2VudCA5MDUvRGVzY2VudCAtMjEwL0NhcEhlaWdodCA3MjgvQXZnV2lkdGggNDc5L01heFdpZHRoIDI2MjgvRm9udFdlaWdodCA3MDAvWEhlaWdodCAyNTAvTGVhZGluZyAzMy9TdGVtViA0Ny9Gb250QkJveFsgLTYyOCAtMjEwIDIwMDAgNzI4XSAvRm9udEZpbGUyIDcwMiAwIFI+Pg0KZW5kb2JqDQoxNiAwIG9iag0KPDwvVHlwZS9Gb250L1N1YnR5cGUvVHJ1ZVR5cGUvTmFtZS9GNC9CYXNlRm9udC9BcmlhbE1UL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZy9Gb250RGVzY3JpcHRvciAxNyAwIFIvRmlyc3RDaGFyIDMyL0xhc3RDaGFyIDE2My9XaWR0aHMgNzA4IDAgUj4+DQplbmRvYmoNCjE3IDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlwdG9yL0ZvbnROYW1lL0FyaWFsTVQvRmxhZ3MgMzIvSXRhbGljQW5nbGUgMC9Bc2NlbnQgOTA1L0Rlc2NlbnQgLTIxMC9DYXBIZWlnaHQgNzI4L0F2Z1dpZHRoIDQ0MS9NYXhXaWR0aCAyNjY1L0ZvbnRXZWlnaHQgNDAwL1hIZWlnaHQgMjUwL0xlYWRpbmcgMzMvU3RlbVYgNDQvRm9udEJCb3hbIC02NjUgLTIxMCAyMDAwIDcyOF0gPj4NCmVuZG9iag0KMTggMCBvYmoNCjw8L1R5cGUvRm9udC9TdWJ0eXBlL1R5cGUwL0Jhc2VGb250L0FyaWFsTVQvRW5jb2RpbmcvSWRlbnRpdHktSC9EZXNjZW5kYW50Rm9udHMgMTkgMCBSL1RvVW5pY29kZSA3MDUgMCBSPj4NCmVuZG9iag0KMTkgMCBvYmoNClsgMjAgMCBSXSANCmVuZG9iag0KMjAgMCBvYmoNCjw8L0Jhc2VGb250L0FyaWFsTVQvU3VidHlwZS9DSURGb250VHlwZTIvVHlwZS9Gb250L0NJRFRvR0lETWFwL0lkZW50aXR5L0RXIDEwMDAvQ0lEU3lzdGVtSW5mbyAyMSAwIFIvRm9udERlc2NyaXB0b3IgMjIgMCBSL1cgNzA3IDAgUj4+DQplbmRvYmoNCjIxIDAgb2JqDQo8PC9PcmRlcmluZyhJZGVudGl0eSkgL1JlZ2lzdHJ5KEFkb2JlKSAvU3VwcGxlbWVudCAwPj4NCmVuZG9iag0KMjIgMCBvYmoNCjw8L1R5cGUvRm9udERlc2NyaXB0b3IvRm9udE5hbWUvQXJpYWxNVC9GbGFncyAzMi9JdGFsaWNBbmdsZSAwL0FzY2VudCA5MDUvRGVzY2VudCAtMjEwL0NhcEhlaWdodCA3MjgvQXZnV2lkdGggNDQxL01heFdpZHRoIDI2NjUvRm9udFdlaWdodCA0MDAvWEhlaWdodCAyNTAvTGVhZGluZyAzMy9TdGVtViA0NC9Gb250QkJveFsgLTY2NSAtMjEwIDIwMDAgNzI4XSAvRm9udEZpbGUyIDcwNiAwIFI+Pg0KZW5kb2JqDQoyMyAwIG9iag0KPDwvU3VidHlwZS9MaW5rL1JlY3RbIDY4LjY1IDMzMy40MyAyMDYuMzQgMzU5LjUxXSAvQlM8PC9XIDA+Pi9GIDQvQTw8L1R5cGUvQWN0aW9uL1MvVVJJL1VSSShtYWlsdG86c3ltYm9sdGVybXNAbmVtLmdyb3VwKSA+Pi9TdHJ1Y3RQYXJlbnQgMT4+DQplbmRvYmoNCjI0IDAgb2JqDQo8PC9TdWJ0eXBlL0xpbmsvUmVjdFsgMTE1IDEwNC4wMyAzMzYuMDIgMTE2LjFdIC9CUzw8L1cgMD4+L0YgNC9BPDwvVHlwZS9BY3Rpb24vUy9VUkkvVVJJKGh0dHBzOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjApID4+L1N0cnVjdFBhcmVudCAyPj4NCmVuZG9iag0KMjUgMCBvYmoNCjw8L1R5cGUvUGFnZS9QYXJlbnQgMiAwIFIvUmVzb3VyY2VzPDwvRm9udDw8L0YxIDUgMCBSL0Y0IDE2IDAgUi9GMyAxMSAwIFIvRjIgOSAwIFI+Pi9FeHRHU3RhdGU8PC9HUzcgNyAwIFIvR1M4IDggMCBSPj4vUHJvY1NldFsvUERGL1RleHQvSW1hZ2VCL0ltYWdlQy9JbWFnZUldID4+L0Fubm90c1sgMjcgMCBSXSAvTWVkaWFCb3hbIDAgMCA1OTUuMDIgODQxLjk4XSAvQ29udGVudHMgMjYgMCBSL0dyb3VwPDwvVHlwZS9Hcm91cC9TL1RyYW5zcGFyZW5jeS9DUy9EZXZpY2VSR0I+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TGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoxOTYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMDEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMDYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMTEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMTYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMjEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyMjcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMzIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyMzcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyNDIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQoyNDcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyNTggMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyNjUgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyNzAgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyODIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyODcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQoyOTYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozMDEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozMTQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozMTkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozMjQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozMjkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozMzQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozMzkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozNDkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozNTQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozNTkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozNjQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozNjkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozNzQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozODAgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozODUgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQozOTAgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQozOTYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0MDMgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0MDggMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0MTcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0MjIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0MjcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo0MzIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo0MzggMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0NDUgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo0NjAgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0NjkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0NzQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0ODYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo0OTEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo1MDYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo1MTEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo1MzYgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1NDEgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo1NTQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo1NTkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1NjQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1NjkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1NzMgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1NzkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1ODQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1ODkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1OTQgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo1OTkgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0xvd2VyQWxwaGE+Pg0KZW5kb2JqDQo2MTIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo2MTcgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo2MjIgMCBvYmoNCjw8L08vTGlzdC9MaXN0TnVtYmVyaW5nL0RlY2ltYWw+Pg0KZW5kb2JqDQo2MjcgMCBvYmoNCjw8L08v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V148Wjvj056fPZbthrWLZzuW5/zKXlZz80f7rJMuJrr/Liq8Y+ARFjseeKHYjb1QIu3pNrGW1xt+/gn9c1mSt+KwVNqxp28e7/5ltuFRf9fK3CNctwzFVxbMYWAAANTlhkoNCmVuZHN0cmVhbQ0KZW5kb2JqDQo3MDMgMCBvYmoNClsgMFsgNzUwXSAgM1sgMjc4XSAgOVsgNzIyXSAgMTFbIDMzMyAzMzNdICAxNVsgMjc4IDMzMyAyNzggMjc4IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiAzMzNdICAzNlsgNzIyIDcyMiA3MjIgNzIyIDY2NyA2MTEgNzc4IDcyMiAyNzggNTU2IDcyMiA2MTEgODMzIDcyMiA3NzggNjY3XSAgNTNbIDcyMiA2NjcgNjExIDcyMiA2NjcgOTQ0IDY2NyA2NjddICA2NlsgNTU2XSAgNjhbIDU1NiA2MTEgNTU2IDYxMSA1NTYgMzMzIDYxMSA2MTEgMjc4IDI3OCA1NTYgMjc4IDg4OSA2MTEgNjExIDYxMV0gIDg1WyAzODkgNTU2IDMzMyA2MTEgNTU2IDc3OCA1NTYgNTU2XSAgMTc3WyA1NTZdICAxNzlbIDUwMCA1MDBdIF0gDQplbmRvYmoNCjcwNCAwIG9iag0KWyAyNzggMCAwIDAgMCAwIDcyMiAwIDMzMyAzMzMgMCAwIDI3OCAzMzMgMjc4IDI3OCA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgMzMzIDAgMCAwIDAgMCAwIDcyMiA3MjIgNzIyIDcyMiA2NjcgNjExIDc3OCA3MjIgMjc4IDU1NiA3MjIgNjExIDgzMyA3MjIgNzc4IDY2NyAwIDcyMiA2NjcgNjExIDcyMiA2NjcgOTQ0IDY2NyA2NjcgMCAwIDAgMCAwIDU1NiAwIDU1NiA2MTEgNTU2IDYxMSA1NTYgMzMzIDYxMSA2MTEgMjc4IDI3OCA1NTYgMjc4IDg4OSA2MTEgNjExIDYxMSAwIDM4OSA1NTYgMzMzIDYxMSA1NTYgNzc4IDU1NiA1NTZdIA0KZW5kb2JqDQo3MDUgMCBvYmoNCjw8L0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMzUwPj4NCnN0cmVhbQ0KeJxl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N1sgNTU2IDgzMyA3MjIgNzc4IDY2N10gIDUzWyA3MjIgNjY3IDYxMSA3MjIgNjY3IDk0NCA2NjcgNjY3XSAgNjhbIDU1NiA1NTYgNTAwIDU1NiA1NTYgMjc4IDU1NiA1NTYgMjIyIDIyMiA1MDAgMjIyIDgzMyA1NTYgNTU2IDU1NiA1NTYgMzMzIDUwMCAyNzggNTU2IDUwMCA3MjIgNTAwIDUwMF0gIDEzM1sgNTU2XSAgMTc5WyAzMzMgMzMzIDIyMiAyMjJdIF0gDQplbmRvYmoNCjcwOCAwIG9iag0KWyAyNzggMCAzNTUgMCAwIDAgMCAxOTEgMzMzIDMzMyAwIDAgMjc4IDMzMyAyNzggMjc4IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiA1NTYgNTU2IDU1NiAyNzggMjc4IDAgNTg0IDAgMCAxMDE1IDY2NyA2NjcgNzIyIDcyMiA2NjcgNjExIDc3OCA3MjIgMjc4IDUwMCAwIDU1NiA4MzMgNzIyIDc3OCA2NjcgMCA3MjIgNjY3IDYxMSA3MjIgNjY3IDk0NCA2NjcgNjY3IDAgMCAwIDAgMCAwIDAgNTU2IDU1NiA1MDAgNTU2IDU1NiAyNzggNTU2IDU1NiAyMjIgMjIyIDUwMCAyMjIgODMzIDU1NiA1NTYgNTU2IDU1NiAzMzMgNTAwIDI3OCA1NTYgNTAwIDcyMiA1MDAgNTAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCA1NTZdIA0KZW5kb2JqDQo3MDkgMCBvYmoNClsgMjc4IDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgNTU2IDAgMCAwIDU1NiAwIDAgMCAyMjIgMCAwIDIyMiAwIDU1NiAwIDAgMCAzMzMgMCAyNzhdIA0KZW5kb2JqDQo3MTAgMCBvYmoNCjw8L1R5cGUvTWV0YWRhdGEvU3VidHlwZS9YTUwvTGVuZ3RoIDMwNjA+Pg0Kc3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/Pjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IjMuMS03MDEiPgo8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgo8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiAgeG1sbnM6cGRmPSJodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvIj4KPHBkZjpQcm9kdWNlcj5NaWNyb3NvZnTCriBXb3JkIDIwMTY8L3BkZjpQcm9kdWNlcj48L3JkZjpEZXNjcmlwdGlvbj4KPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyI+CjxkYzpjcmVhdG9yPjxyZGY6U2VxPjxyZGY6bGk+TmVpbCBMb3BlejwvcmRmOmxpPjwvcmRmOlNlcT48L2RjOmNyZWF0b3I+PC9yZGY6RGVzY3JpcHRpb24+CjxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iPgo8eG1wOkNyZWF0b3JUb29sPk1pY3Jvc29mdMKuIFdvcmQgMjAxNjwveG1wOkNyZWF0b3JUb29sPjx4bXA6Q3JlYXRlRGF0ZT4yMDIxLTAyLTE1VDEzOjQwOjQ5KzAxOjAwPC94bXA6Q3JlYXRlRGF0ZT48eG1wOk1vZGlmeURhdGU+MjAyMS0wMi0xNVQxMzo0MDo0OSswMTowMDwveG1wOk1vZGlmeURhdGU+PC9yZGY6RGVzY3JpcHRpb24+CjxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyI+Cjx4bXBNTTpEb2N1bWVudElEPnV1aWQ6Q0RBNUI2MEYtNUU3Qi00NDM3LUEyREMtMjQyRTVGMTgyQUQ1PC94bXBNTTpEb2N1bWVudElEPjx4bXBNTTpJbnN0YW5jZUlEPnV1aWQ6Q0RBNUI2MEYtNUU3Qi00NDM3LUEyREMtMjQyRTVGMTgyQUQ1PC94bXBNTTpJbnN0YW5jZUlEPjwvcmRmOkRlc2NyaXB0aW9uPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKPC9yZGY6UkRGPjwveDp4bXBtZXRhPjw/eHBhY2tldCBlbmQ9InciPz4NCmVuZHN0cmVhbQ0KZW5kb2JqDQo3MTEgMCBvYmoNCjw8L0Rpc3BsYXlEb2NUaXRsZSB0cnVlPj4NCmVuZG9iag0KNzEyIDAgb2JqDQo8PC9UeXBlL1hSZWYvU2l6ZSA3MTIvV1sgMSA0IDJdIC9Sb290IDEgMCBSL0luZm8gNDggMCBSL0lEWzwwRkI2QTVDRDdCNUUzNzQ0QTJEQzI0MkU1RjE4MkFENT48MEZCNkE1Q0Q3QjVFMzc0NEEyREMyNDJFNUYxODJBRDU+XSAvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCAxNjg5Pj4NCnN0cmVhbQ0KeJw92AmYjWUYxvFzDzNmBsOgscwww9j3FqJUU0qLpGwpJRFZSpsoFSVkKaFFRYkKCalURHaVpWRJFEJlTxlFi9L3vP/znK6uftdM9/ceM+c7c/4mFov+OXNG0X8zYzFjVkC1AkkDAlnzAuU7BSq0gkdgfqBi50ClAlgFewPZj8O6QM7qQOXegSqtYS0cCOQ+AesDecsDVW8PVMsI5F8baFEb1gQuOh1oPy3Q4atA3wWBfvxZhowODJ0TGH8qMLF6YMb2wKzSgSUlA59eGFizMPDZzsC2wsD2vMDB4YFDjQKHs6PvW/TvmFg9qA8NoCHUjYg182Uju+6f8FH0SUESFIGikAwpUAxSIVMxaZyf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NTI4IDAwMDAwIG4NCjAwMDAwMDc3NTUgMDAwMDAgbg0KMDAwMDAwNzg4MSAwMDAwMCBuDQowMDAwMDA3OTExIDAwMDAwIG4NCjAwMDAwMDgwNjUgMDAwMDAgbg0KMDAwMDAwODEzOSAwMDAwMCBuDQowMDAwMDA4Mzg0IDAwMDAwIG4NCjAwMDAwMDg1NDUgMDAwMDAgbg0KMDAwMDAwODcxOCAwMDAwMCBuDQowMDAwMDA5MDM2IDAwMDAwIG4NCjAwMDAwMTU0MDAgMDAwMDAgbg0KMDAwMDAxNTU1NyAwMDAwMCBuDQowMDAwMDE1ODY4IDAwMDAwIG4NCjAwMDAwMjE0MDkgMDAwMDAgbg0KMDAwMDAyMTcxMCAwMDAwMCBuDQowMDAwMDI3MzE2IDAwMDAwIG4NCjAwMDAwMjc2MTcgMDAwMDAgbg0KMDAwMDAzMjM5MyAwMDAwMCBuDQowMDAwMDMyNjg0IDAwMDAwIG4NCjAwMDAwMzcxMTEgMDAwMDAgbg0KMDAwMDAzNzQxMiAwMDAwMCBuDQowMDAwMDQyNzEyIDAwMDAwIG4NCjAwMDAwNDMwMjQgMDAwMDAgbg0KMDAwMDA0ODE0MSAwMDAwMCBuDQowMDAwMDQ4NDQzIDAwMDAwIG4NCjAwMDAwNTA2MTYgMDAwMDAgbg0KMDAwMDA1MDkwOCAwMDAwMCBuDQowMDAwMDU1MDI2IDAwMDAwIG4NCjAwMDAwNTUzMjggMDAwMDAgbg0KMDAwMDA1OTUyNCAwMDAwMCBuDQowMDAwMDU5Njk1IDAwMDAwIG4NCjAwMDAwNTk5MzEgMDAwMDAgbg0KMDAwMDAwMDA1MCA2NTUzNSBmDQowMDAwMDAwMDUxIDY1NTM1IGYNCjAwMDAwMDAwNTIgNjU1MzUgZg0KMDAwMDAwMDA1MyA2NTUzNSBmDQowMDAwMDAwMDU0IDY1NTM1IGYNCjAwMDAwMDAwNTUgNjU1MzUgZg0KMDAwMDAwMDA1NiA2NTUzNSBmDQowMDAwMDAwMDU3IDY1NTM1IGYNCjAwMDAwMDAwNTggNjU1MzUgZg0KMDAwMDAwMDA1OSA2NTUzNSBmDQowMDAwMDAwMDYwIDY1NTM1IGYNCjAwMDAwMDAwNjEgNjU1MzUgZg0KMDAwMDAwMDA2MiA2NTUzNSBmDQowMDAwMDAwMDYzIDY1NTM1IGYNCjAwMDAwMDAwNjQgNjU1MzUgZg0KMDAwMDAwMDA2NSA2NTUzNSBmDQowMDAwMDAwMDY3IDY1NTM1IGYNCjAwMDAwNjU5MzQgMDAwMDAgbg0KMDAwMDAwMDA2OCA2NTUzNSBmDQowMDAwMDAwMDY5IDY1NTM1IGYNCjAwMDAwMDAwNzAgNjU1MzUgZg0KMDAwMDAwMDA3MiA2NTUzNSBmDQowMDAwMDY1OTg3IDAwMDAwIG4NCjAwMDAwMDAwNzMgNjU1MzUgZg0KMDAwMDAwMDA3NCA2NTUzNSBmDQowMDAwMDAwMDc1IDY1NTM1IGYNCjAwMDAwMDAwNzYgNjU1MzUgZg0KMDAwMDAwMDA3NyA2NTUzNSBmDQowMDAwMDAwMDc4IDY1NTM1IGYNCjAwMDAwMDAwNzkgNjU1MzUgZg0KMDAwMDAwMDA4MCA2NTUzNSBmDQowMDAwMDAwMDgxIDY1NTM1IGYNCjAwMDAwMDAwODIgNjU1MzUgZg0KMDAwMDAwMDA4MyA2NTUzNSBmDQowMDAwMDAwMDg1IDY1NTM1IGYNCjAwMDAwNjYwNDAgMDAwMDAgbg0KMDAwMDAwMDA4NiA2NTUzNSBmDQowMDAwMDAwMDg3IDY1NTM1IGYNCjAwMDAwMDAwODggNjU1MzUgZg0KMDAwMDAwMDA5MCA2NTUzNSBmDQowMDAwMDY2MDkzIDAwMDAwIG4NCjAwMDAwMDAwOTEgNjU1MzUgZg0KMDAwMDAwMDA5MiA2NTUzNSBmDQowMDAwMDAwMDkzIDY1NTM1IGYNCjAwMDAwMDAwOTQgNjU1MzUgZg0KMDAwMDAwMDA5NSA2NTUzNSBmDQowMDAwMDAwMDk2IDY1NTM1IGYNCjAwMDAwMDAwOTcgNjU1MzUgZg0KMDAwMDAwMDA5OCA2NTUzNSBmDQowMDAwMDAwMDk5IDY1NTM1IGYNCjAwMDAwMDAxMDAgNjU1MzUgZg0KMDAwMDAwMDEwMiA2NTUzNSBmDQowMDAwMDY2MTQ2IDAwMDAwIG4NCjAwMDAwMDAxMDMgNjU1MzUgZg0KMDAwMDAwMDEwNCA2NTUzNSBmDQowMDAwMDAwMTA1IDY1NTM1IGYNCjAwMDAwMDAxMDYgNjU1MzUgZg0KMDAwMDAwMDEwNyA2NTUzNSBmDQowMDAwMDAwMTA4IDY1NTM1IGYNCjAwMDAwMDAxMDkgNjU1MzUgZg0KMDAwMDAwMDExMCA2NTUzNSBmDQowMDAwMDAwMTEyIDY1NTM1IGYNCjAwMDAwNjYyMDMgMDAwMDAgbg0KMDAwMDAwMDExMyA2NTUzNSBmDQowMDAwMDAwMTE0IDY1NTM1IGYNCjAwMDAwMDAxMTUgNjU1MzUgZg0KMDAwMDAwMDExNyA2NTUzNSBmDQowMDAwMDY2MjYwIDAwMDAwIG4NCjAwMDAwMDAxMTggNjU1MzUgZg0KMDAwMDAwMDExOSA2NTUzNSBmDQowMDAwMDAwMTIwIDY1NTM1IGYNCjAwMDAwMDAxMjEgNjU1MzUgZg0KMDAwMDAwMDEyMiA2NTUzNSBmDQowMDAwMDAwMTIzIDY1NTM1IGYNCjAwMDAwMDAxMjQgNjU1MzUgZg0KMDAwMDAwMDEyNSA2NTUzNSBmDQowMDAwMDAwMTI2IDY1NTM1IGYNCjAwMDAwMDAxMjcgNjU1MzUgZg0KMDAwMDAwMDEyOCA2NTUzNSBmDQowMDAwMDAwMTI5IDY1NTM1IGYNCjAwMDAwMDAxMzAgNjU1MzUgZg0KMDAwMDAwMDEzMSA2NTUzNSBmDQowMDAwMDAwMTMyIDY1NTM1IGYNCjAwMDAwMDAxMzMgNjU1MzUgZg0KMDAwMDAwMDEzNCA2NTUzNSBmDQowMDAwMDAwMTM1IDY1NTM1IGYNCjAwMDAwMDAxMzYgNjU1MzUgZg0KMDAwMDAwMDEzNyA2NTUzNSBmDQowMDAwMDAwMTM4IDY1NTM1IGYNCjAwMDAwMDAxMzkgNjU1MzUgZg0KMDAwMDAwMDE0MCA2NTUzNSBmDQowMDAwMDAwMTQxIDY1NTM1IGYNCjAwMDAwMDAxNDIgNjU1MzUgZg0KMDAwMDAwMDE0MyA2NTUzNSBmDQowMDAwMDAwMTQ0IDY1NTM1IGYNCjAwMDAwMDAxNDYgNjU1MzUgZg0KMDAwMDA2NjMxNCAwMDAwMCBuDQowMDAwMDAwMTQ3IDY1NTM1IGYNCjAwMDAwMDAxNDggNjU1MzUgZg0KMDAwMDAwMDE0OSA2NTUzNSBmDQowMDAwMDAwMTUwIDY1NTM1IGYNCjAwMDAwMDAxNTEgNjU1MzUgZg0KMDAwMDAwMDE1MyA2NTUzNSBmDQowMDAwMDY2MzY4IDAwMDAwIG4NCjAwMDAwMDAxNTQgNjU1MzUgZg0KMDAwMDAwMDE1NSA2NTUzNSBmDQowMDAwMDAwMTU2IDY1NTM1IGYNCjAwMDAwMDAxNTggNjU1MzUgZg0KMDAwMDA2NjQyMiAwMDAwMCBuDQowMDAwMDAwMTU5IDY1NTM1IGYNCjAwMDAwMDAxNjAgNjU1MzUgZg0KMDAwMDAwMDE2MSA2NTUzNSBmDQowMDAwMDAwMTYyIDY1NTM1IGYNCjAwMDAwMDAxNjMgNjU1MzUgZg0KMDAwMDAwMDE2NCA2NTUzNSBmDQowMDAwMDAwMTY1IDY1NTM1IGYNCjAwMDAwMDAxNjYgNjU1MzUgZg0KMDAwMDAwMDE2NyA2NTUzNSBmDQowMDAwMDAwMTY4IDY1NTM1IGYNCjAwMDAwMDAxNzAgNjU1MzUgZg0KMDAwMDA2NjQ3NiAwMDAwMCBuDQowMDAwMDAwMTcxIDY1NTM1IGYNCjAwMDAwMDAxNzIgNjU1MzUgZg0KMDAwMDAwMDE3MyA2NTUzNSBmDQowMDAwMDAwMTc1IDY1NTM1IGYNCjAwMDAwNjY1MzAgMDAwMDAgbg0KMDAwMDAwMDE3NiA2NTUzNSBmDQowMDAwMDAwMTc3IDY1NTM1IGYNCjAwMDAwMDAxNzggNjU1MzUgZg0KMDAwMDAwMDE3OSA2NTUzNSBmDQowMDAwMDAwMTgwIDY1NTM1IGYNCjAwMDAwMDAxODEgNjU1MzUgZg0KMDAwMDAwMDE4MiA2NTUzNSBmDQowMDAwMDAwMTgzIDY1NTM1IGYNCjAwMDAwMDAxODQgNjU1MzUgZg0KMDAwMDAwMDE4NSA2NTUzNSBmDQowMDAwMDAwMTg2IDY1NTM1IGYNCjAwMDAwMDAxODcgNjU1MzUgZg0KMDAwMDAwMDE4OCA2NTUzNSBmDQowMDAwMDAwMTg5IDY1NTM1IGYNCjAwMDAwMDAxOTAgNjU1MzUgZg0KMDAwMDAwMDE5MiA2NTUzNSBmDQowMDAwMDY2NTg0IDAwMDAwIG4NCjAwMDAwMDAxOTMgNjU1MzUgZg0KMDAwMDAwMDE5NCA2NTUzNSBmDQowMDAwMDAwMTk1IDY1NTM1IGYNCjAwMDAwMDAxOTcgNjU1MzUgZg0KMDAwMDA2NjY0MSAwMDAwMCBuDQowMDAwMDAwMTk4IDY1NTM1IGYNCjAwMDAwMDAxOTkgNjU1MzUgZg0KMDAwMDAwMDIwMCA2NTUzNSBmDQowMDAwMDAwMjAyIDY1NTM1IGYNCjAwMDAwNjY2OTggMDAwMDAgbg0KMDAwMDAwMDIwMyA2NTUzNSBmDQowMDAwMDAwMjA0IDY1NTM1IGYNCjAwMDAwMDAyMDUgNjU1MzUgZg0KMDAwMDAwMDIwNyA2NTUzNSBmDQowMDAwMDY2NzU1IDAwMDAwIG4NCjAwMDAwMDAyMDggNjU1MzUgZg0KMDAwMDAwMDIwOSA2NTUzNSBmDQowMDAwMDAwMjEwIDY1NTM1IGYNCjAwMDAwMDAyMTIgNjU1MzUgZg0KMDAwMDA2NjgxMiAwMDAwMCBuDQowMDAwMDAwMjEzIDY1NTM1IGYNCjAwMDAwMDAyMTQgNjU1MzUgZg0KMDAwMDAwMDIxNSA2NTUzNSBmDQowMDAwMDAwMjE3IDY1NTM1IGYNCjAwMDAwNjY4NjkgMDAwMDAgbg0KMDAwMDAwMDIxOCA2NTUzNSBmDQowMDAwMDAwMjE5IDY1NTM1IGYNCjAwMDAwMDAyMjAgNjU1MzUgZg0KMDAwMDAwMDIyMiA2NTUzNSBmDQowMDAwMDY2OTI2IDAwMDAwIG4NCjAwMDAwMDAyMjMgNjU1MzUgZg0KMDAwMDAwMDIyNCA2NTUzNSBmDQowMDAwMDAwMjI1IDY1NTM1IGYNCjAwMDAwMDAyMjYgNjU1MzUgZg0KMDAwMDAwMDIyOCA2NTUzNSBmDQowMDAwMDY2OTgwIDAwMDAwIG4NCjAwMDAwMDAyMjkgNjU1MzUgZg0KMDAwMDAwMDIzMCA2NTUzNSBmDQowMDAwMDAwMjMxIDY1NTM1IGYNCjAwMDAwMDAyMzMgNjU1MzUgZg0KMDAwMDA2NzAzNyAwMDAwMCBuDQowMDAwMDAwMjM0IDY1NTM1IGYNCjAwMDAwMDAyMzUgNjU1MzUgZg0KMDAwMDAwMDIzNiA2NTUzNSBmDQowMDAwMDAwMjM4IDY1NTM1IGYNCjAwMDAwNjcwOTQgMDAwMDAgbg0KMDAwMDAwMDIzOSA2NTUzNSBmDQowMDAwMDAwMjQwIDY1NTM1IGYNCjAwMDAwMDAyNDEgNjU1MzUgZg0KMDAwMDAwMDI0MyA2NTUzNSBmDQowMDAwMDY3MTUxIDAwMDAwIG4NCjAwMDAwMDAyNDQgNjU1MzUgZg0KMDAwMDAwMDI0NSA2NTUzNSBmDQowMDAwMDAwMjQ2IDY1NTM1IGYNCjAwMDAwMDAyNDggNjU1MzUgZg0KMDAwMDA2NzIwOCAwMDAwMCBuDQowMDAwMDAwMjQ5IDY1NTM1IGYNCjAwMDAwMDAyNTAgNjU1MzUgZg0KMDAwMDAwMDI1MSA2NTUzNSBmDQowMDAwMDAwMjUyIDY1NTM1IGYNCjAwMDAwMDAyNTMgNjU1MzUgZg0KMDAwMDAwMDI1NCA2NTUzNSBmDQowMDAwMDAwMjU1IDY1NTM1IGYNCjAwMDAwMDAyNTYgNjU1MzUgZg0KMDAwMDAwMDI1NyA2NTUzNSBmDQowMDAwMDAwMjU5IDY1NTM1IGYNCjAwMDAwNjcyNjIgMDAwMDAgbg0KMDAwMDAwMDI2MCA2NTUzNSBmDQowMDAwMDAwMjYxIDY1NTM1IGYNCjAwMDAwMDAyNjIgNjU1MzUgZg0KMDAwMDAwMDI2MyA2NTUzNSBmDQowMDAwMDAwMjY0IDY1NTM1IGYNCjAwMDAwMDAyNjYgNjU1MzUgZg0KMDAwMDA2NzMxNiAwMDAwMCBuDQowMDAwMDAwMjY3IDY1NTM1IGYNCjAwMDAwMDAyNjggNjU1MzUgZg0KMDAwMDAwMDI2OSA2NTUzNSBmDQowMDAwMDAwMjcxIDY1NTM1IGYNCjAwMDAwNjczNzAgMDAwMDAgbg0KMDAwMDAwMDI3MiA2NTUzNSBmDQowMDAwMDAwMjczIDY1NTM1IGYNCjAwMDAwMDAyNzQgNjU1MzUgZg0KMDAwMDAwMDI3NSA2NTUzNSBmDQowMDAwMDAwMjc2IDY1NTM1IGYNCjAwMDAwMDAyNzcgNjU1MzUgZg0KMDAwMDAwMDI3OCA2NTUzNSBmDQowMDAwMDAwMjc5IDY1NTM1IGYNCjAwMDAwMDAyODAgNjU1MzUgZg0KMDAwMDAwMDI4MSA2NTUzNSBmDQowMDAwMDAwMjgzIDY1NTM1IGYNCjAwMDAwNjc0MjQgMDAwMDAgbg0KMDAwMDAwMDI4NCA2NTUzNSBmDQowMDAwMDAwMjg1IDY1NTM1IGYNCjAwMDAwMDAyODYgNjU1MzUgZg0KMDAwMDAwMDI4OCA2NTUzNSBmDQowMDAwMDY3NDc4IDAwMDAwIG4NCjAwMDAwMDAyODkgNjU1MzUgZg0KMDAwMDAwMDI5MCA2NTUzNSBmDQowMDAwMDAwMjkxIDY1NTM1IGYNCjAwMDAwMDAyOTIgNjU1MzUgZg0KMDAwMDAwMDI5MyA2NTUzNSBmDQowMDAwMDAwMjk0IDY1NTM1IGYNCjAwMDAwMDAyOTUgNjU1MzUgZg0KMDAwMDAwMDI5NyA2NTUzNSBmDQowMDAwMDY3NTMyIDAwMDAwIG4NCjAwMDAwMDAyOTggNjU1MzUgZg0KMDAwMDAwMDI5OSA2NTUzNSBmDQowMDAwMDAwMzAwIDY1NTM1IGYNCjAwMDAwMDAzMDIgNjU1MzUgZg0KMDAwMDA2NzU4NiAwMDAwMCBuDQowMDAwMDAwMzAzIDY1NTM1IGYNCjAwMDAwMDAzMDQgNjU1MzUgZg0KMDAwMDAwMDMwNSA2NTUzNSBmDQowMDAwMDAwMzA2IDY1NTM1IGYNCjAwMDAwMDAzMDcgNjU1MzUgZg0KMDAwMDAwMDMwOCA2NTUzNSBmDQowMDAwMDAwMzA5IDY1NTM1IGYNCjAwMDAwMDAzMTAgNjU1MzUgZg0KMDAwMDAwMDMxMSA2NTUzNSBmDQowMDAwMDAwMzEyIDY1NTM1IGYNCjAwMDAwMDAzMTMgNjU1MzUgZg0KMDAwMDAwMDMxNSA2NTUzNSBmDQowMDAwMDY3NjQwIDAwMDAwIG4NCjAwMDAwMDAzMTYgNjU1MzUgZg0KMDAwMDAwMDMxNyA2NTUzNSBmDQowMDAwMDAwMzE4IDY1NTM1IGYNCjAwMDAwMDAzMjAgNjU1MzUgZg0KMDAwMDA2NzY5NCAwMDAwMCBuDQowMDAwMDAwMzIxIDY1NTM1IGYNCjAwMDAwMDAzMjIgNjU1MzUgZg0KMDAwMDAwMDMyMyA2NTUzNSBmDQowMDAwMDAwMzI1IDY1NTM1IGYNCjAwMDAwNjc3NDggMDAwMDAgbg0KMDAwMDAwMDMyNiA2NTUzNSBmDQowMDAwMDAwMzI3IDY1NTM1IGYNCjAwMDAwMDAzMjggNjU1MzUgZg0KMDAwMDAwMDMzMCA2NTUzNSBmDQowMDAwMDY3ODA1IDAwMDAwIG4NCjAwMDAwMDAzMzEgNjU1MzUgZg0KMDAwMDAwMDMzMiA2NTUzNSBmDQowMDAwMDAwMzMzIDY1NTM1IGYNCjAwMDAwMDAzMzUgNjU1MzUgZg0KMDAwMDA2Nzg2MiAwMDAwMCBuDQowMDAwMDAwMzM2IDY1NTM1IGYNCjAwMDAwMDAzMzcgNjU1MzUgZg0KMDAwMDAwMDMzOCA2NTUzNSBmDQowMDAwMDAwMzQwIDY1NTM1IGYNCjAwMDAwNjc5MTkgMDAwMDAgbg0KMDAwMDAwMDM0MSA2NTUzNSBmDQowMDAwMDAwMzQyIDY1NTM1IGYNCjAwMDAwMDAzNDMgNjU1MzUgZg0KMDAwMDAwMDM0NCA2NTUzNSBmDQowMDAwMDAwMzQ1IDY1NTM1IGYNCjAwMDAwMDAzNDYgNjU1MzUgZg0KMDAwMDAwMDM0NyA2NTUzNSBmDQowMDAwMDAwMzQ4IDY1NTM1IGYNCjAwMDAwMDAzNTAgNjU1MzUgZg0KMDAwMDA2Nzk3MyAwMDAwMCBuDQowMDAwMDAwMzUxIDY1NTM1IGYNCjAwMDAwMDAzNTIgNjU1MzUgZg0KMDAwMDAwMDM1MyA2NTUzNSBmDQowMDAwMDAwMzU1IDY1NTM1IGYNCjAwMDAwNjgwMjcgMDAwMDAgbg0KMDAwMDAwMDM1NiA2NTUzNSBmDQowMDAwMDAwMzU3IDY1NTM1IGYNCjAwMDAwMDAzNTggNjU1MzUgZg0KMDAwMDAwMDM2MCA2NTUzNSBmDQowMDAwMDY4MDgxIDAwMDAwIG4NCjAwMDAwMDAzNjEgNjU1MzUgZg0KMDAwMDAwMDM2MiA2NTUzNSBmDQowMDAwMDAwMzYzIDY1NTM1IGYNCjAwMDAwMDAzNjUgNjU1MzUgZg0KMDAwMDA2ODEzOCAwMDAwMCBuDQowMDAwMDAwMzY2IDY1NTM1IGYNCjAwMDAwMDAzNjcgNjU1MzUgZg0KMDAwMDAwMDM2OCA2NTUzNSBmDQowMDAwMDAwMzcwIDY1NTM1IGYNCjAwMDAwNjgxOTUgMDAwMDAgbg0KMDAwMDAwMDM3MSA2NTUzNSBmDQowMDAwMDAwMzcyIDY1NTM1IGYNCjAwMDAwMDAzNzMgNjU1MzUgZg0KMDAwMDAwMDM3NSA2NTUzNSBmDQowMDAwMDY4MjUyIDAwMDAwIG4NCjAwMDAwMDAzNzYgNjU1MzUgZg0KMDAwMDAwMDM3NyA2NTUzNSBmDQowMDAwMDAwMzc4IDY1NTM1IGYNCjAwMDAwMDAzNzkgNjU1MzUgZg0KMDAwMDAwMDM4MSA2NTUzNSBmDQowMDAwMDY4MzA2IDAwMDAwIG4NCjAwMDAwMDAzODIgNjU1MzUgZg0KMDAwMDAwMDM4MyA2NTUzNSBmDQowMDAwMDAwMzg0IDY1NTM1IGYNCjAwMDAwMDAzODYgNjU1MzUgZg0KMDAwMDA2ODM2MCAwMDAwMCBuDQowMDAwMDAwMzg3IDY1NTM1IGYNCjAwMDAwMDAzODggNjU1MzUgZg0KMDAwMDAwMDM4OSA2NTUzNSBmDQowMDAwMDAwMzkxIDY1NTM1IGYNCjAwMDAwNjg0MTQgMDAwMDAgbg0KMDAwMDAwMDM5MiA2NTUzNSBmDQowMDAwMDAwMzkzIDY1NTM1IGYNCjAwMDAwMDAzOTQgNjU1MzUgZg0KMDAwMDAwMDM5NSA2NTUzNSBmDQowMDAwMDAwMzk3IDY1NTM1IGYNCjAwMDAwNjg0NzEgMDAwMDAgbg0KMDAwMDAwMDM5OCA2NTUzNSBmDQowMDAwMDAwMzk5IDY1NTM1IGYNCjAwMDAwMDA0MDAgNjU1MzUgZg0KMDAwMDAwMDQwMSA2NTUzNSBmDQowMDAwMDAwNDAyIDY1NTM1IGYNCjAwMDAwMDA0MDQgNjU1MzUgZg0KMDAwMDA2ODUyNSAwMDAwMCBuDQowMDAwMDAwNDA1IDY1NTM1IGYNCjAwMDAwMDA0MDYgNjU1MzUgZg0KMDAwMDAwMDQwNyA2NTUzNSBmDQowMDAwMDAwNDA5IDY1NTM1IGYNCjAwMDAwNjg1NzkgMDAwMDAgbg0KMDAwMDAwMDQxMCA2NTUzNSBmDQowMDAwMDAwNDExIDY1NTM1IGYNCjAwMDAwMDA0MTIgNjU1MzUgZg0KMDAwMDAwMDQxMyA2NTUzNSBmDQowMDAwMDAwNDE0IDY1NTM1IGYNCjAwMDAwMDA0MTUgNjU1MzUgZg0KMDAwMDAwMDQxNiA2NTUzNSBmDQowMDAwMDAwNDE4IDY1NTM1IGYNCjAwMDAwNjg2MzMgMDAwMDAgbg0KMDAwMDAwMDQxOSA2NTUzNSBmDQowMDAwMDAwNDIwIDY1NTM1IGYNCjAwMDAwMDA0MjEgNjU1MzUgZg0KMDAwMDAwMDQyMyA2NTUzNSBmDQowMDAwMDY4Njg3IDAwMDAwIG4NCjAwMDAwMDA0MjQgNjU1MzUgZg0KMDAwMDAwMDQyNSA2NTUzNSBmDQowMDAwMDAwNDI2IDY1NTM1IGYNCjAwMDAwMDA0MjggNjU1MzUgZg0KMDAwMDA2ODc0MSAwMDAwMCBuDQowMDAwMDAwNDI5IDY1NTM1IGYNCjAwMDAwMDA0MzAgNjU1MzUgZg0KMDAwMDAwMDQzMSA2NTUzNSBmDQowMDAwMDAwNDMzIDY1NTM1IGYNCjAwMDAwNjg3OTggMDAwMDAgbg0KMDAwMDAwMDQzNCA2NTUzNSBmDQowMDAwMDAwNDM1IDY1NTM1IGYNCjAwMDAwMDA0MzYgNjU1MzUgZg0KMDAwMDAwMDQzNyA2NTUzNSBmDQowMDAwMDAwNDM5IDY1NTM1IGYNCjAwMDAwNjg4NTUgMDAwMDAgbg0KMDAwMDAwMDQ0MCA2NTUzNSBmDQowMDAwMDAwNDQxIDY1NTM1IGYNCjAwMDAwMDA0NDIgNjU1MzUgZg0KMDAwMDAwMDQ0MyA2NTUzNSBmDQowMDAwMDAwNDQ0IDY1NTM1IGYNCjAwMDAwMDA0NDYgNjU1MzUgZg0KMDAwMDA2ODkwOSAwMDAwMCBuDQowMDAwMDAwNDQ3IDY1NTM1IGYNCjAwMDAwMDA0NDggNjU1MzUgZg0KMDAwMDAwMDQ0OSA2NTUzNSBmDQowMDAwMDAwNDUwIDY1NTM1IGYNCjAwMDAwMDA0NTEgNjU1MzUgZg0KMDAwMDAwMDQ1MiA2NTUzNSBmDQowMDAwMDAwNDUzIDY1NTM1IGYNCjAwMDAwMDA0NTQgNjU1MzUgZg0KMDAwMDAwMDQ1NSA2NTUzNSBmDQowMDAwMDAwNDU2IDY1NTM1IGYNCjAwMDAwMDA0NTcgNjU1MzUgZg0KMDAwMDAwMDQ1OCA2NTUzNSBmDQowMDAwMDAwNDU5IDY1NTM1IGYNCjAwMDAwMDA0NjEgNjU1MzUgZg0KMDAwMDA2ODk2NiAwMDAwMCBuDQowMDAwMDAwNDYyIDY1NTM1IGYNCjAwMDAwMDA0NjMgNjU1MzUgZg0KMDAwMDAwMDQ2NCA2NTUzNSBmDQowMDAwMDAwNDY1IDY1NTM1IGYNCjAwMDAwMDA0NjYgNjU1MzUgZg0KMDAwMDAwMDQ2NyA2NTUzNSBmDQowMDAwMDAwNDY4IDY1NTM1IGYNCjAwMDAwMDA0NzAgNjU1MzUgZg0KMDAwMDA2OTAyMCAwMDAwMCBuDQowMDAwMDAwNDcxIDY1NTM1IGYNCjAwMDAwMDA0NzIgNjU1MzUgZg0KMDAwMDAwMDQ3MyA2NTUzNSBmDQowMDAwMDAwNDc1IDY1NTM1IGYNCjAwMDAwNjkwNzQgMDAwMDAgbg0KMDAwMDAwMDQ3NiA2NTUzNSBmDQowMDAwMDAwNDc3IDY1NTM1IGYNCjAwMDAwMDA0NzggNjU1MzUgZg0KMDAwMDAwMDQ3OSA2NTUzNSBmDQowMDAwMDAwNDgwIDY1NTM1IGYNCjAwMDAwMDA0ODEgNjU1MzUgZg0KMDAwMDAwMDQ4MiA2NTUzNSBmDQowMDAwMDAwNDgzIDY1NTM1IGYNCjAwMDAwMDA0ODQgNjU1MzUgZg0KMDAwMDAwMDQ4NSA2NTUzNSBmDQowMDAwMDAwNDg3IDY1NTM1IGYNCjAwMDAwNjkxMjggMDAwMDAgbg0KMDAwMDAwMDQ4OCA2NTUzNSBmDQowMDAwMDAwNDg5IDY1NTM1IGYNCjAwMDAwMDA0OTAgNjU1MzUgZg0KMDAwMDAwMDQ5MiA2NTUzNSBmDQowMDAwMDY5MTgyIDAwMDAwIG4NCjAwMDAwMDA0OTMgNjU1MzUgZg0KMDAwMDAwMDQ5NCA2NTUzNSBmDQowMDAwMDAwNDk1IDY1NTM1IGYNCjAwMDAwMDA0OTYgNjU1MzUgZg0KMDAwMDAwMDQ5NyA2NTUzNSBmDQowMDAwMDAwNDk4IDY1NTM1IGYNCjAwMDAwMDA0OTkgNjU1MzUgZg0KMDAwMDAwMDUwMCA2NTUzNSBmDQowMDAwMDAwNTAxIDY1NTM1IGYNCjAwMDAwMDA1MDIgNjU1MzUgZg0KMDAwMDAwMDUwMyA2NTUzNSBmDQowMDAwMDAwNTA0IDY1NTM1IGYNCjAwMDAwMDA1MDUgNjU1MzUgZg0KMDAwMDAwMDUwNyA2NTUzNSBmDQowMDAwMDY5MjM2IDAwMDAwIG4NCjAwMDAwMDA1MDggNjU1MzUgZg0KMDAwMDAwMDUwOSA2NTUzNSBmDQowMDAwMDAwNTEwIDY1NTM1IGYNCjAwMDAwMDA1MTIgNjU1MzUgZg0KMDAwMDA2OTI5MCAwMDAwMCBuDQowMDAwMDAwNTEzIDY1NTM1IGYNCjAwMDAwMDA1MTQgNjU1MzUgZg0KMDAwMDAwMDUxNSA2NTUzNSBmDQowMDAwMDAwNTE2IDY1NTM1IGYNCjAwMDAwMDA1MTcgNjU1MzUgZg0KMDAwMDAwMDUxOCA2NTUzNSBmDQowMDAwMDAwNTE5IDY1NTM1IGYNCjAwMDAwMDA1MjAgNjU1MzUgZg0KMDAwMDAwMDUyMSA2NTUzNSBmDQowMDAwMDAwNTIyIDY1NTM1IGYNCjAwMDAwMDA1MjMgNjU1MzUgZg0KMDAwMDAwMDUyNCA2NTUzNSBmDQowMDAwMDAwNTI1IDY1NTM1IGYNCjAwMDAwMDA1MjYgNjU1MzUgZg0KMDAwMDAwMDUyNyA2NTUzNSBmDQowMDAwMDAwNTI4IDY1NTM1IGYNCjAwMDAwMDA1MjkgNjU1MzUgZg0KMDAwMDAwMDUzMCA2NTUzNSBmDQowMDAwMDAwNTMxIDY1NTM1IGYNCjAwMDAwMDA1MzIgNjU1MzUgZg0KMDAwMDAwMDUzMyA2NTUzNSBmDQowMDAwMDAwNTM0IDY1NTM1IGYNCjAwMDAwMDA1MzUgNjU1MzUgZg0KMDAwMDAwMDUzNyA2NTUzNSBmDQowMDAwMDY5MzQ0IDAwMDAwIG4NCjAwMDAwMDA1MzggNjU1MzUgZg0KMDAwMDAwMDUzOSA2NTUzNSBmDQowMDAwMDAwNTQwIDY1NTM1IGYNCjAwMDAwMDA1NDIgNjU1MzUgZg0KMDAwMDA2OTQwMSAwMDAwMCBuDQowMDAwMDAwNTQzIDY1NTM1IGYNCjAwMDAwMDA1NDQgNjU1MzUgZg0KMDAwMDAwMDU0NSA2NTUzNSBmDQowMDAwMDAwNTQ2IDY1NTM1IGYNCjAwMDAwMDA1NDcgNjU1MzUgZg0KMDAwMDAwMDU0OCA2NTUzNSBmDQowMDAwMDAwNTQ5IDY1NTM1IGYNCjAwMDAwMDA1NTAgNjU1MzUgZg0KMDAwMDAwMDU1MSA2NTUzNSBmDQowMDAwMDAwNTUyIDY1NTM1IGYNCjAwMDAwMDA1NTMgNjU1MzUgZg0KMDAwMDAwMDU1NSA2NTUzNSBmDQowMDAwMDY5NDU1IDAwMDAwIG4NCjAwMDAwMDA1NTYgNjU1MzUgZg0KMDAwMDAwMDU1NyA2NTUzNSBmDQowMDAwMDAwNTU4IDY1NTM1IGYNCjAwMDAwMDA1NjAgNjU1MzUgZg0KMDAwMDA2OTUwOSAwMDAwMCBuDQowMDAwMDAwNTYxIDY1NTM1IGYNCjAwMDAwMDA1NjIgNjU1MzUgZg0KMDAwMDAwMDU2MyA2NTUzNSBmDQowMDAwMDAwNTY1IDY1NTM1IGYNCjAwMDAwNjk1NjYgMDAwMDAgbg0KMDAwMDAwMDU2NiA2NTUzNSBmDQowMDAwMDAwNTY3IDY1NTM1IGYNCjAwMDAwMDA1NjggNjU1MzUgZg0KMDAwMDAwMDU3MCA2NTUzNSBmDQowMDAwMDY5NjIzIDAwMDAwIG4NCjAwMDAwMDA1NzEgNjU1MzUgZg0KMDAwMDAwMDU3MiA2NTUzNSBmDQowMDAwMDAwNTc0IDY1NTM1IGYNCjAwMDAwNjk2ODAgMDAwMDAgbg0KMDAwMDAwMDU3NSA2NTUzNSBmDQowMDAwMDAwNTc2IDY1NTM1IGYNCjAwMDAwMDA1NzcgNjU1MzUgZg0KMDAwMDAwMDU3OCA2NTUzNSBmDQowMDAwMDAwNTgwIDY1NTM1IGYNCjAwMDAwNjk3MzcgMDAwMDAgbg0KMDAwMDAwMDU4MSA2NTUzNSBmDQowMDAwMDAwNTgyIDY1NTM1IGYNCjAwMDAwMDA1ODMgNjU1MzUgZg0KMDAwMDAwMDU4NSA2NTUzNSBmDQowMDAwMDY5Nzk0IDAwMDAwIG4NCjAwMDAwMDA1ODYgNjU1MzUgZg0KMDAwMDAwMDU4NyA2NTUzNSBmDQowMDAwMDAwNTg4IDY1NTM1IGYNCjAwMDAwMDA1OTAgNjU1MzUgZg0KMDAwMDA2OTg1MSAwMDAwMCBuDQowMDAwMDAwNTkxIDY1NTM1IGYNCjAwMDAwMDA1OTIgNjU1MzUgZg0KMDAwMDAwMDU5MyA2NTUzNSBmDQowMDAwMDAwNTk1IDY1NTM1IGYNCjAwMDAwNjk5MDggMDAwMDAgbg0KMDAwMDAwMDU5NiA2NTUzNSBmDQowMDAwMDAwNTk3IDY1NTM1IGYNCjAwMDAwMDA1OTggNjU1MzUgZg0KMDAwMDAwMDYwMCA2NTUzNSBmDQowMDAwMDY5OTY1IDAwMDAwIG4NCjAwMDAwMDA2MDEgNjU1MzUgZg0KMDAwMDAwMDYwMiA2NTUzNSBmDQowMDAwMDAwNjAzIDY1NTM1IGYNCjAwMDAwMDA2MDQgNjU1MzUgZg0KMDAwMDAwMDYwNSA2NTUzNSBmDQowMDAwMDAwNjA2IDY1NTM1IGYNCjAwMDAwMDA2MDcgNjU1MzUgZg0KMDAwMDAwMDYwOCA2NTUzNSBmDQowMDAwMDAwNjA5IDY1NTM1IGYNCjAwMDAwMDA2MTAgNjU1MzUgZg0KMDAwMDAwMDYxMSA2NTUzNSBmDQowMDAwMDAwNjEzIDY1NTM1IGYNCjAwMDAwNzAwMjIgMDAwMDAgbg0KMDAwMDAwMDYxNCA2NTUzNSBmDQowMDAwMDAwNjE1IDY1NTM1IGYNCjAwMDAwMDA2MTYgNjU1MzUgZg0KMDAwMDAwMDYxOCA2NTUzNSBmDQowMDAwMDcwMDc2IDAwMDAwIG4NCjAwMDAwMDA2MTkgNjU1MzUgZg0KMDAwMDAwMDYyMCA2NTUzNSBmDQowMDAwMDAwNjIxIDY1NTM1IGYNCjAwMDAwMDA2MjMgNjU1MzUgZg0KMDAwMDA3MDEzMCAwMDAwMCBuDQowMDAwMDAwNjI0IDY1NTM1IGYNCjAwMDAwMDA2MjUgNjU1MzUgZg0KMDAwMDAwMDYyNiA2NTUzNSBmDQowMDAwMDAwNjI4IDY1NTM1IGYNCjAwMDAwNzAxODQgMDAwMDAgbg0KMDAwMDAwMDYyOSA2NTUzNSBmDQowMDAwMDAwNjMwIDY1NTM1IGYNCjAwMDAwMDA2MzEgNjU1MzUgZg0KMDAwMDAwMDYzMyA2NTUzNSBmDQowMDAwMDcwMjM4IDAwMDAwIG4NCjAwMDAwMDA2MzQgNjU1MzUgZg0KMDAwMDAwMDYzNSA2NTUzNSBmDQowMDAwMDAwNjM2IDY1NTM1IGYNCjAwMDAwMDA2MzggNjU1MzUgZg0KMDAwMDA3MDI5MiAwMDAwMCBuDQowMDAwMDAwNjM5IDY1NTM1IGYNCjAwMDAwMDA2NDAgNjU1MzUgZg0KMDAwMDAwMDY0MSA2NTUzNSBmDQowMDAwMDAwNjQzIDY1NTM1IGYNCjAwMDAwNzAzNDYgMDAwMDAgbg0KMDAwMDAwMDY0NCA2NTUzNSBmDQowMDAwMDAwNjQ1IDY1NTM1IGYNCjAwMDAwMDA2NDYgNjU1MzUgZg0KMDAwMDAwMDY0OCA2NTUzNSBmDQowMDAwMDcwNDAwIDAwMDAwIG4NCjAwMDAwMDA2NDkgNjU1MzUgZg0KMDAwMDAwMDY1MCA2NTUzNSBmDQowMDAwMDAwNjUxIDY1NTM1IGYNCjAwMDAwMDA2NTIgNjU1MzUgZg0KMDAwMDAwMDY1NCA2NTUzNSBmDQowMDAwMDcyNDc5IDAwMDAwIG4NCjAwMDAwMDA2NTUgNjU1MzUgZg0KMDAwMDAwMDY1NiA2NTUzNSBmDQowMDAwMDAwNjU3IDY1NTM1IGYNCjAwMDAwMDA2NTkgNjU1MzUgZg0KMDAwMDA3MjUzMyAwMDAwMCBuDQowMDAwMDAwNjYwIDY1NTM1IGYNCjAwMDAwMDA2NjEgNjU1MzUgZg0KMDAwMDAwMDY2MiA2NTUzNSBmDQowMDAwMDAwNjY0IDY1NTM1IGYNCjAwMDAwNzI1ODcgMDAwMDAgbg0KMDAwMDAwMDY2NSA2NTUzNSBmDQowMDAwMDAwNjY2IDY1NTM1IGYNCjAwMDAwMDA2NjcgNjU1MzUgZg0KMDAwMDAwMDY2OCA2NTUzNSBmDQowMDAwMDAwNjY5IDY1NTM1IGYNCjAwMDAwMDA2NzAgNjU1MzUgZg0KMDAwMDAwMDY3MSA2NTUzNSBmDQowMDAwMDAwNjcyIDY1NTM1IGYNCjAwMDAwMDA2NzMgNjU1MzUgZg0KMDAwMDAwMDY3NCA2NTUzNSBmDQowMDAwMDAwNjc1IDY1NTM1IGYNCjAwMDAwMDA2NzcgNjU1MzUgZg0KMDAwMDA3MjY0MSAwMDAwMCBuDQowMDAwMDAwNjc4IDY1NTM1IGYNCjAwMDAwMDA2NzkgNjU1MzUgZg0KMDAwMDAwMDY4MCA2NTUzNSBmDQowMDAwMDAwNjgyIDY1NTM1IGYNCjAwMDAwNzI2OTUgMDAwMDAgbg0KMDAwMDAwMDY4MyA2NTUzNSBmDQowMDAwMDAwNjg0IDY1NTM1IGYNCjAwMDAwMDA2ODUgNjU1MzUgZg0KMDAwMDAwMDY4NyA2NTUzNSBmDQowMDAwMDcyNzQ5IDAwMDAwIG4NCjAwMDAwMDA2ODggNjU1MzUgZg0KMDAwMDAwMDY4OSA2NTUzNSBmDQowMDAwMDAwNjkwIDY1NTM1IGYNCjAwMDAwMDA2OTIgNjU1MzUgZg0KMDAwMDA3MjgwMyAwMDAwMCBuDQowMDAwMDAwNjkzIDY1NTM1IGYNCjAwMDAwMDA2OTQgNjU1MzUgZg0KMDAwMDAwMDY5NSA2NTUzNSBmDQowMDAwMDAwNjk3IDY1NTM1IGYNCjAwMDAwNzI4NTcgMDAwMDAgbg0KMDAwMDAwMDY5OCA2NTUzNSBmDQowMDAwMDAwMDAwIDY1NTM1IGYNCjAwMDAwNzI5MTEgMDAwMDAgbg0KMDAwMDA3MjkzOSAwMDAwMCBuDQowMDAwMDkyNDIwIDAwMDAwIG4NCjAwMDAwOTI4MzMgMDAwMDAgbg0KMDAwMDEzMjQxOSAwMDAwMCBuDQowMDAwMTMyODAyIDAwMDAwIG4NCjAwMDAxMzMxNDIgMDAwMDAgbg0KMDAwMDEzMzU2OCAwMDAwMCBuDQowMDAwMTg0MzEwIDAwMDAwIG4NCjAwMDAxODQ3MTQgMDAwMDAgbg0KMDAwMDE4NTE0NyAwMDAwMCBuDQowMDAwMTg1MzU3IDAwMDAwIG4NCjAwMDAxODg1MDEgMDAwMDAgbg0KMDAwMDE4ODU0NyAwMDAwMCBuDQp0cmFpbGVyDQo8PC9TaXplIDcxMy9Sb290IDEgMCBSL0luZm8gNDggMCBSL0lEWzwwRkI2QTVDRDdCNUUzNzQ0QTJEQzI0MkU1RjE4MkFENT48MEZCNkE1Q0Q3QjVFMzc0NEEyREMyNDJFNUYxODJBRDU+XSA+Pg0Kc3RhcnR4cmVmDQoxOTA0NDANCiUlRU9GDQp4cmVmDQowIDANCnRyYWlsZXINCjw8L1NpemUgNzEzL1Jvb3QgMSAwIFIvSW5mbyA0OCAwIFIvSURbPDBGQjZBNUNEN0I1RTM3NDRBMkRDMjQyRTVGMTgyQUQ1PjwwRkI2QTVDRDdCNUUzNzQ0QTJEQzI0MkU1RjE4MkFENT5dIC9QcmV2IDE5MDQ0MC9YUmVmU3RtIDE4ODU0Nz4+DQpzdGFydHhyZWYNCjIwNDg2MA0KJSVFT0Y="
+}
diff --git a/src/events.ts b/src/events.ts
new file mode 100644
index 0000000..a097724
--- /dev/null
+++ b/src/events.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import Vue from 'vue';
+
+/// region event bus (events propagated on parallel thread)
+/**
+ * This event bus channels following events:
+ *
+ * - newConnection with \a nodeUrl
+ * - onProfileChange with \a profileName
+ * - onAccountChange with \a accountAddress
+ */
+export const $eventBus = new Vue();
+/// end-region event bus
diff --git a/src/language/en-US.json b/src/language/en-US.json
new file mode 100644
index 0000000..e5df329
--- /dev/null
+++ b/src/language/en-US.json
@@ -0,0 +1,1112 @@
+{
+ "about_app_release": "Release",
+ "about_app_url": "Homepage",
+ "about_default_node": "Default node",
+ "about_dependencies": "Dependencies",
+ "about_generation_hash": "Generation hash",
+ "about_network": "Network",
+ "about_network_type": "Network type",
+ "about_rxjs_version": "RxJs Library",
+ "about_sdk_version": "Symbol SDK",
+ "about_typescript_version": "Typescript",
+ "about_vue_version": "Vue Framework",
+ "absolute": "absolute",
+ "access_ledger": "Access Ledger",
+ "access_my_profile": "Access my profile",
+ "access_trezor": "Access Trezor",
+ "access_trezor_account": "Access your Trezor account",
+ "access_your_ledger_account": "Access your Ledger account",
+ "account_address": "Address",
+ "ACCOUNT_LINK": "Account link",
+ "account_management": "My accounts",
+ "account_name": "Name",
+ "account_name_input_error": "Account name input error!",
+ "account_network_does_not_match_current_network_type": "The profile's network is different from the network of the connected node. Please create a new one.",
+ "account_network_type_does_not_match_current_network_type": "The profile's network type does not match with the network type of the connected node.",
+ "account_public_key": "Public Key",
+ "account_restrictions": "Account restrictions",
+ "account_restrictions_tab_address": "Address restrictions",
+ "account_restrictions_tab_mosaic": "Asset restrictions",
+ "account_restrictions_tab_operation": "Operation restrictions",
+ "accounts": "Accounts",
+ "accounts_backup_keystore_explain_p1": "Use the button on the right to backup your private and public keys by downloading an encrypted key file.",
+ "accounts_backup_keystore_explain_p2": "You will be asked to unlock your profile. After unlocking your profile, the download will start automatically.",
+ "accounts_backup_mnemonic_explain_p1": "Use the button on the right to backup your mnemonic passphrase by displaying the 24 words on the screen.",
+ "accounts_backup_mnemonic_explain_p2": "You will be asked to unlock your profile. After unlocking your profile, the mnemonic passphrase will appear.",
+ "accounts_backup_mnemonic_explain_p3": "Please, make sure to backup the following {num} words in a safe place. These {num} words represent your mnemonic passphrase and can be used to import your profile and its' child accounts at a later point in time.",
+ "accounts_backup_mnemonic_explain_qrcode": "Please, make sure to backup the following QRCode in a safe place. This QRCode can be used to import your profile and its' child accounts at a later point in time.",
+ "accounts_backup_qrcode_explain_p1": "Use the button on the right to backup your mnemonic passphrase by downloading a QRCode.",
+ "accounts_backup_qrcode_explain_p2": "You will be asked to unlock your profile. After unlocking your profile, the download will start automatically.",
+ "accounts_backup_tile_description": "Backup your wallet(s) now",
+ "accounts_backup_tile_keystore": "Download keys",
+ "accounts_backup_tile_keystore_desc": "Download a keys file",
+ "accounts_backup_tile_mnemonic": "Display Mnemonic",
+ "accounts_backup_tile_mnemonic_desc": "Display your passphrase",
+ "accounts_backup_tile_title": "Mnemonic QRCode",
+ "accounts_backup_title": "Backup & Security",
+ "accounts_backup_title_keystore": "Download keys",
+ "accounts_backup_title_mnemonic": "Mnemonic passphrase",
+ "accounts_backup_title_qrcode": "Encrypted Mnemonic QRCode",
+ "accounts_backup_transactions": "Export the transaction list to a CSV file",
+ "accounts_backup_transactions_description": "Download all the transaction information, save it locally and view it even if you don't have an Internet connection",
+ "accounts_change_password_description": "Change your password",
+ "accounts_change_password_title": "Change Password",
+ "accounts_create_invoice": "Create an invoice",
+ "accounts_flags_default_account": "Default",
+ "accounts_flags_default_account_explain": "This is your default account",
+ "accounts_flags_known_by_network": "Broadcasted Account",
+ "accounts_flags_multisig": "Multi-signature",
+ "accounts_flags_multisig_explain": "This is a multi-signature account",
+ "accounts_flags_simple": "Simple account",
+ "accounts_flags_simple_explain": "This is a simple account",
+ "accounts_flags_unknown_by_network": "Private Account",
+ "accounts_harvesting_remote_explain_p1": "Use the button on the right to configure a remote account for harvesting. This will later permit your account to activate delegated harvesting.",
+ "accounts_harvesting_remote_explain_p2": "You will be asked to unlock your account and will then view options for the setup of a remote account for harvesting.",
+ "accounts_harvesting_request_explain_p1": "Use the button on the right to send a harvesting delegation request. If approved by the node, this will activate harvesting for your account.",
+ "accounts_harvesting_request_explain_p2": "You will be asked to unlock your account and will then view options for sending harvesting delegation requests to Peer nodes.",
+ "accounts_harvesting_tile_remote": "Remote account",
+ "accounts_harvesting_tile_remote_description": "Importance transfer",
+ "accounts_harvesting_tile_request": "Delegation request(s)",
+ "accounts_harvesting_tile_request_description": "Start harvesting!",
+ "accounts_harvesting_title_remote": "Setup a remote account",
+ "accounts_harvesting_title_request": "Send delegation request(s)",
+ "accounts_label_flags": "Flags",
+ "accounts_links_explorer": "Explorer",
+ "accounts_links_faucet": "Faucet",
+ "accounts_setup_harvesting_description": "Configure delegated harvesting",
+ "accounts_setup_harvesting_title": "Setup harvesting",
+ "accounts_share_qr_code": "Share public details",
+ "accounts_subtitle_account_links": "Useful links",
+ "accounts_view_dashboard": "View in dashboard",
+ "accounts_view_explorer_description": "Open in explorer",
+ "accounts_view_multisig": "Multi-signature",
+ "accounts_view_open_faucet": "Open the faucet",
+ "action": "Action",
+ "action_label_alias_link": "Link Alias",
+ "action_label_alias_unlink": "Unlink Alias",
+ "action_label_extend_duration": "Extend duration",
+ "action_label_modify_supply": "Modify supply",
+ "activate": "Activate",
+ "activating": "Activating...",
+ "add_account_failed": "Failed to add account, reason: {reason}",
+ "add_account_restrictions": "Account restrictions",
+ "add_address_restrictions": "New address restriction",
+ "add_contact": "Add contact",
+ "add_metadata": "Add metadata",
+ "add_mosaic": "Add an asset",
+ "add_mosaic_restrictions": "New asset restriction",
+ "add_node": "Add node",
+ "add_operation_restrictions": "New operation restriction",
+ "address": "Address",
+ "address_alias_not_exist": "Address alias does not exist",
+ "address_format_error": "Address format error",
+ "address_invalid": "This address is invalid",
+ "address_not_valid": "Cosignatory address is not valid",
+ "address_qr_code": "Address QR code",
+ "address_to_interact_with": "Address to interact with",
+ "address_unknown": "This address is unknown to the network, please try with its public key instead",
+ "address_unknown_by_network": "The account is unknown by the network until it sends a first transaction.",
+ "aggregate_send": "Send aggregate",
+ "alias": "Alias",
+ "alias_name_format_error": "alias hexadecimal format error",
+ "aliases": "Aliases",
+ "all_nodes_cannot_be_deleted": "All nodes cannot be deleted",
+ "allow": "Allow",
+ "amount": "Amount",
+ "amount_asset": "Amount",
+ "amount_can_not_be_less_than_0": "The amount should be greater than 0",
+ "any_information_cannot_be_empty": "Fields cannot be empty. Please, verify your input.",
+ "approval_greater_than_cosignatories": "There are {delta} more required cosignatories for min. approval than available cosignatories. Please add cosignatories or reduce the min. approval number.",
+ "article_by": "Article by {creator}",
+ "assets": "Assets",
+ "at_block": "at block {blockNumber}",
+ "automatically_generated_by_node_url": "Automatically generated by node URL",
+ "back": "Back",
+ "backup_address_book": "Backup address book",
+ "backup_mnemonic": "Backup mnemonic",
+ "backup_mnemonic_phrase": "Backup Phrase",
+ "backup_mnemonic_words": "Backup mnemonic words",
+ "backup_profile": "Backup Profile",
+ "backup_profile_explanation_desc": "Download a paper (PDF) copy of your profile. All of your accounts inside this profile will be listed in the downloaded file. This backup file will enable you to restore all of your accounts. Please keep them in a safe place and do not share with third parties since it stores highly sensitive information.",
+ "backup_profile_explanation_title": "Backup Your Profile as Paper Wallet",
+ "balance": "Balance",
+ "block": "Block",
+ "block_height": "Height",
+ "blocks_made": "Blocks made",
+ "button_add_account": "Add an account",
+ "button_download": "Download",
+ "button_download_paper_wallet": "Download Paper Wallet",
+ "button_download_qr": "Download",
+ "button_understand_title": "Understood",
+ "cancel": "Cancel",
+ "chain_height": "Chain height",
+ "choose_network": "Choose network",
+ "choose_profile_name_and_password": "Choose a profile name and a password",
+ "clear_staged_transactions": "Discard all transactions",
+ "click_to_cosign": "Click to cosign",
+ "click_to_load": "Click to load data",
+ "close": "Close",
+ "co_signers_amount_less_than_0": "Multi-signature accounts must have at least 1 co-signatory",
+ "confirm": "Confirm",
+ "confirm_backup": "Confirm backup",
+ "CONFIRMATION": "Confirmation",
+ "confirmation_title": "Confirmation",
+ "confirmations_height": "Height",
+ "confirmed_transaction": "Confirmed",
+ "confirmPassword": "Confirm password",
+ "connect_ledger_prompt": "Connect to Ledger",
+ "connect_ledger_title": "Connect to a Ledger Hardware Wallet",
+ "contact_address": "Address",
+ "contact_email": "Email",
+ "contact_information": "Contact information",
+ "contact_name": "Name",
+ "contact_notes": "Notes",
+ "contact_phone": "Phone",
+ "contact_qr_action_desc": "Click continue to be redirected to the transfer page to make a transfer to this recipient.",
+ "contact_qr_code": "Contact QR code",
+ "continue": "Continue",
+ "copy_failed": "Copy failed",
+ "copy_mnemonic": "Copy mnemonic",
+ "cosignatory_of": "Cosignatory of",
+ "cosignature_added": "Cosignature received",
+ "cosignature_qr_action_desc": "Continue to transaction details page to sign your part.",
+ "create_a_new_account": "Create a new profile",
+ "create_a_new_profile": "Create a new profile",
+ "create_lock_check_pw_remind": "Two passwords are inconsistent",
+ "create_lock_pw_remind": "Password setting error",
+ "create_lock_pw_txt_remind": "Password hint error",
+ "create_mnemonic": "Create Mnemonic",
+ "create_profile": "Create Profile",
+ "create_profile_failed": "Failed to create profile, reason: {reason}",
+ "create_sub_namespace": "Create a sub-namespace",
+ "creation_successful": "Congratulations, the profile was created successfully!",
+ "current_cosigner_matches_current_account": "You can't add the currently selected account as a co-signatory of itself.",
+ "current_endpoint": "Current Node",
+ "current_network": "Current Network",
+ "current_profile_network": "Current profile network",
+ "current_speed": "The current speed",
+ "current_validity": "Expires in",
+ "deadline": "Deadline",
+ "decrease": "Decrease",
+ "decrypt_message": "Decrypt",
+ "define": "Registration",
+ "harvesting_delegated_description": "Delegated Harvesting allows receiving rewards from creating new blocks using the account's importance score without running a node. To activate Delegated Harvesting you have to link all keys and request a node to harvest for your account.",
+ "harvesting_node_selection": "Please select a node from the dropdown list below. You can find more nodes in the dHealth Explorer and use them by entering their URL.",
+ "open_explorer_node_list": "Visit dHealth Explorer's node list",
+ "harvesting_keys_linked_next_step_guide": "Keys are linked. You can now request a node to harvest for your account. If you want to change the node, you will have to unlink the keys first. Use buttons below.",
+ "harvesting_delegated_request_warning": "Depending on your account's importance score and the node's free harvesting slots, your request might not be granted.\n\nAlso, please note that nodes may remove accounts from their harvesting slots at any time.\n\nIn these cases you need to switch to a different node and repeat the Delegated Harvesting activation process. Transaction fees paid for the activation will not be refunded.\n\nIf you entered a custom node URL, the Harvesting status shown may not be accurate on all your devices.",
+ "harvesting_delegated_request_warning_title": "Delegated Harvesting",
+ "delegated_harvesting_info": "Delegated harvesting allows using the importance score of an account to create new blocks and receive rewards\n without having to run a node locally. You can send a Delegated Harvesting Request to the selected Node or swap\n to another one.",
+ "delegated_harvesting_keys_info": "Linked keys are used for both remote and delegated harvesting. If you own a node you must copy the following keys into your node configuration to enable remote harvesting. Otherwise, the wallet holds these keys for you when enabling delegated harvesting.",
+ "open_harvesting_keys_warning_title": "Open harvesting linked keys",
+ "open_harvesting_keys_warning_text": "Linked keys is an advanced feature and should only be managed by users that understand how harvesting keys work. Please use the delegated harvesting screen if this is not your case.",
+ "harvesting_activated_from_another_device": "Harvesting has been activated using another device. The harvesting status displayed could be incorrect because this wallet does not have all the required information. If you know the node you selected in the other device, you can select it below.",
+ "harvesting_keys_linked_missing": "In order to activate harvesting wallet needs to have all linked key pairs. Please re-link them.",
+ "delete": "Delete",
+ "delete_account": "Delete Account",
+ "delete_account_confirmation_message": "Deleting an account is not recommended without backing up your account. Loss of funds may occur. Are you sure you would like to delete \"{accountName}\"?",
+ "delete_account_confirmation_title": "Delete Account",
+ "delete_account_confirmation_checkbox": "Yes, I would like to delete this account.",
+ "delete_profile_confirmation_title": "Delete Profile",
+ "delete_profile_confirmation_message": "Deleting a profile is not recommended without a backup. Loss of funds may occur. Are you sure you would like to delete \"{profileName}\"?",
+ "delete_profile_confirmation_checkbox": "Yes, I would like to delete this profile.",
+ "delete_confirmation_message": "Are you sure you want to delete?",
+ "delete_contact": "Delete contact",
+ "delete_contact_confirmation_message": "Are you sure you want to delete \"{contactName}\"?",
+ "delete_contact_confirmation_title": "Delete Contact?",
+ "delete_profile": "Delete Profile",
+ "delta": "Delta",
+ "description": "Description",
+ "direction": "Direction",
+ "display_mnemonic": "Display mnemonic words",
+ "display_mnemonic_qr_code": "Display mnemonic QR code",
+ "divisibility": "Divisibility",
+ "divisibility_can_not_less_than_0": "Divisibility cannot be less than 0",
+ "divisibility_can_not_more_than_6": "Divisibility cannot exceed 6.",
+ "divisibility_invalid": "This divisibility is invalid [0-6]",
+ "do_not_disclose": "Please, keep this information private. Sharing your mnemonic passphrase with others may put your funds at risk.",
+ "do_not_disclose_title": "Keep this private!",
+ "do_not_disclose_title_mnemonic": "Backup your mnemonic passphrase",
+ "do_not_share_mnemonics_with_anyone": "Don't share mnemonics with anyone",
+ "download": "Download",
+ "duration": "Duration",
+ "duration_can_not_less_than_0": "Duration cannot be less than 0",
+ "duration_can_not_more_than_1_years": "Duration cannot be greater than 1 year",
+ "duration_can_not_more_than_10_years": "Duration cannot be greater than 10 years",
+ "duration_permanent": "Unlimited duration",
+ "edit_object": "Edit {objectName}",
+ "edit_metadata": "Edit metadata",
+ "encrypt_message": "Encrypt message",
+ "encrypted_message": "Encrypted message",
+ "encrypted_message_empty_error": "Message payload cannot be empty for encrypted message",
+ "end_finalization_epoch": "End Finalization Epoch",
+ "endpoint": "Node",
+ "enter_your_private_key": "Enter your private key",
+ "error_account_name_already_exists": "This account name already exists. Please, enter a unique account name.",
+ "error_contact_already_exists": "This contact already exists.",
+ "error_delete_all_peers": "You cannot delete all the nodes",
+ "error_incorrect_field": "The {_field_} field is incorrect.",
+ "error_incorrect_url": "This is not a valid URL",
+ "error_invalid_password": "This password is invalid",
+ "error_new_namespace_duration_max_value": "The new namespace duration cannot be greater than {maxValue}",
+ "error_new_password_format": "The password should contain at least one letter and one number.",
+ "error_peer_connection_went_wrong": "Something went wrong. Connection to the node {peerUrl} timed out",
+ "error_peer_unreachable": "This node is unreachable.",
+ "error_profile_does_not_exist": "Profile does not exist",
+ "error_too_many_seed_accounts": "You cannot create more than {maxSeedAccountsNumber} child accounts",
+ "estimated_period_of_validity": "Estimated Period Of Validity",
+ "estimated_rental_fee": "Estimated rental fee",
+ "existing_profile": "Do you already have a profile?",
+ "expired_for": "Expired for",
+ "expires_in": "Expires in",
+ "explorer_url": "Explorer URL",
+ "export_mnemonic": "Export mnemonic",
+ "export_transactions": "Export Transactions",
+ "fee": "Fee",
+ "fee_can_not_be_less_than_0": "Fee cannot be less than 0",
+ "fee_speed_fast": "Fast",
+ "fee_speed_fastest": "Fastest",
+ "fee_speed_free": "No Fee",
+ "fee_speed_highest": "Highest",
+ "fee_speed_median": "Average",
+ "fee_speed_normal": "Normal",
+ "fee_speed_slow": "Slow",
+ "fee_speed_slowest": "Slowest",
+ "fees_collected": "Fees collected",
+ "fees_earned": "Fees Earned",
+ "filter_peers": "Filter peers",
+ "finish": "Finish",
+ "finished": "Finished",
+ "flags_divisibility": "Determines the number of decimal places to which the assets can be divided. The divisibility must be between 0 and 6 (included).",
+ "flags_duration_permanent": "If set to true, the assets will never expire.",
+ "flags_restrictable": "If set to true, the assets owner can configure custom restrictions.",
+ "flags_supply": "The total supply must be in the range of 0 and 9,000,000,000,000,000 atomic units.",
+ "flags_transferable": "If set to true, the assets can be transferred to arbitrary accounts.",
+ "flags_variable_supply": "If set to true, the assets supply will be mutable.",
+ "form_label_account_to_be_converted": "Account to be converted",
+ "form_label_add_cosignatory": "Add a cosignatory",
+ "form_label_additional_duration": "Additional duration",
+ "form_label_alias_type": "Alias type",
+ "form_label_by_account": "By account",
+ "form_label_choose_namespace": "Choose a namespace",
+ "form_label_cosignatory_modifications": "Cosignatory modifications",
+ "form_label_current_supply": "Current supply",
+ "form_label_default_account": "Preferred default account",
+ "form_label_default_max_fee": "Default max fee",
+ "form_label_description_min_approval": "Minimum signatures to sign a transaction or to add a cosigner",
+ "form_label_description_min_removal": "Minimum signatures required to remove a cosigner",
+ "form_label_duration": "Duration",
+ "form_label_language": "Preferred language",
+ "form_label_link_address": "Link an address",
+ "form_label_link_mosaic": "Link an asset",
+ "form_label_max_fee": "Max fee",
+ "form_label_min_approval": "Min. approval",
+ "form_label_min_removal": "Min. removal",
+ "form_label_multisig_account": "Multi-signature account",
+ "form_label_multisig_accounts": "Multi-signature accounts",
+ "form_label_multisig_current_info": "Cosignatories",
+ "form_label_multisig_operation_type": "Operation type",
+ "form_label_namespace_name": "Namespace name",
+ "form_label_network_node_url": "Enter a harvesting node URL here (e.g: http://localhost:3000)",
+ "form_label_network_custom_node": "Type your custom harvesting node URL below",
+ "form_label_new_absolute_supply": "New absolute supply",
+ "form_label_new_account_name": "New account name",
+ "form_label_new_account_type": "Select the type of account",
+ "form_label_new_contact_address": "New contact address",
+ "form_label_new_contact_name": "New contact name",
+ "form_label_new_cosignatories": "Added cosignatories",
+ "form_label_new_expiration_time": "New expiration time",
+ "form_label_new_min_approval": "New min. approval",
+ "form_label_new_min_removal": "New min. removal",
+ "form_label_new_password": "Enter a new password",
+ "form_label_new_password_confirm": "Confirm your new password",
+ "form_label_new_password_hint": "Password hint",
+ "form_label_new_supply": "New supply",
+ "form_label_parent_namespace": "Parent namespace",
+ "form_label_password": "Password",
+ "form_label_password_hint": "Please enter the current profile password",
+ "form_label_private_key": "Enter your private key",
+ "form_label_registration_type": "Namespace type",
+ "form_label_remove_cosignatory": "Remove a cosignatory",
+ "form_label_removed_cosignatory": "Removed cosignatory",
+ "form_label_removed_cosignatory_tooltip": "Only one cosignatory removal is allowed within a transaction",
+ "form_label_restriction_type_tooltip": "An account can only configure a block or an allow list per type of restriction",
+ "form_label_scoped_metadata_key": "Scoped metadata key",
+ "form_label_scoped_metadata_key_hint": "Metadata key scoped (update or addition ?)",
+ "form_label_supply_delta": "Supply change amount",
+ "form_label_supply_direction": "Supply change direction",
+ "form_label_target_account": "Target account",
+ "form_label_target_account_hint": "Please enter the target account address or public key",
+ "form_label_target_mosaic_id": "Target Assets ID",
+ "form_label_target_namespace_id": "Target Namespace ID",
+ "form_label_value": "value",
+ "form_label_value_hint": "The value linked to an identifier is a string up to 1024 characters",
+ "from_qr_code": "From QR Code",
+ "from_to_action": "From/To (action)",
+ "Failure_Core_Past_Deadline": "Validation failed because the deadline passed",
+ "Failure_Core_Future_Deadline": "Validation failed because the deadline is too far in the future",
+ "Failure_Core_Insufficient_Balance": "Validation failed because the account has an insufficient balance",
+ "Failure_Core_Too_Many_Transactions": "Validation failed because there are too many transactions in a block",
+ "Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block": "Validation failed because an entity originated from the nemesis account after the nemesis block",
+ "Failure_Core_Wrong_Network": "Validation failed because the entity has the wrong network specified",
+ "Failure_Core_Invalid_Address": "Validation failed because an address is invalid",
+ "Failure_Core_Invalid_Version": "Validation failed because entity version is invalid",
+ "Failure_Core_Invalid_Transaction_Fee": "Validation failed because a transaction fee is invalid",
+ "Failure_Core_Block_Harvester_Ineligible": "Validation failed because a block was harvested by an ineligible harvester",
+ "Failure_Core_Zero_Address": "Validation failed because an address is zero",
+ "Failure_Core_Zero_Public_Key": "Validation failed because a public key is zero",
+ "Failure_Core_Nonzero_Internal_Padding": "Validation failed because internal padding is nonzero",
+ "Failure_Core_Address_Collision": "Validation failed because an address collision is detected",
+ "Failure_Core_Importance_Block_Mismatch": "Validation failed because the block does not match the schema of an importance block",
+ "Failure_Core_Unexpected_Block_Type": "Validation failed because the block type is unexpected",
+ "Failure_Core_Invalid_Link_Action": "Validation failed because link action is invalid",
+ "Failure_Core_Link_Already_Exists": "Validation failed because main account is already linked to another account",
+ "Failure_Core_Inconsistent_Unlink_Data": "Validation failed because unlink data is not consistent with existing account link",
+ "Failure_Core_Invalid_Link_Range": "Validation failed because link range is invalid",
+ "Failure_Core_Too_Many_Links": "Validation failed because main account has too many links of the specified type",
+ "Failure_Signature_Not_Verifiable": "Validation failed because the verification of the signature failed",
+ "Failure_AccountLink_Link_Already_Exists": "Validation failed because main account is already linked to another account",
+ "Failure_AccountLink_Inconsistent_Unlink_Data": "Validation failed because unlink data is not consistent with existing account link",
+ "Failure_AccountLink_Unknown_Link": "Validation failed because main account is not linked to another account",
+ "Failure_AccountLink_Remote_Account_Ineligible": "Validation failed because link is attempting to convert ineligible account to remote",
+ "Failure_AccountLink_Remote_Account_Signer_Prohibited": "Validation failed because remote is not allowed to sign a transaction",
+ "Failure_AccountLink_Remote_Account_Participant_Prohibited": "Validation failed because remote is not allowed to participate in the transaction",
+ "Failure_Aggregate_Too_Many_Transactions": "Validation failed because aggregate has too many transactions",
+ "Failure_Aggregate_No_Transactions": "Validation failed because aggregate does not have any transactions",
+ "Failure_Aggregate_Too_Many_Cosignatures": "Validation failed because aggregate has too many cosignatures",
+ "Failure_Aggregate_Redundant_Cosignatures": "Validation failed because redundant cosignatures are present",
+ "Failure_Aggregate_Ineligible_Cosignatories": "Validation failed because at least one cosignatory is ineligible",
+ "Failure_Aggregate_Missing_Cosignatures": "Validation failed because at least one required cosignature is missing",
+ "Failure_Aggregate_Transactions_Hash_Mismatch": "Validation failed because the aggregate transactions hash does not match the calculated value",
+ "Failure_LockHash_Invalid_Mosaic_Id": "Validation failed because lock does not allow the specified asset",
+ "Failure_LockHash_Invalid_Mosaic_Amount": "Validation failed because lock does not allow the specified amount",
+ "Failure_LockHash_Hash_Already_Exists": "Validation failed because hash is already present in cache",
+ "Failure_LockHash_Unknown_Hash": "Validation failed because hash is not present in cache",
+ "Failure_LockHash_Inactive_Hash": "Validation failed because hash is inactive",
+ "Failure_LockHash_Invalid_Duration": "Validation failed because duration is too long",
+ "Failure_LockSecret_Invalid_Hash_Algorithm": "Validation failed because hash algorithm for lock type secret is invalid",
+ "Failure_LockSecret_Hash_Already_Exists": "Validation failed because hash is already present in cache",
+ "Failure_LockSecret_Proof_Size_Out_Of_Bounds": "Validation failed because proof is too small or too large",
+ "Failure_LockSecret_Secret_Mismatch": "Validation failed because secret does not match proof",
+ "Failure_LockSecret_Unknown_Composite_Key": "Validation failed because composite key is unknown",
+ "Failure_LockSecret_Inactive_Secret": "Validation failed because secret is inactive",
+ "Failure_LockSecret_Hash_Algorithm_Mismatch": "Validation failed because hash algorithm does not match",
+ "Failure_LockSecret_Invalid_Duration": "Validation failed because duration is too long",
+ "Failure_Metadata_Value_Too_Small": "Validation failed because the metadata value is too small",
+ "Failure_Metadata_Value_Too_Large": "Validation failed because the metadata value is too large",
+ "Failure_Metadata_Value_Size_Delta_Too_Large": "Validation failed because the metadata value size delta is larger in magnitude than the value size",
+ "Failure_Metadata_Value_Size_Delta_Mismatch": "Validation failed because the metadata value size delta does not match expected value based on the current state",
+ "Failure_Metadata_Value_Change_Irreversible": "Validation failed because a metadata value change (truncation) is irreversible",
+ "Failure_Mosaic_Invalid_Duration": "Validation failed because the duration has an invalid value",
+ "Failure_Mosaic_Invalid_Name": "Validation failed because the name is invalid",
+ "Failure_Mosaic_Name_Id_Mismatch": "Validation failed because the name and id don't match",
+ "Failure_Mosaic_Expired": "Validation failed because the parent is expired",
+ "Failure_Mosaic_Owner_Conflict": "Validation failed because the parent owner conflicts with the child owner",
+ "Failure_Mosaic_Id_Mismatch": "Validation failed because the id is not the expected id generated from signer and nonce",
+ "Failure_Mosaic_Parent_Id_Conflict": "Validation failed because the existing parent id does not match the supplied parent id",
+ "Failure_Mosaic_Invalid_Property": "Validation failed because an asset property is invalid",
+ "Failure_Mosaic_Invalid_Flags": "Validation failed because the assets flags are invalid",
+ "Failure_Mosaic_Invalid_Divisibility": "Validation failed because the assets divisibility is invalid",
+ "Failure_Mosaic_Invalid_Supply_Change_Action": "Validation failed because the assets supply change action is invalid",
+ "Failure_Mosaic_Invalid_Supply_Change_Amount": "Validation failed because the assets supply change amount is invalid",
+ "Failure_Mosaic_Invalid_Id": "Validation failed because the assets id is invalid",
+ "Failure_Mosaic_Modification_Disallowed": "Validation failed because assets modification is not allowed",
+ "Failure_Mosaic_Modification_No_Changes": "Validation failed because assets modification would not result in any changes",
+ "Failure_Mosaic_Supply_Immutable": "Validation failed because the assets supply is immutable",
+ "Failure_Mosaic_Supply_Negative": "Validation failed because the resulting assets supply is negative",
+ "Failure_Mosaic_Supply_Exceeded": "Validation failed because the resulting assets supply exceeds the maximum allowed value",
+ "Failure_Mosaic_Non_Transferable": "Validation failed because this asset is not transferable",
+ "Failure_Mosaic_Max_Mosaics_Exceeded": "Validation failed because the credit of the asset would exceed the maximum of different assets an account is allowed to own",
+ "Failure_Mosaic_Required_Property_Flag_Unset": "Validation failed because the asset has at least one required property flag unset",
+ "Failure_Multisig_Account_In_Both_Sets": "Validation failed because account is specified to be both added and removed",
+ "Failure_Multisig_Multiple_Deletes": "Validation failed because multiple removals are present",
+ "Failure_Multisig_Redundant_Modification": "Validation failed because a modification is redundant",
+ "Failure_Multisig_Unknown_Multisig_Account": "Validation failed because account is not in multisig cache",
+ "Failure_Multisig_Not_A_Cosignatory": "Validation failed because account to be removed is not present",
+ "Failure_Multisig_Already_A_Cosignatory": "Validation failed because account to be added is already a cosignatory",
+ "Failure_Multisig_Min_Setting_Out_Of_Range": "Validation failed because new minimum settings are out of range",
+ "Failure_Multisig_Min_Setting_Larger_Than_Num_Cosignatories": "Validation failed because min settings are larger than number of cosignatories",
+ "Failure_Multisig_Invalid_Modification_Action": "Validation failed because the modification action is invalid",
+ "Failure_Multisig_Max_Cosigned_Accounts": "Validation failed because the cosignatory already cosigns the maximum number of accounts",
+ "Failure_Multisig_Max_Cosignatories": "Validation failed because the multisig account already has the maximum number of cosignatories",
+ "Failure_Multisig_Loop": "Validation failed because a multisig loop is created",
+ "Failure_Multisig_Max_Multisig_Depth": "Validation failed because the max multisig depth is exceeded",
+ "Failure_Multisig_Operation_Prohibited_By_Account": "Validation failed because an operation is not permitted by a multisig account",
+ "Failure_Namespace_Invalid_Duration": "Validation failed because the duration has an invalid value",
+ "Failure_Namespace_Invalid_Name": "Validation failed because the name is invalid",
+ "Failure_Namespace_Name_Id_Mismatch": "Validation failed because the name and id don't match",
+ "Failure_Namespace_Expired": "Validation failed because the parent is expired",
+ "Failure_Namespace_Owner_Conflict": "Validation failed because the parent owner conflicts with the child owner",
+ "Failure_Namespace_Id_Mismatch": "Validation failed because the id is not the expected id generated from signer and nonce",
+ "Failure_Namespace_Invalid_Registration_Type": "Validation failed because the namespace registration type is invalid",
+ "Failure_Namespace_Root_Name_Reserved": "Validation failed because the root namespace has a reserved name",
+ "Failure_Namespace_Too_Deep": "Validation failed because the resulting namespace would exceed the maximum allowed namespace depth",
+ "Failure_Namespace_Unknown_Parent": "Validation failed because the namespace parent is unknown",
+ "Failure_Namespace_Already_Exists": "Validation failed because the namespace already exists",
+ "Failure_Namespace_Already_Active": "Validation failed because the namespace is already active",
+ "Failure_Namespace_Eternal_After_Nemesis_Block": "Validation failed because an eternal namespace was received after the nemesis block",
+ "Failure_Namespace_Max_Children_Exceeded": "Validation failed because the maximum number of children for a root namespace was exceeded",
+ "Failure_Namespace_Alias_Invalid_Action": "Validation failed because alias action is invalid",
+ "Failure_Namespace_Unknown": "Validation failed because namespace does not exist",
+ "Failure_Namespace_Alias_Already_Exists": "Validation failed because namespace is already linked to an alias",
+ "Failure_Namespace_Unknown_Alias": "Validation failed because namespace is not linked to an alias",
+ "Failure_Namespace_Alias_Inconsistent_Unlink_Type": "Validation failed because unlink type is not consistent with existing alias",
+ "Failure_Namespace_Alias_Inconsistent_Unlink_Data": "Validation failed because unlink data is not consistent with existing alias",
+ "Failure_Namespace_Alias_Invalid_Address": "Validation failed because aliased address is invalid",
+ "Failure_RestrictionAccount_Invalid_Restriction_Flags": "Validation failed because the account restriction flags are invalid",
+ "Failure_RestrictionAccount_Invalid_Modification_Action": "Validation failed because a modification action is invalid",
+ "Failure_RestrictionAccount_Invalid_Modification_Address": "Validation failed because a modification address is invalid",
+ "Failure_RestrictionAccount_Modification_Operation_Type_Incompatible": "Validation failed because the operation type is incompatible",
+ "Failure_RestrictionAccount_Redundant_Modification": "Validation failed because a modification is redundant",
+ "Failure_RestrictionAccount_Invalid_Modification": "Validation failed because a value is not in the container",
+ "Failure_RestrictionAccount_Modification_Count_Exceeded": "Validation failed because the transaction has too many modifications",
+ "Failure_RestrictionAccount_No_Modifications": "Validation failed because the transaction has no modifications",
+ "Failure_RestrictionAccount_Values_Count_Exceeded": "Validation failed because the resulting account restriction has too many values",
+ "Failure_RestrictionAccount_Invalid_Value": "Validation failed because the account restriction value is invalid",
+ "Failure_RestrictionAccount_Address_Interaction_Prohibited": "Validation failed because the addresses involved in the transaction are not allowed to interact",
+ "Failure_RestrictionAccount_Mosaic_Transfer_Prohibited": "Validation failed because assets transfer is prohibited by the recipient",
+ "Failure_RestrictionAccount_Operation_Type_Prohibited": "Validation failed because the operation type is not allowed to be initiated by the signer",
+ "Failure_RestrictionMosaic_Invalid_Restriction_Type": "Validation failed because the assets restriction type is invalid",
+ "Failure_RestrictionMosaic_Previous_Value_Mismatch": "Validation failed because specified previous value does not match current value",
+ "Failure_RestrictionMosaic_Previous_Value_Must_Be_Zero": "Validation failed because specified previous value is nonzero",
+ "Failure_RestrictionMosaic_Max_Restrictions_Exceeded": "Validation failed because the maximum number of restrictions would be exceeded",
+ "Failure_RestrictionMosaic_Cannot_Delete_Nonexistent_Restriction": "Validation failed because nonexistent restriction cannot be deleted",
+ "Failure_RestrictionMosaic_Unknown_Global_Restriction": "Validation failed because required global restriction does not exist",
+ "Failure_RestrictionMosaic_Invalid_Global_Restriction": "Validation failed because the asset has invalid global restriction",
+ "Failure_RestrictionMosaic_Account_Unauthorized": "Validation failed because account lacks proper permissions to move the assets",
+ "Failure_Transfer_Message_Too_Large": "Validation failed because the message is too large",
+ "Failure_Transfer_Out_Of_Order_Mosaics": "Validation failed because assets are out of order",
+ "Failure_Chain_Unlinked": "Validation failed because a block was received that did not link with the existing chain",
+ "Failure_Chain_Block_Not_Hit": "Validation failed because a block was received that is not a hit",
+ "Failure_Chain_Block_Inconsistent_State_Hash": "Validation failed because a block was received that has an inconsistent state hash",
+ "Failure_Chain_Block_Inconsistent_Receipts_Hash": "Validation failed because a block was received that has an inconsistent receipts hash",
+ "Failure_Chain_Block_Invalid_Vrf_Proof": "Validation failed because the VRF proof is invalid",
+ "Failure_Chain_Block_Unknown_Signer": "Validation failed because the block signer is unknown",
+ "Failure_Chain_Unconfirmed_Cache_Too_Full": "Validation failed because the unconfirmed cache is too full",
+ "Failure_Consumer_Empty_Input": "Validation failed because the consumer input is empty",
+ "Failure_Consumer_Block_Transactions_Hash_Mismatch": "Validation failed because the block transactions hash does not match the calculated value",
+ "Neutral_Consumer_Hash_In_Recency_Cache": "Validation failed because an entity hash is present in the recency cache",
+ "Failure_Consumer_Remote_Chain_Too_Many_Blocks": "Validation failed because the chain part has too many blocks",
+ "Failure_Consumer_Remote_Chain_Improper_Link": "Validation failed because the chain is internally improperly linked",
+ "Failure_Consumer_Remote_Chain_Duplicate_Transactions": "Validation failed because the chain part contains duplicate transactions",
+ "Failure_Consumer_Remote_Chain_Unlinked": "Validation failed because the chain part does not link to the current chain",
+ "Failure_Consumer_Remote_Chain_Difficulties_Mismatch": "Validation failed because the remote chain difficulties do not match the calculated difficulties",
+ "Failure_Consumer_Remote_Chain_Score_Not_Better": "Validation failed because the remote chain score is not better",
+ "Failure_Consumer_Remote_Chain_Too_Far_Behind": "Validation failed because the remote chain is too far behind",
+ "Failure_Consumer_Remote_Chain_Too_Far_In_Future": "Validation failed because the remote chain timestamp is too far in the future",
+ "Failure_Consumer_Batch_Signature_Not_Verifiable": "Validation failed because the verification of the signature failed during a batch operation",
+ "Failure_Consumer_Remote_Chain_Improper_Importance_Link": "Validation failed because the remote chain has an improper importance link",
+ "Failure_Extension_Partial_Transaction_Cache_Prune": "Validation failed because the partial transaction was pruned from the temporal cache",
+ "Failure_Extension_Partial_Transaction_Dependency_Removed": "Validation failed because the partial transaction was pruned from the temporal cache due to its dependency being removed",
+ "Failure_Extension_Read_Rate_Limit_Exceeded": "Validation failed because socket read rate limit was exceeded",
+ "generate_a_new_profile": "Generate a new profile",
+ "generate_entropy_increase_success": "Successfully generated a random mnemonic pass phrase.",
+ "generate_mnemonic": "Generate Mnemonic",
+ "generate_mnemonic_title": "Generate your mnemonic passphrase",
+ "generating_mnemonic": "Next",
+ "getting_a_mnemonic_equals_ownership_of_a_account_asset": "This mnemonic passphrase is enough to take the control of all the assets of a profile.",
+ "go_to_login": "Click here to login now",
+ "harvested_blocks": "Harvested Blocks",
+ "harvesting": "Harvesting",
+ "harvesting_account_insufficient_balance": "Insufficient balance, the account needs to hold at least 10000 XYMs to start delegated harvesting.",
+ "harvesting_account_has_extra_balance": "To start delegated harvesting your account cannot hold more than 50 million XYM.",
+ "harvesting_account_has_zero_importance": "Your account cannot start delegated harvesting while importance is equal to 0.",
+ "harvesting_confirmation_description_1": "You can see the transaction(s) details displayed below. After you have entered your password, and pressed the Next button, these transaction(s) will be announced to the network.",
+ "harvesting_confirmation_description_2": "Harvesting will be activated automatically provided that the network node is harvesting and accepts delegation requests.",
+ "harvesting_create_remote_account": "You will first need to setup a remote account, if you have not done this before.",
+ "harvesting_delegation_description_1": "Select the account that should start harvesting and select the harvesting node to which you want to send a delegation request.",
+ "harvesting_delegation_description_2": "Then, select a max fee to include in the transaction. You can send delegation requests to multiple nodes.",
+ "harvesting_node_get_node_info": "Get node info ",
+ "harvesting_node_not_eligible": "This not is not eligible for harvesting",
+ "harvesting_remote_account": "remote account",
+ "harvesting_remote_account_creation_successful_1": "Your remote account has been created successfully. Please keep its private key secure",
+ "harvesting_remote_account_description_1": "For security reasons, we will create a remote account (proxy) for delegated harvesting.",
+ "harvesting_remote_account_description_3": "Enter your password and click \"Start\" to create a remote account.",
+ "harvesting_remote_linked_description_1": "Your account is currently linked to the following remote account (proxy) for delegated harvesting.",
+ "harvesting_remote_linked_description_2": "You can unlink your account from this remote account in the Accounts section. Click Next to configure a delegation request for the harvesting node of your choice.",
+ "harvesting_status": "Harvesting status",
+ "harvesting_status_active": "Active",
+ "harvesting_status_inactive": "Inactive",
+ "harvesting_status_failed": "Failed",
+ "harvesting_status_inprogress_activation": "Activation in progress",
+ "harvesting_status_inprogress_deactivation": "Deactivation in progress",
+ "harvesting_status_keys_linked": "Keys Linked",
+ "harvesting_subtitle_confirmation": "Overview",
+ "harvesting_subtitle_delegation": "Node selection",
+ "harvesting_subtitle_overview": "Overview",
+ "harvesting_warning_node_swap": "Swapping to another node will relink your node public keys",
+ "hash_date": "Date",
+ "hd_account_path_error": "Address path error",
+ "hidden_accounts": "Hidden Accounts",
+ "hide_account": "Hide Account",
+ "id": "#",
+ "if_you_need_to_backup_your_mnemonics_again_you_can": "If you need to backup your mnemonics again, you can find them in 'Accounts - My Accounts - Backup Profile'.",
+ "illegal_public_key_error": "This public key is invalid",
+ "illegal_publicKey": "The account public key you provided is invalid",
+ "import": "Import",
+ "import_address_book": "Import address book",
+ "import_mnemonic": "Import mnemonic",
+ "import_mnemonic_passphrase_create_profile": "Import profile",
+ "import_private_key": "Import Private Key",
+ "import_private_key_account_successfully": "Congratulations, Private key account imported successfully.",
+ "import_private_key_account_successfully_title_tips": "The current profile was created using a private key. It is not possible to add other accounts to it. Hope you have a pleasant experience and journey.",
+ "import_private_key_description": "Import your private key to create a profile",
+ "import_private_key_finalize_tip_text1": "1. Please, make sure to backup your private key in a safe place. It is only encrypted and mounted under you local current profile. It has nothing to do with any mnemonic.",
+ "import_private_key_finalize_tip_text2": "2. A profile can mount any number of independent private keys for you. Be careful!",
+ "import_private_key_input_tip1": "Enter your private key in the input field. Please make sure your private key is correct. When you enter the correct private key, the corresponding public key and address will appear at the bottom of the input box. Note the network type.",
+ "import_private_key_profile_description_tip1": "Before you start using this software, you need to create a profile name and password. Used to encrypt your account information locally.",
+ "import_private_key_profile_description_tip2": "The password will be used to secure the access to your profile, like 'Transfer' and any transaction operations.",
+ "import_qr_code": "Import QR Code",
+ "import_successful": "Congratulations, the profile was imported successfully!",
+ "import_transaction_uri": "Import Transaction URI",
+ "importance": "Importance",
+ "incoming": "Incoming",
+ "increase": "Increase",
+ "info_active_cosignatory_mode": "The selected transaction signer is a multi-signature account.",
+ "info_connecting_peer": "Connecting to the node {peerUrl} ...",
+ "inner_transaction_hash": "inner transaction hash",
+ "input_here": "Input here",
+ "input_mnemonic": "Enter a mnemonic passphrase",
+ "input_mnemonic_tips": "Enter the 12 or 24 words of your mnemonic passphrase separated by space. The mnemonic passphrase is composed of 12 or 24 randomly chosen words. After setting the words, your assets will be restored.",
+ "input_namespace_name": "Enter a namespace name",
+ "invalid_address_book": "Invalid address book",
+ "invalid_mnemonic_input": "The entered mnemonic passphrase is invalid",
+ "invalid_namespace_or_mosaic_id": "The asset id or name is invalid",
+ "invalid_node": "Invalid node",
+ "keep_it_in_a_safe_place_on_the_isolated_network_mnemonics": "Keep it in a safe place. Do not share and store mnemonics in any shared or remote environment, such as emails, photo albums, social applications, etc.",
+ "keystore_decryption_failed": "Keystore decryption failed",
+ "label_add_cosignatory": "Add a cosignatory",
+ "label_duration_unlimited": "Unlimited",
+ "label_for_approvals": "co-signatures required for approving transactions",
+ "label_for_removals": "co-signatures required for removing cosignatories",
+ "label_multisig_operation_conversion": "Converting account to multi-signature",
+ "label_multisig_operation_modification": "Modifying account multisig properties",
+ "label_of": "{min} of {max}",
+ "label_postfix_multisig": "(Multisig)",
+ "label_signed_by": "Signed by co-signatory=>",
+ "latest_news_articles": "Latest news and articles",
+ "ledger_connected_other_app": "Ledger device cannot access the path, please use your ledger to verify your address or close any other opened apps then try again.",
+ "ledger_correct_account": "You are using the correct Symbol Ledger account",
+ "ledger_description": "Import a wallet from a Ledger device",
+ "ledger_device_locked": "Please unlock your Ledger device",
+ "ledger_no_device": "Ledger device not found",
+ "ledger_no_device_selected": "No Ledger device was selected",
+ "ledger_not_correct_account": "You are not using the correct Symbol Ledger account",
+ "ledger_not_opened_app": "Please open Symbol app on your Ledger device",
+ "ledger_not_supported_app": "Please check if you have an up-to-date Symbol application open on your Ledger device",
+ "ledger_not_using_xym_app": "You are not using Symbol app on your Ledger device",
+ "ledger_profile_import": "Ledger Profile import",
+ "ledger_user_reject_request": "Request canceled by user",
+ "link": "Link",
+ "link_action": "Link Action",
+ "linked_account_address": "Linked Account Address",
+ "linked_account_public_key": "Linked Account Public Key",
+ "linked_node_public_key": "Node Public Key",
+ "linked_public_key": "Remote Public Key",
+ "linked_vrf_public_key": "VRF Public Key",
+ "linked_remote_private_key": "Remote Private Key",
+ "linked_vrf_private_key": "VRF Private Key",
+ "linked_keys_info": "Keys Info:",
+ "link_keys": "Link all keys",
+ "loading": "Loading...",
+ "locked_mosaic": "locked asset",
+ "login": "Login",
+ "login_to_symbol_account": "Login to your account",
+ "logout": "Logout",
+ "low_fee_warning_message": "Transactions with less than the average fee might not get accepted and eventually expire",
+ "max_approval_amount_more_than_10": "The maximum number of co-signatories needed for approval cannot exceed 10",
+ "max_decimal_number_error": "The {_field_} field must have {maxDecimalNumber} decimals or less.",
+ "max_message_length_error": "The {_field_} may not be greater than {maxMessageNumber} characters.",
+ "positive_decimal_error": "Only digits and \"{decimalSeparator}\" allowed",
+ "max_fee": "Max Fee",
+ "max_removal_amount_more_than_10": "The maximum number of co-signatories needed for removal cannot exceed 10",
+ "message": "Message",
+ "message_empty_cosignatories": "This account does not have co-signatories.",
+ "metadata": "Metadata",
+ "metadata_attached_to_account": "Metadata attached to your account",
+ "metadata_value": "Metadata value",
+ "min_approval_amount_illegal": "The minimum number of co-signatories needed for approval must be a number",
+ "min_approval_amount_less_than_0": "The minimum number of co-signatories needed for approval cannot be smaller than 1",
+ "min_approval_delta": "Min. Approval Delta",
+ "min_removal_amount_illegal": "The minimum number of co-signatories needed for removal must be a number",
+ "min_removal_amount_less_than_0": "The minimum number of co-signatories needed for removal cannot be smaller than 1",
+ "min_removal_delta": "Min. Removal Delta",
+ "minimal_fee_transaction": "Please note that the minimal fee multiplier for the currently selected node is ",
+ "mnemonic_backup_options_copy_desc": "Copy the mnemonic words and keep them in a safe place.",
+ "mnemonic_backup_options_download_desc": "Download QR Code encrypted with your password. This QR Code can be used to import your accounts in different wallets (e.g. Mobile Wallet)",
+ "mnemonic_copy": "Copy",
+ "mnemonic_generation_error": "Something went wrong when generating your profile seed.",
+ "mnemonic_inconsistency": "Mnemonic is not correct",
+ "mnemonic_correct": "Mnemonic is correct",
+ "mnemonic_not_found": "Cannot find mnemonics!",
+ "mnemonic_phrase": "Mnemonic Passphrase",
+ "mnemonic_qr_action_desc": "Click continue to set imported Mnemonic Words to the text area.",
+ "modal_account_unlock_title": "Unlock your account",
+ "modal_backup_reminder_content": "Please note that the Private Key account cannot be restored from your mnemonic passphrase. Backup your profile again after import is complete to include this account in the Paper Wallet.",
+ "modal_backup_reminder_title": "Warning",
+ "modal_title_account_metadata": "Account metadata",
+ "modal_title_backup_mnemonic_display": "Display Mnemonic Passphrase",
+ "modal_title_backup_mnemonic_qrcode": "Export Mnemonic QR Code",
+ "modal_title_backup_profile": "Backup Profile",
+ "modal_title_backup_transaction": "Export Transactions",
+ "modal_title_debug_console": "Diagnostic Console",
+ "modal_title_delete": "Delete confirmation",
+ "modal_title_enter_account_name": "Configure your new account",
+ "modal_title_extend_namespace_duration": "Extend namespace duration",
+ "modal_title_link_alias": "Create an alias",
+ "modal_title_mosaic_metadata": "Asset metadata",
+ "modal_title_mosaic_supply_change": "Modify assets supply",
+ "modal_title_namespace_metadata": "Namespace metadata",
+ "modal_title_transaction_confirmation": "Sign transaction(s)",
+ "modal_title_transaction_details": "Details about a transaction",
+ "modal_title_unlink_alias": "Unlink alias from namespace",
+ "more_access_tool_is_working": "More authentication tools are being worked on...",
+ "mosaic": "Asset",
+ "mosaic_alias_not_exist": "Asset alias does not exist",
+ "mosaic_describe_text": "An asset could be a token, but it could also be a collection of more specialized assets such as reward points, company shares, signatures, status flags, votes or even currencies.",
+ "mosaic_expired": "Expired",
+ "mosaic_hex_format_error": "Assets hexadecimal format error",
+ "mosaic_id": "Assets id",
+ "mosaic_name_can_not_be_null": "Asset name cannot be null/empty",
+ "mosaic_not_set": "Select an asset",
+ "mosaic_transaction": "Assets Transaction ",
+ "mosaic_supply_transaction": "Supply Change Transaction ",
+ "mosaic_transfer_type": "Assets transactions",
+ "mosaics_list": "Assets List",
+ "move_your_mouse": "Please move your mouse to improve randomness when generating the mnemonic passphrase",
+ "move_your_mouse_tip1": "We are going to generate your mnemonic passphrase.",
+ "multisig_account_graph": "Multisig Tree",
+ "multisig_accounts_can_not_send_a_transaction_by_themselves": "Multi-signature accounts cannot initiate transactions. Please, use co-signatories accounts.",
+ "multisig_transaction": "Multisig Transaction ",
+ "multisignature_transfer_type": "Multisignature transaction",
+ "my_transaction_title": "My transactions",
+ "namespace": "Namespace",
+ "namespace_and_sub_namespace": "Namespaces and Sub-namespaces",
+ "namespace_can_only_contain_numbers_letters_and_other": "A namespace name can only contain 0-9, A-Z, a-z, _ and - characters",
+ "namespace_cannot_be_a_null_or_empty_string": "The namespace name cannot be an empty string",
+ "namespace_cannot_use_forbidden_words": "This namespace name is protected and cannot be used",
+ "namespace_definition": "A namespace starts with a name that you choose, similar to an internet domain name.",
+ "namespace_description": "Namespace description",
+ "namespace_duration_tip_1": "The duration is calculated in blocks, one block is 15 seconds, one block = 1XYM, and the maximum period is 365 days.",
+ "namespace_id": "Namespace id",
+ "namespace_must_start_with_a_letter": "A namespace name must start with a lowercase character",
+ "namespace_name": "Namespace name",
+ "namespace_name_constraint": "The name must be unique in the network, and may have a maximum length of 64 characters, and the allowed characters are a, b, c, …, z, 0, 1, 2, …, 9, _ , -.",
+ "namespace_tips_key_1": "1. The name must be unique in the network, and may have a maximum length of 64 characters. Accepted characters include:",
+ "namespace_tips_key_2": "2. Following characters are not accepted:",
+ "namespace_tips_key_3": "3. The namespace can be defined as up to three levels deep.",
+ "namespace_tips_value_1": "a, b, c, …, z, 0, 1, 2, …, 9, _ , -",
+ "namespace_tips_value_2": "nem, user, account, org, com, biz, net, edu, mil, gov , info.",
+ "namespace_transaction": "Namespace Transaction ",
+ "namespace_transfer_type": "Namespace transaction",
+ "network_settings": "Network settings",
+ "network_type": "Network type",
+ "network_type_invalid": "Network types do not match",
+ "new_password_label": "Password",
+ "news": "News",
+ "news_read_more": "Read more",
+ "next": "Next",
+ "no_confirmed_transactions": "There are currently no confirmed transactions",
+ "no_data_mosaics": "No assets were found for this account",
+ "no_data_namespace_tips": "You do not have a namespace, please create one first",
+ "no_data_namespaces": "No namespaces were found for this account",
+ "no_data_transactions": "No transactions were found for this account",
+ "no_harvested_blocks_yet": "No harvested blocks yet",
+ "no_mnemonic": "No mnemonic",
+ "no_network_currency_alert": "The wallet could not load data about the network currency (e.g. dhealth:dhp), please connect to a valid node.",
+ "no_partial_transactions": "There are currently no partial transactions",
+ "no_profiles_in_database": "No profile in the wallet database",
+ "no_unconfirmed_transactions": "There are currently no unconfirmed transactions",
+ "node": "Node",
+ "node_connection_failed": "Node connection failed",
+ "node_connection_succeeded": "Node connection succeeded",
+ "node_exists_error": "The added node already exists",
+ "node_list": "List of nodes",
+ "node_not_available_please_check_your_node_or_network_settings": "Node is not available. Please check your node or network settings.",
+ "node_public_key_input": "Couldn't find the public key, please enter here or select another node",
+ "node_publicKey": "Node Public Key",
+ "node_url": "Node url",
+ "not_yet_open": "Not yet open",
+ "notes_should_not_exceed_25_character": "Notes should not exceed 25 characters",
+ "notification_new_aggregate_bonded": "A new aggregate partial transaction has been announced",
+ "notification_new_cosignature": "An aggregate transaction has been co-signed",
+ "notification_new_transaction_confirmed": "New transaction confirmed",
+ "notification_new_unconfirmed_transaction": "New unconfirmed transaction",
+ "offline_storage": "Offline storage",
+ "open_restrictions_warning_text": "Account restrictions is an advanced functionality that can invalidate your account. Please be careful with the operations you perform in the following screens. \nAre you sure that you want to access Account Restrictions?",
+ "open_restrictions_warning_title": "Open account restrictions",
+ "operation_failed": "Request Failed",
+ "operation_type": "Operation Type",
+ "option_child_account": "I want to create a seed account for my profile",
+ "option_hd_account": "I want to create HD account",
+ "option_link_address": "Link an address",
+ "option_link_mosaic": "Link an asset",
+ "option_privatekey_account": "I want to import an existing account private key",
+ "option_root_namespace": "Root Namespace",
+ "option_sub_namespace": "Sub-namespace",
+ "outgoing": "Outgoing",
+ "page_title_account_actions": "Actions",
+ "page_title_account_backup": "Profile Backup",
+ "page_title_account_details": "Account Information",
+ "page_title_account_harvesting": "Harvesting",
+ "page_title_account_metadata": "Metadata",
+ "page_title_dashboard": "Dashboard",
+ "page_title_delegated_harvesting": "Delegated Harvesting",
+ "page_title_harvesting": "Harvesting",
+ "page_title_history": "History",
+ "page_title_invoice": "Invoice",
+ "page_title_mosaics": "Owned assets",
+ "page_title_mosaics_create": "Create new assets",
+ "page_title_multisig_convert": "Convert an account",
+ "page_title_multisig_cosign": "Sign transactions",
+ "page_title_multisig_manage": "Manage multi-signature",
+ "page_title_namespaces": "Owned namespaces",
+ "page_title_namespaces_create": "Create new namespaces",
+ "page_title_send": "Send",
+ "page_title_settings_about": "About",
+ "page_title_settings_diagnostic": "Diagnostic",
+ "page_title_settings_general": "General settings",
+ "page_title_settings_password": "Profile password",
+ "page_title_transfer": "Transfer",
+ "paid_fee": "paid fee",
+ "parent_namespace": "Parent Namespace",
+ "password": "Password",
+ "password_error": "This password is incorrect",
+ "password_hint": "Hint",
+ "password_is_invalid": "The password must contain a minimum of 8 characters with alphabet letters and numbers.",
+ "passwords_not_matching": "Passwords do not match",
+ "peer_tip": "You can use the {setting} page for node management or to configure a new network",
+ "peers_number": "Peers number",
+ "phishing_warning": "Beware of phishing! This program will not ask you to enter your mnemonic except when restoring a profile from scratch.",
+ "placeholder_address": "Enter an address",
+ "placeholder_address_or_alias": "Enter address or alias (e.g., nem.group)",
+ "placeholder_address_or_public_key": "Address or public key",
+ "placeholder_transaction_uri": "Enter a valid transaction URI",
+ "please_accurately_copy_the_safety_backup_mnemonic": "Please accurately copy the safety backup mnemonic",
+ "i_accept": "I accept",
+ "terms": "Terms",
+ "conditions": "Conditions",
+ "please_backup_mnemonic_passphrase": "Make sure to create a backup copy of the mnemonic passphrase. You will need this backup when trying to recover your profile.",
+ "please_backup_mnemonic_passphrase_title": "Create a backup!",
+ "please_check_device_connection": "Please check your device connection!",
+ "please_click_on_the_mnemonic_in_order_to_confirm_that_you_are_backing_up_correctly": "Please click on the mnemonic in order to confirm that you are backing up correctly.",
+ "please_enter_a_correct_number": "Please enter a valid number",
+ "please_enter_a_custom_nod_address": "Enter a custom node URL",
+ "please_enter_a_mnemonic_to_ensure_that_the_mnemonic_is_correct": "Please enter a mnemonic to ensure that it is correct",
+ "please_enter_notes": "Enter a message",
+ "please_enter_your_account_password": "Enter your profile password",
+ "please_enter_your_new_password_again": "Please enter your profile password again",
+ "please_enter_your_password_again": "Please enter your password again",
+ "please_set_your_account_password": "Please set your account password",
+ "please_update_symbol_bolos_app": "Please update your Symbol app on your Ledger device!",
+ "point_null_error": "Node null error",
+ "preview_and_action": "Preview & Action",
+ "previous": "Previous",
+ "privacy_policy": "Privacy policy",
+ "private_key": "Private Key",
+ "private_key_invalid_error": "This private key is invalid.",
+ "profile_creation_description": "Before you start using this software, you need to create a profile name and password. The password will be used to secure the access to your profile.",
+ "profile_description": "Profile description",
+ "profile_description_tips1": "Before you start using this software, you need to create a profile name and password. This wallet software leverages the power of hierarchical deterministic wallets (HD-Wallets)",
+ "profile_description_tips2": "The password will be used to secure the access to your profile, it is used to encrypt your mnemonic passphrase. Multiple addresses can be managed under one profile and you can switch between profiles on the startup page.",
+ "profile_description_tips3": "Please, backup both your password and 24-words mnemonic passphrase.",
+ "profile_import": "Profile import",
+ "profile_name": "Profile name",
+ "profile_name_already_exists": "Profile name already taken",
+ "profile_name_error": "Invalid profile name",
+ "profile_not_matching_network_option_1": "Logout and change profile",
+ "profile_not_matching_network_option_2": "Create new profile",
+ "profile_not_matching_network_option_3": "Close and switch network",
+ "profile_not_matching_network_warning_message": "Your profile's network does not match the current network. Please select one of the following options to resolve the issue.",
+ "profile_not_matching_network_warning_title": "Warning",
+ "program_description_line1": "This program is designed based on dHealth blockchain,",
+ "program_description_line2": "an open source digital asset management system. Access the dHealth",
+ "program_description_line3": "network, create profiles, manage accounts and assets and many more.",
+ "progress": "Download in progress.",
+ "public_key": "Public Key",
+ "public_key_addition": "Added cosigner",
+ "public_key_deletion": "Removed cosigner",
+ "public_key_invalid": "This public key is invalid",
+ "qr_code": "QR Code",
+ "qr_code_generation_failed": "QR code generation failed",
+ "qrcode_detail_item_address": "Address",
+ "qrcode_detail_item_contact_name": "Contact Name",
+ "qrcode_detail_item_mnemonic_passphrase": "Mnemonic Passphrase",
+ "qrcode_detail_item_network_type": "Network Type",
+ "qrcode_detail_item_type": "QR Code Type",
+ "qrcode_detail_item_type_contactqr": "Address",
+ "qrcode_detail_item_type_cosignatureqr": "Request Cosignature",
+ "qrcode_detail_item_type_mnemonicqr": "Import Mnemonic",
+ "qrcode_detail_item_type_transactionqr": "Invoice",
+ "qrcode_detail_item_type_signedqr": "Signed transaction",
+ "qrcode_password_info": "Uploaded QR Code is password protected. Please enter your password at the time this QR Code was generated.",
+ "recipient": "Recipient",
+ "recipient_linked_address_invalid": "The recipient's alias name does not have a linked address",
+ "recipient_public_key_invalid_error": "Invalid recipient public key",
+ "refresh": "Refresh",
+ "refresh_failed": "An error ocurred. Please, try again later.",
+ "refresh_success": "Updated successfully",
+ "refresh_too_fast_warning": "Too many network requests have been executed. Please, try again later.",
+ "register": "Sign up",
+ "relative": "relative",
+ "removal_greater_than_cosignatories": "There are {delta} more required cosignatories for min removal than available cosignatories. Please add cosignatories or reduce the min. removal number.",
+ "removal_or_approval_is_zero": "Minimum approval and/or minimum removal cannot be set to 0 while there are {delta} cosignatories in your list",
+ "repeat_password_label": "Confirm your password",
+ "reset": "Reset",
+ "resolving_address": "Resolving address {address}...",
+ "restore_mnemonic": "Restore mnemonic passphrase",
+ "restrictable": "Restrictable",
+ "rules_describe": "Rules description",
+ "safe_storage_tips": "Safe storage tips",
+ "save": "Save",
+ "save_backups": "Make multiple copies offline and save backups in multiple locations. Use encrypted disks for digital backups.",
+ "scenes_to_be_used": "Use cases",
+ "see_transactions_other_account": "Display multi-signature account transactions",
+ "seed_account_can_not_be_more_than_10": "You have reached the limit of accounts that can be created in one profile. Please use a different profile to create a new account.",
+ "select": "Select",
+ "select_a_namespace": "Select a namespace",
+ "select_a_profile": "Select a profile",
+ "select_accounts": "Selected Accounts",
+ "select_opt_in_accounts": "Selected Opt In Accounts",
+ "select_all": "Check all",
+ "select_contact": "Select contact",
+ "send": "Send",
+ "sender": "From",
+ "set_account_name": "Enter a profile name",
+ "set_default_explorer": "The URL entered is not valid, a default URL has been set for you.",
+ "set_explorer_link": "Explorer URL",
+ "set_network_type": "Select a network type",
+ "SET_UP": "Node selection",
+ "settings": "Settings",
+ "settings_tab_about": "About",
+ "settings_tab_general": "General settings",
+ "settings_tab_network": "Network settings",
+ "settings_tab_password": "Profile password",
+ "show_button": "Show",
+ "show_expired_mosaics": "Show expired assets",
+ "show_expired_namespaces": "Show expired namespaces",
+ "show_on_ledger": "Show on Ledger",
+ "show_wizard": "Show wizard",
+ "sidebar_item_accounts": "Identities",
+ "sidebar_item_aggregate": "Contracts",
+ "sidebar_item_community": "News",
+ "sidebar_item_harvesting": "Harvesting",
+ "sidebar_item_home": "Dashboard",
+ "sidebar_item_mosaics": "Assets",
+ "sidebar_item_multisig": "Multiparty",
+ "sidebar_item_namespaces": "Namespaces",
+ "sign_transaction_failed": "Failed to sign transaction, reason: {reason}",
+ "signature": "Signature",
+ "signer_public_key": "Signer public key",
+ "simple_transaction": "Simple Transaction ",
+ "simple_transfer_type": "Simple transaction",
+ "skip": "Skip",
+ "speed": "Speed",
+ "start": "Start",
+ "start_finalization_epoch": "Start Finalization Epoch",
+ "start_harvesting": "Start Harvesting",
+ "status": "Status",
+ "stop_harvesting": "Stop Harvesting",
+ "success_account_unlocked": "Account unlocked successfully",
+ "success_password_changed": "Your password was updated successfully. You will now be logged out.",
+ "success_settings_updated": "Your settings have been updated successfully.",
+ "success_transaction_partial_announced": "Partial transaction announced successfully.",
+ "success_transactions_announced": "Transaction announced successfully.",
+ "success_transactions_signed": "Transaction(s) signed successfully.",
+ "successful_copy": "Copied to clipboard!",
+ "successful_operation": "Request succeeded",
+ "supply": "Supply",
+ "supply_can_not_less_than_0": "Supply cannot be less than 0",
+ "swap": "Swap",
+ "tab_accounts_accounts": "My accounts",
+ "tab_accounts_addressbook": "My contacts",
+ "tab_harvesting_delegated_harvesting": "Delegated harvesting",
+ "tab_harvesting_key_links": "Key Links",
+ "table_header_action": "Action",
+ "table_header_alias_identifier": "Alias",
+ "table_header_alias_type": "Alias type",
+ "table_header_balance": "Balance",
+ "table_header_change_times": "changeTimes",
+ "table_header_direction": "Direction",
+ "table_header_divisibility": "Divisibility",
+ "table_header_expiration": "Expiration",
+ "table_header_expired": "Expired",
+ "table_header_hex_id": "Id",
+ "table_header_name": "Name",
+ "table_header_restrictable": "Restrictable",
+ "table_header_scoped_key": "ScopedMetadataKey",
+ "table_header_status": "status",
+ "table_header_supply": "Supply",
+ "table_header_supply_mutable": "Supply mutable",
+ "table_header_target_address": "TargetAddress",
+ "table_header_target_id": "TargetID",
+ "table_header_target_type": "TargetType",
+ "table_header_transferable": "Transferable",
+ "table_header_value": "Value",
+ "target_account_invalid_name": "target account",
+ "terms_and_conditions": "Terms and Conditions",
+ "the_backup_is_wrong": "Please, carefully select your mnemonic words in the correct order.",
+ "the_mnemonic_order_is_correct_and_the_backup_is_successful": "The mnemonic order is correct and the backup is successful.",
+ "the_mosaic_to_be_sent_is_empty": "The assets list cannot be empty",
+ "the_root_namespace_cannot_be_longer_than_16": "A root namespace name cannot be longer than 16 characters",
+ "the_sub_namespace_cannot_be_longer_than_16": "A sub-namespace name cannot be longer than 64 characters",
+ "the_value_of_duration_cannot_be_less_than_1": "The duration must be greater than or equal to 1",
+ "tips": "Tips",
+ "title": "Title",
+ "to": "To",
+ "to_symbol": "to dHealth",
+ "too_many_cosignatories": "The maximum number of cosignatories is {maxCosignatoriesPerAccount}, please remove {delta} cosignatories",
+ "top_window_console": "Console",
+ "transaction_cancel": "Transaction cancel!",
+ "transaction_descriptor_16705": "Aggregate complete",
+ "transaction_descriptor_16707": "Voting Key Link",
+ "transaction_descriptor_16708": "Account metadata",
+ "transaction_descriptor_16712": "Funds lock",
+ "transaction_descriptor_16716": "Account link",
+ "transaction_descriptor_16717": "Assets definition",
+ "transaction_descriptor_16718": "Namespace registration",
+ "transaction_descriptor_16720": "Account address restriction",
+ "transaction_descriptor_16721": "Assets global restriction",
+ "transaction_descriptor_16722": "Secret lock",
+ "transaction_descriptor_16724": "Transfer",
+ "transaction_descriptor_16725": "Multisig account modification",
+ "transaction_descriptor_16961": "Aggregate bonded",
+ "transaction_descriptor_16963": "VRF Key Link",
+ "transaction_descriptor_16964": "Assets metadata",
+ "transaction_descriptor_16972": "Node Key Link",
+ "transaction_descriptor_16973": "Assets supply change",
+ "transaction_descriptor_16974": "Address alias",
+ "transaction_descriptor_16976": "Account asset restriction",
+ "transaction_descriptor_16977": "Assets address restriction",
+ "transaction_descriptor_16978": "Secret proof",
+ "transaction_descriptor_17220": "Namespace metadata",
+ "transaction_descriptor_17230": "Assets alias",
+ "transaction_descriptor_17232": "Account operation restriction",
+ "transaction_details": "Transaction details",
+ "transaction_expired": "Transaction has expired",
+ "transaction_has_cosignature": "Co-signatures received",
+ "transaction_needs_cosignature": "Transaction awaiting co-signature(s)",
+ "transaction_needs_cosignature_explain": "This multisignature transaction needs multiple parties to sign it before it is approved. Please enter your password and confirm to add your signature.",
+ "transaction_needs_cosignature_explain_signed": "This transaction needs multiple parties to approve by sending co-signature. You have already sent a co-signature for this transaction. Please, wait until other co-signatories approve. You can download the QR Code and send to other co-signatories for them to sign their part easily.",
+ "transaction_qr_action_desc": "Click continue to open the transfer page with these details.",
+ "transaction_qr_signed_action_desc": "Click continue to broadcast the transaction with these details.",
+ "transaction_qr_code": "Transaction QR Code",
+ "transaction_received_cosignature_explain": "Received the minimum required co-signatories",
+ "transaction_status_confirmed": "Confirmed",
+ "transaction_status_partial": "Partial",
+ "transaction_status_unconfirmed": "Unconfirmed",
+ "transaction_too_long": "The transaction is too long!",
+ "transaction_type": "Type",
+ "transaction_type_title": "Transaction type",
+ "transaction_uri": "Transaction URI",
+ "transaction_uri_explanation": "URI representation of this transaction. You can copy this URI and send to another device or someone else to import and sign the transaction.",
+ "transactions": "Transactions",
+ "transactions_tab_confirmed": "Confirmed",
+ "transactions_tab_partial": "Partial",
+ "transactions_tab_unconfirmed": "Unconfirmed",
+ "transfer_target": "To",
+ "transferable": "Transferable",
+ "transmittable": "Transferable",
+ "type": "Type",
+ "uncheck_all": "Un-check all",
+ "unconfirmed": "Unconfirmed",
+ "unconfirmed_transaction": "Unconfirmed",
+ "unknown": "Unknown",
+ "unlink": "Unlink",
+ "unlink_namespace_from": "Unlink {aliasTarget} from {namespaceName}",
+ "update_completed": "Update completed",
+ "upload_address_book_explanation": "Upload a valid address book json file. Once the address book is uploaded, all the contacts in the address book will be restored",
+ "upload_file_message": "Click or drag a file here to upload",
+ "upload_qr_code": "Upload QR Code",
+ "upload_qr_code_explanation": "Upload or scan one of the following valid QR Codes. Once QR Code type is identified you will be taken to the next step for the relevant action.",
+ "upload_qr_code_explanation_type_contactqr": "Address QR Code",
+ "upload_qr_code_explanation_type_cosignatureqr": "Cosignature QR Code",
+ "upload_qr_code_explanation_type_mnemonicqr": "Mnemonic QR Code",
+ "upload_qr_code_explanation_type_transactionqr": "Invoice QR Code",
+ "upload_qr_code_explanation_type_signedtransactionqr": "Signed Transaction QR Code",
+ "upload_qr_code_explanation_type_cosignaturesignedtransactionqr": "Cosignature Signed QR Code",
+ "upload_qr_code_invalid_type_message": "Type({type}) not allowed! Try again with a valid QR Code listed above.",
+ "upload_qr_tab_scan": "Scan via Camera",
+ "upload_qr_tab_upload_image": "Upload Image",
+ "uploaded_qr_code": "Uploaded QR Code",
+ "use_paper_and_pen_to_correctly_copy_mnemonics": "Use a pen and paper to correctly copy mnemonics. If you lose access via this install/device your mnemonic will restore your accounts and assets.",
+ "used_to_bind_a_account_address": "Used to give friendly names to accounts or assets",
+ "user_aborted_transaction_confirmation": "User aborted transaction confirmation",
+ "value_too_big": "This value is too big",
+ "variable_supply": "Supply mutable",
+ "verify_backup_mnemonics": "Next",
+ "verify_device_information": "Verify information in your device!",
+ "verify_Mnemonic_phrase": "Verification",
+ "verify_mnemonics": "Verify mnemonic words backup",
+ "version": "Version",
+ "view_metadata": "View metadata",
+ "warning_already_a_cosignatory": "This account is already a cosignatory!",
+ "warning_unknown_account": "This account is unknown to the network. Please make sure that address is correct and account received at least one transaction",
+ "web_wallet_warning": "Please, check the domain name currently open.",
+ "welcome": "Welcome",
+ "welcome_to_symbol": "Welcome to dHealth",
+ "word": "Word",
+ "x_seconds": "{seconds}s.",
+ "activate_delegated_harvesting_message": "To activate delegated harvesting, we need your password to encrypt your VRF key in the persistent harvesting message.",
+ "activate_delegated_harvesting": "Activate Harvesting",
+ "create_persistent_message": "Generate secure persistent harvesting message",
+ "Insert_your_node_linked_public_key": "Add your node public key",
+ "Insert_your_vrf_linked_public_key": "Add your VRF public key",
+ "Insert_your_account_linked_public_key": "Add your remote account public key",
+ "not_linked": "Not linked",
+ "form_label_use_link_remote_public_key_icon": "Use link button to link your remote public key",
+ "form_label_use_link_vrf_public_key_icon": "Use link button to link your VRF public key",
+ "form_label_use_link_node_public_key_icon": "Use link button to link your node public key",
+ "label_unlink_node_account_public_key": "Unlink your node public key",
+ "label_unlink_remote_account_public_key": "Unlink your remote public key",
+ "label_unlink_vrf_account_public_key": "Unlink your VRF public key",
+ "please_link_your_public_key": "Please relink your public key to generate your private key",
+ "linking": "Linking...",
+ "stoping": "Stopping...",
+ "request_harvesting": "Request Harvesting",
+ "unlink_keys": "Unlink Keys",
+ "requesting": "Requesting...",
+ "unlinking": "Unlinking...",
+ "remote_keys_linked": "You have remote & VRF keys linked to your account, if you want to activate delegated harvesting, please select a harvesting node and link the node key. If you are harvesting already, please select your harvesting node to update your harvesting status.",
+ "encrypt_ledger_keys_on_sign": "As a Ledger user your password is needed to encrypt your remote account and VRF private keys",
+ "harvesting_status_not_detected": "Harvesting status cannot be detected. Please select the node you are harvesting on.",
+ "click_to_retry": "Click to retry",
+ "symbol_node_cannot_connect": "Cannot connect to the dHealth node",
+ "current_node_is_not_available": "Current node is not available. Trying to connect to node #{0}/{1}",
+ "nodes_unavailable_check_network_and": "Nodes({0}/{1}) are currently unavailable. Please check your network connection, settings and ",
+ "copyright": "Copyright © 2021 dHealth Network",
+ "address_list_cannot_be_empty": "At lease 1 non-opted-in account must be selected from the list.",
+ "opt_in_account_notification": "This account is obtained by an older derivation. It is recommended that you move the funds to a Seed Account",
+ "ws_connection_failed": "The wallet cannot monitor the activities of your account on the dHealth chain. Please try selecting a different node.",
+ "offline_transactions_title": "Offline transactions",
+ "offline_transactions_text1": "To be completely safe, make sure to use a computer that is NEVER connected to the internet.",
+ "offline_transactions_text2": "Only simple transactions can be created because a connection is needed to fetch assets and multisig information from dHealth nodes.",
+ "offline_transactions_text3": "After clicking the \"Sign\" button in the right panel, the signed transaction will be shown.",
+ "offline_transactions_text4": "A signed transaction is immutable and will be effective only if announced to the network before the default deadline of 24 hours.",
+ "offline_transactions_prepare_transaction": "Prepare transaction",
+ "offline_transactions_download": "Download QR",
+ "offline_transactions_success": "Transaction signed successfully",
+ "offline_transactions_success_text": "You can now download this QR code or copy the JSON text above and broadcast it using an online wallet or symbol-cli.",
+ "signed_transaction_qr": "Signed Transaction QR",
+ "go_to_offline_transactions": "Go to offline transactions",
+ "go_to_login_offline": "Go to login",
+ "cosign_transaction": "Cosign transaction",
+ "offline_transactions_import_qr": "Import Cosignature",
+ "offline_transactions_chose_account": "Sign Transaction",
+ "offline_transactions_import_qr_title": "Import the cosignature transaction that you want to sign",
+ "offline_transaction_confirm_import": "Go to next step to sign the transaction",
+ "sign": "Sign",
+ "hash": "Hash",
+ "form_label_import_placeholder": "Paste the transaction payload",
+ "payload_not_valid": "Payload not valid",
+ "import_payload": "Import payload",
+ "import_payload_text": "You can also enter transaction payloads generated by symbol-cli",
+ "ledger_available_on_standalone_app": "To use Ledger please download the desktop native app.",
+ "select_custom_node": "Select custom node",
+ "delegated_harvesting_request_failed": "Your delegated harvesting request has failed, please stop harvesting and try a different node.",
+ "create_vrf_public_key": "Create VRF Public Key",
+ "create_remote_public_key": "Create Remote Public Key",
+ "generate_random_public_key": "Generate Key",
+ "import_key_manually": "Import Key manually",
+ "key_type": "Key Type"
+}
diff --git a/src/language/index.ts b/src/language/index.ts
new file mode 100644
index 0000000..60fec10
--- /dev/null
+++ b/src/language/index.ts
@@ -0,0 +1,37 @@
+// external dependencies
+import VueI18n from 'vue-i18n';
+import Vue from 'vue';
+
+// internal translation messages
+import zh_CN from '@/language/zh-CN.json';
+import en_US from '@/language/en-US.json';
+import ja_JP from '@/language/ja-JP.json';
+
+// external translation messages
+import enValidationMessages from 'vee-validate/dist/locale/en.json';
+import zh_CNValidationMessages from 'vee-validate/dist/locale/zh_CN.json';
+import jaValidationMessages from 'vee-validate/dist/locale/ja.json';
+
+const messages = {
+ 'en-US': { ...en_US, validation: enValidationMessages.messages },
+ 'zh-CN': { ...zh_CN, validation: zh_CNValidationMessages.messages },
+ 'ja-JP': { ...ja_JP, validation: jaValidationMessages.messages },
+};
+
+const navLang = navigator.language;
+const localLang = navLang === 'zh-CN' || navLang === 'en-US' ? navLang : false;
+const lang = window.localStorage.getItem('locale') || localLang || 'en-US';
+
+Vue.use(VueI18n);
+
+const i18n = new VueI18n({
+ locale: lang,
+ messages,
+ silentTranslationWarn: true,
+});
+
+// @ts-ignore
+Vue.use({ i18n: (key, value) => i18n.t(key, value) });
+window.localStorage.setItem('locale', lang);
+
+export default i18n;
diff --git a/src/language/ja-JP.json b/src/language/ja-JP.json
new file mode 100644
index 0000000..510ad1c
--- /dev/null
+++ b/src/language/ja-JP.json
@@ -0,0 +1,1112 @@
+{
+ "about_app_release": "リリース",
+ "about_app_url": "ホームページ",
+ "about_default_node": "デフォルトノード",
+ "about_dependencies": "依存関係",
+ "about_generation_hash": "ジェネレーションハッシュ",
+ "about_network": "ネットワーク",
+ "about_network_type": "ネットワークタイプ",
+ "about_rxjs_version": "RxJs ライブラリ",
+ "about_sdk_version": "Symbol SDK",
+ "about_typescript_version": "Typescript",
+ "about_vue_version": "Vue フレームワーク",
+ "absolute": "絶対",
+ "access_ledger": "Ledger にアクセス",
+ "access_my_profile": "プロファイルにアクセス",
+ "access_trezor": "Trezor にアクセス",
+ "access_trezor_account": "Trezor ウォレットにアクセス",
+ "access_your_ledger_account": "Ledger ウォレットにアクセス",
+ "account_address": "アドレス",
+ "ACCOUNT_LINK": "アカウントリンク",
+ "account_management": "アカウント",
+ "account_name": "名前",
+ "account_name_input_error": "アカウント名の入力エラー!",
+ "account_network_does_not_match_current_network_type": "プロファイルのネットワークが接続されたノードのネットワークと異なります。新しく作成してください。",
+ "account_network_type_does_not_match_current_network_type": "プロファイルのネットワークタイプが接続ノードのネットワークタイプに一致しません",
+ "account_public_key": "公開鍵",
+ "account_restrictions": "アカウント制限",
+ "account_restrictions_tab_address": "アドレス制限",
+ "account_restrictions_tab_mosaic": "モザイク制限",
+ "account_restrictions_tab_operation": "操作制限",
+ "accounts": "アカウント",
+ "accounts_backup_keystore_explain_p1": "右側のボタンで暗号化済みキーファイルをダウンロードし、秘密鍵と公開鍵をバックアップします。",
+ "accounts_backup_keystore_explain_p2": "プロファイルのロック解除を要求します。プロファイルのロックを解除すると、ダウンロードが自動的に開始されます。",
+ "accounts_backup_mnemonic_explain_p1": "右側のボタンで画面に24単語を表示して、ニーモニックパス語群をバックアップします。",
+ "accounts_backup_mnemonic_explain_p2": "プロファイルのロック解除を要求します。プロファイルのロックを解除すると、ニーモニックパス語群が表示されます。",
+ "accounts_backup_mnemonic_explain_p3": "次の {num} 単語を安全な場所にバックアップしてください。これらの {num} 語はニーモニックパス語群を表し、後でプロファイルとその子アカウントをインポートするために使用できます。",
+ "accounts_backup_mnemonic_explain_qrcode": "次のQRコードを安全な場所へバックアップしてください。このQRコードはプロファイルとその子アカウントのインポートに使用します。",
+ "accounts_backup_qrcode_explain_p1": "右側のボタンからQRコードをダウンロードして、ニーモニックパス語群をバックアップします。",
+ "accounts_backup_qrcode_explain_p2": "プロファイルのロック解除を要求します。プロファイルのロックを解除すると、ダウンロードが自動的に開始されます。",
+ "accounts_backup_tile_description": "ウォレットのバックアップ",
+ "accounts_backup_tile_keystore": "キーのダウンロード",
+ "accounts_backup_tile_keystore_desc": "キーファイルのダウンロード",
+ "accounts_backup_tile_mnemonic": "ニーモニックを表示",
+ "accounts_backup_tile_mnemonic_desc": "パス語群の表示",
+ "accounts_backup_tile_title": "ニーモニックQRコード",
+ "accounts_backup_title": "バックアップ&セキュリティ",
+ "accounts_backup_title_keystore": "キーのダウンロード",
+ "accounts_backup_title_mnemonic": "ニーモニックパス語群",
+ "accounts_backup_title_qrcode": "ニーモニックQRコードの暗号化",
+ "accounts_backup_transactions": "トランザクションリストをCSVファイルにエクスポートする",
+ "accounts_backup_transactions_description": "すべてのトランザクション情報をダウンロードしローカルに保存することで、インターネット未接続でも表示できます。",
+ "accounts_change_password_description": "パスワードを変更",
+ "accounts_change_password_title": "パスワードを変更",
+ "accounts_create_invoice": "インボイスの作成",
+ "accounts_flags_default_account": "デフォルト",
+ "accounts_flags_default_account_explain": "これはデフォルトアカウントです",
+ "accounts_flags_known_by_network": "Broadcasted Account",
+ "accounts_flags_multisig": "マルチシグネチャ",
+ "accounts_flags_multisig_explain": "これはマルチシグアカウントです",
+ "accounts_flags_simple": "シンプルアカウント",
+ "accounts_flags_simple_explain": "これはシンプルアカウントです",
+ "accounts_flags_unknown_by_network": "プライベートアカウント",
+ "accounts_harvesting_remote_explain_p1": "右側のボタンを使用してハーベスト用のリモートアカウントを構成します。これにより、後でアカウントがデリゲートハーベストを有効化できるようになります。",
+ "accounts_harvesting_remote_explain_p2": "アカウントのロックを解除するよう求められます。その後、リモートアカウントを設定するためのオプションが表示されます。",
+ "accounts_harvesting_request_explain_p1": "右側のボタンを使用して、ハーベスティング委任リクエストを送信します。ノードによって承認された場合、アカウントのハーベスティングが有効になります。",
+ "accounts_harvesting_request_explain_p2": "アカウントのロックを解除するよう求められ、ピアノードにハーベスティング委任リクエストを送信するためのオプションが表示されます。",
+ "accounts_harvesting_tile_remote": "リモートアカウント",
+ "accounts_harvesting_tile_remote_description": "インポータンス転送",
+ "accounts_harvesting_tile_request": "デリゲーションリクエスト",
+ "accounts_harvesting_tile_request_description": "ハーベスティングの開始",
+ "accounts_harvesting_title_remote": "リモートアカウントのセットアップ",
+ "accounts_harvesting_title_request": "デリゲーションリクエストの送信",
+ "accounts_label_flags": "フラグ",
+ "accounts_links_explorer": "エクスプローラ",
+ "accounts_links_faucet": "フォーセット",
+ "accounts_setup_harvesting_description": "デリゲートハーベスティングを設定",
+ "accounts_setup_harvesting_title": "ハーベストのセットアップ",
+ "accounts_share_qr_code": "詳細を共有",
+ "accounts_subtitle_account_links": "便利なリンク",
+ "accounts_view_dashboard": "ダッシュボードで見る",
+ "accounts_view_explorer_description": "エクスプローラを開く",
+ "accounts_view_multisig": "マルチシグネチャ",
+ "accounts_view_open_faucet": "フォーセットを開く",
+ "action": "アクション",
+ "action_label_alias_link": "エイリアスをリンク",
+ "action_label_alias_unlink": "エイリアスを解除",
+ "action_label_extend_duration": "期限延長",
+ "action_label_modify_supply": "供給量変更",
+ "activate": "有効化",
+ "activating": "有効化中...",
+ "add_account_failed": "アカウントの追加に失敗しました: {reason}",
+ "add_account_restrictions": "アカウント制限",
+ "add_address_restrictions": "新規アドレス制限",
+ "add_contact": "連絡先を追加",
+ "add_metadata": "メタデータ追加",
+ "add_mosaic": "モザイク追加",
+ "add_mosaic_restrictions": "新規モザイク制限",
+ "add_node": "ノードを追加する",
+ "add_operation_restrictions": "新規操作制限",
+ "address": "アドレス",
+ "address_alias_not_exist": "アドレスエイリアスは存在しません",
+ "address_format_error": "アドレスフォーマットエラー",
+ "address_invalid": "アドレスは無効です",
+ "address_not_valid": "連署名アドレスは無効です",
+ "address_qr_code": "アドレスQRコード",
+ "address_to_interact_with": "疎通するアドレス",
+ "address_unknown": "このアドレスはネットワークにありません。公開鍵で試してみてください。",
+ "address_unknown_by_network": "最初のトランザクションを送信するまで、このアカウントはネットワークに認識されません。",
+ "aggregate_send": "アグリゲートを送信",
+ "alias": "エイリアス",
+ "alias_name_format_error": "エイリアスHEXフォーマットエラー",
+ "aliases": "エイリアス",
+ "all_nodes_cannot_be_deleted": "すべてのノードは削除できません",
+ "allow": "許可",
+ "amount": "量",
+ "amount_asset": "量",
+ "amount_can_not_be_less_than_0": "量は 0 以下にできません",
+ "any_information_cannot_be_empty": "このフィールドは空にできません。入力を確認してください。",
+ "approval_greater_than_cosignatories": "最小承認数に必要な連署者は {delta} より多い有効な連署者が必要です。署名者を追加するか、最小承認数を減らしてください。",
+ "article_by": "{creator} 著",
+ "assets": "アセット",
+ "at_block": "{blockNumber} ブロック",
+ "automatically_generated_by_node_url": "ノードURLより自動生成",
+ "back": "戻る",
+ "backup_address_book": "アドレス帳をバックアップ",
+ "backup_mnemonic": "ニーモニックのバックアップ",
+ "backup_mnemonic_phrase": "ニーモニック語群をバックアップ",
+ "backup_mnemonic_words": "ニーモニック単語のバックアップ",
+ "backup_profile": "プロファイルをバックアップ",
+ "backup_profile_explanation_desc": "プロファイルのコピーとしてペーパー (PDF) をダウンロードします。このプロファイル内の全アカウントは、ダウンロードしたファイルに一覧表示されます。このバックアップファイルを使用すると、必要なときに他のデバイスまたは同じデバイスにすべてのアカウントを復元できます。 機密性の高い情報が保存されているため、安全な場所に保管して、第三者と共有しないでください。",
+ "backup_profile_explanation_title": "プロファイルをペーパーウォレットへバックアップ",
+ "balance": "残高",
+ "block": "ブロック",
+ "block_height": "ブロック高",
+ "blocks_made": "生成ブロック",
+ "button_add_account": "アカウント追加",
+ "button_download": "ダウンロード",
+ "button_download_paper_wallet": "ペーパーウォレットをダウンロード",
+ "button_download_qr": "ダウンロード",
+ "button_understand_title": "理解した",
+ "cancel": "キャンセル",
+ "chain_height": "ブロック",
+ "choose_network": "ネットワーク選択",
+ "choose_profile_name_and_password": "アカウントとパスワードの選択",
+ "clear_staged_transactions": "すべてのトランザクションを破棄",
+ "click_to_cosign": "クリックして署名",
+ "click_to_load": "クリックしてデータを読み込む",
+ "close": "閉じる",
+ "co_signers_amount_less_than_0": "マルチシグアカウントには 1 つ以上の連署者が必要です。",
+ "confirm": "確認",
+ "confirm_backup": "バックアップの確認",
+ "CONFIRMATION": "承認",
+ "confirmation_title": "承認",
+ "confirmations_height": "ブロック高",
+ "confirmed_transaction": "承認済",
+ "confirmPassword": "パスワードの確認",
+ "connect_ledger_prompt": "Ledger に接続",
+ "connect_ledger_title": "Ledger ハードウェアウォレットに接続",
+ "contact_address": "アドレス",
+ "contact_email": "Eメール",
+ "contact_information": "連絡先",
+ "contact_name": "名前",
+ "contact_notes": "備考",
+ "contact_phone": "電話",
+ "contact_qr_action_desc": "この受信者に転送するには、続行 をクリックして転送ページにリダイレクトします",
+ "contact_qr_code": "連絡先QRコード",
+ "continue": "続行",
+ "copy_failed": "コピーに失敗",
+ "copy_mnemonic": "ニーモニックをコピー",
+ "cosignatory_of": "連署者",
+ "cosignature_added": "連署名を受信",
+ "cosignature_qr_action_desc": "トランザクション詳細ページに進み、署名してください",
+ "create_a_new_account": "プロファイルを新規作成",
+ "create_a_new_profile": "プロファイルを新規作成",
+ "create_lock_check_pw_remind": "2つのパスワードが一致しません",
+ "create_lock_pw_remind": "パスワード設定エラー",
+ "create_lock_pw_txt_remind": "パスワードヒントのエラー",
+ "create_mnemonic": "ニーモニックを作成",
+ "create_profile": "プロファイルを作成",
+ "create_profile_failed": "プロファイルの作成に失敗しました: {reason}",
+ "create_sub_namespace": "サブネームスペース作成",
+ "creation_successful": "おめでとうございます、プロファイルが作成できました!",
+ "current_cosigner_matches_current_account": "現在選択されているアカウントをそれ自体の連署者として追加することはできません",
+ "current_endpoint": "現在のノード",
+ "current_network": "現在のネットワーク",
+ "current_profile_network": "現在のプロファイルネットワーク",
+ "current_speed": "現在のスピード",
+ "current_validity": "有効期限",
+ "deadline": "期限",
+ "decrease": "減少",
+ "decrypt_message": "復号",
+ "define": "登録",
+ "harvesting_delegated_description": "デリゲートハーベスティングは、ノードを起動せずに、アカウントのインポータンススコアを使用して、ブロック生成による報酬を受け取ることができます。デリゲートハーベスティングを有効化するには、すべてのキーをリンクして、アカウントのハーベスティングをノードへリクエストします。",
+ "harvesting_node_selection": "下部のドロップダウンリストからノードを選択します。 dHealth エクスプローラからノードを発見し、その URL を入力して使用することもできます。",
+ "open_explorer_node_list": "dHealth エクスプローラのノードリストにアクセス",
+ "harvesting_keys_linked_next_step_guide": "キーはリンクされました。これでアカウントのハーベスティングをノードへリクエストできます。ノードを変更する場合は、最初にキーのリンクを解除する必要があります。下部のボタンを使用してください。",
+ "harvesting_delegated_request_warning": "アカウントのインポータンススコアとノードの空きハーベスティングスロットによってはリクエストが受理されない場合があります。\n\nまた、ノードはいつでもハーベスティングスロットからアカウントを削除することができることに注意してください。\n\nこのような場合は、別のノードに切り替えて、デリゲートハーベスティング有効化手順をやり直す必要があります。有効化で使用したトランザクション手数料は返還されません。\n\nカスタムノード URL を入力した場合、表示されるハーベスティングステータスはすべてのデバイスで正確ではない可能性があります。",
+ "harvesting_delegated_request_warning_title": "デリゲートハーベスティング",
+ "delegated_harvesting_info": "デリゲートハーベスティングでは、アカウントのインポータンススコアを使用して新しいブロックを生成し、報酬を受け取ることができます。\n ノードをローカルで実行する必要はありません。\n選択したノードにデリゲートハーベスティング要求を送信するか、別のものにスワップすることができます。",
+ "delegated_harvesting_keys_info": "リンクしたキーは、リモートおよびデリゲートハーベスティングに使用します。ノードを所有している場合は、次のキーをノード設定へコピーする必要があります。デリゲートハーベスティングウォレットを実行している場合は、このキーが保持されます。",
+ "open_harvesting_keys_warning_title": "リンクキーのハーベスティングを開く",
+ "open_harvesting_keys_warning_text": "リンクしたキーは、高度な機能であり、ハーベスティングキーがどのように機能するかを理解している専門家のみに管理されるべきです。一般ユーザーは、デリゲートハーベスティング画面にとどまることを推奨します。",
+ "harvesting_activated_from_another_device": "他のデバイスを使用して、ハーベスティングが有効化されました。このウォレットにはすべての情報が含まれていないため、表示されるデリゲート状態は正しくない可能性があります。",
+ "harvesting_keys_linked_missing": "ハーベスティングウォレットをアクティブ化するには、すべてのリンクされたキーペアが必要です。再リンクしてください。",
+ "delete": "削除",
+ "delete_account": "アカウントを削除",
+ "delete_account_confirmation_message": "本当に \"{accountName}\" を削除しますか?続行する前にバックアップを取得できます。",
+ "delete_account_confirmation_title": "アカウントを削除しますか?",
+ "delete_account_confirmation_checkbox": "はい、このアカウントを削除します。",
+ "delete_profile_confirmation_title": "プロファイルの削除",
+ "delete_profile_confirmation_message": "バックアップせずにプロファイルを削除することはお勧めできません。資産w紛失する可能性があります。本当に \"{profileName}\" を削除しますか?",
+ "delete_profile_confirmation_checkbox": "はい、このプロファイルを削除します。",
+ "delete_confirmation_message": "削除してもよろしいですか?",
+ "delete_contact": "連絡先を削除",
+ "delete_contact_confirmation_message": "本当に \"{contactName}\" を削除しますか?",
+ "delete_contact_confirmation_title": "連絡先を削除しますか?",
+ "delete_profile": "プロファイルの削除",
+ "delta": "変化数",
+ "description": "説明",
+ "direction": "方向",
+ "display_mnemonic": "ニーモニック単語を表示",
+ "display_mnemonic_qr_code": "ニーモニックQRコードを表示",
+ "divisibility": "可分性",
+ "divisibility_can_not_less_than_0": "可分性は 0 未満にできません",
+ "divisibility_can_not_more_than_6": "可分性は 6 より大きくできません",
+ "divisibility_invalid": "可分性が無効です [0-6]",
+ "do_not_disclose": "この情報は秘密にしてください。ニーモニックパス語群を他人と共有した場合、アセットは危険に晒される可能性があります。",
+ "do_not_disclose_title": "絶対に秘密にしてください!",
+ "do_not_disclose_title_mnemonic": "ニーモニックパスフレーズをバックアップします",
+ "do_not_share_mnemonics_with_anyone": "ニーモニックは誰にも共有してはいけません",
+ "download": "ダウンロード",
+ "duration": "期間",
+ "duration_can_not_less_than_0": "期間は 0 未満にできません",
+ "duration_can_not_more_than_1_years": "期間は 1 年より多くはできません",
+ "duration_can_not_more_than_10_years": "期間は 10 年より多くはできません",
+ "duration_permanent": "無期限",
+ "edit_object": "{objectName} 編集",
+ "edit_metadata": "メタデータを編集",
+ "encrypt_message": "メッセージを暗号化",
+ "encrypted_message": "暗号化されたメッセージ",
+ "encrypted_message_empty_error": "暗号化メッセージのペイロードを空にすることはできません",
+ "end_finalization_epoch": "ファイナライズエポックの終了",
+ "endpoint": "ノード",
+ "enter_your_private_key": "秘密鍵を入力してください",
+ "error_account_name_already_exists": "アカウント名は既に存在します。一意なアカウント名を入力してください。",
+ "error_contact_already_exists": "この連絡先は既に存在します",
+ "error_delete_all_peers": "ノードはすべてを削除できません",
+ "error_incorrect_field": "{_field_} フィールドは不正です",
+ "error_incorrect_url": "有効なURLではありません",
+ "error_invalid_password": "パスワードは無効です",
+ "error_new_namespace_duration_max_value": "新しいネームスペース期間は {maxValue} より大きくできません",
+ "error_new_password_format": "パスワードは 1 つ以上の文字と数字を含めなければなりません",
+ "error_peer_connection_went_wrong": "ノード {peerUrl} への接続がタイムアウトしました",
+ "error_peer_unreachable": "到達不可能ノードです",
+ "error_profile_does_not_exist": "プロフィールは存在しません",
+ "error_too_many_seed_accounts": "{maxSeedAccountsNumber} 以上の子アカウントを作ることはできません",
+ "estimated_period_of_validity": "有効期間の見積もり",
+ "estimated_rental_fee": "推定レンタル手数料",
+ "existing_profile": "プロファイルはお持ちですか?",
+ "expired_for": "期限切れ",
+ "expires_in": "有効期限",
+ "explorer_url": "エクスプローラ URL",
+ "export_mnemonic": "ニーモニックのエクスポート",
+ "export_transactions": "トランザクションのエクスポート",
+ "fee": "手数料",
+ "fee_can_not_be_less_than_0": "手数料は 0 未満にできません",
+ "fee_speed_fast": "早い",
+ "fee_speed_fastest": "最速",
+ "fee_speed_free": "手数料なし",
+ "fee_speed_highest": "最高",
+ "fee_speed_median": "平均",
+ "fee_speed_normal": "通常",
+ "fee_speed_slow": "遅い",
+ "fee_speed_slowest": "最遅",
+ "fees_collected": "徴収手数料",
+ "fees_earned": "報酬手数料",
+ "filter_peers": "ピアフィルタ",
+ "finish": "完了",
+ "finished": "完了",
+ "flags_divisibility": "モザイクを分割する小数点以下の桁数を指定します。可分性は 0 から 6 の範囲を指定できます。",
+ "flags_duration_permanent": "True の場合、モザイクは無期限になります",
+ "flags_restrictable": "True の場合、モザイク所有者はカスタム制限を設定できます",
+ "flags_supply": "総供給量は 0 ~ 9,000,000,000,000,000 単位の範囲でなければなりません",
+ "flags_transferable": "True の場合、任意のアカウント間で転送できます",
+ "flags_variable_supply": "True の場合、モザイク供給量は変更できます",
+ "form_label_account_to_be_converted": "変換されるアカウント",
+ "form_label_add_cosignatory": "連署者を追加",
+ "form_label_additional_duration": "追加期間",
+ "form_label_alias_type": "エイリアスタイプ",
+ "form_label_by_account": "アカウント別",
+ "form_label_choose_namespace": "ネームスペースの選択",
+ "form_label_cosignatory_modifications": "連署者の変更",
+ "form_label_current_supply": "既存供給量",
+ "form_label_default_account": "優先アカウント",
+ "form_label_default_max_fee": "デフォルト最大手数料",
+ "form_label_description_min_approval": "複数の署名をするため、または署名者を追加する最小署名数",
+ "form_label_description_min_removal": "連署者を削除するためには最小署名数が必要です",
+ "form_label_duration": "期間",
+ "form_label_language": "選択言語",
+ "form_label_link_address": "アドレスにリンク",
+ "form_label_link_mosaic": "モザイクにリンク",
+ "form_label_max_fee": "最大手数料",
+ "form_label_min_approval": "最小承認者数",
+ "form_label_min_removal": "最小削除承認者数",
+ "form_label_multisig_account": "マルチシグアカウント",
+ "form_label_multisig_accounts": "マルチシグアカウント",
+ "form_label_multisig_current_info": "連署者",
+ "form_label_multisig_operation_type": "操作タイプ",
+ "form_label_namespace_name": "スペース名",
+ "form_label_network_node_url": "ハーベスティングノードURLを入力 (例: http://localhost:3000)",
+ "form_label_network_custom_node": "ハーベスティングノードURLを入力",
+ "form_label_new_absolute_supply": "新しい絶対供給量",
+ "form_label_new_account_name": "新しいアカウント名",
+ "form_label_new_account_type": "アカウントタイプの選択",
+ "form_label_new_contact_address": "新しい連絡先アドレス",
+ "form_label_new_contact_name": "新しい連絡先名",
+ "form_label_new_cosignatories": "追加済み連署者",
+ "form_label_new_expiration_time": "新しい期限切れ時間",
+ "form_label_new_min_approval": "新しい最小承認者数",
+ "form_label_new_min_removal": "新しい最小削除承認者数",
+ "form_label_new_password": "新しいパスワードを入力",
+ "form_label_new_password_confirm": "新しいパスワードを確認",
+ "form_label_new_password_hint": "パスワードヒント",
+ "form_label_new_supply": "新しい供給量",
+ "form_label_parent_namespace": "親ネームスペース",
+ "form_label_password": "パスワード",
+ "form_label_password_hint": "プロファイルのパスワードを入力",
+ "form_label_private_key": "秘密鍵を入力してください",
+ "form_label_registration_type": "ネームスペースタイプ",
+ "form_label_remove_cosignatory": "連署者を削除",
+ "form_label_removed_cosignatory": "署名者を削除",
+ "form_label_removed_cosignatory_tooltip": "トランザクション内で許可される署名者の削除は 1 つだけです",
+ "form_label_restriction_type_tooltip": "アカウントは制限タイプごとにブロックまたは許可リストのみ構成できます",
+ "form_label_scoped_metadata_key": "スコープメタデータキー",
+ "form_label_scoped_metadata_key_hint": "スコープメタデータキー (更新 / 追加)",
+ "form_label_supply_delta": "供給変更量",
+ "form_label_supply_direction": "供給変更方向",
+ "form_label_target_account": "対象アカウント",
+ "form_label_target_account_hint": "対象のアドレスまたは公開鍵を入力してください",
+ "form_label_target_mosaic_id": "対象モザイクID",
+ "form_label_target_namespace_id": "対象ネームスペースID",
+ "form_label_value": "値",
+ "form_label_value_hint": "識別子にリンクされる値は 1024 文字までの文字列です",
+ "from_qr_code": "QRコードから",
+ "from_to_action": "From/To (アクション)",
+ "Failure_Core_Past_Deadline": "期限が過ぎたため、検証に失敗しました",
+ "Failure_Core_Future_Deadline": "期限が遠すぎるため、検証に失敗しました",
+ "Failure_Core_Insufficient_Balance": "アカウントの残高が不足しているため、検証に失敗しました",
+ "Failure_Core_Too_Many_Transactions": "ブロック内のトランザクションが多すぎるため、検証に失敗しました",
+ "Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block": "エンティティがネメシスブロックの後にネメシスアカウントから発信されたため、検証に失敗しました",
+ "Failure_Core_Wrong_Network": "エンティティに間違ったネットワークが指定されているため、検証に失敗しました",
+ "Failure_Core_Invalid_Address": "アドレスが無効なため、検証に失敗しました",
+ "Failure_Core_Invalid_Version": "エンティティのバージョンが無効であるため、検証に失敗しました",
+ "Failure_Core_Invalid_Transaction_Fee": "取引手数料が無効なため、検証に失敗しました",
+ "Failure_Core_Block_Harvester_Ineligible": "不適格なハーベスターによってブロックがハーベスティングされたため、検証に失敗しました",
+ "Failure_Core_Zero_Address": "アドレスがゼロであるため、検証に失敗しました",
+ "Failure_Core_Zero_Public_Key": "アドレスがゼロであるため、検証に失敗しました",
+ "Failure_Core_Nonzero_Internal_Padding": "内部パディングがゼロ以外であるため、検証に失敗しました",
+ "Failure_Core_Address_Collision": "アドレスの衝突が検出されたため、検証に失敗しました",
+ "Failure_Core_Importance_Block_Mismatch": "ブロックが重要度ブロックのスキーマと一致しないため、検証に失敗しました",
+ "Failure_Core_Unexpected_Block_Type": "ブロックタイプが予期しないため、検証に失敗しました",
+ "Failure_Core_Invalid_Link_Action": "リンクアクションが無効なため、検証に失敗しました",
+ "Failure_Core_Link_Already_Exists": "メインアカウントがすでに別のアカウントにリンクされているため、検証に失敗しました",
+ "Failure_Core_Inconsistent_Unlink_Data": "リンク解除データが既存のアカウントリンクと一致しないため、検証に失敗しました",
+ "Failure_Core_Invalid_Link_Range": "リンク範囲が無効なため、検証に失敗しました",
+ "Failure_Core_Too_Many_Links": "メインアカウントに指定されたタイプのリンクが多すぎるため、検証に失敗しました",
+ "Failure_Signature_Not_Verifiable": "署名の検証に失敗したため、検証に失敗しました",
+ "Failure_AccountLink_Link_Already_Exists": "メインアカウントがすでに別のアカウントにリンクされているため、検証に失敗しました",
+ "Failure_AccountLink_Inconsistent_Unlink_Data": "リンク解除データが既存のアカウントリンクと一致しないため、検証に失敗しました",
+ "Failure_AccountLink_Unknown_Link": "メインアカウントが別のアカウントにリンクされていないため、検証に失敗しました",
+ "Failure_AccountLink_Remote_Account_Ineligible": "リンクが不適格なアカウントをリモートに変換しようとしているため、検証に失敗しました",
+ "Failure_AccountLink_Remote_Account_Signer_Prohibited": "リモートがトランザクションに署名することを許可されていないため、検証に失敗しました",
+ "Failure_AccountLink_Remote_Account_Participant_Prohibited": "リモートがトランザクションへの参加を許可されていないため、検証に失敗しました",
+ "Failure_Aggregate_Too_Many_Transactions": "集計にトランザクションが多すぎるため、検証に失敗しました",
+ "Failure_Aggregate_No_Transactions": "アグリゲートにトランザクションがないため、検証に失敗しました",
+ "Failure_Aggregate_Too_Many_Cosignatures": "集計に共同署名が多すぎるため、検証に失敗しました",
+ "Failure_Aggregate_Redundant_Cosignatures": "冗長な共同署名が存在するため、検証に失敗しました",
+ "Failure_Aggregate_Ineligible_Cosignatories": "少なくとも1つの署名者が不適格であるため、検証に失敗しました",
+ "Failure_Aggregate_Missing_Cosignatures": "少なくとも1つの必要な署名が欠落しているため、検証に失敗しました",
+ "Failure_Aggregate_Transactions_Hash_Mismatch": "集計トランザクションハッシュが計算値と一致しないため、検証に失敗しました",
+ "Failure_LockHash_Invalid_Mosaic_Id": "ロックが指定されたモザイクを許可しないため、検証に失敗しました",
+ "Failure_LockHash_Invalid_Mosaic_Amount": "ロックが指定された量を許可しないため、検証に失敗しました",
+ "Failure_LockHash_Hash_Already_Exists": "ハッシュがすでにキャッシュに存在するため、検証に失敗しました",
+ "Failure_LockHash_Unknown_Hash": "ハッシュがキャッシュに存在しないため、検証に失敗しました",
+ "Failure_LockHash_Inactive_Hash": "ハッシュが非アクティブであるため、検証に失敗しました",
+ "Failure_LockHash_Invalid_Duration": "期間が長すぎるため、検証に失敗しました",
+ "Failure_LockSecret_Invalid_Hash_Algorithm": "ロックタイプシークレットのハッシュアルゴリズムが無効であるため、検証に失敗しました",
+ "Failure_LockSecret_Hash_Already_Exists": "ハッシュがすでにキャッシュに存在するため、検証に失敗しました",
+ "Failure_LockSecret_Proof_Size_Out_Of_Bounds": "証明が小さすぎるか大きすぎるため、検証に失敗しました",
+ "Failure_LockSecret_Secret_Mismatch": "シークレットが証明と一致しないため、検証に失敗しました",
+ "Failure_LockSecret_Unknown_Composite_Key": "複合キーが不明なため、検証に失敗しました",
+ "Failure_LockSecret_Inactive_Secret": "シークレットが非アクティブであるため、検証に失敗しました",
+ "Failure_LockSecret_Hash_Algorithm_Mismatch": "ハッシュアルゴリズムが一致しないため、検証に失敗しました",
+ "Failure_LockSecret_Invalid_Duration": "期間が長すぎるため、検証に失敗しました",
+ "Failure_Metadata_Value_Too_Small": "メタデータ値が小さすぎるため、検証に失敗しました",
+ "Failure_Metadata_Value_Too_Large": "メタデータ値が大きすぎるため、検証に失敗しました",
+ "Failure_Metadata_Value_Size_Delta_Too_Large": "メタデータの値のサイズのデルタが値のサイズよりも大きいため、検証に失敗しました",
+ "Failure_Metadata_Value_Size_Delta_Mismatch": "メタデータ値のサイズのデルタが現在の状態に基づく期待値と一致しないため、検証に失敗しました",
+ "Failure_Metadata_Value_Change_Irreversible": "メタデータ値の変更(切り捨て)が元に戻せないため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Duration": "期間の値が無効であるため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Name": "名前が無効なため、検証に失敗しました",
+ "Failure_Mosaic_Name_Id_Mismatch": "名前とIDが一致しないため、検証に失敗しました",
+ "Failure_Mosaic_Expired": "親の有効期限が切れているため、検証に失敗しました",
+ "Failure_Mosaic_Owner_Conflict": "親の所有者が子の所有者と競合するため、検証に失敗しました",
+ "Failure_Mosaic_Id_Mismatch": "IDが署名者とナンスから生成された予期されたIDではないため、検証に失敗しました",
+ "Failure_Mosaic_Parent_Id_Conflict": "既存の親IDが指定された親IDと一致しないため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Property": "モザイクプロパティが無効なため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Flags": "モザイクフラグが無効なため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Divisibility": "モザイクの分割可能性が無効であるため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Supply_Change_Action": "モザイク供給変更アクションが無効であるため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Supply_Change_Amount": "モザイク供給の変更量が無効であるため、検証に失敗しました",
+ "Failure_Mosaic_Invalid_Id": "モザイクIDが無効なため、検証に失敗しました",
+ "Failure_Mosaic_Modification_Disallowed": "モザイクの変更が許可されていないため、検証に失敗しました",
+ "Failure_Mosaic_Modification_No_Changes": "モザイクの変更によって変更が発生しないため、検証に失敗しました",
+ "Failure_Mosaic_Supply_Immutable": "モザイクの供給が不変であるため、検証に失敗しました",
+ "Failure_Mosaic_Supply_Negative": "結果のモザイク供給が負であるため、検証に失敗しました",
+ "Failure_Mosaic_Supply_Exceeded": "結果のモザイク供給が最大許容値を超えているため、検証に失敗しました",
+ "Failure_Mosaic_Non_Transferable": "モザイクを転送できないため、検証に失敗しました",
+ "Failure_Mosaic_Max_Mosaics_Exceeded": "モザイクのクレジットが、アカウントが所有できるさまざまなモザイクの最大数を超えるため、検証に失敗しました",
+ "Failure_Mosaic_Required_Property_Flag_Unset": "モザイクに少なくとも1つの必須プロパティフラグが設定されていないため、検証に失敗しました",
+ "Failure_Multisig_Account_In_Both_Sets": "アカウントの追加と削除の両方が指定されているため、検証に失敗しました",
+ "Failure_Multisig_Multiple_Deletes": "複数の削除が存在するため、検証に失敗しました",
+ "Failure_Multisig_Redundant_Modification": "変更が冗長であるため、検証に失敗しました",
+ "Failure_Multisig_Unknown_Multisig_Account": "アカウントがマルチシグキャッシュにないため、検証に失敗しました",
+ "Failure_Multisig_Not_A_Cosignatory": "削除するアカウントが存在しないため、検証に失敗しました",
+ "Failure_Multisig_Already_A_Cosignatory": "追加するアカウントがすでに共同署名者であるため、検証に失敗しました",
+ "Failure_Multisig_Min_Setting_Out_Of_Range": "新しい最小設定が範囲外であるため、検証に失敗しました",
+ "Failure_Multisig_Min_Setting_Larger_Than_Num_Cosignatories": "最小設定が署名者の数よりも大きいため、検証に失敗しました",
+ "Failure_Multisig_Invalid_Modification_Action": "変更アクションが無効なため、検証に失敗しました",
+ "Failure_Multisig_Max_Cosigned_Accounts": "署名者がすでに最大数のアカウントを共同署名しているため、検証に失敗しました",
+ "Failure_Multisig_Max_Cosignatories": "multisigアカウントにはすでに最大数の共同署名者がいるため、検証に失敗しました",
+ "Failure_Multisig_Loop": "マルチシグループが作成されたため、検証に失敗しました",
+ "Failure_Multisig_Max_Multisig_Depth": "最大マルチシグ深度を超えたため、検証に失敗しました",
+ "Failure_Multisig_Operation_Prohibited_By_Account": "マルチシグアカウントで操作が許可されていないため、検証に失敗しました",
+ "Failure_Namespace_Invalid_Duration": "期間の値が無効であるため、検証に失敗しました",
+ "Failure_Namespace_Invalid_Name": "名前が無効なため、検証に失敗しました",
+ "Failure_Namespace_Name_Id_Mismatch": "名前とIDが一致しないため、検証に失敗しました",
+ "Failure_Namespace_Expired": "親の有効期限が切れているため、検証に失敗しました",
+ "Failure_Namespace_Owner_Conflict": "親の所有者が子の所有者と競合しているため、検証に失敗しました",
+ "Failure_Namespace_Id_Mismatch": "IDが署名者とナンスから生成された予期されたIDではないため、検証に失敗しました",
+ "Failure_Namespace_Invalid_Registration_Type": "名前空間登録タイプが無効なため、検証に失敗しました",
+ "Failure_Namespace_Root_Name_Reserved": "ルート名前空間に予約名があるため、検証に失敗しました",
+ "Failure_Namespace_Too_Deep": "結果の名前空間が最大許容名前空間の深さを超えるため、検証に失敗しました",
+ "Failure_Namespace_Unknown_Parent": "名前空間の親が不明なため、検証に失敗しました",
+ "Failure_Namespace_Already_Exists": "名前空間が既に存在するため、検証に失敗しました",
+ "Failure_Namespace_Already_Active": "名前空間がすでにアクティブであるため、検証に失敗しました",
+ "Failure_Namespace_Eternal_After_Nemesis_Block": "ネメシスブロックの後に永遠の名前空間が受信されたため、検証に失敗しました",
+ "Failure_Namespace_Max_Children_Exceeded": "ルート名前空間の子の最大数を超えたため、検証に失敗しました",
+ "Failure_Namespace_Alias_Invalid_Action": "エイリアスアクションが無効なため、検証に失敗しました",
+ "Failure_Namespace_Unknown": "名前空間が存在しないため、検証に失敗しました",
+ "Failure_Namespace_Alias_Already_Exists": "名前空間が既にエイリアスにリンクされているため、検証に失敗しました",
+ "Failure_Namespace_Unknown_Alias": "名前空間がエイリアスにリンクされていないため、検証に失敗しました",
+ "Failure_Namespace_Alias_Inconsistent_Unlink_Type": "リンク解除タイプが既存のエイリアスと一致しないため、検証に失敗しました",
+ "Failure_Namespace_Alias_Inconsistent_Unlink_Data": "リンク解除データが既存のエイリアスと一致しないため、検証に失敗しました",
+ "Failure_Namespace_Alias_Invalid_Address": "エイリアスアドレスが無効なため、検証に失敗しました",
+ "Failure_RestrictionAccount_Invalid_Restriction_Flags": "アカウント制限フラグが無効なため、検証に失敗しました",
+ "Failure_RestrictionAccount_Invalid_Modification_Action": "変更アクションが無効なため、検証に失敗しました",
+ "Failure_RestrictionAccount_Invalid_Modification_Address": "変更アドレスが無効なため、検証に失敗しました",
+ "Failure_RestrictionAccount_Modification_Operation_Type_Incompatible": "操作タイプに互換性がないため、検証に失敗しました",
+ "Failure_RestrictionAccount_Redundant_Modification": "変更が冗長であるため、検証に失敗しました",
+ "Failure_RestrictionAccount_Invalid_Modification": "値がコンテナーにないため、検証に失敗しました",
+ "Failure_RestrictionAccount_Modification_Count_Exceeded": "トランザクションの変更が多すぎるため、検証に失敗しました",
+ "Failure_RestrictionAccount_No_Modifications": "トランザクションに変更がないため、検証に失敗しました",
+ "Failure_RestrictionAccount_Values_Count_Exceeded": "結果のアカウント制限に値が多すぎるため、検証に失敗しました",
+ "Failure_RestrictionAccount_Invalid_Value": "アカウント制限値が無効なため、検証に失敗しました",
+ "Failure_RestrictionAccount_Address_Interaction_Prohibited": "トランザクションに関係するアドレスが相互作用することを許可されていないため、検証に失敗しました",
+ "Failure_RestrictionAccount_Mosaic_Transfer_Prohibited": "モザイク転送が受信者によって禁止されているため、検証に失敗しました",
+ "Failure_RestrictionAccount_Operation_Type_Prohibited": "署名者による操作タイプの開始が許可されていないため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Invalid_Restriction_Type": "モザイク制限タイプが無効なため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Previous_Value_Mismatch": "指定された前の値が現在の値と一致しないため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Previous_Value_Must_Be_Zero": "指定された前の値がゼロ以外であるため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Max_Restrictions_Exceeded": "制限の最大数を超えるため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Cannot_Delete_Nonexistent_Restriction": "存在しない制限を削除できないため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Unknown_Global_Restriction": "必要なグローバル制限が存在しないため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Invalid_Global_Restriction": "モザイクに無効なグローバル制限があるため、検証に失敗しました",
+ "Failure_RestrictionMosaic_Account_Unauthorized": "アカウントにモザイクを移動するための適切な権限がないため、検証に失敗しました",
+ "Failure_Transfer_Message_Too_Large": "メッセージが大きすぎるため、検証に失敗しました",
+ "Failure_Transfer_Out_Of_Order_Mosaics": "モザイクが故障しているため、検証に失敗しました",
+ "Failure_Chain_Unlinked": "既存のチェーンとリンクしていないブロックを受信したため、検証に失敗しました",
+ "Failure_Chain_Block_Not_Hit": "ヒットではないブロックが受信されたため、検証に失敗しました",
+ "Failure_Chain_Block_Inconsistent_State_Hash": "一貫性のない状態ハッシュを持つブロックが受信されたため、検証に失敗しました",
+ "Failure_Chain_Block_Inconsistent_Receipts_Hash": "レシートハッシュに一貫性のないブロックが受信されたため、検証に失敗しました",
+ "Failure_Chain_Block_Invalid_Vrf_Proof": "VRF証明が無効なため、検証に失敗しました",
+ "Failure_Chain_Block_Unknown_Signer": "ブロック署名者が不明なため、検証に失敗しました",
+ "Failure_Chain_Unconfirmed_Cache_Too_Full": "未確認のキャッシュがいっぱいであるため、検証に失敗しました",
+ "Failure_Consumer_Empty_Input": "コンシューマー入力が空であるため、検証に失敗しました",
+ "Failure_Consumer_Block_Transactions_Hash_Mismatch": "ブロックトランザクションハッシュが計算値と一致しないため、検証に失敗しました",
+ "Neutral_Consumer_Hash_In_Recency_Cache": "エンティティハッシュが最新のキャッシュに存在するため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Too_Many_Blocks": "チェーン部分のブロックが多すぎるため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Improper_Link": "チェーンが内部的に不適切にリンクされているため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Duplicate_Transactions": "チェーン部分に重複するトランザクションが含まれているため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Unlinked": "チェーン部分が現在のチェーンにリンクされていないため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Difficulties_Mismatch": "リモートチェーンの難易度が計算された難易度と一致しないため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Score_Not_Better": "リモートチェーンのスコアが良くないため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Too_Far_Behind": "リモートチェーンが大幅に遅れているため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Too_Far_In_Future": "リモートチェーンのタイムスタンプが遠すぎるため、検証に失敗しました",
+ "Failure_Consumer_Batch_Signature_Not_Verifiable": "バッチ操作中に署名の検証に失敗したため、検証に失敗しました",
+ "Failure_Consumer_Remote_Chain_Improper_Importance_Link": "リモートチェーンに不適切な重要度リンクがあるため、検証に失敗しました",
+ "Failure_Extension_Partial_Transaction_Cache_Prune": "部分トランザクションが一時キャッシュから削除されたため、検証に失敗しました",
+ "Failure_Extension_Partial_Transaction_Dependency_Removed": "依存関係が削除されたため、部分トランザクションが一時キャッシュから削除されたため、検証に失敗しました",
+ "Failure_Extension_Read_Rate_Limit_Exceeded": "ソケットの読み取りレート制限を超えたため、検証に失敗しました",
+ "generate_a_new_profile": "新しいプロファイルの生成",
+ "generate_entropy_increase_success": "ニーモニックパス語群の生成に成功",
+ "generate_mnemonic": "ニーモニックの生成",
+ "generate_mnemonic_title": "ニーモニックパスフレーズの生成",
+ "generating_mnemonic": "次へ",
+ "getting_a_mnemonic_equals_ownership_of_a_account_asset": "このニーモニックパス語群は、プロファイルが持つすべてのアセットの権限を取得するのに十分です。",
+ "go_to_login": "クリックしてログイン",
+ "harvested_blocks": "ハーベストされたブロック",
+ "harvesting": "ハーベスティング",
+ "harvesting_account_insufficient_balance": "残高が不足しています。デリゲートハーベスティングを開始するには、アカウントは最低でも 10,000 XYM を保有していなければなりません。",
+ "harvesting_account_has_extra_balance": "デリゲートハーベスティングを開始するには、アカウントが 5,000 万 XYM を超えて保持してはいけません。",
+ "harvesting_account_has_zero_importance": "インポータンスが 0 の場合、アカウントはハーベスティングを開始できません。",
+ "harvesting_confirmation_description_1": "トランザクション詳細は以下に表示されます。パスワードを入力し、次へ ボタンを押下すると、これらのトランザクションはネットワークにアナウンスされます。",
+ "harvesting_confirmation_description_2": "ネットワークノードがハーベスティング中かつデリゲートリクエストを受け入れる場合、ハーベスティングは自動的にアクティブになります。",
+ "harvesting_create_remote_account": "以前にこれを行っていない場合は、まずリモートアカウントを設定する必要があります。",
+ "harvesting_delegation_description_1": "ハーベスティングを開始するアカウントを選択し、デリゲートリクエストを送信するハーベスティングノードを選択します。",
+ "harvesting_delegation_description_2": "次に、トランザクションに含める最大手数料を選択します。デリゲートリクエストは複数のノードに送信できます。",
+ "harvesting_node_get_node_info": "ノード情報の取得",
+ "harvesting_node_not_eligible": "ハーベスティングには不適格です",
+ "harvesting_remote_account": "リモートアカウント",
+ "harvesting_remote_account_creation_successful_1": "リモートアカウントが正常に作成されました。秘密鍵は安全に保管してください。",
+ "harvesting_remote_account_description_1": "セキュリティ上の理由から、デリゲートハーベスティングのために、リモートアカウント (プロキシ) を作成します。",
+ "harvesting_remote_account_description_3": "リモートアカウントを作成するためにパスワードを入力して \"Start\" をクリックしてください",
+ "harvesting_remote_linked_description_1": "現在、あなたのアカウントは、デリゲートハーベスティングのために、次のリモートアカウント (プロキシ) にリンクされています。",
+ "harvesting_remote_linked_description_2": "アカウントセクションで、このリモートアカウントからのアカウントリンクを解除できます。次へ をクリックして、選択したハーベスティングノードのデリゲートリクエストを構成します。",
+ "harvesting_status": "ハーベスト状況",
+ "harvesting_status_active": "有効",
+ "harvesting_status_inactive": "無効",
+ "harvesting_status_failed": "失敗しました",
+ "harvesting_status_inprogress_activation": "有効化が進行中",
+ "harvesting_status_inprogress_deactivation": "無効化が進行中",
+ "harvesting_status_keys_linked": "リンク済みキー",
+ "harvesting_subtitle_confirmation": "概要",
+ "harvesting_subtitle_delegation": "ノード選択",
+ "harvesting_subtitle_overview": "概要",
+ "harvesting_warning_node_swap": "別のノードに交換すると、すべてのキーを再リンクします",
+ "hash_date": "日付",
+ "hd_account_path_error": "アドレスパスエラー",
+ "hidden_accounts": "非表示にしたアカウント",
+ "hide_account": "アカウントを非表示",
+ "id": "#",
+ "if_you_need_to_backup_your_mnemonics_again_you_can": "'アカウント - マイアカウント - プロファイルをバックアップ' からニーモニックを再バックアップできます。",
+ "illegal_public_key_error": "公開鍵は無効です",
+ "illegal_publicKey": "指定したアカウントの公開鍵は無効です",
+ "import": "インポート",
+ "import_address_book": "アドレス帳をインポート",
+ "import_mnemonic": "ニーモニックのインポート",
+ "import_mnemonic_passphrase_create_profile": "ニーモニックパス語群をインポートしてアカウントを作成",
+ "import_private_key": "秘密鍵のインポート",
+ "import_private_key_account_successfully": "おめでとう!秘密鍵アカウントが正常にインポートされました。",
+ "import_private_key_account_successfully_title_tips": "現在のプロファイルは秘密鍵から作成されています。他のアカウントを追加することはできません。快適な体験と旅をお楽しみください。",
+ "import_private_key_description": "秘密鍵をインポートしてプロファイルを作成",
+ "import_private_key_finalize_tip_text1": "1. 秘密鍵は安全な場所にバックアップしてください。暗号化され、ローカルの現在のプロファイルの下にマウントされます。ニーモニックとは関係ありません。",
+ "import_private_key_finalize_tip_text2": "2. プロファイルは独立した秘密鍵をいくつでもマウントできます。注意してください!",
+ "import_private_key_input_tip1": "入力フィールドに秘密鍵を入力してください。秘密鍵が正しいことを確認してください。正しい秘密鍵を入力すると、対応する公開鍵とアドレスが入力ボックスの下部に表示されます。ネットワークに注意してくださいタイプ。",
+ "import_private_key_profile_description_tip1": "このソフトウェアを使い始める前に、プロファイル名とパスワードを作成する必要があります。アカウント情報をローカルで暗号化するために使用されます。",
+ "import_private_key_profile_description_tip2": "パスワードは転送やトランザクション操作など、プロファイルへのアクセスを保護するために使用されます。",
+ "import_qr_code": "QRコードをインポート",
+ "import_successful": "おめでとうございます、プロファイルのインポートができました!",
+ "import_transaction_uri": "トランザクションURIをインポート",
+ "importance": "インポータンス",
+ "incoming": "受信",
+ "increase": "増加",
+ "info_active_cosignatory_mode": "選択したトランザクション署名者はマルチシグアカウントです。",
+ "info_connecting_peer": "ノード {peerUrl} に接続中...",
+ "inner_transaction_hash": "内部トランザクションハッシュ",
+ "input_here": "ここに入力",
+ "input_mnemonic": "ニーモニックパス語群の入力",
+ "input_mnemonic_tips": "ニーモニックパス語群の 12 または 24 単語をスペース区切りで入力します。ニーモニックパス語群はランダムに選択された 12 または 24 個の単語で構成されます。単語を設定するとアセットが復元されます。",
+ "input_namespace_name": "ネームスペース名を入力",
+ "invalid_address_book": "アドレス帳が無効です",
+ "invalid_mnemonic_input": "入力されたニーモニックパスフレーズは無効です",
+ "invalid_namespace_or_mosaic_id": "モザイクIDまたは名前が無効です",
+ "invalid_node": "無効なノード",
+ "keep_it_in_a_safe_place_on_the_isolated_network_mnemonics": "安全な場所に保管してください。ニーモニックをメール、フォトアルバム、ソーシャルアプリケーションなどの共有またはリモート環境で共有や保存をしないでください。",
+ "keystore_decryption_failed": "キーストアの復号に失敗",
+ "label_add_cosignatory": "連署者を追加",
+ "label_duration_unlimited": "無期限",
+ "label_for_approvals": "トランザクション承認に必要な連署名",
+ "label_for_removals": "連署者の削除に必要な連署名",
+ "label_multisig_operation_conversion": "アカウントをマルチシグに変換中",
+ "label_multisig_operation_modification": "アカウントマルチシグプロパティの変更",
+ "label_of": "{min} / {max}",
+ "label_postfix_multisig": "(マルチシグ)",
+ "label_signed_by": "連署者の署名 =>",
+ "latest_news_articles": "最新ニュース",
+ "ledger_connected_other_app": "Ledger デバイスはパスにアクセスできません。Ledger を使用してアドレスを確認するか、開いている他のアプリをすべて閉じてから、再試行してください。",
+ "ledger_correct_account": "正しい Symbol Ledger アカウントを使用中です",
+ "ledger_description": "Ledger デバイスからウォレットをインポートします",
+ "ledger_device_locked": "Ledger デバイスをアンロックしてください",
+ "ledger_no_device": "Ledger が見つかりませんでした",
+ "ledger_no_device_selected": "選択された Ledger デバイスはありません",
+ "ledger_not_correct_account": "正しい Symbol Ledger アカウントが使用されていません",
+ "ledger_not_opened_app": "Ledger デバイスで Symbol アプリを開いてください",
+ "ledger_not_supported_app": "Ledger デバイスで最新の Symbol アプリケーションを開いていることを確認してください",
+ "ledger_not_using_xym_app": "Ledger デバイスで Symbol アプリを使用していません",
+ "ledger_profile_import": "Ledger プロファイルのインポート",
+ "ledger_user_reject_request": "ユーザがリクエストをキャンセルしました",
+ "link": "リンク",
+ "link_action": "リンクアクション",
+ "linked_account_address": "リンクされたアカウントアドレス",
+ "linked_account_public_key": "リンクされたアカウント公開鍵",
+ "linked_node_public_key": "リンクされたノード公開鍵",
+ "linked_public_key": "リンクされた公開鍵",
+ "linked_vrf_public_key": "VRF公開鍵",
+ "linked_remote_private_key": "リモート秘密鍵",
+ "linked_vrf_private_key": "VRF秘密鍵",
+ "linked_keys_info": "キー情報:",
+ "link_keys": "すべてのキーをリンク",
+ "loading": "読込中…",
+ "locked_mosaic": "ロック済みモザイク",
+ "login": "ログイン",
+ "login_to_symbol_account": "アカウントにログイン",
+ "logout": "ログアウト",
+ "low_fee_warning_message": "平均手数料未満のトランザクションは受け入れられず、最終的に期限切れとなる場合があります",
+ "max_approval_amount_more_than_10": "承認に必要な連署者の最大数は 10 を超えることはできません",
+ "max_decimal_number_error": "{_field_} には {maxDecimalNumber} 小数点以下の桁数を指定してください",
+ "max_message_length_error": "{_field_} フィールドは {maxMessageNumber} 文字を超えることはできません",
+ "positive_decimal_error": "数字と \"{decimalSeparator}\" のみが利用可能です",
+ "max_fee": "最大手数料",
+ "max_removal_amount_more_than_10": "削除に必要な連署者の最大数は 10 を超えることはできません",
+ "message": "メッセージ",
+ "message_empty_cosignatories": "このアカウントには連署者がいません",
+ "metadata": "メタデータ",
+ "metadata_attached_to_account": "アカウントに添付されたメタデータ",
+ "metadata_value": "メタデータ値",
+ "min_approval_amount_illegal": "承認に必要な連署者の最小数は数字でなければなりません",
+ "min_approval_amount_less_than_0": "承認に必要な連署者の最小数を 1 未満にできません",
+ "min_approval_delta": "最小削除承認者変更数",
+ "min_removal_amount_illegal": "削除に必要な連署者の最小数は数字でなければなりません",
+ "min_removal_amount_less_than_0": "削除に必要な連署者の最小数を 1 未満にできません",
+ "min_removal_delta": "最小削除承認者変更数",
+ "minimal_fee_transaction": "選択中ノードの最小手数料乗数:",
+ "mnemonic_backup_options_copy_desc": "ニーモニック語群をコピーして、安全な場所に保管してください。",
+ "mnemonic_backup_options_download_desc": "パスワードで暗号化されたQRコードをダウンロードします。このQRコードを使用して、アカウントをさまざまなウォレット (モバイルウォレットなど) にインポートできます。",
+ "mnemonic_copy": "コピー",
+ "mnemonic_generation_error": "プロファイルシードの生成に問題が発生しました。",
+ "mnemonic_inconsistency": "ニーモニックが正しくありません",
+ "mnemonic_correct": "正しいニーモニックです",
+ "mnemonic_not_found": "ニーモニックが見つかりません!",
+ "mnemonic_phrase": "ニーモニックパス語群",
+ "mnemonic_qr_action_desc": "続行 をクリックして、インポートされたニーモニック語群をテキストエリアに設定します。",
+ "modal_account_unlock_title": "アカウントのアンロック",
+ "modal_backup_reminder_content": "秘密鍵アカウントはニーモニックパス語群から復元できないことを念頭に置いてください。インポートが完了したら、プロファイルを再度バックアップして、このアカウントをペーパーウォレットに含めてください。",
+ "modal_backup_reminder_title": "警告",
+ "modal_title_account_metadata": "アカウントメタデータ",
+ "modal_title_backup_mnemonic_display": "ニーモニックパス語群の表示",
+ "modal_title_backup_mnemonic_qrcode": "ニーモニックQRコードのエクスポート",
+ "modal_title_backup_profile": "プロファイルのバックアップ",
+ "modal_title_backup_transaction": "トランザクションのエクスポート",
+ "modal_title_debug_console": "診断コンソール",
+ "modal_title_delete": "削除承認",
+ "modal_title_enter_account_name": "新しいアカウントを設定",
+ "modal_title_extend_namespace_duration": "ネームスペース期限の延長",
+ "modal_title_link_alias": "エイリアスの作成",
+ "modal_title_mosaic_metadata": "モザイクメタデータ",
+ "modal_title_mosaic_supply_change": "モザイク供給量変更",
+ "modal_title_namespace_metadata": "ネームスペースメタデータ",
+ "modal_title_transaction_confirmation": "トランザクションに署名",
+ "modal_title_transaction_details": "トランザクション詳細",
+ "modal_title_unlink_alias": "エイリアスをネームスペースからアンリンク",
+ "more_access_tool_is_working": "たくさんの認証ツールを開発中です",
+ "mosaic": "モザイク",
+ "mosaic_alias_not_exist": "モザイクエイリアスは存在しません",
+ "mosaic_describe_text": "モザイクはトークンとしてだけでなく、報酬ポイント、会社株式、署名、ステータスフラグ、投票、通貨などの専門的なアセットの集合でもあります。",
+ "mosaic_expired": "期限切れ",
+ "mosaic_hex_format_error": "モザイクHEXフォーマットエラー",
+ "mosaic_id": "モザイクID",
+ "mosaic_name_can_not_be_null": "モザイク名は空にできません",
+ "mosaic_not_set": "モザイクを選択してください",
+ "mosaic_transaction": "モザイクトランザクション",
+ "mosaic_supply_transaction": "供給量変更トランザクション",
+ "mosaic_transfer_type": "モザイクトランザクション",
+ "mosaics_list": "モザイクリスト",
+ "move_your_mouse": "より複雑さでランダムなニーモニックパス語群を生成するためにマウスを動かしてください。",
+ "move_your_mouse_tip1": "ニーモニックパスフレーズを生成します",
+ "multisig_account_graph": "マルチシグツリー",
+ "multisig_accounts_can_not_send_a_transaction_by_themselves": "マルチシグアカウントはトランザクションを開始できません。連署者のアカウントを使用してください。",
+ "multisig_transaction": "マルチシグトランザクション",
+ "multisignature_transfer_type": "マルチシグネチャトランザクション",
+ "my_transaction_title": "マイトランザクション",
+ "namespace": "ネームスペース",
+ "namespace_and_sub_namespace": "ネームスペースとサブネームスペース",
+ "namespace_can_only_contain_numbers_letters_and_other": "ネームスペース名には 0-9, A-Z, a-z, _, - の文字のみ使用できます",
+ "namespace_cannot_be_a_null_or_empty_string": "ネームスペース名を空文字にすることはできません",
+ "namespace_cannot_use_forbidden_words": "このネームスペース名は保護されているため使用できません",
+ "namespace_definition": "ネームスペースは、NEMブロックチェーン上であなたのビジネスと資産のためのチェーン上の唯一の識別子を作成できます。インターネットドメインと類似しています。",
+ "namespace_description": "ネームスペースの説明",
+ "namespace_duration_tip_1": "期間はブロック数で計算され、1 ブロック = 15 秒、1 ブロック = 1 XYM、最大有効期間は 365 日です。",
+ "namespace_id": "ネームスペースID",
+ "namespace_must_start_with_a_letter": "ネームスペース名は小文字で始まる必要があります",
+ "namespace_name": "スペース名",
+ "namespace_name_constraint": "名前はネットワーク内で一意である必要があります。最大 64 文字で a, b, c, …, z, 0, 1, 2, …, 9, _ , - を使用できます。",
+ "namespace_tips_key_1": "1. 名前はネットワークに一意でなければなりません。最大長は 64 文字です。許可された文字:",
+ "namespace_tips_key_2": "2. 次の文字は使用できません:",
+ "namespace_tips_key_3": "3. ネームスペースは 3 階層まで定義できます。",
+ "namespace_tips_value_1": "a, b, c, …, z, 0, 1, 2, …, 9, _ , -",
+ "namespace_tips_value_2": "nem, user, account, org, com, biz, net, edu, mil, gov, info.",
+ "namespace_transaction": "ネームスペーストランザクション",
+ "namespace_transfer_type": "ネームスペーストランザクション",
+ "network_settings": "ネットワーク設定",
+ "network_type": "ネットワークタイプ",
+ "network_type_invalid": "ネットワークタイプが一致しません",
+ "new_password_label": "パスワード",
+ "news": "ニュース",
+ "news_read_more": "もっと読む",
+ "next": "次へ",
+ "no_confirmed_transactions": "承認済トランザクションはありません",
+ "no_data_mosaics": "このアカウントには保有モザイクがありません",
+ "no_data_namespace_tips": "ネームスペースをお持ちでない?では作りましょう。",
+ "no_data_namespaces": "このアカウントには保有ネームスペースがありません",
+ "no_data_transactions": "このアカウントにはトランザクションがありません",
+ "no_harvested_blocks_yet": "ハーベストしたブロックはまだありません",
+ "no_mnemonic": "ニーモニックなし",
+ "no_network_currency_alert": "ウォレットにはネットワーク通貨に関するデータを取得できません (例: dhealth:dhp) 有効なノードに接続してください。",
+ "no_partial_transactions": "パーシャルトランザクションはありません",
+ "no_profiles_in_database": "ウォレットデータベースにプロファイルはありません",
+ "no_unconfirmed_transactions": "未承認トランザクションはありません",
+ "node": "ノード",
+ "node_connection_failed": "ノード接続に失敗",
+ "node_connection_succeeded": "ノード接続に成功",
+ "node_exists_error": "ノードは既に存在します",
+ "node_list": "ノードリスト",
+ "node_not_available_please_check_your_node_or_network_settings": "ノードが利用できません。ノードまたはネットワーク設定を確認してください。",
+ "node_public_key_input": "公開鍵が見つかりません。ここに入力するか、別のノードを選択してください。",
+ "node_publicKey": "ノード公開鍵",
+ "node_url": "ノードURL",
+ "not_yet_open": "まだ公開されていません",
+ "notes_should_not_exceed_25_character": "メモは 25 文字以下にしてください",
+ "notification_new_aggregate_bonded": "新しいアグリゲートトランザクションがアナウンスされました",
+ "notification_new_cosignature": "アグリゲートトランザクションに署名がされました",
+ "notification_new_transaction_confirmed": "新しいトランザクションが承認されました",
+ "notification_new_unconfirmed_transaction": "新しいトランザクションが未承認になりました",
+ "offline_storage": "オフラインストレージ",
+ "open_restrictions_warning_text": "アカウント制限は、アカウントが無効になる可能性がある高度な機能です。次の画面での操作に注意してください。\nアカウント制限にアクセスしますか?",
+ "open_restrictions_warning_title": "アカウント制限を開く",
+ "operation_failed": "リクエスト失敗",
+ "operation_type": "操作タイプ",
+ "option_child_account": "プロファイルのシードアカウントを作成する",
+ "option_hd_account": "HDアカウントを作成する",
+ "option_link_address": "アドレスにリンク",
+ "option_link_mosaic": "モザイクにリンク",
+ "option_privatekey_account": "既存アカウントに秘密鍵をインポート",
+ "option_root_namespace": "ルートネームスペース",
+ "option_sub_namespace": "サブネームスペース",
+ "outgoing": "発信",
+ "page_title_account_actions": "アクション",
+ "page_title_account_backup": "プロファイルバックアップ",
+ "page_title_account_details": "アカウント情報",
+ "page_title_account_harvesting": "ハーベスティング",
+ "page_title_account_metadata": "メタデータ",
+ "page_title_dashboard": "ダッシュボード",
+ "page_title_delegated_harvesting": "デリゲートハーベスティング",
+ "page_title_harvesting": "ハーベスティング",
+ "page_title_history": "履歴",
+ "page_title_invoice": "インボイス",
+ "page_title_mosaics": "保有モザイク",
+ "page_title_mosaics_create": "モザイク作成",
+ "page_title_multisig_convert": "アカウントの変換",
+ "page_title_multisig_cosign": "トランザクションに署名",
+ "page_title_multisig_manage": "マルチシグネチャの管理",
+ "page_title_namespaces": "保有ネームスペース",
+ "page_title_namespaces_create": "ネームスペース作成",
+ "page_title_send": "送信",
+ "page_title_settings_about": "ソフトウェア情報",
+ "page_title_settings_diagnostic": "診断",
+ "page_title_settings_general": "一般設定",
+ "page_title_settings_password": "プロファイルパスワード",
+ "page_title_transfer": "転送",
+ "paid_fee": "支払手数料",
+ "parent_namespace": "親ネームスペース",
+ "password": "パスワード",
+ "password_error": "パスワードのエラー",
+ "password_hint": "パスワードヒント",
+ "password_is_invalid": "パスワードはアルファベットと数字を含む8文字以上でなければなりません",
+ "passwords_not_matching": "パスワードが一致しません",
+ "peer_tip": "{setting} ページでノードの管理、新しいネットワークの構成ができます",
+ "peers_number": "ピア数",
+ "phishing_warning": "フィッシングに注意してください!このプログラムではプロファイルを復元する場合以外に、ニーモニックの入力は求めることはありません。",
+ "placeholder_address": "アドレスを入力",
+ "placeholder_address_or_alias": "アドレスまたはエイリアス (例 nem.group)",
+ "placeholder_address_or_public_key": "アドレスまたは公開鍵",
+ "placeholder_transaction_uri": "有効なトランザクション URI を入力してください",
+ "please_accurately_copy_the_safety_backup_mnemonic": "正確にコピーして、ニーモニックを安全にバックアップしてください",
+ "i_accept": "同意します",
+ "terms": "規約",
+ "conditions": "条件",
+ "please_backup_mnemonic_passphrase": "必ずニーモニックパス語群のバックアップコピーを作成してください。プロファイルを復元するときは、このバックアップが必要になります。",
+ "please_backup_mnemonic_passphrase_title": "バックアップを作成する!",
+ "please_check_device_connection": "デバイスの接続を確認してください!",
+ "please_click_on_the_mnemonic_in_order_to_confirm_that_you_are_backing_up_correctly": "バックアップが正しくできているかを確認するため、ニーモニックをクリックしてください。",
+ "please_enter_a_correct_number": "有効な番号を入力してください",
+ "please_enter_a_custom_nod_address": "カスタムノード URL を入力してください",
+ "please_enter_a_mnemonic_to_ensure_that_the_mnemonic_is_correct": "正しいことを確認するために、ニーモニックを入力してください",
+ "please_enter_notes": "メッセージの入力",
+ "please_enter_your_account_password": "プロファイルのパスワードを入力",
+ "please_enter_your_new_password_again": "プロファイルのパスワードをもう一度入力",
+ "please_enter_your_password_again": "パスワードを再入力",
+ "please_set_your_account_password": "アカウントパスワードを設定",
+ "please_update_symbol_bolos_app": "Ledger デバイスの Symbol アプリを更新してください!",
+ "point_null_error": "ノード NULL エラー",
+ "preview_and_action": "プレビュー&アクション",
+ "previous": "戻る",
+ "privacy_policy": "プライバシーポリシー",
+ "private_key": "秘密鍵",
+ "private_key_invalid_error": "秘密鍵が不正です",
+ "profile_creation_description": "このソフトウェアの使用を開始する前に、プロファイルとパスワードを作成する必要があります。パスワードはプロファイルへのアクセスを保護するために使用されます。",
+ "profile_description": "プロファイル説明",
+ "profile_description_tips1": "このソフトウェアを使用する前に、プロファイルとパスワードを作成する必要があります。このウォレットソフトウェアは階層的決定性ウォレット (HD-Wallets) を使用します。",
+ "profile_description_tips2": "パスワードはプロファイルへのアクセスを保護するために使用され、ニーモニックパス語群を暗号化するために使用されます。複数のアドレスを 1 つのアカウントで管理でき、スタートアップページでアカウントを切り替えることができます。",
+ "profile_description_tips3": "パスワードと 24 単語のニーモニックパス語群の両方をバックアップしてください。",
+ "profile_import": "プロファイルのインポート",
+ "profile_name": "プロファイル名",
+ "profile_name_already_exists": "プロファイル名は既に使用済みです",
+ "profile_name_error": "不正なプロファイル名です",
+ "profile_not_matching_network_option_1": "ログアウトしてプロファイルを変更する",
+ "profile_not_matching_network_option_2": "新しいプロファイルを作成する",
+ "profile_not_matching_network_option_3": "ネットワークを閉じて切り替えます",
+ "profile_not_matching_network_warning_message": "プロファイルのネットワークが現在のネットワークと一致しません。問題を解決するには、次のオプションを選択してください。",
+ "profile_not_matching_network_warning_title": "警告",
+ "program_description_line1": "このプログラムは、オープンソースのデジタルアセット管理システムである",
+ "program_description_line2": "dHealth ブロックチェーンを基礎として構成されています",
+ "program_description_line3": "ネットワークへアクセスし、プロファイルの作成、アカウントやアセットの管理などを行います。",
+ "progress": "ダウンロード中",
+ "public_key": "公開鍵",
+ "public_key_addition": "追加済み連署者",
+ "public_key_deletion": "削除済み連署者",
+ "public_key_invalid": "公開鍵は無効です",
+ "qr_code": "QRコード",
+ "qr_code_generation_failed": "QRコード生成に失敗",
+ "qrcode_detail_item_address": "アドレス",
+ "qrcode_detail_item_contact_name": "連絡先",
+ "qrcode_detail_item_mnemonic_passphrase": "ニーモニックパスフレーズ",
+ "qrcode_detail_item_network_type": "ネットワークタイプ",
+ "qrcode_detail_item_type": "QRコードタイプ",
+ "qrcode_detail_item_type_contactqr": "アドレス",
+ "qrcode_detail_item_type_cosignatureqr": "署名リクエスト",
+ "qrcode_detail_item_type_mnemonicqr": "ニーモニックのインポート",
+ "qrcode_detail_item_type_transactionqr": "請求書",
+ "qrcode_detail_item_type_signedqr": "署名済みトランザクション",
+ "qrcode_password_info": "アップロードされた QR コードはパスワードで保護されています。この QR コードが生成されたときのパスワードを入力してください。",
+ "recipient": "受信者",
+ "recipient_linked_address_invalid": "受信者のエイリアス名にリンクされたアドレスがありません",
+ "recipient_public_key_invalid_error": "無効な受信者公開鍵",
+ "refresh": "更新",
+ "refresh_failed": "エラーが起きました。あとで再試行してください。",
+ "refresh_success": "更新に成功しました",
+ "refresh_too_fast_warning": "実行されたネットワークリクエストが多すぎます。後でもう一度試してください。",
+ "register": "サインアップ",
+ "relative": "相対",
+ "removal_greater_than_cosignatories": "最小削除数に必要な署名者は {delta} より多い有効な連署者が必要です。署名者を追加するか、最小削除数を減らしてください。",
+ "removal_or_approval_is_zero": "リストに {delta} つの署名者がいる場合、最小承認と最小削除を 0 に設定することはできません",
+ "repeat_password_label": "パスワードの再確認",
+ "reset": "リセット",
+ "resolving_address": "アドレス {address} 解決中...",
+ "restore_mnemonic": "ニーモニック語群のリストア",
+ "restrictable": "制限可",
+ "rules_describe": "ルール説明",
+ "safe_storage_tips": "安全な保管の知識",
+ "save": "保存",
+ "save_backups": "複数のコピーをオフラインで作成し、複数の場所にバックアップを保存します。デジタルバックアップには暗号化されたディスクを使用してください。",
+ "scenes_to_be_used": "使用例",
+ "see_transactions_other_account": "マルチシグアカウントのトランザクション表示",
+ "seed_account_can_not_be_more_than_10": "1 つのプロファイルに作成できるアカウントの上限に達しました。別のプロファイルで新しいアカウントを作成してください。",
+ "select": "選択",
+ "select_a_namespace": "ネームスペースの選択",
+ "select_a_profile": "プロファイルを選択",
+ "select_accounts": "選択済みアカウント",
+ "select_opt_in_accounts": "選択したオプトイン済みアカウント",
+ "select_all": "すべて選択",
+ "select_contact": "連絡先を選択",
+ "send": "送信",
+ "sender": "送信者",
+ "set_account_name": "プロファイル名の入力",
+ "set_default_explorer": "入力されたURLは無効です。既定のURLが設定されています。",
+ "set_explorer_link": "エクスプローラリンクの設定",
+ "set_network_type": "ネットワークタイプ選択",
+ "SET_UP": "ノード選択",
+ "settings": "設定",
+ "settings_tab_about": "ソフトウェア情報",
+ "settings_tab_general": "一般設定",
+ "settings_tab_network": "ネットワーク設定",
+ "settings_tab_password": "プロファイルパスワード",
+ "show_button": "表示",
+ "show_expired_mosaics": "期限切れモザイクを表示",
+ "show_expired_namespaces": "期限切れネームスペースを表示",
+ "show_on_ledger": "Ledger で表示する",
+ "show_wizard": "ウィザードを表示",
+ "sidebar_item_accounts": "アカウント",
+ "sidebar_item_aggregate": "アグリゲート",
+ "sidebar_item_community": "ニュース",
+ "sidebar_item_harvesting": "ハーベスティング",
+ "sidebar_item_home": "ホーム",
+ "sidebar_item_mosaics": "モザイク",
+ "sidebar_item_multisig": "マルチシグ",
+ "sidebar_item_namespaces": "ネームスペース",
+ "sign_transaction_failed": "トランザクションの署名に失敗しました: {reason}",
+ "signature": "署名",
+ "signer_public_key": "署名者公開鍵",
+ "simple_transaction": "シンプルトランザクション",
+ "simple_transfer_type": "シンプルトランザクション",
+ "skip": "スキップ",
+ "speed": "速度",
+ "start": "開始",
+ "start_finalization_epoch": "ファイナライズエポックを開始",
+ "start_harvesting": "ハーベスティングを開始",
+ "status": "ステータス",
+ "stop_harvesting": "ハーベスティングを停止",
+ "success_account_unlocked": "アカウントのアンロックに成功",
+ "success_password_changed": "パスワードを更新しました。ログアウトします。",
+ "success_settings_updated": "設定を更新しました",
+ "success_transaction_partial_announced": "パーシャルトランザクションのアナウンスに成功",
+ "success_transactions_announced": "トランザクションのアナウンスに成功",
+ "success_transactions_signed": "トランザクションの署名に成功",
+ "successful_copy": "クリップボードにコピー!",
+ "successful_operation": "リクエスト成功",
+ "supply": "供給量",
+ "supply_can_not_less_than_0": "供給量は 0 未満にできません",
+ "swap": "スワップ",
+ "tab_accounts_accounts": "マイアカウント",
+ "tab_accounts_addressbook": "マイ連絡先",
+ "tab_harvesting_delegated_harvesting": "デリゲートハーベスティング",
+ "tab_harvesting_key_links": "キーリンク",
+ "table_header_action": "アクション",
+ "table_header_alias_identifier": "エイリアス",
+ "table_header_alias_type": "エイリアスタイプ",
+ "table_header_balance": "残高",
+ "table_header_change_times": "時間の変更",
+ "table_header_direction": "方向",
+ "table_header_divisibility": "可分性",
+ "table_header_expiration": "有効期限",
+ "table_header_expired": "期限切れ",
+ "table_header_hex_id": "Id",
+ "table_header_name": "名前",
+ "table_header_restrictable": "制限可",
+ "table_header_scoped_key": "スコープメタデータキー",
+ "table_header_status": "状態",
+ "table_header_supply": "供給量",
+ "table_header_supply_mutable": "可変供給量",
+ "table_header_target_address": "ターゲットアドレス",
+ "table_header_target_id": "ターゲットID",
+ "table_header_target_type": "ターゲットタイプ",
+ "table_header_transferable": "転送可能",
+ "table_header_value": "値",
+ "target_account_invalid_name": "対象アカウント",
+ "terms_and_conditions": "利用規約",
+ "the_backup_is_wrong": "正しい順序でニーモニック語群を慎重に選択してください。",
+ "the_mnemonic_order_is_correct_and_the_backup_is_successful": "ニーモニックの順序は正しく、バックアップは成功しました。",
+ "the_mosaic_to_be_sent_is_empty": "モザイクリストは空にできません",
+ "the_root_namespace_cannot_be_longer_than_16": "ルートネームスペース名は 16 文字以下にする必要があります。",
+ "the_sub_namespace_cannot_be_longer_than_16": "サブネームスペース名は 64 文字以下にする必要があります。",
+ "the_value_of_duration_cannot_be_less_than_1": "期間は 1 以上でなければなりません",
+ "tips": "ヒント",
+ "title": "タイトル",
+ "to": "To",
+ "to_symbol": "to dHealth",
+ "too_many_cosignatories": "署名者の最大数は {maxCosignatoriesPerAccount} です。 {delta} 署名者を削除してください。",
+ "top_window_console": "コンソール",
+ "transaction_cancel": "トランザクションがキャンセル!",
+ "transaction_descriptor_16705": "アグリゲートコンプリート",
+ "transaction_descriptor_16707": "投票キーリンク",
+ "transaction_descriptor_16708": "アカウントメタデータ",
+ "transaction_descriptor_16712": "ファンドロック",
+ "transaction_descriptor_16716": "アカウントリンク",
+ "transaction_descriptor_16717": "モザイク定義",
+ "transaction_descriptor_16718": "ネームスペース登録",
+ "transaction_descriptor_16720": "アカウントアドレス制限",
+ "transaction_descriptor_16721": "モザイクグローバル制限",
+ "transaction_descriptor_16722": "シークレットロック",
+ "transaction_descriptor_16724": "転送",
+ "transaction_descriptor_16725": "マルチシグアカウントの変更",
+ "transaction_descriptor_16961": "アグリゲートボンデッド",
+ "transaction_descriptor_16963": "VRFキーリンク",
+ "transaction_descriptor_16964": "モザイクメタデータ",
+ "transaction_descriptor_16972": "ノードキーリンク",
+ "transaction_descriptor_16973": "モザイク供給変更",
+ "transaction_descriptor_16974": "アドレスエイリアス",
+ "transaction_descriptor_16976": "アカウントモザイク制限",
+ "transaction_descriptor_16977": "モザイクアドレス制限",
+ "transaction_descriptor_16978": "シークレットプルーフ",
+ "transaction_descriptor_17220": "ネームスペースメタデータ",
+ "transaction_descriptor_17230": "モザイクエイリアス",
+ "transaction_descriptor_17232": "アカウント操作制限",
+ "transaction_details": "トランザクション詳細",
+ "transaction_expired": "トランザクション期限切れ",
+ "transaction_has_cosignature": "連署名の受信",
+ "transaction_needs_cosignature": "連署名待機トランザクション",
+ "transaction_needs_cosignature_explain": "このマルチシグトランザクションは承認される前に複数の当事者が署名する必要があります。パスワードを入力し、署名の追加を確認してください。",
+ "transaction_needs_cosignature_explain_signed": "このトランザクションでは、承認のために複数の署名が必要です。あなたはこのトランザクションへの連署名をすでに送信しています。他の連署者が署名するまでお待ちください。QRコードをダウンロードして他の連署者へ送信し、署名をさせることもできます。",
+ "transaction_qr_action_desc": "続行 をクリックして、これらの詳細が記載された転送ページを開きます。",
+ "transaction_qr_signed_action_desc": "続行をクリックして、これらの詳細を含むトランザクションをブロードキャストします。",
+ "transaction_qr_code": "トランザクションQRコード",
+ "transaction_received_cosignature_explain": "最小限必要な連署名を受信",
+ "transaction_status_confirmed": "承認済",
+ "transaction_status_partial": "パーシャル",
+ "transaction_status_unconfirmed": "未承認",
+ "transaction_too_long": "トランザクションが長すぎます!",
+ "transaction_type": "タイプ",
+ "transaction_type_title": "トランザクションタイプ",
+ "transaction_uri": "トランザクション URI",
+ "transaction_uri_explanation": "トランザクションのURI形式表現。この URI をコピーして、別のデバイスまたは他の人へ送信し、トランザクションをインポートして署名することができます。",
+ "transactions": "トランザクション",
+ "transactions_tab_confirmed": "承認済",
+ "transactions_tab_partial": "パーシャル",
+ "transactions_tab_unconfirmed": "未承認",
+ "transfer_target": "宛先",
+ "transferable": "転送可能",
+ "transmittable": "転送可",
+ "type": "タイプ",
+ "uncheck_all": "チェックを外す",
+ "unconfirmed": "未承認",
+ "unconfirmed_transaction": "未承認",
+ "unknown": "不明",
+ "unlink": "アンリンク",
+ "unlink_namespace_from": "{aliasTarget} を {namespaceName} からアンリンク",
+ "update_completed": "更新完了",
+ "upload_address_book_explanation": "有効なアドレス帳の json ファイルをアップロードします。アドレス帳がアップロードされると、アドレス帳のすべての連絡先が復元されます。",
+ "upload_file_message": "ここをクリックするか、ファイルをドラッグしてアップロードしてください",
+ "upload_qr_code": "QRコードをアップロード",
+ "upload_qr_code_explanation": "次の有効なQRコードのいずれかをアップロードまたはスキャンします。QRコードのタイプが特定されると、関連するアクションの次のステップに進みます。",
+ "upload_qr_code_explanation_type_contactqr": "アドレスQRコード",
+ "upload_qr_code_explanation_type_cosignatureqr": "連署QRコード",
+ "upload_qr_code_explanation_type_mnemonicqr": "ニーモニックQRコード",
+ "upload_qr_code_explanation_type_transactionqr": "請求QRコード",
+ "upload_qr_code_explanation_type_signedtransactionqr": "署名済みトランザクションQRコード",
+ "upload_qr_code_explanation_type_cosignaturesignedtransactionqr": "連署済みQRコード",
+ "upload_qr_code_invalid_type_message": "タイプ ({type}) は許可されていません!上記の有効なQRコードでもう一度お試しください。",
+ "upload_qr_tab_scan": "カメラでスキャン",
+ "upload_qr_tab_upload_image": "画像をアップロード",
+ "uploaded_qr_code": "アップロードしたQRコード",
+ "use_paper_and_pen_to_correctly_copy_mnemonics": "ペンと紙を使用して正しくニーモニックを書き写してください。このインストール/デバイスからアクセスできなくなった場合、アカウントとアセットを復元するためにニーモニックが必要です。",
+ "used_to_bind_a_account_address": "アカウントやモザイクにわかりやすい名前を付けます",
+ "user_aborted_transaction_confirmation": "ユーザーがトランザクションの承認を中止しました",
+ "value_too_big": "値が大きすぎます",
+ "variable_supply": "可変供給量",
+ "verify_backup_mnemonics": "次へ",
+ "verify_device_information": "デバイス内の情報を確認してください!",
+ "verify_Mnemonic_phrase": "確認",
+ "verify_mnemonics": "ニーモニック語群のバックアップ確認",
+ "version": "バージョン",
+ "view_metadata": "メタデータを表示",
+ "warning_already_a_cosignatory": "このアカウントは既に連署者です",
+ "warning_unknown_account": "このアカウントはネットワークに認識されていません。アドレスが正しく、アカウントが少なくとも1回のトランザクションを受信していることを確認してください",
+ "web_wallet_warning": "このウェブウォレットはデモンストレーション専用です!",
+ "welcome": "ようこそ",
+ "welcome_to_symbol": "ようこそ dHealth へ",
+ "word": "文字",
+ "x_seconds": "{seconds} 秒",
+ "activate_delegated_harvesting_message": "デリゲートハーベスティングを有効にするために、永続ハーベスティングメッセージでVRFキーを暗号化するにはパスワードが必要です。",
+ "activate_delegated_harvesting": "ハーベスティングを有効にする",
+ "create_persistent_message": "secure persistent harvesting メッセージを生成",
+ "Insert_your_node_linked_public_key": "ノード公開鍵を追加する",
+ "Insert_your_vrf_linked_public_key": "VRF公開鍵を追加",
+ "Insert_your_account_linked_public_key": "リモートアカウント公開鍵を追加する",
+ "not_linked": "リンクしていません",
+ "form_label_use_link_remote_public_key_icon": "リモート公開鍵をリンクするにはリンクボタンを押下してください",
+ "form_label_use_link_vrf_public_key_icon": "VRF公開鍵をリンクするにはリンクボタンを押下してください",
+ "form_label_use_link_node_public_key_icon": "ノード公開鍵をリンクするにはリンクボタンを押下してください",
+ "label_unlink_node_account_public_key": "ノード公開鍵のリンク解除",
+ "label_unlink_remote_account_public_key": "リモート公開鍵のリンク解除",
+ "label_unlink_vrf_account_public_key": "VRF公開鍵のリンク解除",
+ "please_link_your_public_key": "秘密鍵を生成するために、公開鍵を再リンクしてください",
+ "linking": "リンク中...",
+ "stoping": "停止中...",
+ "request_harvesting": "ハーベスティングをリクエスト",
+ "unlink_keys": "キーのリンクを解除する",
+ "requesting": "リクエスト中...",
+ "unlinking": "リンクを解除中...",
+ "remote_keys_linked": "アカウントにリモートキーとVRFキーがリンクされていて、デリゲートハーベスティングを有効化する場合は、ハーベスティングノードを選択してノードキーをリンクしてください。すでにハーベスティングしている場合は、ハーベスティングノードを選択してハーベスティングステータスを更新してください",
+ "encrypt_ledger_keys_on_sign": "Ledger ユーザとして、リモートアカウントとVRF秘密鍵を暗号化するためのパスワードが必要です",
+ "harvesting_status_not_detected": "ハーベスティング状態を検出できませんでした。ハーベスティングしているノードを選択してください。",
+ "click_to_retry": "クリックして再試行",
+ "symbol_node_cannot_connect": "dHealthノードに接続できません",
+ "current_node_is_not_available": "現在のノードは無効です。ノード #{0}/{1} を試してください。",
+ "nodes_unavailable_check_network_and": "ノード (#{0}/{1}) は現在無効です。ネットワーク接続や設定を確認してください。",
+ "copyright": "Copyright © 2021 dHealth Network",
+ "address_list_cannot_be_empty": "リストから最低でもオプトインされていないアカウントを 1 つ選択する必要があります。",
+ "opt_in_account_notification": "このアカウントは古い派生によって取得されています。資産をシードアカウントへ移動することを推奨します。",
+ "ws_connection_failed": "ウォレットは、シンボルチェーン上のアカウントのアクティビティを監視できません。別のノードを選択してみてください。",
+ "offline_transactions_title": "オフライントランザクション",
+ "offline_transactions_text1": "完璧な安全性のために、インターネットに接続したことがないコンピュータを使用してください。",
+ "offline_transactions_text2": "NEMノードからモザイクおよびマルチシグ情報を取得するためにインターネット接続が必要なので、単純なトランザクションのみを作成できます。",
+ "offline_transactions_text3": "右側パネルの\"署名\"ボタンをクリックすると、署名済みトランザクションが表示されます。",
+ "offline_transactions_text4": "署名済みトランザクションは不変であり、デフォルト期限の24時間以内にネットワークへアナウンスした場合にのみ有効になります。",
+ "offline_transactions_prepare_transaction": "トランザクションを準備",
+ "offline_transactions_download": "QRをダウンロード",
+ "offline_transactions_success": "トランザクション署名に成功",
+ "offline_transactions_success_text": "このQRコードをダウンロードするか、上記のJSONテキストをコピーして、オンラインウォレットまたは symbol-cli でブロードキャストできます。",
+ "signed_transaction_qr": "署名済みトランザクションQR",
+ "go_to_offline_transactions": "オフライントランザクションへ",
+ "go_to_login_offline": "ログインへ",
+ "cosign_transaction": "トランザクションに連署",
+ "offline_transactions_import_qr": "連署者をインポート",
+ "offline_transactions_chose_account": "トランザクションに署名",
+ "offline_transactions_import_qr_title": "署名する連署名トランザクションをインポート",
+ "offline_transaction_confirm_import": "トランザクションに署名するために次のステップへ進む",
+ "sign": "署名",
+ "hash": "ハッシュ",
+ "form_label_import_placeholder": "トランザクションペイロードをペースト",
+ "payload_not_valid": "ペイロードは不正です",
+ "import_payload": "ペイロードをインポート",
+ "import_payload_text": "symbol-cli が生成したトランザクションのペイロードを入力することもできます。",
+ "ledger_available_on_standalone_app": "Ledgerを使用するには、デスクトップネイティブアプリをダウンロードしてください。",
+ "select_custom_node": "カスタムノードを選択",
+ "delegated_harvesting_request_failed": "デリゲートハーベスティングリクエストが失敗しています。ハーベスティングを停止して、別のノードを試してください。",
+ "create_vrf_public_key": "VRF公開鍵を作成する",
+ "create_remote_public_key": "リモート公開鍵を作成する",
+ "generate_random_public_key": "キーの生成",
+ "import_key_manually": "キーを手動でインポートする",
+ "key_type": "キータイプ"
+}
diff --git a/src/language/zh-CN.json b/src/language/zh-CN.json
new file mode 100644
index 0000000..9e44d79
--- /dev/null
+++ b/src/language/zh-CN.json
@@ -0,0 +1,1112 @@
+{
+ "about_app_release": "版本",
+ "about_app_url": "主页",
+ "about_default_node": "默认节点",
+ "about_dependencies": "依赖",
+ "about_generation_hash": "生成哈希",
+ "about_network": "网络",
+ "about_network_type": "网络类型",
+ "about_rxjs_version": "RxJs库",
+ "about_sdk_version": "Symbol SDK",
+ "about_typescript_version": "Typescript",
+ "about_vue_version": "Vue框架",
+ "absolute": "绝对",
+ "access_ledger": "使用Ledger登录",
+ "access_my_profile": "进入我的账户",
+ "access_trezor": "使用Trezor登录",
+ "access_trezor_account": "连接你的Trezor钱包,并进入操作",
+ "access_your_ledger_account": "连接你的Ledger钱包,并进入操作",
+ "account_address": "钱包地址",
+ "ACCOUNT_LINK": "帐户连结",
+ "account_management": "钱包管理",
+ "account_name": "钱包名",
+ "account_name_input_error": "钱包名输入错误!",
+ "account_network_does_not_match_current_network_type": "钱包网络与当前节点网络不匹配。",
+ "account_network_type_does_not_match_current_network_type": "钱包网络类型与当前节点网络类型不匹配。",
+ "account_public_key": "公钥",
+ "account_restrictions": "账户限制",
+ "account_restrictions_tab_address": "地址限制",
+ "account_restrictions_tab_mosaic": "马赛克限制",
+ "account_restrictions_tab_operation": "操作限制",
+ "accounts": "帳目",
+ "accounts_backup_keystore_explain_p1": "点击右侧按钮,下载加密密钥文件来备份您的私钥和公钥,",
+ "accounts_backup_keystore_explain_p2": "系统将要求您解锁您的帐户,然后将自动开始下载。",
+ "accounts_backup_mnemonic_explain_p1": "点击右侧按钮,查看您的助记词;",
+ "accounts_backup_mnemonic_explain_p2": "系统将要求您解锁您的帐户,然后将显示助记",
+ "accounts_backup_mnemonic_explain_p3": "请务必将以下 {num} 个单词备份到安全的地方; 这 {num} 个单词代表你的助记词,以后可以用来导入你的钱包和它的子钱包。",
+ "accounts_backup_mnemonic_explain_qrcode": "请务必将以下二维码备份在安全的地方。此二维码可用于稍后导入您的钱包及其子钱包。",
+ "accounts_backup_qrcode_explain_p1": "点击右侧按钮,下载二维码来备份您的助记词;",
+ "accounts_backup_qrcode_explain_p2": "系统将要求您解锁您的帐户,然后将自动开始下载。",
+ "accounts_backup_tile_description": "立即备份钱包",
+ "accounts_backup_tile_keystore": "下载密匙",
+ "accounts_backup_tile_keystore_desc": "密匙文件下载",
+ "accounts_backup_tile_mnemonic": "查看助记词",
+ "accounts_backup_tile_mnemonic_desc": "密码显示",
+ "accounts_backup_tile_title": "助记词二维码",
+ "accounts_backup_title": "安全与备份",
+ "accounts_backup_title_keystore": "下载密匙",
+ "accounts_backup_title_mnemonic": "查看助记词",
+ "accounts_backup_title_qrcode": "备份助记词",
+ "accounts_backup_transactions": "将交易清单汇出至CSV档案",
+ "accounts_backup_transactions_description": "下载所有交易信息,保存在本地并查看,即使您没有互联网连接",
+ "accounts_change_password_description": "更改密码",
+ "accounts_change_password_title": "修改密码",
+ "accounts_create_invoice": "创建发票",
+ "accounts_flags_default_account": "默认钱包",
+ "accounts_flags_default_account_explain": "这是一个默认钱包",
+ "accounts_flags_known_by_network": "公共账户",
+ "accounts_flags_multisig": "多重签名",
+ "accounts_flags_multisig_explain": "这是一个多签钱包",
+ "accounts_flags_simple": "基本账户",
+ "accounts_flags_simple_explain": "这是一个基本钱包",
+ "accounts_flags_unknown_by_network": "私人帐户",
+ "accounts_harvesting_remote_explain_p1": "点击右侧的按钮来配置远程帐户,这将允许您的帐户稍后激活委托收益",
+ "accounts_harvesting_remote_explain_p2": "您将解锁您的帐户,然后可查看用于设置远程帐户以进行收益的选项。",
+ "accounts_harvesting_request_explain_p1": "点击右侧的按钮发送收益委托请求,如果节点批准,这将激活您的帐户收益",
+ "accounts_harvesting_request_explain_p2": "您将解锁您的帐户,然后可查看用于向对等节点发送收益委托请求的选项。",
+ "accounts_harvesting_tile_remote": "远程帐户",
+ "accounts_harvesting_tile_remote_description": "重要性传输",
+ "accounts_harvesting_tile_request": "委托请求",
+ "accounts_harvesting_tile_request_description": "开始收益",
+ "accounts_harvesting_title_remote": "设置远程帐户",
+ "accounts_harvesting_title_request": "发送委托请求",
+ "accounts_label_flags": "标志",
+ "accounts_links_explorer": "区块浏览器",
+ "accounts_links_faucet": "开关",
+ "accounts_setup_harvesting_description": "配置委托收益",
+ "accounts_setup_harvesting_title": "设置收益",
+ "accounts_share_qr_code": "共享详情信息",
+ "accounts_subtitle_account_links": "指南链接",
+ "accounts_view_dashboard": "在仪表板中查看",
+ "accounts_view_explorer_description": "在浏览器中打开",
+ "accounts_view_multisig": "多重签名",
+ "accounts_view_open_faucet": "开启收益开关",
+ "action": "行为",
+ "action_label_alias_link": "绑定别名",
+ "action_label_alias_unlink": "解绑别名",
+ "action_label_extend_duration": "延时",
+ "action_label_modify_supply": "修改供应量",
+ "activate": "启用",
+ "activating": "激活...",
+ "add_account_failed": "添加账户失败, 原因: {reason}",
+ "add_account_restrictions": "添加帐户限制",
+ "add_address_restrictions": "新地址限制",
+ "add_contact": "增加联系人",
+ "add_metadata": "添加元数据",
+ "add_mosaic": "添加马赛克",
+ "add_mosaic_restrictions": "新的马赛克限制",
+ "add_node": "添加节点",
+ "add_operation_restrictions": "新操作限制",
+ "address": "地址",
+ "address_alias_not_exist": "地址别名不存在",
+ "address_format_error": "地址格式错误",
+ "address_invalid": "地址错误",
+ "address_not_valid": "委托人地址无效",
+ "address_qr_code": "地址二维码",
+ "address_to_interact_with": "与钱包互动的地址",
+ "address_unknown": "未知地址,此地址尚未在网络中发送任何交易。",
+ "address_unknown_by_network": "该地址尚未被网络知晓, 建议您向本地址发送一笔交易。",
+ "aggregate_send": "发送聚合",
+ "alias": "别名",
+ "alias_name_format_error": "别名格式错误",
+ "aliases": "别名",
+ "all_nodes_cannot_be_deleted": "节点列表不可为空",
+ "allow": "允许",
+ "amount": "金额",
+ "amount_asset": "数量",
+ "amount_can_not_be_less_than_0": "马赛克交易数量不可小于0",
+ "any_information_cannot_be_empty": "任意信息不能为空",
+ "approval_greater_than_cosignatories": "最小批准所需余项比可用余项多 {delta}。请添加余数或减少最小批准号。",
+ "article_by": "创作者 {creator}",
+ "assets": "资产",
+ "at_block": "在 {blockNumber} 块高",
+ "automatically_generated_by_node_url": "通过输入的节点URL自动形成",
+ "back": "返回",
+ "backup_address_book": "备份通讯录",
+ "backup_mnemonic": "备份助记词",
+ "backup_mnemonic_phrase": "备份助记词",
+ "backup_mnemonic_words": "备份好助记词",
+ "backup_profile": "备份个人资料",
+ "backup_profile_explanation_desc": "下载您的个人资料的纸本(PDF)副本。您在此配置文件中的所有帐户都将列在下载的文件中。当您需要在其他设备或同一设备上还原所有帐户时,此备份文件将使您能够使用。 请保存在安全的地方,不要与第三方共享,因为它存储了高度敏感的信息。",
+ "backup_profile_explanation_title": "将您的个人资料备份为纸钱包",
+ "balance": "余额",
+ "block": "块",
+ "block_height": "块高",
+ "blocks_made": "积木",
+ "button_add_account": "增加或导入钱包",
+ "button_download": "下载",
+ "button_download_paper_wallet": "下载纸钱包",
+ "button_download_qr": "下载",
+ "button_understand_title": ">>得到它了",
+ "cancel": "取消",
+ "chain_height": "区块高度",
+ "choose_network": "选择网络",
+ "choose_profile_name_and_password": "创建账户和密码",
+ "clear_staged_transactions": "取消交易",
+ "click_to_cosign": "点击联署",
+ "click_to_load": "点击以加载数据",
+ "close": "关闭",
+ "co_signers_amount_less_than_0": "共签人数不可小于1",
+ "confirm": "确认",
+ "confirm_backup": "确认备份",
+ "CONFIRMATION": "确认书",
+ "confirmation_title": "确认书",
+ "confirmations_height": "高度",
+ "confirmed_transaction": "已确认事务",
+ "confirmPassword": "确认密码",
+ "connect_ledger_prompt": "连接Ledger",
+ "connect_ledger_title": "连接到Ledger硬件钱包",
+ "contact_address": "联系地址",
+ "contact_email": "电子邮件",
+ "contact_information": "联系信息",
+ "contact_name": "名称",
+ "contact_notes": "笔记",
+ "contact_phone": "电话",
+ "contact_qr_action_desc": "单击继续将重定向到转移页面以转移到该收件人。",
+ "contact_qr_code": "联系二维码",
+ "continue": "继续",
+ "copy_failed": "复制失败",
+ "copy_mnemonic": "复制助记词",
+ "cosignatory_of": "共同签字人",
+ "cosignature_added": "已接收联署",
+ "cosignature_qr_action_desc": "继续到交易详细信息页面以签名。",
+ "create_a_new_account": "创建一个新账户",
+ "create_a_new_profile": "建立一个新的账户",
+ "create_lock_check_pw_remind": "两次密码不一致",
+ "create_lock_pw_remind": "密码设置错误",
+ "create_lock_pw_txt_remind": "设置密码提示错误",
+ "create_mnemonic": "创建新助记词账户",
+ "create_profile": "创建钱包",
+ "create_profile_failed": "创建钱包失败, 原因: {reason}",
+ "create_sub_namespace": "创建子命名空间",
+ "creation_successful": "恭喜,创建账户成功!",
+ "current_cosigner_matches_current_account": "您不能将当前选择的帐户添加为其自身的共同签名人.",
+ "current_endpoint": "当前节点",
+ "current_network": "当前网络类型",
+ "current_profile_network": "当前个人资料网络",
+ "current_speed": "当前网速",
+ "current_validity": "当前有效期",
+ "deadline": "截止时间",
+ "decrease": "减少",
+ "decrypt_message": "解密",
+ "define": "定义",
+ "delegated_harvesting_info": "委托收获允许使用帐户的重要性得分来创建新区块并获得奖励\n \n无需在本地运行节点。\n您可以将委派的收获请求发送到选定的节点或交换\n \n到另一个。",
+ "delete": "删除",
+ "delete_account": "删除帐户",
+ "delete_account_confirmation_message": "您确定要删除“ {accountName}”吗?\n您可能需要先备份,然后再继续。",
+ "delete_account_confirmation_title": "删除帐户?",
+ "delete_profile_confirmation_title": "删除档案",
+ "delete_profile_confirmation_message": "Deleting a profile is not recommended without a backup. Loss of funds may occur. Are you sure you would like to delete \"{profileName}\"?",
+ "delete_profile_confirmation_checkbox": "Yes, I would like to delete this profile.",
+ "delete_confirmation_message": "您确定要删除吗?",
+ "delete_contact": "删除联络人",
+ "delete_contact_confirmation_message": "您确定要删除“ {contactName}”吗?",
+ "delete_contact_confirmation_title": "删除联系人?",
+ "delete_profile": "删除档案",
+ "delta": "绝对值",
+ "description": "描述",
+ "direction": "方向",
+ "display_mnemonic": "显示助记词",
+ "display_mnemonic_qr_code": "显示助记词二维码",
+ "divisibility": "可分割性",
+ "divisibility_can_not_less_than_0": "可分性不可小于零",
+ "divisibility_can_not_more_than_6": "可分性不可大于6",
+ "divisibility_invalid": "当前值与可分性位于区间 [0-6] 不匹配",
+ "do_not_disclose": "请不要透露你备份的记助词,任何人有了记助词将可以彻底掌控其下的钱包资产。",
+ "do_not_disclose_title": "保持私密",
+ "do_not_disclose_title_mnemonic": "备份助记密码",
+ "do_not_share_mnemonics_with_anyone": "不要和任何人分享助记词",
+ "download": "下载",
+ "duration": "持续时间",
+ "duration_can_not_less_than_0": "持续时间不可小于零",
+ "duration_can_not_more_than_1_years": "持续时间不可大于1年",
+ "duration_can_not_more_than_10_years": "持续时间不可大于10年",
+ "duration_permanent": "是否永久存在",
+ "edit_object": "编辑 {objectName}",
+ "edit_metadata": "编辑元数据",
+ "encrypt_message": "加密消息",
+ "encrypted_message": "加密的消息",
+ "encrypted_message_empty_error": "加密消息内容不可为空",
+ "end_finalization_epoch": "结束敲定时代",
+ "endpoint": "节点",
+ "enter_your_private_key": "输入您的私钥",
+ "error_account_name_already_exists": "该帐户名已经存在。请重新输入唯一的帐户名。",
+ "error_contact_already_exists": "该联系人已經存在",
+ "error_delete_all_peers": "不能删除所有节点",
+ "error_incorrect_field": "{_field_} 字段不正确",
+ "error_incorrect_url": "无效URL地址",
+ "error_invalid_password": "无效密码",
+ "error_new_namespace_duration_max_value": "新的名称空间持续时间不能大于 {maxValue}",
+ "error_new_password_format": "密码至少应该包含一个字母和一个数字",
+ "error_peer_connection_went_wrong": "连接到节点{peerUrl}时发生错误超时",
+ "error_peer_unreachable": "此节点暂不可用",
+ "error_profile_does_not_exist": "钱包不存在",
+ "error_too_many_seed_accounts": "子帐户数量不能超过{maxSeedAccountsNumber}个",
+ "estimated_period_of_validity": "预估有效期",
+ "estimated_rental_fee": "预估租金",
+ "existing_profile": "已有账户",
+ "expired_for": "已过期",
+ "expires_in": "有效期限",
+ "explorer_url": "浏览器 URL",
+ "export_mnemonic": "导出助记词",
+ "export_transactions": "出口交易",
+ "fee": "费用",
+ "fee_can_not_be_less_than_0": "费用不可小于0",
+ "fee_speed_fast": "快",
+ "fee_speed_fastest": "最快",
+ "fee_speed_free": "免费",
+ "fee_speed_highest": "最高费用",
+ "fee_speed_median": "平均费用",
+ "fee_speed_normal": "普通",
+ "fee_speed_slow": "慢",
+ "fee_speed_slowest": "最慢",
+ "fees_collected": "收费",
+ "fees_earned": "赚到的钱",
+ "filter_peers": "节点过滤",
+ "finish": "完成",
+ "finished": "完成",
+ "flags_divisibility": "确定可以分割马赛克的小数点位置。可分割性必须在0和6之间",
+ "flags_duration_permanent": "如果选择,马赛克将永远不会过期",
+ "flags_restrictable": "如果选择,马赛克创建者可以配置自定义限制",
+ "flags_supply": "马赛克总供应量必须在0和9 000,000,000,000,000个原子单位之间",
+ "flags_transferable": "如果选择,马赛克可以在任意帐户之间转移",
+ "flags_variable_supply": "如果选择,马赛克供应量将是可变的",
+ "form_label_account_to_be_converted": "要转换的帐户",
+ "form_label_add_cosignatory": "添加共签人",
+ "form_label_additional_duration": "附加持续时间",
+ "form_label_alias_type": "别名类型",
+ "form_label_by_account": "按帐户",
+ "form_label_choose_namespace": "选择命名空间",
+ "form_label_cosignatory_modifications": "共签修改",
+ "form_label_current_supply": "现有供应量",
+ "form_label_default_account": "默认钱包",
+ "form_label_default_max_fee": "默认最大费用",
+ "form_label_description_min_approval": "从多签中添加某人或完成此多签交易所需的签名数",
+ "form_label_description_min_removal": "移除其他共签人的最小所需签名数",
+ "form_label_duration": "持续时间",
+ "form_label_language": "默认语言",
+ "form_label_link_address": "绑定地址",
+ "form_label_link_mosaic": "绑定马赛克",
+ "form_label_max_fee": "最高费用",
+ "form_label_min_approval": "最小签名数",
+ "form_label_min_removal": "最小删除数",
+ "form_label_multisig_account": "多重签名帐户",
+ "form_label_multisig_accounts": "多重签名帐户",
+ "form_label_multisig_current_info": "联署人",
+ "form_label_multisig_operation_type": "操作类型",
+ "form_label_namespace_name": "空间名",
+ "form_label_network_node_url": "输入收益节点URL(例: http://localhost:3000)",
+ "form_label_network_custom_node": "输入收益节点URL",
+ "form_label_new_absolute_supply": "新增绝对供应量",
+ "form_label_new_account_name": "新钱包名称",
+ "form_label_new_account_type": "选择钱包类型",
+ "form_label_new_contact_address": "新的联络地址",
+ "form_label_new_contact_name": "新联络人姓名",
+ "form_label_new_cosignatories": "新增联署人",
+ "form_label_new_expiration_time": "新的过期时间",
+ "form_label_new_min_approval": "最低审核数",
+ "form_label_new_min_removal": "最低移除数",
+ "form_label_new_password": "请输入密码",
+ "form_label_new_password_confirm": "确认新密码",
+ "form_label_new_password_hint": "密码提示",
+ "form_label_new_supply": "新供应量",
+ "form_label_parent_namespace": "父命名空间",
+ "form_label_password": "锁密码",
+ "form_label_password_hint": "请输入当前的个人资料密码",
+ "form_label_private_key": "请输入私钥",
+ "form_label_registration_type": "命名空间类型",
+ "form_label_remove_cosignatory": "移除联署人",
+ "form_label_removed_cosignatory": "删除签字人",
+ "form_label_removed_cosignatory_tooltip": "交易中仅允许一次委托人移除",
+ "form_label_restriction_type_tooltip": "每个限制类型的帐户只能配置一个阻止或允许列表",
+ "form_label_scoped_metadata_key": "作用域元数据密钥",
+ "form_label_scoped_metadata_key_hint": "元数据键范围(更新或添加?)",
+ "form_label_supply_delta": "改变供应数量",
+ "form_label_supply_direction": "改变供应量管理",
+ "form_label_target_account": "目标账户",
+ "form_label_target_account_hint": "请输入目标帐户地址或公钥",
+ "form_label_target_mosaic_id": "目标马赛克ID",
+ "form_label_target_namespace_id": "目标命名空间ID",
+ "form_label_value": "值",
+ "form_label_value_hint": "链接到标识符的值是一个字符串,最多1024个字符",
+ "from_qr_code": "从二维码",
+ "from_to_action": "发起/接受(行为)",
+ "Failure_Core_Past_Deadline": "验证失败,因为截止日期已过",
+ "Failure_Core_Future_Deadline": "验证失败,因为最后期限太长了",
+ "Failure_Core_Insufficient_Balance": "验证失败,因为帐户余额不足",
+ "Failure_Core_Too_Many_Transactions": "验证失败,因为块中有太多事务",
+ "Failure_Core_Nemesis_Account_Signed_After_Nemesis_Block": "验证失败,创世块后无法验证创世帐户。",
+ "Failure_Core_Wrong_Network": "验证失败,因为该实体指定了错误的网络",
+ "Failure_Core_Invalid_Address": "验证失败,因为地址无效",
+ "Failure_Core_Invalid_Version": "验证失败,因为实体版本无效",
+ "Failure_Core_Invalid_Transaction_Fee": "验证失败,因为交易费无效",
+ "Failure_Core_Block_Harvester_Ineligible": "验证失败,因为不合格的收割机收割了一块木块",
+ "Failure_Core_Zero_Address": "验证失败,因为地址为零",
+ "Failure_Core_Zero_Public_Key": "验证失败,因为公钥为零",
+ "Failure_Core_Nonzero_Internal_Padding": "验证失败,因为内部填充不为零",
+ "Failure_Core_Address_Collision": "验证失败,因为检测到地址冲突",
+ "Failure_Core_Importance_Block_Mismatch": "验证失败,因为该块与重要块的模式不匹配",
+ "Failure_Core_Unexpected_Block_Type": "验证失败,因为块类型是意外的",
+ "Failure_Core_Invalid_Link_Action": "验证失败,因为链接操作无效",
+ "Failure_Core_Link_Already_Exists": "验证失败,因为主帐户已经链接到另一个帐户了,",
+ "Failure_Core_Inconsistent_Unlink_Data": "验证失败,因为取消链接数据与现有帐户链接不一致。",
+ "Failure_Core_Invalid_Link_Range": "验证失败,因为链接范围无效",
+ "Failure_Core_Too_Many_Links": "验证失败,因为主帐户具有指定类型的过多链接",
+ "Failure_Signature_Not_Verifiable": "验证失败,因为签名验证失败",
+ "Failure_AccountLink_Link_Already_Exists": "验证失败,因为主帐户已经链接到另一个帐户了,",
+ "Failure_AccountLink_Inconsistent_Unlink_Data": "验证失败,因为取消链接的数据与现有的帐户链接不一致",
+ "Failure_AccountLink_Unknown_Link": "验证失败,因为主帐户未链接到另一个帐户",
+ "Failure_AccountLink_Remote_Account_Ineligible": "验证失败,因为链接正试图将不合格的帐户转换为远程帐户",
+ "Failure_AccountLink_Remote_Account_Signer_Prohibited": "验证失败,因为不允许远程签署交易",
+ "Failure_AccountLink_Remote_Account_Participant_Prohibited": "验证失败,因为不允许远程参与交易",
+ "Failure_Aggregate_Too_Many_Transactions": "验证失败,因为聚合交易太多”",
+ "Failure_Aggregate_No_Transactions": "验证失败,因为聚合没有任何交易",
+ "Failure_Aggregate_Too_Many_Cosignatures": "验证失败,因为聚合具有太多的共同签名",
+ "Failure_Aggregate_Redundant_Cosignatures": "验证失败,因为至少一个委托人不符合资格",
+ "Failure_Aggregate_Ineligible_Cosignatories": "验证失败,因为缺少至少一个必需的共同签名",
+ "Failure_Aggregate_Missing_Cosignatures": "验证失败,因为缺少至少一个必需的共同签名",
+ "Failure_Aggregate_Transactions_Hash_Mismatch": "验证失败,因为聚合交易哈希与计算值不匹配",
+ "Failure_LockHash_Invalid_Mosaic_Id": "验证失败,因为锁不允许指定的镶嵌",
+ "Failure_LockHash_Invalid_Mosaic_Amount": "验证失败,因为锁不允许指定的数量",
+ "Failure_LockHash_Hash_Already_Exists": "验证失败,因为缓存中已经存在哈希",
+ "Failure_LockHash_Unknown_Hash": "验证失败,因为缓存中不存在哈希",
+ "Failure_LockHash_Inactive_Hash": "验证失败,因为哈希处于非活动状态",
+ "Failure_LockHash_Invalid_Duration": "验证失败,因为持续时间太长”",
+ "Failure_LockSecret_Invalid_Hash_Algorithm": "验证失败,因为锁类型密钥的哈希算法无效",
+ "Failure_LockSecret_Hash_Already_Exists": "验证失败,因为缓存中已经存在哈希",
+ "Failure_LockSecret_Proof_Size_Out_Of_Bounds": "验证失败,因为证明过小或过大",
+ "Failure_LockSecret_Secret_Mismatch": "验证失败,因为机密与证明不匹配",
+ "Failure_LockSecret_Unknown_Composite_Key": "验证失败,因为组合键未知",
+ "Failure_LockSecret_Inactive_Secret": "由于密码不活跃,验证失败",
+ "Failure_LockSecret_Hash_Algorithm_Mismatch": "验证失败,因为哈希算法不匹配",
+ "Failure_LockSecret_Invalid_Duration": "验证失败,因为持续时间太长”",
+ "Failure_Metadata_Value_Too_Small": "验证失败,因为元数据值太小",
+ "Failure_Metadata_Value_Too_Large": "验证失败,因为元数据值太大",
+ "Failure_Metadata_Value_Size_Delta_Too_Large": "验证失败,因为元数据值大小增量的大小大于值大小",
+ "Failure_Metadata_Value_Size_Delta_Mismatch": "V验证失败,因为元数据值大小增量与基于当前状态的预期值不匹配",
+ "Failure_Metadata_Value_Change_Irreversible": "验证失败,因为元数据值更改(截断)是不可逆的",
+ "Failure_Mosaic_Invalid_Duration": "验证失败,因为持续时间具有无效值",
+ "Failure_Mosaic_Invalid_Name": "验证失败,因为名称无效",
+ "Failure_Mosaic_Name_Id_Mismatch": "验证失败,因为名称和ID不匹配",
+ "Failure_Mosaic_Expired": "验证失败,因为父项已过期",
+ "Failure_Mosaic_Owner_Conflict": "验证失败,因为父所有者与子所有者发生冲突",
+ "Failure_Mosaic_Id_Mismatch": "验证失败,因为该ID不是从签名者和随机数生成的预期ID",
+ "Failure_Mosaic_Parent_Id_Conflict": "验证失败,因为现有的父ID与提供的父ID不匹配",
+ "Failure_Mosaic_Invalid_Property": "验证失败,因为镶嵌属性无效",
+ "Failure_Mosaic_Invalid_Flags": "验证失败,因为镶嵌标志无效",
+ "Failure_Mosaic_Invalid_Divisibility": "验证失败,因为镶嵌的可分割性无效",
+ "Failure_Mosaic_Invalid_Supply_Change_Action": "验证失败,因为镶嵌供应更改操作无效",
+ "Failure_Mosaic_Invalid_Supply_Change_Amount": "验证失败,因为镶嵌供应更改量无效",
+ "Failure_Mosaic_Invalid_Id": "验证失败,因为镶嵌ID无效",
+ "Failure_Mosaic_Modification_Disallowed": "验证失败,因为不允许修改镶嵌",
+ "Failure_Mosaic_Modification_No_Changes": "验证失败,因为镶嵌修改不会导致任何更改",
+ "Failure_Mosaic_Supply_Immutable": "验证失败,因为镶嵌供应是不可变的",
+ "Failure_Mosaic_Supply_Negative": "验证失败,因为生成的镶嵌物为负数",
+ "Failure_Mosaic_Supply_Exceeded": "验证失败,因为生成的镶嵌物供应超出了最大允许值",
+ "Failure_Mosaic_Non_Transferable": "验证失败,因为镶嵌图不可转让",
+ "Failure_Mosaic_Max_Mosaics_Exceeded": "验证失败,因为镶嵌的信誉将超过允许帐户拥有的不同镶嵌的最大值。",
+ "Failure_Mosaic_Required_Property_Flag_Unset": "验证失败,因为镶嵌图未设置至少一个必需的属性标志",
+ "Failure_Multisig_Account_In_Both_Sets": "验证失败,因为指定同时添加和删除帐户",
+ "Failure_Multisig_Multiple_Deletes": "验证失败,因为存在多次删除",
+ "Failure_Multisig_Redundant_Modification": "验证失败,因为修改是多余的",
+ "Failure_Multisig_Unknown_Multisig_Account": "验证失败,因为帐户不在多签名缓存中",
+ "Failure_Multisig_Not_A_Cosignatory": "验证失败,因为不存在要删除的帐户",
+ "Failure_Multisig_Already_A_Cosignatory": "验证失败,因为要添加的帐户已经是一个委托人了,",
+ "Failure_Multisig_Min_Setting_Out_Of_Range": "验证失败,因为新的最小设置超出范围",
+ "Failure_Multisig_Min_Setting_Larger_Than_Num_Cosignatories": "验证失败,因为最小设置大于共同签署者的数量",
+ "Failure_Multisig_Invalid_Modification_Action": "验证失败,因为修改操作无效",
+ "Failure_Multisig_Max_Cosigned_Accounts": "验证失败,因为委托人已经共同委托了最大帐户数",
+ "Failure_Multisig_Max_Cosignatories": "验证失败,因为multisig帐户已经具有最大数量的共同签名者",
+ "Failure_Multisig_Loop": "验证失败,因为创建了多重签名循环",
+ "Failure_Multisig_Max_Multisig_Depth": "验证失败,因为超过了最大多重签名深度",
+ "Failure_Multisig_Operation_Prohibited_By_Account": "验证失败,因为多签名帐户不允许操作",
+ "Failure_Namespace_Invalid_Duration": "验证失败,因为持续时间具有无效值",
+ "Failure_Namespace_Invalid_Name": "验证失败,因为名称无效",
+ "Failure_Namespace_Name_Id_Mismatch": "验证失败,因为名称和ID不匹配",
+ "Failure_Namespace_Expired": "验证失败,因为父项已过期",
+ "Failure_Namespace_Owner_Conflict": "验证失败,因为父所有者与子所有者发生冲突",
+ "Failure_Namespace_Id_Mismatch": "验证失败,因为该ID不是从签名者和随机数生成的预期ID",
+ "Failure_Namespace_Invalid_Registration_Type": "验证失败,因为名称空间注册类型无效",
+ "Failure_Namespace_Root_Name_Reserved": "验证失败,因为根名称空间具有保留名称",
+ "Failure_Namespace_Too_Deep": "验证失败,因为结果命名空间将超过允许的最大命名空间深度",
+ "Failure_Namespace_Unknown_Parent": "由于名称空间父级未知,验证失败",
+ "Failure_Namespace_Already_Exists": "验证失败,因为名称空间已经存在",
+ "Failure_Namespace_Already_Active": "验证失败,因为名称空间已经处于活动状态",
+ "Failure_Namespace_Eternal_After_Nemesis_Block": "验证失败,因为在nemesis块之后收到了永恒的名称空间",
+ "Failure_Namespace_Max_Children_Exceeded": "验证失败,因为超过了根名称空间的最大子代数",
+ "Failure_Namespace_Alias_Invalid_Action": "验证失败,因为别名操作无效",
+ "Failure_Namespace_Unknown": "验证失败,因为名称空间不存在",
+ "Failure_Namespace_Alias_Already_Exists": "验证失败,因为名称空间已经链接到别名",
+ "Failure_Namespace_Unknown_Alias": "验证失败,因为名称空间未链接到别名",
+ "Failure_Namespace_Alias_Inconsistent_Unlink_Type": "验证失败,因为取消链接类型与现有别名不一致",
+ "Failure_Namespace_Alias_Inconsistent_Unlink_Data": "验证失败,因为取消链接数据与现有别名不一致。",
+ "Failure_Namespace_Alias_Invalid_Address": "验证失败,因为别名地址无效",
+ "Failure_RestrictionAccount_Invalid_Restriction_Flags": "验证失败,因为帐户限制标志无效",
+ "Failure_RestrictionAccount_Invalid_Modification_Action": "验证失败,因为修改操作无效",
+ "Failure_RestrictionAccount_Invalid_Modification_Address": "验证失败,因为修改地址无效",
+ "Failure_RestrictionAccount_Modification_Operation_Type_Incompatible": "由于操作类型不兼容,验证失败",
+ "Failure_RestrictionAccount_Redundant_Modification": "验证失败,因为修改是多余的",
+ "Failure_RestrictionAccount_Invalid_Modification": "验证失败,因为值不在容器中",
+ "Failure_RestrictionAccount_Modification_Count_Exceeded": "验证失败,因为交易有太多修改",
+ "Failure_RestrictionAccount_No_Modifications": "验证失败,因为事务没有修改",
+ "Failure_RestrictionAccount_Values_Count_Exceeded": "验证失败,因为所产生的帐户限制包含太多值",
+ "Failure_RestrictionAccount_Invalid_Value": "验证失败,因为帐户限制值无效",
+ "Failure_RestrictionAccount_Address_Interaction_Prohibited": "验证失败,因为不允许交易中涉及的地址进行交互",
+ "Failure_RestrictionAccount_Mosaic_Transfer_Prohibited": "验证失败,因为收件人禁止马赛克传输",
+ "Failure_RestrictionAccount_Operation_Type_Prohibited": "验证失败,因为签名者不允许启动操作类型",
+ "Failure_RestrictionMosaic_Invalid_Restriction_Type": "验证失败,因为镶嵌限制类型无效",
+ "Failure_RestrictionMosaic_Previous_Value_Mismatch": "验证失败,因为指定的先前值与当前值不匹配",
+ "Failure_RestrictionMosaic_Previous_Value_Must_Be_Zero": "验证失败,因为指定的先前值不为零",
+ "Failure_RestrictionMosaic_Max_Restrictions_Exceeded": "验证失败,因为将超过最大限制数",
+ "Failure_RestrictionMosaic_Cannot_Delete_Nonexistent_Restriction": "验证失败,因为无法删除不存在的限制",
+ "Failure_RestrictionMosaic_Unknown_Global_Restriction": "验证失败,因为所需的全局限制不存在",
+ "Failure_RestrictionMosaic_Invalid_Global_Restriction": "验证失败,因为镶嵌具有无效的全局限制",
+ "Failure_RestrictionMosaic_Account_Unauthorized": "验证失败,因为帐户缺少适当的权限来移动镶嵌图",
+ "Failure_Transfer_Message_Too_Large": "验证失败,因为消息太大",
+ "Failure_Transfer_Out_Of_Order_Mosaics": "验证失败,因为镶嵌顺序不正确",
+ "Failure_Chain_Unlinked": "验证失败,因为收到的块未与现有链链接",
+ "Failure_Chain_Block_Not_Hit": "验证失败,因为收到不是命中的块",
+ "Failure_Chain_Block_Inconsistent_State_Hash": "验证失败,因为收到的块具有不一致的状态哈希",
+ "Failure_Chain_Block_Inconsistent_Receipts_Hash": "验证失败,因为收到的收据哈希不一致的块",
+ "Failure_Chain_Block_Invalid_Vrf_Proof": "验证失败,因为Vrf证明无效",
+ "Failure_Chain_Block_Unknown_Signer": "验证失败,因为块签名者未知",
+ "Failure_Chain_Unconfirmed_Cache_Too_Full": "验证失败,因为未确认的缓存太满了",
+ "Failure_Consumer_Empty_Input": "验证失败,因为使用者输入为空",
+ "Failure_Consumer_Block_Transactions_Hash_Mismatch": "验证失败,因为大宗交易哈希与计算值不匹配",
+ "Neutral_Consumer_Hash_In_Recency_Cache": "验证失败,因为在近期缓存中存在实体哈希",
+ "Failure_Consumer_Remote_Chain_Too_Many_Blocks": "验证失败,因为链部分有太多块",
+ "Failure_Consumer_Remote_Chain_Improper_Link": "验证失败,因为链条内部链接不正确",
+ "Failure_Consumer_Remote_Chain_Duplicate_Transactions": "验证失败,因为链部分包含重复的交易",
+ "Failure_Consumer_Remote_Chain_Unlinked": "验证失败,因为链部分未链接到当前链",
+ "Failure_Consumer_Remote_Chain_Difficulties_Mismatch": "验证失败,因为远程链难度与计算的难度不匹配",
+ "Failure_Consumer_Remote_Chain_Score_Not_Better": "验证失败,因为远程链得分不高",
+ "Failure_Consumer_Remote_Chain_Too_Far_Behind": "验证失败,因为远程链太远了",
+ "Failure_Consumer_Remote_Chain_Too_Far_In_Future": "验证失败,因为远程链时间戳太远了。",
+ "Failure_Consumer_Batch_Signature_Not_Verifiable": "验证失败,因为在批处理操作期间签名验证失败",
+ "Failure_Consumer_Remote_Chain_Improper_Importance_Link": "验证失败,因为远程链的重要性链接不正确",
+ "Failure_Extension_Partial_Transaction_Cache_Prune": "验证失败,因为从临时缓存中删除了部分事务",
+ "Failure_Extension_Partial_Transaction_Dependency_Removed": "验证失败,因为由于删除了部分依赖关系,因此从临时缓存中删除了部分事务,",
+ "Failure_Extension_Read_Rate_Limit_Exceeded": "验证失败,因为超出了套接字读取速率限制",
+ "generate_a_new_profile": "生成一个新账户",
+ "generate_entropy_increase_success": "生成熵增成功,页面即将跳转。",
+ "generate_mnemonic": "生成助记词",
+ "generate_mnemonic_title": "生成助记密码",
+ "generating_mnemonic": "生成助记词",
+ "getting_a_mnemonic_equals_ownership_of_a_account_asset": "获得助记词等于拥有钱包资产所有权",
+ "go_to_login": "直接登陆",
+ "harvested_blocks": "收获的块",
+ "harvesting": "收获",
+ "harvesting_account_insufficient_balance": "余额不足,该帐户至少需要持有10000个XYM才能开始委托收获。",
+ "harvesting_confirmation_description_1": "下方可见事务细节信息。输入密码和点击 Next按钮后, 事务将在网络实现。",
+ "harvesting_confirmation_description_2": "如果节点接收委托收获,收获将自动被开启。",
+ "harvesting_create_remote_account": "远程账户未设置,您需要设置远程账户。",
+ "harvesting_delegation_description_1": "选择开启收获的账户,并选择您想要委托的节点发送委托请求。",
+ "harvesting_delegation_description_2": "而后选择事务费用,您可以发送委托到多个节点。",
+ "harvesting_node_get_node_info": "获取节点信息",
+ "harvesting_node_not_eligible": "无法使用此节点收获",
+ "harvesting_remote_account": "远程账户",
+ "harvesting_remote_account_creation_successful_1": "您的远程账户已创建,以保障您的私钥安全。",
+ "harvesting_remote_account_description_1": "为安全原因,我们将创建一个远程账户用于委托收获。",
+ "harvesting_remote_account_description_3": "输入您的密码并点击 开启 用于创建远程账户。",
+ "harvesting_remote_linked_description_1": "您的账户当前连接到以下远程账户用于委托收获。",
+ "harvesting_remote_linked_description_2": "您可以在账户管理中解除远程账户的连接,. 点击 下一步 向您所选择的节点发送委托请求。",
+ "harvesting_status": "收割状态",
+ "harvesting_status_active": "活性",
+ "harvesting_status_inactive": "不活跃",
+ "harvesting_status_failed": "失败的",
+ "harvesting_status_inprogress_activation": "激活中",
+ "harvesting_status_inprogress_deactivation": "正在停用中",
+ "harvesting_status_keys_linked": "按键链接",
+ "harvesting_subtitle_confirmation": "总览",
+ "harvesting_subtitle_delegation": "节点选择",
+ "harvesting_subtitle_overview": "Overview",
+ "harvesting_warning_node_swap": "交换到另一个节点将重新链接所有密钥",
+ "hash_date": "hash/日期",
+ "hd_account_path_error": "HD 钱包路径输入错误",
+ "hidden_accounts": "隐藏账户",
+ "hide_account": "隐藏账户",
+ "id": "ID",
+ "if_you_need_to_backup_your_mnemonics_again_you_can": "如果您需要再次备份助记词,请在“账户 - 我的账户 - 备份个人资料”页面操作。",
+ "illegal_public_key_error": "公钥格式错误",
+ "illegal_publicKey": "存在不合法的账户公钥",
+ "import": "进口",
+ "import_address_book": "导入通讯录",
+ "import_mnemonic": "导入已有助记词",
+ "import_mnemonic_passphrase_create_profile": "直接导入助记词短语以建立帐户",
+ "import_private_key": "导入私钥",
+ "import_private_key_account_successfully": "恭喜,私钥帐户已成功导入。",
+ "import_private_key_account_successfully_title_tips": "当前配置文件是使用私钥创建的。无法向其添加其他帐户。希望您有愉快的经历和旅途。",
+ "import_private_key_description": "导入您的私钥以创建配置文件",
+ "import_private_key_finalize_tip_text1": "1。请确保将您的私钥备份在一个安全的地方。它仅被加密并安装在您本地的当前配置文件下。与任何助记符无关。",
+ "import_private_key_finalize_tip_text2": " 2.一个配置文件可以为您安装任意数量的独立私钥。请小心!",
+ "import_private_key_input_tip1": "在输入字段中输入私钥。请确保您的私钥正确。输入正确的私钥时,相应的公钥和地址将显示在输入框的底部。请注意网络类型。",
+ "import_private_key_profile_description_tip1": "在开始使用此软件之前,您需要创建一个配置文件名称和密码。用于在本地加密您的帐户信息。",
+ "import_private_key_profile_description_tip2": "该密码将用于保护对您的个人资料的访问,例如'Transfer'和任何交易操作。",
+ "import_qr_code": "导入二维码",
+ "import_successful": "恭喜,导入账户成功!",
+ "import_transaction_uri": "导入交易URI",
+ "importance": "重要性",
+ "incoming": "传入",
+ "increase": "增加",
+ "info_active_cosignatory_mode": "选定的事务签名者是一个多签帐户",
+ "info_connecting_peer": "正在连接到节点 {peerUrl} ...",
+ "inner_transaction_hash": "内部事务hash",
+ "input_here": "这里输入...",
+ "input_mnemonic": "输入助记词",
+ "input_mnemonic_tips": "请在输入单词之间用空格隔开,助记词数量为12或24个的英文单词。助记词是遵循HD-WALLET协议的种子文件,由12或24个随机单词成,导入本文件后,将会恢复你种子下的所有资产。导入记助词后,将会被你上一步设置的密码保存在你的本地设备中,使用中请注意网络安全!",
+ "input_namespace_name": "请输入名称空间名称",
+ "invalid_address_book": "通讯录无效",
+ "invalid_mnemonic_input": "输入的助记词口令无效",
+ "invalid_namespace_or_mosaic_id": "这不是合法的马赛克哈希或命名空间",
+ "invalid_node": "节点连接失败",
+ "keep_it_in_a_safe_place_on_the_isolated_network_mnemonics": "妥善保管至隔离网络的安全地方,请勿将助记词在联网环境下分享和存储,比如邮件、相册、社交应用等",
+ "keystore_decryption_failed": "keystore解密失败",
+ "label_add_cosignatory": "添加联署人",
+ "label_duration_unlimited": "Unlimited",
+ "label_for_approvals": "审批交易需要联署",
+ "label_for_removals": "删除联署人所需的联署",
+ "label_multisig_operation_conversion": "将帐户转换为多签账户",
+ "label_multisig_operation_modification": "修改帐户多签属性",
+ "label_of": "{min} 到 {max}",
+ "label_postfix_multisig": "(多重)",
+ "label_signed_by": "由联署人签署:",
+ "latest_news_articles": "最新资讯",
+ "ledger_connected_other_app": "Ledger 已经连接到其他程序,请关闭正在使用的程序并重试",
+ "ledger_correct_account": "Symbol Ledger 账户正确",
+ "ledger_description": "从Ledger导入钱包",
+ "ledger_device_locked": "请解锁Ledger设备",
+ "ledger_no_device": "无法找到Ledger设备",
+ "ledger_no_device_selected": "请选择Ledger设备",
+ "ledger_not_correct_account": "Symbol Ledger账户不正确",
+ "ledger_not_opened_app": "请在Ledger上打开Symbol程序",
+ "ledger_not_supported_app": "请检查Ledger上的Symbol程序是否为最新版版",
+ "ledger_not_using_xym_app": "You are not using Symbol app on your Ledger device",
+ "ledger_profile_import": "导入个人资料",
+ "ledger_user_reject_request": "用户取消请求",
+ "link": "绑定",
+ "link_action": "链接动作",
+ "linked_account_address": "关联帐户地址",
+ "linked_account_public_key": "关联帐户公钥",
+ "linked_node_public_key": "链接节点公钥",
+ "linked_public_key": "链接公钥",
+ "linked_vrf_public_key": "链接的Vrf公钥",
+ "loading": "加载中...",
+ "locked_mosaic": "锁定马赛克",
+ "login": "登 录",
+ "login_to_symbol_account": "登录到您的dHealth帐户",
+ "logout": "登出",
+ "low_fee_warning_message": "少于建议费用的交易可能不会被接受并最终到期",
+ "max_approval_amount_more_than_10": "最小删除账户审批数不可大于10",
+ "max_decimal_number_error": "{_field_} 字段最多 {maxDecimalNumber} 位小数或更少。",
+ "max_message_length_error": "{_field_} 栏位不得超过 {maxMessageNumber} 个字元",
+ "positive_decimal_error": "只允许使用数字和\"{decimalSeparator}\"",
+ "max_fee": "最大费用",
+ "max_removal_amount_more_than_10": "最小删除账户审批数不可大于10",
+ "message": "消息",
+ "message_empty_cosignatories": "此帐户没有联署人",
+ "metadata": "元数据",
+ "metadata_attached_to_account": "附加到您帐户的元数据",
+ "metadata_value": "元数据值",
+ "min_approval_amount_illegal": "最小删除账户审批数必须为数字",
+ "min_approval_amount_less_than_0": "最小删除账户审批数不可小于1",
+ "min_approval_delta": "最低审核数",
+ "min_removal_amount_illegal": "最小删除账户审批数必须为数字",
+ "min_removal_amount_less_than_0": "最小删除账户审批数不可小于1",
+ "min_removal_delta": "最低移除数",
+ "minimal_fee_transaction": "请注意当前选择的节点最小费用为:",
+ "mnemonic_backup_options_copy_desc": "複製助記詞並將其保存在安全的地方。",
+ "mnemonic_backup_options_download_desc": "下載使用密碼加密的QR碼。 此QR碼可用於將您的帳戶導入不同的錢包(例如,移動錢包)",
+ "mnemonic_copy": "复制",
+ "mnemonic_generation_error": "生成钱包种子失败",
+ "mnemonic_inconsistency": "助记词不一致",
+ "mnemonic_correct": "助记词正确",
+ "mnemonic_not_found": "找不到助记符!",
+ "mnemonic_phrase": "助记词",
+ "mnemonic_qr_action_desc": "单击继续以将导入的助记词设置为文本区域。",
+ "modal_account_unlock_title": "解锁钱包",
+ "modal_backup_reminder_content": ">>請注意,私鑰帳戶無法從您的助記密碼中恢復。 導入完成後,請再次備份您的個人資料,以將該帳戶包含在Paper Wallet中",
+ "modal_backup_reminder_title": ">>警告",
+ "modal_title_account_metadata": "帐户元数据",
+ "modal_title_backup_mnemonic_display": "显示助记词",
+ "modal_title_backup_mnemonic_qrcode": "导出助记词二维码",
+ "modal_title_backup_profile": "备份个人资料",
+ "modal_title_backup_transaction": "出口交易",
+ "modal_title_debug_console": "诊断控制台",
+ "modal_title_delete": "删除确认",
+ "modal_title_enter_account_name": "配置新钱包",
+ "modal_title_extend_namespace_duration": "延长命名空间持续时间",
+ "modal_title_link_alias": "绑定别名",
+ "modal_title_mosaic_metadata": "马赛克元数据",
+ "modal_title_mosaic_supply_change": "修改马赛克供应量",
+ "modal_title_namespace_metadata": "命名空间元数据",
+ "modal_title_transaction_confirmation": "签署交易",
+ "modal_title_transaction_details": "交易详情",
+ "modal_title_unlink_alias": "取消别名与命名空间的链接",
+ "more_access_tool_is_working": "更多接入方式正在开发中",
+ "mosaic": "马赛克",
+ "mosaic_alias_not_exist": "马赛克别名不存在",
+ "mosaic_describe_text": "马赛克是NEM区块链上的数字资产,也可以表示一组不变的相同事物, 是使智能资产系统独特而灵活的一部分。 可以是令牌TOKEN,也可以是专属的资产集合,例如奖励积分,股票, 签名,状态标志,投票或者其他流量性资产。",
+ "mosaic_expired": "已过期",
+ "mosaic_hex_format_error": "马赛克hex格式错误",
+ "mosaic_id": "马赛克ID",
+ "mosaic_name_can_not_be_null": "马赛克名称不能为空",
+ "mosaic_not_set": "请选择马赛克",
+ "mosaic_transaction": "马赛克交易 ",
+ "mosaic_supply_transaction": ">> 供应变更交易 ",
+ "mosaic_transfer_type": "镶嵌交易",
+ "mosaics_list": "马赛克列表",
+ "move_your_mouse": "请移动你的鼠标,产生墒增,帮助产生随机助记词",
+ "move_your_mouse_tip1": "我们将生成您的助记密码。",
+ "multisig_account_graph": "多签名树",
+ "multisig_accounts_can_not_send_a_transaction_by_themselves": "多重签名账户自身不能发起交易。",
+ "multisig_transaction": "多签名交易 ",
+ "multisignature_transfer_type": "多重签名交易",
+ "my_transaction_title": "我的交易",
+ "namespace": "命名空间",
+ "namespace_and_sub_namespace": "命名空间和子命名空间",
+ "namespace_can_only_contain_numbers_letters_and_other": "Namespace 只能包含数字,字母,_和-",
+ "namespace_cannot_be_a_null_or_empty_string": "Namespace 不能为空值或空字符串",
+ "namespace_cannot_use_forbidden_words": "Namespace 不能使用禁止的单词",
+ "namespace_definition": "命名空间使您可以在NEM区块链上为您的业务和资产创建一个链上唯 一的标识符,类似于互联网域名。",
+ "namespace_description": "命名空间说明",
+ "namespace_duration_tip_1": "持续时间以块计算,一个块为12秒,一个块=1/20000XYM,最大有效期为365天",
+ "namespace_id": "命名空间ID",
+ "namespace_must_start_with_a_letter": "Namespace 必须以小写字母开头",
+ "namespace_name": "命名空间名称",
+ "namespace_name_constraint": "该名称在网络中必须显示为唯一,并且最大长度 为64个字符。",
+ "namespace_tips_key_1": "1.命名空间名称在网络中必须是唯一的,最大长度为64个字符,有效字符:",
+ "namespace_tips_key_2": "2.不被允许的命名空间包含字符串有:",
+ "namespace_tips_key_3": "3.命名空间最多可以被定义为三层",
+ "namespace_tips_value_1": "a, b, c, …, z, 0, 1, 2, …, 9, _ , -",
+ "namespace_tips_value_2": "nem, user, account, org, com, biz, net, edu, mil, gov , info.",
+ "namespace_transaction": "命名空间交易 ",
+ "namespace_transfer_type": "命名空间交易",
+ "network_settings": "网络设置",
+ "network_type": "网络类型",
+ "network_type_invalid": "网络类型不匹配",
+ "new_password_label": "密码",
+ "news": "资讯",
+ "news_read_more": "Read more",
+ "next": "下一步",
+ "no_confirmed_transactions": "暂无已确认交易",
+ "no_data_mosaics": "此账户暂无马赛克",
+ "no_data_namespace_tips": "您还没有父命名空间,请先创建一个父命名空间",
+ "no_data_namespaces": "此账户暂无命名空间",
+ "no_data_transactions": "此账户暂无交易记录",
+ "no_harvested_blocks_yet": "尚无收获块",
+ "no_mnemonic": "暂无助记词",
+ "no_network_currency_alert": "钱包没有有关网络货币的数据(例如nem:xym),请连接到有效节点。",
+ "no_partial_transactions": "暂无挂载交易",
+ "no_profiles_in_database": "本地缓存中暂无钱包",
+ "no_unconfirmed_transactions": "暂无未确认交易",
+ "node": "节点",
+ "node_connection_failed": "节点连接失败",
+ "node_connection_succeeded": "节点连接成功",
+ "node_exists_error": "节点已存在",
+ "node_list": "节点列表",
+ "node_not_available_please_check_your_node_or_network_settings": "节点不可用,请检查您的节点或网络设置。",
+ "node_public_key_input": "找不到公钥,请在此处输入或选择另一个节点",
+ "node_publicKey": "节点公钥",
+ "node_url": "节点URL",
+ "not_yet_open": "暂未开放",
+ "notes_should_not_exceed_25_character": "备注信息不应超过25个字符",
+ "notification_new_aggregate_bonded": "一个新的聚合交易被发布了",
+ "notification_new_cosignature": "已有聚合交易被共签人签署",
+ "notification_new_transaction_confirmed": "节点已确认事务",
+ "notification_new_unconfirmed_transaction": "节点已接收事务",
+ "offline_storage": "离线保管",
+ "open_restrictions_warning_text": "帐户限制是一项高级功能,可以使您的帐户无效。 请注意在以下屏幕中执行的操作。您确定要访问帐户限制吗?",
+ "open_restrictions_warning_title": "开户限制",
+ "operation_failed": "操作失败",
+ "operation_type": "操作类型",
+ "option_child_account": "我想为我的个人资料创建一个种子帐户",
+ "option_hd_account": "我想创建一个超确定性帐户",
+ "option_link_address": "关联钱包地址",
+ "option_link_mosaic": "关联马赛克",
+ "option_privatekey_account": "导入已存在的私钥",
+ "option_root_namespace": "根命名空间",
+ "option_sub_namespace": "子命名空间",
+ "outgoing": "外向",
+ "page_title_account_actions": "操作",
+ "page_title_account_backup": "资料备份",
+ "page_title_account_details": "钱包信息",
+ "page_title_account_harvesting": "收获",
+ "page_title_account_metadata": "元数据",
+ "page_title_dashboard": "仪表盘",
+ "page_title_delegated_harvesting": "委托收获",
+ "page_title_harvesting": "收获",
+ "page_title_history": ">>歷史",
+ "page_title_invoice": "发票",
+ "page_title_mosaics": "马赛克列表",
+ "page_title_mosaics_create": "创建新的马赛克",
+ "page_title_multisig_convert": "转换多签帐户",
+ "page_title_multisig_cosign": "签名",
+ "page_title_multisig_manage": "管理多签帐户",
+ "page_title_namespaces": "命名空间列表",
+ "page_title_namespaces_create": "创建新的命名空间",
+ "page_title_settings_about": "关于",
+ "page_title_settings_diagnostic": "诊断",
+ "page_title_settings_general": "常规设置",
+ "page_title_settings_password": "账户密码",
+ "page_title_send": ">>發送",
+ "page_title_transfer": "转账",
+ "paid_fee": "已付费用",
+ "parent_namespace": "父命名空间",
+ "password": "密码",
+ "password_error": "密码错误",
+ "password_hint": "密码提示",
+ "password_is_invalid": "密码必须包含至少一个字母和数字,且密码长度必须大于等于8",
+ "passwords_not_matching": "密码不匹配",
+ "peer_tip": "你可以使用 {setting} 来管理节点或者是配置一个新的网络",
+ "peers_number": "节点数量",
+ "phishing_warning": "小心网络钓鱼!一般来说,Wallet不会要求您输入助记词。",
+ "placeholder_address": "请输入地址",
+ "placeholder_address_or_alias": "直接输入接收地址或别名(例如:nem.group)",
+ "placeholder_address_or_public_key": "地址或公钥",
+ "placeholder_transaction_uri": "输入有效的交易URI",
+ "please_accurately_copy_the_safety_backup_mnemonic": "请准确抄写安全备份助记词",
+ "i_accept": "我接受",
+ "terms": "条款",
+ "conditions": "条件",
+ "please_backup_mnemonic_passphrase": "请将你的记助词离线写在纸上并做多份保存,或者离线的加密磁盘和存储介质等",
+ "please_backup_mnemonic_passphrase_title": "創建備份!",
+ "please_check_device_connection": "Please check your device connection!",
+ "please_click_on_the_mnemonic_in_order_to_confirm_that_you_are_backing_up_correctly": "请按顺序点击助记词,以确认您正确备份",
+ "please_enter_a_correct_number": "请输入正确金额",
+ "please_enter_a_custom_nod_address": "请输入节点完整URL",
+ "please_enter_a_mnemonic_to_ensure_that_the_mnemonic_is_correct": "请输入助记词,确保助记词是正确的",
+ "please_enter_notes": "请输入备注信息",
+ "please_enter_your_account_password": "请输入密码",
+ "please_enter_your_new_password_again": "请再次输入新的密码",
+ "please_enter_your_password_again": "请再次输入你设置的密码",
+ "please_set_your_account_password": "请输入设置的密码",
+ "please_update_symbol_bolos_app": "Please update your Symbol app on your Ledger device!",
+ "point_null_error": "节点数据不可为空",
+ "preview_and_action": "预习",
+ "previous": "上一步",
+ "privacy_policy": "隐私政策",
+ "private_key": "私钥",
+ "private_key_invalid_error": "该私钥不合法。",
+ "profile_creation_description": "在开始使用本程序之前,你需要为自己创建一个账户和密码来方便管理自己的钱包资产",
+ "profile_description": "账户说明",
+ "profile_description_tips1": "在开始使用本程序之前,你需要一个账户和密码来管理自己的钱包。为了提供更便捷的钱包管理,此终端采用HD-WALLET协议;一个账户会绑定一个记助词。",
+ "profile_description_tips2": "账户和密码将用于加密你的记助词,所有一定管理好你的密码; 同时备份好记助词,在忘记密码后可以让你方便回复钱包资产管理",
+ "profile_description_tips3": "“一个账户标示一个记助词,一个对应的密码,由记助词产生所有钱包地址",
+ "profile_import": "导入一个老账户",
+ "profile_name": "账户名",
+ "profile_name_already_exists": "账户名已存在",
+ "profile_name_error": "账户名输入错误!",
+ "profile_not_matching_network_option_1": "注销并更改个人资料",
+ "profile_not_matching_network_option_2": "创建新的个人资料",
+ "profile_not_matching_network_option_3": "关闭并切换网络",
+ "profile_not_matching_network_warning_message": "您的个人资料的网络与当前网络不匹配。请选择以下选项之一来解决此问题。",
+ "profile_not_matching_network_warning_title": "警告",
+ "program_description_line1": "此程序是基于dHealth区块链设计的,",
+ "program_description_line2": "一个开放源代码数字资产管理系统。访问dHealth",
+ "program_description_line3": "建立网络,创建配置文件,管理帐户和资产等。",
+ "progress": "正在下载",
+ "public_key": "公钥",
+ "public_key_addition": "添加联署人",
+ "public_key_deletion": "删除联署人",
+ "public_key_invalid": "此公钥不合法",
+ "qr_code": "二维码",
+ "qr_code_generation_failed": "二维码生成失败",
+ "qrcode_detail_item_address": "地址",
+ "qrcode_detail_item_contact_name": "联系人姓名",
+ "qrcode_detail_item_mnemonic_passphrase": "助记密码",
+ "qrcode_detail_item_network_type": "网络类型",
+ "qrcode_detail_item_type": "QR码类型",
+ "qrcode_detail_item_type_contactqr": "地址",
+ "qrcode_detail_item_type_cosignatureqr": "要求共同签名",
+ "qrcode_detail_item_type_mnemonicqr": "导入助记符",
+ "qrcode_detail_item_type_transactionqr": "发票",
+ "qrcode_password_info": "上载的QR码受密码保护。\n请在生成此二维码时输入您的密码。",
+ "recipient": "接收人",
+ "recipient_linked_address_invalid": "接受账户的别名没有链接的地址",
+ "recipient_public_key_invalid_error": "接受人公匙不合法",
+ "refresh": "刷新",
+ "refresh_failed": "刷新失败",
+ "refresh_success": "刷新成功",
+ "refresh_too_fast_warning": "刷新频率过高,请稍后再试。",
+ "register": "注册",
+ "relative": "相对",
+ "removal_greater_than_cosignatories": "最小删除所需账户数比可用账户数多{delta}。请添加账户数或减少最小删除数。",
+ "removal_or_approval_is_zero": "如果列表中有 {delta} 个签署者,则“最小批准”和“最小删除”不能设置为零",
+ "repeat_password_label": "确认密码",
+ "reset": "重置",
+ "resolving_address": "解析地址 {address}...",
+ "restore_mnemonic": "恢复助记词",
+ "restrictable": "是否可限制",
+ "rules_describe": "规则描述",
+ "safe_storage_tips": "安全储存提示",
+ "save": "救",
+ "save_backups": "在多个位置保存备份",
+ "scenes_to_be_used": "使用场景",
+ "see_transactions_other_account": "查看多签帐户交易记录",
+ "seed_account_can_not_be_more_than_10": "本账户创建钱包数量已达上限,请更换账户以创建新钱包。",
+ "select": "选择",
+ "select_a_namespace": "选择一个命名空间",
+ "select_a_profile": "读取已有钱包",
+ "select_accounts": "选择钱包",
+ "select_all": "全选",
+ "select_contact": "选择联系人",
+ "send": "发送",
+ "sender": "发送者",
+ "set_account_name": "设置账户名",
+ "set_default_explorer": "输入的url不合法,已为您设置默认url",
+ "set_explorer_link": "默认区块浏览器",
+ "set_network_type": "设置网络类型",
+ "SET_UP": "节点选择",
+ "settings": "设置",
+ "settings_tab_about": "关于",
+ "settings_tab_general": "首选项设置",
+ "settings_tab_network": "网络设置",
+ "settings_tab_password": "资料密码",
+ "show_button": "显示",
+ "show_expired_mosaics": "显示过期马赛克",
+ "show_expired_namespaces": "显示过期命名空间",
+ "show_on_ledger": "在账本显示",
+ "show_wizard": "显示提示",
+ "sidebar_item_accounts": "资产",
+ "sidebar_item_aggregate": "骨料",
+ "sidebar_item_community": "资讯",
+ "sidebar_item_harvesting": "收成",
+ "sidebar_item_home": "首页",
+ "sidebar_item_mosaics": "马赛克",
+ "sidebar_item_multisig": "多签",
+ "sidebar_item_namespaces": "命名空间",
+ "sign_transaction_failed": "签署交易失败,原因: {reason}",
+ "signature": "签名",
+ "signer_public_key": "签名者公钥",
+ "simple_transaction": "简单交易 ",
+ "simple_transfer_type": "简单转移",
+ "skip": "跳过",
+ "speed": "产块速度",
+ "start": "开始",
+ "start_finalization_epoch": "开始完成时代",
+ "start_harvesting": "开始收获",
+ "status": "状态",
+ "stop_harvesting": "停止收割",
+ "success_account_unlocked": "账户解锁成功",
+ "success_password_changed": "密码已成功更新,请重新登录。",
+ "success_settings_updated": "设置已成功更新",
+ "success_transaction_partial_announced": "挂载事务宣布成功",
+ "success_transactions_announced": "交易宣布成功",
+ "success_transactions_signed": "签署事务成功",
+ "successful_copy": "复制成功",
+ "successful_operation": "操作成功",
+ "supply": "供应量",
+ "supply_can_not_less_than_0": "供应量不可小于零",
+ "swap": "交换",
+ "tab_accounts_accounts": "我的帐户",
+ "tab_accounts_addressbook": "我的联系方式",
+ "table_header_action": "行动",
+ "table_header_alias_identifier": "别名",
+ "table_header_alias_type": "别名类型",
+ "table_header_balance": "剩余数量",
+ "table_header_change_times": "更改时间",
+ "table_header_direction": "方向",
+ "table_header_divisibility": "可分割性",
+ "table_header_expiration": "有效期",
+ "table_header_expired": "是否过期",
+ "table_header_hex_id": "ID",
+ "table_header_name": "别名",
+ "table_header_restrictable": "限制性",
+ "table_header_scoped_key": "元数据Key",
+ "table_header_status": "状态",
+ "table_header_supply": "可供应量",
+ "table_header_supply_mutable": "可变供应",
+ "table_header_target_address": "目标地址",
+ "table_header_target_id": "目标ID",
+ "table_header_target_type": "目标类型",
+ "table_header_transferable": "可传输性",
+ "table_header_value": "值",
+ "target_account_invalid_name": "目标账户",
+ "terms_and_conditions": "条款和条件",
+ "the_backup_is_wrong": "请以正确的顺序仔细选择您的助记词。",
+ "the_mnemonic_order_is_correct_and_the_backup_is_successful": "助记词顺序正确,备份成功",
+ "the_mosaic_to_be_sent_is_empty": "待发送马赛克为空",
+ "the_root_namespace_cannot_be_longer_than_16": "Root namespace 长度不能大于16",
+ "the_sub_namespace_cannot_be_longer_than_16": "Sub-namespace 长度不能大于64",
+ "the_value_of_duration_cannot_be_less_than_1": "Duration 的值不能小于1",
+ "tips": "提示",
+ "title": "标题",
+ "to": "至",
+ "to_symbol": "to dHealth",
+ "too_many_cosignatories": "最大联名签字人数量为 {maxCosignatoriesPerAccount} ,请删除 {delta} 联名签字人",
+ "top_window_console": "控制台",
+ "transaction_cancel": "Transaction cancel!",
+ "transaction_descriptor_16705": "完成聚合",
+ "transaction_descriptor_16707": "投票关键链接",
+ "transaction_descriptor_16708": "账户元数据",
+ "transaction_descriptor_16712": "资金锁定",
+ "transaction_descriptor_16716": "绑定账户",
+ "transaction_descriptor_16717": "马赛克定义",
+ "transaction_descriptor_16718": "注册命名空间",
+ "transaction_descriptor_16720": "账户地址约束",
+ "transaction_descriptor_16721": "马赛克全局约束",
+ "transaction_descriptor_16722": "密码锁定",
+ "transaction_descriptor_16724": "转账",
+ "transaction_descriptor_16725": "修改多签名帐户",
+ "transaction_descriptor_16961": "担保聚合",
+ "transaction_descriptor_16963": "验证密钥链接",
+ "transaction_descriptor_16964": "马赛克元数据",
+ "transaction_descriptor_16972": "Link node key",
+ "transaction_descriptor_16973": "改变马赛克供应量",
+ "transaction_descriptor_16974": "地址别名",
+ "transaction_descriptor_16976": "账户马赛克约束",
+ "transaction_descriptor_16977": "马赛克地址约束",
+ "transaction_descriptor_16978": "密证",
+ "transaction_descriptor_17220": "命名空间元数据",
+ "transaction_descriptor_17230": "马赛克别名",
+ "transaction_descriptor_17232": "账户操作约束",
+ "transaction_details": "事务细节",
+ "transaction_expired": "交易已过期",
+ "transaction_has_cosignature": "已接收的联合签名",
+ "transaction_needs_cosignature": "等待共同签名的交易",
+ "transaction_needs_cosignature_explain": "这笔交易需要多方联署审批,请立即解锁您的帐户以发送联名交易。",
+ "transaction_needs_cosignature_explain_signed": "此交易需要多方通过发送共同签名进行批准。\n您已经为此交易发送了共同签名。\n请等待其他共同签署人批准。\n您可以下载QR码并将其发送给其他共同签名者,以使他们可以轻松地对其部分进行签名。",
+ "transaction_qr_action_desc": "单击继续以打开包含这些详细信息的传输页面。",
+ "transaction_qr_code": "交易二维码",
+ "transaction_received_cosignature_explain": "已完成联合签名",
+ "transaction_status_confirmed": "历史记录",
+ "transaction_status_partial": "挂载事务",
+ "transaction_status_unconfirmed": "未确认",
+ "transaction_too_long": "事务过长!",
+ "transaction_type": "交易类型",
+ "transaction_type_title": "交易类型",
+ "transaction_uri": "交易URI",
+ "transaction_uri_explanation": "此事务的URI表示形式。\n您可以复制此URI并将其发送到另一台设备或其他人以导入并签署交易。",
+ "transactions": "交易",
+ "transactions_tab_confirmed": "历史记录",
+ "transactions_tab_partial": "挂载事务",
+ "transactions_tab_unconfirmed": "未确认",
+ "transfer_target": "转账目标",
+ "transferable": "可传输",
+ "transmittable": "可传输",
+ "type": "类型",
+ "uncheck_all": "全部取消",
+ "unconfirmed": "未确认",
+ "unconfirmed_transaction": "未确认事务",
+ "unknown": "未知",
+ "unlink": "解绑",
+ "unlink_namespace_from": "解绑 {aliasTarget} 从 {namespaceName}",
+ "update_completed": "更新成功",
+ "upload_address_book_explanation": "上载有效的通讯录json文件。 通讯录上传后,通讯录中的所有联系人都会恢复",
+ "upload_file_message": "单击或拖动文件以上传",
+ "upload_qr_code": "上传二维码",
+ "upload_qr_code_explanation": "上载或扫描以下有效QR码之一。\n识别QR码类型后,您将进入下一步执行相关操作。",
+ "upload_qr_code_explanation_type_contactqr": "地址二维码",
+ "upload_qr_code_explanation_type_cosignatureqr": "共同签名QR码",
+ "upload_qr_code_explanation_type_mnemonicqr": "助记码",
+ "upload_qr_code_explanation_type_transactionqr": "发票二维码",
+ "upload_qr_code_invalid_type_message": "不允许输入Type({type})!\n请使用上面列出的有效QR码重试。",
+ "upload_qr_tab_scan": "通过相机扫描",
+ "upload_qr_tab_upload_image": "上传图片",
+ "uploaded_qr_code": "上载QR码",
+ "use_paper_and_pen_to_correctly_copy_mnemonics": "使用纸和笔正确抄写助记词,如果你的手机丢失、被盗、损坏,助记词将可以恢复你的资产",
+ "used_to_bind_a_account_address": "用于绑定一个钱包地址,作为其转账别名使用; 用于设置账户过滤器; 用于绑定一个Mosaic ID 。",
+ "user_aborted_transaction_confirmation": "已中止交易",
+ "value_too_big": "输入的值太大",
+ "variable_supply": "可变供应量",
+ "verify_backup_mnemonics": "下一步:验证备份助记词",
+ "verify_device_information": "在您的账户确认信息!",
+ "verify_Mnemonic_phrase": "验证助记词",
+ "verify_mnemonics": "验证备份助记词",
+ "version": "版",
+ "view_metadata": "查看元数据",
+ "warning_already_a_cosignatory": "此帐户已是联名用户!",
+ "warning_unknown_account": ">>該帳戶是網絡未知的。 請確保地址正確,並且帳戶至少收到一筆交易",
+ "web_wallet_warning": "该网络钱包仅供演示使用!",
+ "welcome": "Welcome",
+ "welcome_to_symbol": "欢迎使用dHealth",
+ "word": "字",
+ "x_seconds": "{seconds}秒",
+ "linked_remote_private_key": "已链接的远程私钥",
+ "linked_vrf_private_key": "已链接的Linked Vrf私钥",
+ "linked_keys_info": "密钥信息:",
+ "link_keys": "链接所有密钥",
+ "activate_delegated_harvesting_message": "为激活委托收获,我们需要您的密码用以加密您的vrf密钥。",
+ "activate_delegated_harvesting": "激活收获",
+ "create_persistent_message": "生成安全的收获消息",
+ "Insert_your_node_linked_public_key": "添加您的节点公钥",
+ "Insert_your_vrf_linked_public_key": "添加您的vrf公钥",
+ "Insert_your_account_linked_public_key": "添加您的远程账户公钥",
+ "not_linked": "未链接",
+ "form_label_use_link_remote_public_key_icon": "使用链接按钮连接远程公钥",
+ "form_label_use_link_vrf_public_key_icon": "使用链接按钮连接vrf公钥",
+ "form_label_use_link_node_public_key_icon": "使用链接按钮连接节点公钥",
+ "label_unlink_node_account_public_key": "解除您的节点公钥链接",
+ "label_unlink_remote_account_public_key": "解除您的远程公钥链接",
+ "label_unlink_vrf_account_public_key": "解除您的vrf公钥链接",
+ "please_link_your_public_key": "请重新链接您的公钥以生成您的私钥",
+ "linking": "链接中...",
+ "stoping": "停止中...",
+ "remote_keys_linked": "您的远程私钥和vrf私钥已链接到您的帐户,如果您想要开启委托收获,请选择一个远程节点,并链接节点密钥。如果您已经在收获,请选择您的收货节点以更新您的收获状态",
+ "encrypt_ledger_keys_on_sign": "作为Ledger用户,我们需要您的密码来加密远程账户和vrf私钥。",
+ "harvesting_status_not_detected": "我们无法检测到您的收割状态,请选择您要收割的节点。",
+ "click_to_retry": "点击重试",
+ "symbol_node_cannot_connect": "无法连接到dHealth节点",
+ "current_node_is_not_available": "当前节点不可用。\n尝试连接到节点",
+ "nodes_unavailable_check_network_and": "节点({0} / {1})当前不可用。\n请检查您的网络连接,设置和",
+ "copyright": "版权所有©2021 dHealth Network",
+ "address_list_cannot_be_empty": "请从列表中选择至少一个1个非选择加入账户。",
+ "ws_connection_failed": "钱包无法监视您在dHealth链上的帐户活动。请尝试选择其他节点。",
+ "select_opt_in_accounts": "请选择Opt In账户",
+ "opt_in_account_notification": "该帐户是通过较早的派生算法获得的。建议您将资金转移到新的种子帐户",
+ "qrcode_detail_item_type_signedqr": "已签署的交易",
+ "transaction_qr_signed_action_desc": "点击下一步来发布交易",
+ "upload_qr_code_explanation_type_signedtransactionqr": "已签署的交易QR码",
+ "upload_qr_code_explanation_type_cosignaturesignedtransactionqr": "多重签署的交易QR码",
+ "offline_transactions_title": "离线交易",
+ "offline_transactions_text1": "确保绝对安全, 请在未联网的计算机上进行交易",
+ "offline_transactions_text2": "只有非多重签名交易可进行离线交易",
+ "offline_transactions_text3": "点击左侧的‘创建’按钮, 签署的交易将出现在下方",
+ "offline_transactions_text4": "已签署的交易是不可变更的,必须在24小时内发布到网络上去",
+ "offline_transactions_prepare_transaction": "准备交易",
+ "offline_transactions_download": "下载QR码",
+ "offline_transactions_success": "交易签署成功",
+ "offline_transactions_success_text": "您现在可以下载QR码或者复制交易JSON, 使用钱包或者CLI发布到网路上",
+ "signed_transaction_qr": "已签署的交易QR码",
+ "go_to_offline_transactions": "离线交易",
+ "go_to_login_offline": "登录账户",
+ "cosign_transaction": "联合签署交易",
+ "offline_transactions_import_qr": "导入联合签名",
+ "offline_transactions_chose_account": "签署交易",
+ "offline_transactions_import_qr_title": "导入需要联合签署的交易",
+ "offline_transaction_confirm_import": "选择下一步来签署交易",
+ "sign": "签署",
+ "hash": "Hash值",
+ "form_label_import_placeholder": "粘贴交易有效负载",
+ "payload_not_valid": "负载无效",
+ "import_payload": "导入负载",
+ "import_payload_text": "您也可以选择使用CLI生成的交易负载",
+ "ledger_available_on_standalone_app": "Ledger不适用于Web版本。 要使用Ledger,请下载桌面应用程序。",
+ "select_custom_node": "选择自定义节点",
+ "delegated_harvesting_request_failed": "请注意,您委托的“收割”请求失败,请停止收割并尝试其他节点。",
+ "tab_harvesting_key_links": "关键链接",
+ "tab_harvesting_delegated_harvesting": "委托收获",
+ "open_harvesting_keys_warning_title": "打开收割链接的钥匙",
+ "open_harvesting_keys_warning_text": "链接密钥是一项高级功能,只能由了解收集密钥工作原理的专家进行管理。\n如果您是普通用户,我们建议您留在委派的收获屏幕中。",
+ "delete_account_confirmation_checkbox": "是的,我想删除此帐户。",
+ "delegated_harvesting_keys_info": "链接的密钥用于远程和委派收获。\n如果您拥有节点,则必须将以下密钥复制到您的节点配置中,如果您只是在进行委托收获,钱包将为您保留此密钥。",
+ "harvesting_activated_from_another_device": "收割已使用其他设备激活。\n显示的收获状态可能不正确,因为此钱包没有所有信息。",
+ "create_remote_public_key": "创建远程公钥",
+ "generate_random_public_key": "产生金钥",
+ "import_key_manually": "手动导入密钥",
+ "create_vrf_public_key": "创建VRF公钥",
+ "harvesting_account_has_extra_balance": "要开始委派收割,您的帐户必须持有少于50000000的XYM。",
+ "harvesting_account_has_zero_importance": "重要性低,重要性为0时,帐户无法开始收获。",
+ "harvesting_delegated_description": "委托收获允许在不运行节点的情况下使用帐户的重要性得分从创建新区块中获得奖励。\n要激活委派收获,您必须链接所有键并请求一个节点来收获您的帐户。",
+ "harvesting_delegated_request_warning": "根据您帐户的重要性得分和该节点的免费收获时段,可能不会批准您的请求。\n\n\n另外,请注意,节点可以随时从其收获槽中删除帐户。\n\n\n在这些情况下,您需要切换到其他节点并重复Delegated Harvesting激活过程。\n激活支付的交易费用将不予退还。\n\n\n如果输入了自定义节点URL,则显示的“收获”状态可能在所有设备上都不正确。",
+ "harvesting_delegated_request_warning_title": "委托收获",
+ "harvesting_keys_linked_missing": "为了激活收款钱包,需要具有所有链接的密钥对。\n请重新链接它们。",
+ "harvesting_keys_linked_next_step_guide": "键已链接。\n现在,您可以请求一个节点来收获您的帐户。\n如果要更改节点,则必须首先取消链接。\n使用下面的按钮。",
+ "harvesting_node_selection": "请从下面的下拉列表中选择一个节点。\n您可以在dHealth Explorer中找到更多节点,并通过输入其URL来使用它们。",
+ "key_type": "密钥类型",
+ "open_explorer_node_list": "访问dHealth Explorer的节点列表",
+ "request_harvesting": "要求收获",
+ "requesting": "正在要求...",
+ "unlink_keys": "取消链接键",
+ "unlinking": "取消连结..."
+}
diff --git a/src/main.ts b/src/main.ts
new file mode 100644
index 0000000..3eacdd3
--- /dev/null
+++ b/src/main.ts
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ * Copyright 2021-present [Using Blockchain Ltd](https://using-blockchain.org), All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import Vue from 'vue';
+import Router from 'vue-router';
+import VueRx from 'vue-rx';
+import moment from 'vue-moment';
+import iView from 'view-design';
+import locale from 'view-design/dist/locale/en-US';
+import 'view-design/dist/styles/iview.css';
+import infiniteScroll from 'vue-infinite-scroll';
+import Toast from 'vue-toastification';
+import 'vue-toastification/dist/index.css';
+
+// internal dependencies
+import { UIBootstrapper } from '@/app/UIBootstrapper';
+import { AppStore } from '@/app/AppStore';
+import i18n from '@/language/index.ts';
+import router from '@/router/AppRouter';
+import VueNumber from 'vue-number-animation';
+import { VeeValidateSetup } from '@/core/validation/VeeValidateSetup';
+// @ts-ignore
+import App from '@/app/App.vue';
+import clickOutsideDirective from '@/directives/clickOutside';
+import { PluginOptions } from 'vue-toastification/dist/types/src/types';
+// @ts-ignore
+import { library } from '@fortawesome/fontawesome-svg-core';
+// @ts-ignore
+import { faFileCsv } from '@fortawesome/free-solid-svg-icons';
+// @ts-ignore
+import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
+
+/// region UI plugins
+Vue.use(iView, { locale });
+Vue.use(moment as any);
+Vue.use(Router);
+Vue.use(VueRx);
+Vue.use(VueNumber);
+VeeValidateSetup.initialize();
+Vue.use(infiniteScroll);
+const toastDefaultOptions: PluginOptions = {
+ closeButton: false,
+ timeout: 3000,
+ transition: 'Vue-Toastification__fade',
+ transitionDuration: 300,
+};
+Vue.use(Toast, toastDefaultOptions);
+library.add(faFileCsv);
+Vue.component('font-awesome-icon', FontAwesomeIcon);
+/// end-region UI plugins
+
+/// directives
+Vue.directive('click-outside', clickOutsideDirective);
+/// end-region directives
+
+const app = new Vue({
+ router,
+ store: AppStore,
+ i18n,
+ created: function () {
+ // This will execute following processes:
+ // - configure Electron
+ // - configure Vue directives
+ UIBootstrapper.configure(this);
+ },
+ render: (h) => h(App),
+});
+
+app.$mount('#app');
+export default app;
diff --git a/src/router/AppRoute.ts b/src/router/AppRoute.ts
new file mode 100644
index 0000000..c1fe9bf
--- /dev/null
+++ b/src/router/AppRoute.ts
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import RouteConfig from 'vue-router';
+
+// internal dependencies
+import { RouteMeta } from './RouteMeta';
+
+/**
+ * Vue Router route extension
+ * @interface AppRoute
+ * @extends {RouteConfig}
+ */
+export interface AppRoute extends RouteConfig {
+ name: string;
+ meta: RouteMeta;
+ path?: string;
+ children?: AppRoute[];
+}
diff --git a/src/router/AppRouter.ts b/src/router/AppRouter.ts
new file mode 100644
index 0000000..fca0c6a
--- /dev/null
+++ b/src/router/AppRouter.ts
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import Router, { RawLocation } from 'vue-router';
+// internal dependencies
+import { routes } from '@/router/routes';
+import { AppRoute } from './AppRoute';
+import { TabEntry } from './TabEntry';
+import { AppStore } from '@/app/AppStore';
+import { ProfileService } from '@/services/ProfileService';
+
+/**
+ * Extension of Vue Router
+ * @class AppRouter
+ * @extends {Router}
+ */
+export class AppRouter extends Router {
+ /**
+ * Application routes
+ */
+ public readonly routes: AppRoute[];
+
+ constructor(options) {
+ super(options);
+ this.routes = options.routes;
+ const originalPush = this.push;
+ this.push = (location: RawLocation) => {
+ return originalPush.call(this, location).catch(() => {
+ /* eslint */
+ });
+ };
+ this.beforeEach((to, from, next) => {
+ const service = new ProfileService();
+ const hasAccounts = service.getProfiles().length > 0;
+
+ // No account when app is opened: redirect to create account page
+ const skipRedirect: string[] = ['profiles.importProfile.importStrategy'];
+ if (!from.name && !hasAccounts && !skipRedirect.includes(to.name)) {
+ return next({ name: 'profiles.importProfile.importStrategy' });
+ }
+
+ if (!to.meta.protected) {
+ return next(/* no-redirect */);
+ }
+
+ const isAuthenticated = AppStore.getters['profile/isAuthenticated'] === true;
+ if (!isAuthenticated) {
+ return next({ name: 'profiles.login' });
+ }
+
+ return next();
+ });
+ }
+
+ /**
+ * Gets routes from Parent Route Name
+ * @param {string} [parentRouteName]
+ * @returns {AppRoute[]}
+ */
+ public getRoutes(parentRouteName?: string): AppRoute[] {
+ const parentRoute = this.getParentRoute(parentRouteName);
+ if (!parentRoute) {
+ return [];
+ }
+ return this.getChildRoutes(parentRoute);
+ }
+
+ /**
+ * Get Tab Entries from Parent Route Name
+ *
+ * @param {string} [parentRouteName]
+ * @returns {TabEntry[]}
+ */
+ public getTabEntries(parentRouteName?: string): TabEntry[] {
+ const routes = this.getRoutes(parentRouteName);
+ return TabEntry.getFromRoutes(routes);
+ }
+
+ /**
+ * Gets a route from string
+ * @private
+ * @param {string} [parentRouteName]
+ * @returns {RouteConfig[]}
+ */
+ private getParentRoute(parentRouteName: string = ''): AppRoute {
+ const routes = [...this.routes];
+
+ // - read custom route configuration
+ // - first top level route contains all app routes
+ // - second top level route contains login
+ const appRoute = routes.shift();
+ /* const loginRoute =*/ routes.shift();
+
+ if (!parentRouteName.length) {
+ return appRoute;
+ }
+
+ // - find requested top level route
+ const modules = ['dashboard', 'mosaics', 'multisig', 'namespaces', 'settings', 'accounts', 'community', 'harvesting', 'aggregate'];
+
+ // - app modules
+ const moduleRoutes = appRoute.children.filter(({ name }) => modules.includes(name));
+
+ // - find by name
+ const module = moduleRoutes.find((r) => r.name === parentRouteName);
+
+ // - name does not represent a top level route
+ if (undefined === module) {
+ throw new Error(`Top level (module) route with name '${parentRouteName}' does not exist.`);
+ }
+
+ return module;
+ }
+
+ /**
+ * Gets child routes from a route
+ * @private
+ * @param {AppRoute[]} routes
+ * @returns {AppRoute[]}
+ */
+ private getChildRoutes(parentRoute: AppRoute): AppRoute[] {
+ if (!parentRoute.children) {
+ return [];
+ }
+ return [...parentRoute.children].filter(({ meta }) => !meta.hideFromMenu);
+ }
+}
+
+// create router instance
+const router = new AppRouter({
+ mode: 'hash',
+ routes,
+});
+
+export default router;
diff --git a/src/router/RouteMeta.ts b/src/router/RouteMeta.ts
new file mode 100644
index 0000000..58bb20e
--- /dev/null
+++ b/src/router/RouteMeta.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+/**
+ * Metadata added to Vue Router routes
+ * @interface RouteMeta
+ */
+export interface RouteMeta {
+ /**
+ * Authentication required
+ * @type {boolean}
+ */
+ protected: boolean;
+ /**
+ * Localized route name shown in the view
+ * @type {string}
+ */
+ title?: string;
+ // @TODO: REVIEW
+ clickable?: boolean;
+ isLedger?: boolean;
+ icon?: unknown;
+ active?: boolean;
+ nextPage?: string;
+ hideFromMenu?: boolean;
+}
diff --git a/src/router/TabEntry.ts b/src/router/TabEntry.ts
new file mode 100644
index 0000000..c423d9f
--- /dev/null
+++ b/src/router/TabEntry.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { Route } from 'vue-router';
+
+// internal dependencies
+import { AppRoute } from './AppRoute';
+
+export class TabEntry {
+ /**
+ * Get Tab Entries from routes
+ * @static
+ * @param {AppRoute[]} routes
+ * @returns {TabEntry[]}
+ */
+ public static getFromRoutes(routes: AppRoute[]): TabEntry[] {
+ return routes.map(({ meta, name }) => new TabEntry(meta?.title, name, meta?.icon as string));
+ }
+
+ /**
+ * Checks if the Tab Entry is the current route
+ * @param {Route} activeRoute
+ * @returns {boolean}
+ */
+ public isActive(activeRoute: Route): boolean {
+ return activeRoute.matched.map(({ name }) => name).includes(this.route);
+ }
+
+ /**
+ * Creates an instance of TabEntry.
+ * @param {string} title
+ * @param {string} route
+ * @param {string} icon
+ */
+ private constructor(public readonly title: string, public readonly route: string, public readonly icon: string | undefined) {}
+}
diff --git a/src/router/routes.ts b/src/router/routes.ts
new file mode 100644
index 0000000..2390fb1
--- /dev/null
+++ b/src/router/routes.ts
@@ -0,0 +1,561 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { createStepImage, importStepImage, officialIcons } from '@/views/resources/Images';
+import { AppRoute } from './AppRoute';
+
+export const routes: AppRoute[] = [
+ {
+ path: '/',
+ name: 'home',
+ meta: { protected: false },
+ redirect: { name: 'profiles.login' },
+ // @ts-ignore
+ component: () => import('@/views/layout/PageLayout/PageLayout.vue'),
+ /// region PageLayout children
+ children: [
+ {
+ path: '/dashboard',
+ name: 'dashboard',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_home',
+ icon: officialIcons.dashboard,
+ },
+ redirect: '/home',
+ // @ts-ignore
+ component: () => import('@/views/pages/dashboard/Dashboard.vue'),
+ children: [
+ {
+ path: '/home/:action?',
+ name: 'dashboard.index',
+ meta: {
+ protected: true,
+ title: 'page_title_history',
+ icon: officialIcons.history,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/dashboard/home/DashboardHomePage.vue'),
+ },
+ {
+ path: '/transfer/:recipientAddress?',
+ name: 'dashboard.transfer',
+ meta: {
+ protected: true,
+ title: 'page_title_send',
+ icon: officialIcons.send2,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/dashboard/transfer/DashboardTransferPage.vue'),
+ props: true,
+ },
+ {
+ path: '/invoice',
+ name: 'dashboard.invoice',
+ meta: {
+ protected: true,
+ title: 'page_title_invoice',
+ icon: officialIcons.receive2,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/dashboard/invoice/DashboardInvoicePage.vue'),
+ },
+ // {
+ // path: '/harvesting',
+ // name: 'dashboard.harvesting',
+ // meta: {
+ // protected: true,
+ // title: 'page_title_harvesting',
+ // },
+ // // @ts-ignore
+ // component: () => import('@/views/pages/dashboard/harvesting/DashboardHarvestingPage.vue'),
+ // }
+ ],
+ },
+ {
+ path: '/accounts',
+ name: 'accounts',
+ redirect: '/details',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_accounts',
+ icon: officialIcons.wallet,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/accounts/Accounts.vue'),
+ children: [
+ {
+ path: '/details',
+ name: 'accounts.details',
+ meta: {
+ protected: true,
+ title: 'page_title_account_details',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/accounts/AccountDetailsPage/AccountDetailsPage.vue'),
+ },
+ ],
+ },
+ {
+ path: '/mosaics',
+ name: 'mosaics',
+ redirect: '/mosaicList',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_mosaics',
+ icon: officialIcons.mosaic,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/mosaics/MosaicsDashboardPage/MosaicsDashboardPage.vue'),
+ children: [
+ {
+ path: '/mosaicList',
+ name: 'mosaics.list',
+ meta: {
+ protected: true,
+ title: 'page_title_mosaics',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/mosaics/MosaicListPage/MosaicListPage.vue'),
+ },
+ {
+ path: '/createMosaic',
+ name: 'mosaics.create',
+ meta: {
+ protected: true,
+ title: 'page_title_mosaics_create',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/mosaics/CreateMosaicPage/CreateMosaicPage.vue'),
+ },
+ ],
+ },
+ /**
+ * Namespaces module disabled as of 03.05.2021
+ *
+ * :note: Namespace prices are intentionally very high with dHealth,
+ * noteably because namespaces should not be created without consent
+ * of the dHealth team. For more information, please contact dHealth.
+ */
+ /*
+ * DISABLED
+ {
+ path: '/namespaces',
+ name: 'namespaces',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_namespaces',
+ icon: officialIcons.namespace,
+ },
+ redirect: '/namespaceList',
+ // @ts-ignore
+ component: () => import('@/views/pages/namespaces/NamespacesDashboardPage/NamespacesDashboardPage.vue'),
+ children: [
+ {
+ path: '/namespaceList',
+ name: 'namespaces.list',
+ meta: {
+ protected: true,
+ title: 'page_title_namespaces',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/namespaces/NamespaceListPage/NamespaceListPage.vue'),
+ },
+ {
+ path: '/createNamespace',
+ name: 'namespaces.createRootNamespace',
+ meta: {
+ protected: true,
+ title: 'page_title_namespaces_create',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/namespaces/CreateNamespacePage/CreateNamespacePage.vue'),
+ },
+ {
+ path: '/createSubNamespace',
+ name: 'namespaces.createSubNamespace',
+ meta: {
+ protected: true,
+ title: 'create_sub_namespace',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/namespaces/createSubNamespace/CreateSubNamespace.vue'),
+ },
+ ],
+ },
+ * END DISABLED
+**/
+ {
+ path: '/multisig',
+ name: 'multisig',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_multisig',
+ icon: officialIcons.multisig,
+ },
+ redirect: '/multisigManagement',
+ // @ts-ignore
+ component: () => import('@/views/pages/multisig/MultisigDashboardPage/MultisigDashboardPage.vue'),
+ children: [
+ {
+ path: '/multisigManagement',
+ name: 'multisig.management',
+ meta: {
+ protected: true,
+ title: 'page_title_multisig_manage',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/multisig/ManageAccountPage/ManageAccountPage.vue'),
+ },
+ ],
+ },
+ {
+ path: '/harvesting', //TODO: Harvesting
+ name: 'harvesting',
+ redirect: '/delegatedHarvesting',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_harvesting',
+ icon: officialIcons.harvest,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/harvesting/HarvestingDashboardPage/HarvestingDashboardPage.vue'),
+ children: [
+ {
+ path: '/delegatedHarvesting',
+ name: 'harvesting.delegated',
+ meta: { protected: true, title: 'page_title_delegated_harvesting' },
+ // @ts-ignore
+ component: () => import('@/views/pages/harvesting/HarvestingPage/HarvestingPage.vue'),
+ },
+ ],
+ },
+ {
+ path: '/aggregate',
+ name: 'aggregate',
+ redirect: '/aggregate/simple',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_aggregate',
+ icon: officialIcons.aggregate,
+ },
+ // @ts-ignore
+ component: () => import('@/views/forms/FormAggregateTransaction/FormAggregateTransaction.vue'),
+ children: [
+ {
+ path: '/aggregate/simple',
+ name: 'aggregate.simple',
+ meta: {
+ protected: true,
+ title: 'simple_transaction',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/aggregate/aggregateTransaction/AggregateTransaction.vue'),
+ },
+ {
+ path: '/aggregate/mosaic',
+ name: 'aggregate.mosaic',
+ meta: {
+ protected: true,
+ title: 'mosaic_transaction',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/aggregate/aggregateTransaction/AggregateTransaction.vue'),
+ },
+ {
+ path: '/aggregate/supply',
+ name: 'aggregate.supply',
+ meta: {
+ protected: true,
+ title: 'mosaic_supply_transaction',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/aggregate/aggregateTransaction/AggregateTransaction.vue'),
+ },
+ {
+ path: '/aggregate/namespace',
+ name: 'aggregate.namespace',
+ meta: {
+ protected: true,
+ title: 'namespace_transaction',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/aggregate/aggregateTransaction/AggregateTransaction.vue'),
+ },
+ ],
+ },
+ {
+ path: '/communityPanel', //TODO: Harvesting
+ name: 'community',
+ redirect: '/information',
+ meta: {
+ protected: true,
+ clickable: true,
+ title: 'sidebar_item_community',
+ icon: officialIcons.news,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/community/Community.vue'),
+ children: [
+ {
+ path: '/information',
+ name: 'community.index',
+ meta: { protected: true },
+ // @ts-ignore
+ component: () => import('@/views/pages/community/information/Information.vue'),
+ },
+ ],
+ },
+ ],
+ /// end-region PageLayout children
+ },
+ {
+ path: '/profiles',
+ name: 'profiles',
+ // @ts-ignore
+ component: () => import('@/views/layout/RouterPage.vue'),
+ meta: {
+ protected: false,
+ hideFromMenu: true,
+ },
+ children: [
+ {
+ path: 'create',
+ name: 'profiles.importProfile.importStrategy',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/import-profile/import-strategy/ImportStrategy.vue'),
+ },
+ {
+ path: 'create',
+ name: 'profiles.createProfile',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/create-profile/CreateProfile.vue'),
+ children: [
+ {
+ path: 'info',
+ name: 'profiles.createProfile.info',
+ meta: {
+ protected: false,
+ icon: createStepImage.createStepImage1,
+ nextPage: 'profiles.createProfile.generateMnemonic',
+ },
+ // @ts-ignore
+ component: () => import('@/views/forms/FormProfileCreation/FormProfileCreation.vue'),
+ },
+ {
+ path: 'generateMnemonic',
+ name: 'profiles.createProfile.generateMnemonic',
+ meta: {
+ protected: false,
+ icon: createStepImage.createStepImage2,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/create-profile/generate-mnemonic/GenerateMnemonic.vue'),
+ },
+ {
+ path: 'showMnemonic',
+ name: 'profiles.createProfile.showMnemonic',
+ meta: {
+ protected: false,
+ icon: createStepImage.createStepImage3,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/create-profile/show-mnemonic/ShowMnemonic.vue'),
+ },
+ {
+ path: 'verifyMnemonic',
+ name: 'profiles.createProfile.verifyMnemonic',
+ meta: {
+ protected: false,
+ icon: createStepImage.createStepImage4,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/create-profile/verify-mnemonic/VerifyMnemonic.vue'),
+ },
+ {
+ path: 'finishCreate',
+ name: 'profiles.createProfile.finalize',
+ meta: {
+ protected: false,
+ icon: createStepImage.createStepImage5,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/create-profile/finalize/Finalize.vue'),
+ },
+ ],
+ },
+ {
+ path: 'import',
+ name: 'profiles.importProfile',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/import-profile/ImportProfile.vue'),
+ children: [
+ {
+ path: 'inputAccountInfo',
+ name: 'profiles.importProfile.info',
+ meta: {
+ protected: false,
+ icon: importStepImage.importStepImage1,
+ nextPage: 'profiles.importProfile.importMnemonic',
+ },
+ // @ts-ignore
+ component: () => import('@/views/forms/FormProfileCreation/FormProfileCreation.vue'),
+ },
+ {
+ path: 'importMnemonic',
+ name: 'profiles.importProfile.importMnemonic',
+ meta: {
+ protected: false,
+ icon: importStepImage.importStepImage2,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/import-profile/import-mnemonic/ImportMnemonic.vue'),
+ },
+ {
+ path: 'walletChoose',
+ name: 'profiles.importProfile.walletSelection',
+ meta: {
+ protected: false,
+ icon: importStepImage.importStepImage3,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/import-profile/account-selection/AccountSelection.vue'),
+ },
+ {
+ path: 'finishImport',
+ name: 'profiles.importProfile.finalize',
+ meta: {
+ protected: false,
+ icon: importStepImage.importStepImage4,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/import-profile/finalize/Finalize.vue'),
+ },
+ ],
+ },
+ {
+ path: 'accessLedger',
+ name: 'profiles.accessLedger',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/access-ledger/AccessLedger.vue'),
+ children: [
+ {
+ path: 'info',
+ name: 'profiles.accessLedger.info',
+ meta: {
+ protected: false,
+ isLedger: true,
+ nextPage: 'profiles.accessLedger.walletSelection',
+ },
+ // @ts-ignore
+ component: () => import('@/views/forms/FormProfileCreation/FormProfileCreation.vue'),
+ },
+ {
+ path: 'walletChoose',
+ name: 'profiles.accessLedger.walletSelection',
+ meta: {
+ protected: false,
+ isLedger: true,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/access-ledger/account-selection/AccountSelection.vue'),
+ },
+ {
+ path: 'finishCreate',
+ name: 'profiles.accessLedger.finalize',
+ meta: {
+ protected: false,
+ isLedger: true,
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/access-ledger/finalize/Finalize.vue'),
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: '/login',
+ name: 'profiles.login',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/pages/profiles/LoginPage.vue'),
+ },
+ {
+ path: '/offline',
+ name: 'offline',
+ redirect: '/offline/transaction/simple',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/layout/RouterPage.vue'),
+ children: [
+ {
+ path: '/offlineTransaction',
+ name: 'offlineTransaction',
+ redirect: '/offlineTransaction/simple',
+ meta: { protected: false },
+ // @ts-ignore
+ component: () => import('@/views/pages/offline/OfflineTransaction.vue'),
+ children: [
+ {
+ path: '/offlineTransaction/simple',
+ name: 'offlineTransaction.simple',
+ meta: {
+ protected: false,
+ title: 'simple_transaction',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/offline/offlineTransferTransaction/OfflineTransferTransaction.vue'),
+ },
+ {
+ path: '/offlineTransaction/cosign',
+ name: 'offlineTransaction.cosign',
+ meta: {
+ protected: false,
+ title: 'cosign_transaction',
+ },
+ // @ts-ignore
+ component: () => import('@/views/pages/offline/offlineCosignTransaction/OfflineCosignTransaction.vue'),
+ },
+ ],
+ },
+ ],
+ },
+ {
+ path: '/privacy',
+ name: 'privacy',
+ meta: { protected: false, hideFromMenu: true },
+ // @ts-ignore
+ component: () => import('@/views/pages/privacy/PrivacyPolicy.vue'),
+ },
+ {
+ path: '/terms',
+ name: 'terms',
+ meta: { protected: false, hideFromMenu: true },
+ // @ts-ignore
+ component: () => import('@/views/pages/terms/TermsAndConditions.vue'),
+ },
+];
diff --git a/src/services/AccountService.ts b/src/services/AccountService.ts
new file mode 100755
index 0000000..0ad75c7
--- /dev/null
+++ b/src/services/AccountService.ts
@@ -0,0 +1,479 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Account, PublicAccount, Address, NetworkType, Password, SimpleWallet, Crypto } from 'symbol-sdk';
+import { ExtendedKey, MnemonicPassPhrase, Network, Wallet } from 'symbol-hd-wallets';
+// internal dependencies
+import { DerivationPathLevels, DerivationService } from './DerivationService';
+import { DerivationPathValidator } from '@/core/validation/validators';
+import { AccountModel, AccountType } from '@/core/database/entities/AccountModel';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { SimpleObjectStorage } from '@/core/database/backends/SimpleObjectStorage';
+import { AccountModelStorage } from '@/core/database/storage/AccountModelStorage';
+import { LedgerService } from '@/services/LedgerService';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+
+export class AccountService {
+ private readonly storage = AccountModelStorage.INSTANCE;
+
+ /**
+ * Default account derivation path
+ * @var {string}
+ */
+ private static readonly DEFAULT_ACCOUNT_PATH_MAIN_NET = `m/44'/4343'/0'/0'/0'`;
+ private static readonly DEFAULT_ACCOUNT_PATH_TEST_NET = `m/44'/1'/0'/0'/0'`;
+
+ public getAccounts(): AccountModel[] {
+ return Object.values(this.getAccountsById());
+ }
+
+ public getAccount(id: string): AccountModel | undefined {
+ return this.getAccountsById()[id];
+ }
+
+ public getAccountsById(): Record {
+ return this.storage.get() || {};
+ }
+
+ public saveAccount(account: AccountModel): AccountModel {
+ const accounts = this.getAccountsById();
+ accounts[account.id] = account;
+ this.storage.set(accounts);
+ return account;
+ }
+
+ public deleteAccount(account: AccountModel): void {
+ const accounts = this.getAccountsById();
+ delete accounts[account.id];
+ this.storage.set(accounts);
+ }
+
+ public deleteAccounts(profileName: string): void {
+ const accounts = this.getAccountsById();
+ Object.values(accounts)
+ .filter((account) => account.profileName === profileName)
+ .forEach((account) => delete accounts[account.id]);
+ this.storage.set(accounts);
+ }
+
+ public updateName(account: AccountModel, name: string): AccountModel {
+ return this.saveAccount(Object.assign(account, { name }));
+ }
+
+ public updateIsMultisig(account: AccountModel, isMultisig: boolean): AccountModel {
+ return this.saveAccount(Object.assign(account, { isMultisig }));
+ }
+
+ public updateRemoteAccount(account: AccountModel, encRemoteAccountPrivateKey: string): AccountModel {
+ return this.saveAccount(Object.assign(account, { encRemoteAccountPrivateKey }));
+ }
+
+ public updateSignedPersistentDelReqTxs(account: AccountModel, signedPersistentDelReqTxs): AccountModel {
+ return this.saveAccount(Object.assign(account, { signedPersistentDelReqTxs }));
+ }
+
+ public updateIsPersistentDelReqSent(account: AccountModel, isPersistentDelReqSent: boolean): AccountModel {
+ return this.saveAccount(Object.assign(account, { isPersistentDelReqSent }));
+ }
+
+ public updateSelectedHarvestingNode(account: AccountModel, selectedHarvestingNode: NodeModel): AccountModel {
+ return this.saveAccount(Object.assign(account, { selectedHarvestingNode }));
+ }
+
+ /**
+ * Derive \a path using \a mnemonic pass phrase
+ */
+ public getAccountByPath(mnemonic: MnemonicPassPhrase, networkType: NetworkType, path: string): Account {
+ if (!DerivationPathValidator.validate(path, networkType)) {
+ const errorMessage = 'Invalid derivation path: ' + path;
+ console.error(errorMessage);
+ throw new Error(errorMessage);
+ }
+
+ // create hd extended key
+ const extendedKey = ExtendedKey.createFromSeed(mnemonic.toSeed().toString('hex'), Network.SYMBOL);
+
+ // create account
+ const account = new Wallet(extendedKey);
+ return Account.createFromPrivateKey(account.getChildAccountPrivateKey(path), networkType);
+ }
+
+ /**
+ * Get extended key around \a mnemonic for \a networkTypw
+ * @param {MnemonicPassPhrase} mnemonic
+ * @param curve
+ * @return {ExtendedKey}
+ */
+ public getExtendedKeyFromMnemonic(mnemonic: MnemonicPassPhrase, curve = Network.SYMBOL): ExtendedKey {
+ return ExtendedKey.createFromSeed(mnemonic.toSeed().toString('hex'), curve);
+ }
+
+ /**
+ * Generate \a count accounts using \a mnemonic
+ * @param {MnemonicPassPhrase} mnemonic
+ * @param {NetworkType} networkType
+ * @param {number} count
+ * @param curve
+ * @return {Account[]}
+ */
+ public generateAccountsFromMnemonic(
+ mnemonic: MnemonicPassPhrase,
+ networkType: NetworkType,
+ count: number = 10,
+ curve = Network.SYMBOL,
+ ): Account[] {
+ const derivationService = new DerivationService(networkType);
+
+ // create hd extended key
+ const xkey = this.getExtendedKeyFromMnemonic(mnemonic, curve);
+
+ const default_path = AccountService.getAccountPathByNetworkType(networkType);
+ // increment derivation path \a count times
+ const paths = [...Array(count).keys()].map((index) => {
+ if (index == 0) {
+ return default_path;
+ }
+
+ return derivationService.incrementPathLevel(default_path, DerivationPathLevels.Profile, index);
+ });
+
+ const wallets = paths.map((path) => new Wallet(xkey.derivePath(path)));
+ return wallets.map((wallet) => Account.createFromPrivateKey(wallet.getAccountPrivateKey(), networkType));
+ }
+
+ /**
+ * Generate accounts using a mnemonic and an array of paths
+ * @param {MnemonicPassPhrase} mnemonic
+ * @param {NetworkType} networkType
+ * @param {string[]} paths
+ * @param curve
+ * @returns {Account[]}
+ */
+ public generateAccountsFromPaths(
+ mnemonic: MnemonicPassPhrase,
+ networkType: NetworkType,
+ paths: string[],
+ curve = Network.SYMBOL,
+ ): Account[] {
+ // create hd extended key
+ const xkey = this.getExtendedKeyFromMnemonic(mnemonic, curve);
+ const wallets = paths.map((path) => new Wallet(xkey.derivePath(path)));
+
+ return wallets.map((wallet) => Account.createFromPrivateKey(wallet.getAccountPrivateKey(), networkType));
+ }
+
+ /**
+ * Get list of addresses using \a mnemonic
+ * @return {Address[]}
+ */
+ public getAddressesFromMnemonic(
+ mnemonic: MnemonicPassPhrase,
+ networkType: NetworkType,
+ count: number = 10,
+ curve = Network.SYMBOL,
+ ): Address[] {
+ const accounts = this.generateAccountsFromMnemonic(mnemonic, networkType, count, curve);
+ return accounts.map((acct) => acct.address);
+ }
+
+ public getKnownAccounts(knownAccounts: string[]): AccountModel[] {
+ // search in known accounts
+ return this.getAccounts().filter((wlt) => knownAccounts.includes(wlt.id));
+ }
+
+ /**
+ * Create a account instance from mnemonic
+ * @return {AccountModel}
+ */
+ public getDefaultAccount(
+ currentProfile: ProfileModel,
+ mnemonic: MnemonicPassPhrase,
+ password: Password,
+ networkType: NetworkType,
+ ): AccountModel {
+ const default_path = AccountService.getAccountPathByNetworkType(networkType);
+ const account = this.getAccountByPath(mnemonic, networkType, default_path);
+
+ const simpleWallet = SimpleWallet.createFromPrivateKey('Seed Account 1', password, account.privateKey, networkType);
+
+ return {
+ id: SimpleObjectStorage.generateIdentifier(),
+ profileName: currentProfile.profileName,
+ name: simpleWallet.name,
+ node: '',
+ type: AccountType.SEED,
+ address: simpleWallet.address.plain(),
+ publicKey: account.publicKey,
+ encryptedPrivateKey: simpleWallet.encryptedPrivateKey,
+ path: default_path,
+ isMultisig: false,
+ };
+ }
+
+ /**
+ * Create a child account instance from mnemonic and path
+ * @return {AccountModel}
+ */
+ public getChildAccountByPath(
+ currentProfile: ProfileModel,
+ password: Password,
+ mnemonic: MnemonicPassPhrase,
+ nextPath: string,
+ networkType: NetworkType,
+ childAccountName: string,
+ ): AccountModel {
+ // - derive account
+ const account = this.getAccountByPath(mnemonic, networkType, nextPath);
+
+ const simpleWallet = SimpleWallet.createFromPrivateKey(childAccountName, password, account.privateKey, networkType);
+
+ return {
+ id: SimpleObjectStorage.generateIdentifier(),
+ profileName: currentProfile.profileName,
+ name: childAccountName,
+ node: '',
+ type: AccountType.SEED,
+ address: simpleWallet.address.plain(),
+ publicKey: account.publicKey,
+ encryptedPrivateKey: simpleWallet.encryptedPrivateKey,
+ path: nextPath,
+ isMultisig: false,
+ };
+ }
+
+ /**
+ * Create a sub account by private key
+ * @param currentProfile
+ * @param password
+ * @param childAccountName
+ * @param privateKey
+ * @param networkType
+ * @return {AccountModel}
+ */
+ public getSubAccountByPrivateKey(
+ currentProfile: ProfileModel,
+ password: Password,
+ childAccountName: string,
+ privateKey: string,
+ networkType: NetworkType,
+ ): AccountModel {
+ const account = Account.createFromPrivateKey(privateKey, networkType);
+ const simpleWallet = SimpleWallet.createFromPrivateKey(childAccountName, password, account.privateKey, networkType);
+
+ return {
+ id: SimpleObjectStorage.generateIdentifier(),
+ profileName: currentProfile.profileName,
+ name: childAccountName,
+ node: '',
+ type: AccountType.PRIVATE_KEY,
+ address: simpleWallet.address.plain(),
+ publicKey: account.publicKey,
+ encryptedPrivateKey: simpleWallet.encryptedPrivateKey,
+ path: '',
+ isMultisig: false,
+ };
+ }
+
+ /**
+ * Returns a AccountModel with an updated SimpleWallet
+ * @param {AccountModel} account
+ * @param {Password} oldPassword
+ * @param {Password} newPassword
+ */
+ public updateWalletPassword(account: AccountModel, oldPassword: Password, newPassword: Password): AccountModel {
+ if (account.type !== AccountType.SEED && account.type !== AccountType.PRIVATE_KEY && account.type !== AccountType.OPT_IN) {
+ return account;
+ }
+
+ const privateKey = Crypto.decrypt(account.encryptedPrivateKey, oldPassword.value);
+
+ // Encrypt the private key with the new password
+ const newSimpleWallet = SimpleWallet.createFromPrivateKey(
+ account.name,
+ newPassword,
+ privateKey,
+ AccountModel.getObjects(account).address.networkType,
+ );
+ // Update the account model
+ return {
+ ...account,
+ encryptedPrivateKey: newSimpleWallet.encryptedPrivateKey,
+ };
+ }
+
+ /**
+ * Get list of address from Ledger device
+ * @param {NetworkType} networkType
+ * @param {number} count
+ * @param curve
+ * @return {Promise}
+ */
+ public async getLedgerAccounts(networkType: NetworkType, count: number = 10, curve = Network.SYMBOL): Promise {
+ const isOptinLedgerWallet = curve === Network.BITCOIN;
+ const derivationService = new DerivationService(networkType);
+
+ const default_path = AccountService.getAccountPathByNetworkType(networkType);
+ // increment derivation path \a count times
+ const paths = [...Array(count).keys()].map((index) => {
+ if (index == 0) {
+ return default_path;
+ }
+
+ return derivationService.incrementPathLevel(default_path, DerivationPathLevels.Profile, index);
+ });
+ const publicKeys: string[] = [];
+ for (const path of paths) {
+ const publicKey = await this.getLedgerPublicKeyByPath(networkType, path, false, isOptinLedgerWallet);
+ publicKeys.push(publicKey.toUpperCase());
+ }
+ return publicKeys.map((publicKey) => PublicAccount.createFromPublicKey(publicKey, networkType).address);
+ }
+
+ /**
+ * Get list of public key from Ledger device
+ * @param {NetworkType} networkType
+ * @param {number} count
+ * @param curve
+ * @return {Promise}
+ */
+ public async getLedgerPublicKey(networkType: NetworkType, count: number = 10, curve = Network.SYMBOL): Promise {
+ const isOptinLedgerWallet = curve === Network.BITCOIN;
+ const derivationService = new DerivationService(networkType);
+
+ const default_path = AccountService.getAccountPathByNetworkType(networkType);
+ // increment derivation path \a count times
+ const paths = [...Array(count).keys()].map((index) => {
+ if (index == 0) {
+ return default_path;
+ }
+
+ return derivationService.incrementPathLevel(default_path, DerivationPathLevels.Profile, index);
+ });
+ const publicKeys: string[] = [];
+ for (const path of paths) {
+ const publicKey = await this.getLedgerPublicKeyByPath(networkType, path, false, isOptinLedgerWallet);
+ publicKeys.push(publicKey.toUpperCase());
+ }
+ return publicKeys.map((publicKey) => PublicAccount.createFromPublicKey(publicKey, networkType).publicKey);
+ }
+
+ /**
+ * Derive an public key from Ledger device using a path
+ * @param {NetworkType} networkType
+ * @param {string} paths
+ * @param {boolean} ledgerDisplay
+ * @param {boolean} isOptinLedgerWallet
+ * @return {Promise}
+ */
+ public async getLedgerPublicKeyByPath(
+ networkType: NetworkType,
+ path: string,
+ ledgerDisplay: boolean,
+ isOptinLedgerWallet: boolean,
+ ): Promise {
+ if (!DerivationPathValidator.validate(path, networkType)) {
+ const errorMessage = 'Invalid derivation path: ' + path;
+ console.error(errorMessage);
+ throw new Error(errorMessage);
+ }
+ const ledgerService = new LedgerService(networkType);
+ const accountResult = await ledgerService.getAccount(path, ledgerDisplay, isOptinLedgerWallet);
+ const { publicKey } = accountResult;
+ return publicKey;
+ }
+
+ /**
+ * Derive an account instance of Ledger device using a path
+ * @param {ProfileModel} currentProfile
+ * @param {NetworkType} networkType
+ * @param {string} paths
+ * @param {boolean} ledgerDisplay
+ * @param {boolean} isOptinLedgerWallet
+ * @return {Promise}
+ */
+ public async getLedgerAccountByPath(
+ currentProfile: ProfileModel,
+ networkType: NetworkType,
+ path: string,
+ ledgerDisplay: boolean,
+ isOptinLedgerWallet: boolean,
+ ): Promise {
+ const publicKey = await this.getLedgerPublicKeyByPath(networkType, path, ledgerDisplay, isOptinLedgerWallet);
+ const address = PublicAccount.createFromPublicKey(publicKey.toUpperCase(), networkType).address;
+ return {
+ id: SimpleObjectStorage.generateIdentifier(),
+ profileName: currentProfile.profileName,
+ name: currentProfile.profileName,
+ node: '',
+ type: isOptinLedgerWallet ? AccountType.LEDGER_OPT_IN : AccountType.LEDGER,
+ address: address.plain(),
+ publicKey: publicKey.toUpperCase(),
+ encryptedPrivateKey: '',
+ path: path,
+ isMultisig: false,
+ };
+ }
+
+ /**
+ * Derive accounts of ledger using an array of paths
+ * @param {NetworkType} networkType
+ * @param {string[]} paths
+ * @param curve
+ * @param {boolean} ledgerDisplay
+ * @returns {Promise}
+ */
+ public async generateLedgerAccountsPaths(
+ networkType: NetworkType,
+ paths: string[],
+ curve = Network.SYMBOL,
+ ledgerDisplay: boolean = false,
+ ): Promise {
+ const isOptinLedgerWallet = curve === Network.BITCOIN;
+ const accounts = [];
+ for (const path of paths) {
+ const publicKey = await this.getLedgerPublicKeyByPath(networkType, path, ledgerDisplay, isOptinLedgerWallet);
+ const account = PublicAccount.createFromPublicKey(publicKey.toUpperCase(), networkType);
+ accounts.push(account);
+ }
+ return accounts;
+ }
+
+ /**
+ * Create a account instance of Ledger from default path
+ * @param {ProfileModel} currentProfile
+ * @param {NetworkType} networkType
+ * @param {boolean} isOptinLedgerWallet
+ * @return {Promise}
+ */
+ public async getDefaultLedgerAccount(
+ currentProfile: ProfileModel,
+ networkType: NetworkType,
+ isOptinLedgerWallet: boolean,
+ ): Promise {
+ const defaultPath = AccountService.getAccountPathByNetworkType(networkType);
+ return await this.getLedgerAccountByPath(currentProfile, networkType, defaultPath, false, isOptinLedgerWallet);
+ }
+
+ /**
+ * Return account path by network type
+ * @param networkType Symbol network type
+ */
+ public static getAccountPathByNetworkType(networkType: NetworkType) {
+ if (networkType === NetworkType.MAIN_NET) {
+ return AccountService.DEFAULT_ACCOUNT_PATH_MAIN_NET;
+ }
+ return AccountService.DEFAULT_ACCOUNT_PATH_TEST_NET;
+ }
+}
diff --git a/src/services/AddressBookService.ts b/src/services/AddressBookService.ts
new file mode 100644
index 0000000..d0cb4e8
--- /dev/null
+++ b/src/services/AddressBookService.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { AddressBookModelStorage } from '@/core/database/storage/AddressBookModelStorage';
+import { AddressBook } from 'symbol-address-book/AddressBook';
+
+export class AddressBookService {
+ /**
+ * The namespace information local cache.
+ */
+ private readonly addressBookModelStorage = AddressBookModelStorage.INSTANCE;
+
+ public getAddressBook(profileName: string): AddressBook {
+ try {
+ const allAddressBooks = this.addressBookModelStorage.get() || {};
+ return AddressBook.fromJSON(allAddressBooks[profileName]);
+ } catch (e) {
+ return new AddressBook();
+ }
+ }
+
+ public saveAddressBook(addressBook: AddressBook, profileName: string): void {
+ const allAddressBooks = this.addressBookModelStorage.get() || {};
+ allAddressBooks[profileName] = addressBook.toJSON(false);
+ this.addressBookModelStorage.set(allAddressBooks);
+ }
+
+ public deleteAddressBook(profileName: string): void {
+ const allAddressBooks = this.addressBookModelStorage.get();
+ if (!allAddressBooks) {
+ return;
+ }
+ delete allAddressBooks[profileName];
+ this.addressBookModelStorage.set(allAddressBooks);
+ }
+}
diff --git a/src/services/AssetTableService/AccountRestrictionTableService.ts b/src/services/AssetTableService/AccountRestrictionTableService.ts
new file mode 100644
index 0000000..80f2f56
--- /dev/null
+++ b/src/services/AssetTableService/AccountRestrictionTableService.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+// @ts-ignore
+import i18n from '@/language';
+import RestrictionFlagMapping from '@/views/forms/FormAccountRestrictionTransaction/RestrictionFlagMapping';
+import { AccountRestriction, Address, MosaicId } from 'symbol-sdk';
+import { AssetTableService, TableField } from './AssetTableService';
+
+export class AccountRestrictionTableService extends AssetTableService {
+ constructor(private readonly accountRestrictions: AccountRestriction[]) {
+ super(0);
+ }
+
+ /**
+ * Return table fields to be displayed in a table header
+ * @returns {TableField[]}
+ */
+ public getTableFields(): TableField[] {
+ return [
+ { name: 'direction', label: 'table_header_direction' },
+ { name: 'value', label: 'table_header_value' },
+ { name: 'action', label: 'table_header_action' },
+ ];
+ }
+
+ /**
+ * Return table values to be displayed in a table rows
+ * @returns {MosaicTableRowValues[]}
+ */
+ public getTableRows(): any[] {
+ return this.accountRestrictions
+ .flatMap((r) => r.values.map((v) => ({ ...r, values: [v] } as AccountRestriction)))
+ .map((accountRestriction) => {
+ const direction = RestrictionFlagMapping.toDirection(accountRestriction.restrictionFlags);
+ const action = RestrictionFlagMapping.toBlockType(accountRestriction.restrictionFlags);
+ let rawValue = '';
+
+ if (accountRestriction?.values) {
+ const value = accountRestriction?.values[0];
+ if (value instanceof Address) {
+ rawValue = value.pretty();
+ } else if (value instanceof MosaicId) {
+ rawValue = value.toHex();
+ } else {
+ rawValue += i18n.t(`transaction_descriptor_${value}`);
+ }
+ }
+ return {
+ direction: direction,
+ value: rawValue,
+ action: action,
+ hiddenData: {
+ rowObject: accountRestriction,
+ },
+ };
+ })
+ .filter((x) => x); // filter out mosaics that are not yet available
+ }
+}
diff --git a/src/services/AssetTableService/AssetTableService.ts b/src/services/AssetTableService/AssetTableService.ts
new file mode 100644
index 0000000..d35409f
--- /dev/null
+++ b/src/services/AssetTableService/AssetTableService.ts
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+/**
+ * Table field to be used in a table header
+ * @export
+ * @interface TableField
+ */
+export interface TableField {
+ name: string;
+ label: string;
+}
+
+/**
+ * Sorting directions
+ * @export
+ * @type {SortingDirections}
+ */
+export type SortingDirections = 'asc' | 'desc';
+
+/**
+ * Sorting options
+ * @export
+ * @type {TableSortingOptions}
+ */
+export type TableSortingOptions = {
+ fieldName: string;
+ direction: SortingDirections;
+};
+
+/**
+ * Filtering types
+ * @export
+ * @type {FilteringTypes}
+ */
+export type FilteringTypes = 'show' | 'hide';
+
+/**
+ * Filtering options
+ * @export
+ * @type {TableFilteringOptions}
+ */
+export type TableFilteringOptions = {
+ fieldName: string;
+ filteringType: FilteringTypes;
+};
+
+export abstract class AssetTableService {
+ protected constructor(public readonly currentHeight: number) {}
+
+ /**
+ * Return table fields to be displayed in a table header
+ * @returns {TableField[]}
+ */
+ public abstract getTableFields(): TableField[];
+
+ /**
+ * Return table values to be displayed in a table rows
+ * @returns {TableRowValues[]}
+ */
+ public abstract getTableRows(): any[];
+
+ /**
+ * Filter table rows according to filtering options
+ * @param {TableRowValues[]} values
+ * @param {TableFilteringOptions} filterBy
+ * @returns {TableRowValues[]}
+ */
+ public filter(values: any[], filter: TableFilteringOptions): any[] {
+ if (filter.filteringType === 'show') {
+ return values;
+ }
+
+ if (filter.fieldName === 'expiration') {
+ return values.filter(({ expiration }) => expiration !== 'expired');
+ }
+
+ if (filter.fieldName === 'expired') {
+ return values.filter((value) => 'expired' in value && value.expired);
+ }
+
+ throw new Error(`Sorting by '${filter.fieldName}' field is not yet implemented`);
+ }
+
+ /**
+ * Sorts array values according to sorting options
+ * @param {TableRowValues[]} valuesToSort
+ * @param {TableSortingOptions} sortBy
+ * @returns {TableRowValues[]}
+ */
+ public sort(valuesToSort: any[], options: TableSortingOptions): any[] {
+ const values = [...valuesToSort];
+
+ function sortingMethodChooser(sortedValues) {
+ if (options.direction === 'desc') {
+ return sortedValues.reverse();
+ }
+ return sortedValues;
+ }
+
+ if (!values.length) {
+ return values;
+ }
+
+ // - use sample to identify fields type
+ const sampleValue = [...values][0][options.fieldName];
+
+ if (sampleValue === undefined) {
+ return values;
+ }
+
+ // - sorting method depends on type
+ if ('string' === typeof sampleValue) {
+ return sortingMethodChooser(
+ [...values].sort((a, b) => {
+ return a[options.fieldName]
+ .toLowerCase()
+ .localeCompare(b[options.fieldName].toLowerCase(), navigator.languages[0] || navigator.language, {
+ numeric: true,
+ ignorePunctuation: true,
+ });
+ }),
+ );
+ } else if ('boolean' === typeof sampleValue) {
+ return sortingMethodChooser(
+ [...values].sort((a, b) => {
+ return a[options.fieldName] === b[options.fieldName] ? 0 : a[options.fieldName] ? -1 : 1;
+ }),
+ );
+ } else if ('number' === typeof sampleValue) {
+ return sortingMethodChooser(
+ values.sort((a, b) => {
+ if (!b[options.fieldName] || !a[options.fieldName]) {
+ return 1;
+ }
+ return b[options.fieldName] - a[options.fieldName];
+ }),
+ );
+ }
+
+ throw new Error(`sorting the data type ${typeof sampleValue} is not supported`);
+ }
+}
diff --git a/src/services/AssetTableService/MetadataTableService.ts b/src/services/AssetTableService/MetadataTableService.ts
new file mode 100644
index 0000000..779b411
--- /dev/null
+++ b/src/services/AssetTableService/MetadataTableService.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+// internal dependencies
+import { AssetTableService, TableField } from './AssetTableService';
+import { MetadataModel } from '@/core/database/entities/MetadataModel';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+export class MetadataTableService extends AssetTableService {
+ constructor(
+ currentHeight: number,
+ private readonly metadatas: MetadataModel[],
+ private readonly networkConfiguration: NetworkConfigurationModel,
+ ) {
+ super(currentHeight);
+ }
+
+ /**
+ * Return table fields to be displayed in a table header
+ * @returns {TableField[]}
+ */
+ public getTableFields(): TableField[] {
+ return [
+ { name: 'targetAddress', label: 'table_header_target_address' },
+ { name: 'targetID', label: 'table_header_target_id' },
+ { name: 'targetType', label: 'table_header_target_type' },
+ { name: 'scopedMetadataKey', label: 'table_header_scoped_key' },
+ { name: 'status', label: 'table_header_status' },
+ { name: 'changeTimes', label: 'table_header_change_times' },
+ ];
+ }
+
+ public getTableRows(): any[] {
+ const metadatas: MetadataModel[] = this.metadatas;
+
+ return metadatas.map((metadataModel) => {
+ return {
+ hexId: metadataModel.metadataId,
+ scopedMetadataKey: metadataModel.scopedMetadataKey,
+ targetAddress: metadataModel.targetAddress,
+ targetId: metadataModel.targetId,
+ value: metadataModel.value,
+ };
+ });
+ }
+}
diff --git a/src/services/AssetTableService/MosaicTableService.ts b/src/services/AssetTableService/MosaicTableService.ts
new file mode 100644
index 0000000..ed3863f
--- /dev/null
+++ b/src/services/AssetTableService/MosaicTableService.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { AssetTableService, TableField } from './AssetTableService';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { MosaicService } from '@/services/MosaicService';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+export class MosaicTableService extends AssetTableService {
+ constructor(
+ currentHeight: number,
+ private readonly mosaics: MosaicModel[],
+ private readonly networkConfiguration: NetworkConfigurationModel,
+ ) {
+ super(currentHeight);
+ }
+
+ /**
+ * Return table fields to be displayed in a table header
+ * @returns {TableField[]}
+ */
+ public getTableFields(): TableField[] {
+ return [
+ { name: 'hexId', label: 'table_header_hex_id' },
+ { name: 'name', label: 'table_header_name' },
+ { name: 'supply', label: 'table_header_supply' },
+ { name: 'balance', label: 'table_header_balance' },
+ { name: 'expiration', label: 'table_header_expiration' },
+ { name: 'divisibility', label: 'table_header_divisibility' },
+ { name: 'transferable', label: 'table_header_transferable' },
+ { name: 'supplyMutable', label: 'table_header_supply_mutable' },
+ { name: 'restrictable', label: 'table_header_restrictable' },
+ ];
+ }
+
+ /**
+ * Return table values to be displayed in a table rows
+ * @returns {MosaicTableRowValues[]}
+ */
+ public getTableRows(): any[] {
+ // - get reactive mosaic data from the store
+ const mosaicsInfo = this.mosaics;
+ const currentHeight = this.currentHeight;
+ return mosaicsInfo
+ .map((mosaicInfo) => {
+ const expiration = MosaicService.getExpiration(
+ mosaicInfo,
+ currentHeight,
+ this.networkConfiguration.blockGenerationTargetTime,
+ );
+ // - map table fields
+ return {
+ hexId: mosaicInfo.mosaicIdHex,
+ name: mosaicInfo.name || 'N/A',
+ supply: mosaicInfo.supply.toLocaleString(),
+ balance: (mosaicInfo.balance || 0) / Math.pow(10, mosaicInfo.divisibility),
+ expiration: expiration,
+ divisibility: mosaicInfo.divisibility,
+ transferable: mosaicInfo.transferable,
+ supplyMutable: mosaicInfo.supplyMutable,
+ restrictable: mosaicInfo.restrictable,
+ metadataList: mosaicInfo.metadataList || [],
+ };
+ })
+ .filter((x) => x); // filter out mosaics that are not yet available
+ }
+}
diff --git a/src/services/AssetTableService/NamespaceTableService.ts b/src/services/AssetTableService/NamespaceTableService.ts
new file mode 100644
index 0000000..96cc00c
--- /dev/null
+++ b/src/services/AssetTableService/NamespaceTableService.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import { AliasType } from 'symbol-sdk';
+// internal dependencies
+import { AssetTableService, TableField } from './AssetTableService';
+import { NamespaceModel } from '@/core/database/entities/NamespaceModel';
+import { NamespaceService } from '@/services/NamespaceService';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+
+export class NamespaceTableService extends AssetTableService {
+ constructor(
+ currentHeight: number,
+ private readonly namespaces: NamespaceModel[],
+ private readonly networkConfiguration: NetworkConfigurationModel,
+ ) {
+ super(currentHeight);
+ }
+
+ /**
+ * Return table fields to be displayed in a table header
+ * @returns {TableField[]}
+ */
+ public getTableFields(): TableField[] {
+ return [
+ { name: 'hexId', label: 'table_header_hex_id' },
+ { name: 'name', label: 'table_header_name' },
+ { name: 'expiration', label: 'table_header_expiration' },
+ { name: 'expired', label: 'table_header_expired' },
+ { name: 'aliasType', label: 'table_header_alias_type' },
+ { name: 'aliasIdentifier', label: 'table_header_alias_identifier' },
+ ];
+ }
+
+ public getTableRows(): any[] {
+ const namespaces: NamespaceModel[] = this.namespaces;
+
+ return namespaces.map((namespaceModel) => {
+ const { expired, expiration } = this.getExpiration(namespaceModel);
+
+ return {
+ hexId: namespaceModel.namespaceIdHex,
+ name: namespaceModel.name,
+ expiration: expiration,
+ expired: expired,
+ aliasType: this.getAliasType(namespaceModel),
+ aliasIdentifier: this.getAliasIdentifier(namespaceModel),
+ metadataList: namespaceModel.metadataList || [],
+ };
+ });
+ }
+
+ /**
+ * Gets the namespace type to be displayed in the table
+ * @private
+ * @param the namespace model.
+ * @returns {('N/A' | 'address' | 'mosaic')}
+ */
+ private getAliasType(namespaceModel: NamespaceModel): 'N/A' | 'address' | 'mosaic' {
+ if (!namespaceModel.aliasTargetAddressRawPlain && !namespaceModel.aliasTargetMosaicIdHex) {
+ return 'N/A';
+ }
+ return namespaceModel.aliasType === AliasType.Address ? 'address' : 'mosaic';
+ }
+
+ /**
+ * Gets the namespace identifier to be displayed in the table
+ * @private
+ * @param the namespace model.
+ * @returns {string}
+ */
+ private getAliasIdentifier(namespaceModel: NamespaceModel): string {
+ return namespaceModel.aliasTargetMosaicIdHex || namespaceModel.aliasTargetAddressRawPlain || 'N/A';
+ }
+
+ /**
+ * Returns a view of a namespace expiration info
+ * @public
+ * @param the namespace model.
+ * @returns {string}
+ */
+ private getExpiration(namespaceModel: NamespaceModel): { expiration: string; expired: boolean } {
+ return NamespaceService.getExpiration(this.networkConfiguration, this.currentHeight, namespaceModel.endHeight);
+ }
+}
diff --git a/src/services/BlockService.ts b/src/services/BlockService.ts
new file mode 100644
index 0000000..904f634
--- /dev/null
+++ b/src/services/BlockService.ts
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { BlockInfoModelStorage } from '@/core/database/storage/BlockInfoModelStorage';
+import { RepositoryFactory, UInt64 } from 'symbol-sdk';
+import { BlockInfoModel } from '@/core/database/entities/BlockInfoModel';
+import { Observable, of } from 'rxjs';
+import { flatMap, map, tap } from 'rxjs/operators';
+import * as _ from 'lodash';
+import { ObservableHelpers } from '@/core/utils/ObservableHelpers';
+
+export class BlockService {
+ /**
+ * The namespace information local cache.
+ */
+ private readonly blockInfoModelStorage = BlockInfoModelStorage.INSTANCE;
+
+ public getKnownBlockInfos(generationHash: string): BlockInfoModel[] {
+ return this.blockInfoModelStorage.get(generationHash) || [];
+ }
+
+ public getBlockInfo(
+ repositoryFactory: RepositoryFactory,
+ height: UInt64,
+ alreadyLoadedBlocks: BlockInfoModel[],
+ ): Observable {
+ return repositoryFactory.getGenerationHash().pipe(
+ flatMap((generationHash) => {
+ const blockInfoModels = this.getKnownBlockInfos(generationHash);
+ const cachedModel = blockInfoModels.find((m) => m.height === height.toString());
+ const alreadyLoadedBlock = alreadyLoadedBlocks.find((m) => m.height === height.toString());
+ //Only load from rest the first time in the app session (but using the stored cache for quick user feedback).
+ if (cachedModel && alreadyLoadedBlock && cachedModel.generationHash === alreadyLoadedBlock.generationHash) {
+ return of(cachedModel);
+ }
+ return repositoryFactory
+ .createBlockRepository()
+ .getBlockByHeight(height)
+ .pipe(
+ map((dto) => new BlockInfoModel(dto)),
+ tap((model) => {
+ const blockInfoModels = _.uniqBy([model, ...this.getKnownBlockInfos(generationHash)], 'height');
+ this.blockInfoModelStorage.set(generationHash, blockInfoModels);
+ }),
+ ObservableHelpers.defaultFirst(cachedModel),
+ );
+ }),
+ );
+ }
+}
diff --git a/src/services/CommunityService.ts b/src/services/CommunityService.ts
new file mode 100644
index 0000000..dcc6348
--- /dev/null
+++ b/src/services/CommunityService.ts
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import RSSParser from 'rss-parser';
+// configuration
+import { appConfig } from '@/config';
+
+/// region protected helpers
+/**
+ * Request external feed data
+ * @internal
+ * @return {Promise}
+ */
+const request = async (): Promise => {
+ let feedUrl = appConfig.articlesFeedUrl;
+ if (process.env.NODE_ENV === 'development') {
+ feedUrl = '/nemflash';
+ }
+ // execute request
+ const response = await fetch(feedUrl, {
+ method: 'GET',
+ }).then((response) => {
+ return response.text();
+ });
+ return response;
+};
+
+/// end-region protected helpers
+
+export interface ArticleEntry {
+ /**
+ * Publication date
+ */
+ pubDate: string;
+ /**
+ * Article creator
+ */
+ creator: string;
+ /**
+ * Article title
+ */
+ title: string;
+ /**
+ * Article excerpt
+ */
+ contentSnippet: string;
+ /**
+ * Article link
+ */
+ link: string;
+}
+
+export class CommunityService {
+ /**
+ * Get latest articles from RSS feed
+ * @return {Promise {
+ const data = await request();
+
+ // *safely* parse stream
+ let parsedStream;
+ try {
+ parsedStream = await new RSSParser().parseString(data);
+ } catch (e) {
+ parsedStream = { items: [] };
+ }
+
+ return parsedStream.items.map(({ pubDate, creator, title, contentSnippet, link }) => ({
+ pubDate,
+ creator,
+ title,
+ contentSnippet,
+ link:
+ link && link.length && link.match(/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/g)
+ ? link
+ : '#',
+ }));
+ }
+}
diff --git a/src/services/DerivationService.ts b/src/services/DerivationService.ts
new file mode 100644
index 0000000..0d18f2a
--- /dev/null
+++ b/src/services/DerivationService.ts
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// internal dependencies
+import { DerivationPathValidator } from '@/core/validation/validators';
+import { AccountService } from '@/services/AccountService';
+import { NetworkType } from 'symbol-sdk/dist/src/model/network/NetworkType';
+
+export enum DerivationPathLevels {
+ Purpose = 1,
+ CoinType = 2,
+ Profile = 3,
+ Remote = 4, // BIP44=change
+ Address = 5,
+}
+
+export class DerivationService {
+ /**
+ * constructor
+ * @param networkType network type
+ */
+ constructor(public readonly networkType: NetworkType) {}
+
+ /**
+ * Validate derivation path
+ * @param {string} path
+ * @return {boolean}
+ */
+ public isValidPath(path: string): boolean {
+ return DerivationPathValidator.validate(path, this.networkType);
+ }
+
+ /**
+ * Increment a derivation path level
+ * @param {string} path
+ * @param {DerivationPathLevel} which
+ * @return {string}
+ */
+ public incrementPathLevel(path: string, which: DerivationPathLevels = DerivationPathLevels.Profile, step: number = 1): string {
+ // make sure derivation path is valid
+ this.assertValidPath(path);
+
+ // purpose and coin type cannot be changed
+ this.assertCanModifyLevel(which);
+
+ // read levels and increment
+ const index = which as number;
+ const parts = path.split('/');
+
+ // calculate next index (increment)
+ const next = (step <= 1 ? 1 : step) + parseInt(parts[index].replace(/'/, ''));
+
+ // modify affected level only
+ return parts
+ .map((level, idx) => {
+ if (idx !== index) {
+ return level;
+ }
+ return `${next}'`;
+ })
+ .join('/');
+ }
+
+ /**
+ * Returns the first missing consecutive account path in a path array
+ * @param {string[]} paths
+ * @returns {string}
+ */
+ public getNextAccountPath(paths: string[]): string {
+ const defaultPath = AccountService.getAccountPathByNetworkType(this.networkType);
+
+ // return the default path if no path in the array
+ if (!paths.length) {
+ return defaultPath;
+ }
+
+ // return the default path if it is not in the array
+ if (paths.indexOf(defaultPath) === -1) {
+ return defaultPath;
+ }
+
+ // get the sorted path indexes for the given derivation path level
+ const pathsSortedByIndexes = paths
+ .map((path) => ({
+ path,
+ pathIndex: parseInt(path.split('/')[DerivationPathLevels.Profile], 10),
+ }))
+ .sort((a, b) => a.pathIndex - b.pathIndex);
+
+ // get the first non consecutive path index
+ const firstCandidate = pathsSortedByIndexes
+ // fill an array with indexes with no consecutive next index, and the last index
+ .filter(({ pathIndex }, i, self) => {
+ // the last path is always a candidate
+ if (i === self.length - 1) {
+ return true;
+ }
+
+ // next path is not consecutive, add it to candidates
+ if (self[i + 1].pathIndex !== pathIndex + 1) {
+ return true;
+ }
+
+ // next path is consecutive, skip
+ return false;
+ })
+ .find((path) => path); // find the first candidate
+
+ // return path incremented from the first candidate
+ return this.incrementPathLevel(firstCandidate.path, DerivationPathLevels.Profile);
+ }
+
+ /**
+ * Decrement a derivation path level
+ * @param {string} path
+ * @param {DerivationPathLevel} which
+ * @return {string}
+ */
+ public decrementPathLevel(path: string, which: DerivationPathLevels = DerivationPathLevels.Profile, step: number = 1): string {
+ // make sure derivation path is valid
+ this.assertValidPath(path);
+
+ // purpose and coin type cannot be changed
+ this.assertCanModifyLevel(which);
+
+ // read levels and increment
+ const index = which as number;
+ const parts = path.split('/');
+
+ // calculate next index (decrement)
+ let next = parseInt(parts[index].replace(/'/, '')) - (step <= 1 ? 1 : step);
+ if (next < 0) {
+ next = 0;
+ }
+
+ // modify affected level only
+ return parts
+ .map((level, idx) => {
+ if (idx !== index) {
+ return level;
+ }
+ return `${next}'`;
+ })
+ .join('/');
+ }
+
+ /**
+ * Assert whether \a path is a valid derivation path
+ * @param {string} path
+ * @return {void}
+ * @throws {Error} On \a path with invalid derivation path
+ */
+ public assertValidPath(path: string): void {
+ if (!this.isValidPath(path)) {
+ const errorMessage = 'Invalid derivation path: ' + path;
+ console.error(errorMessage);
+ throw new Error(errorMessage);
+ }
+ }
+
+ /**
+ * Assert whether derivation path level can be modified
+ * @param {DerivationPathLevels} which
+ * @return {void}
+ * @throws {Error} On \a which with protected path level value
+ */
+ public assertCanModifyLevel(which: DerivationPathLevels): void {
+ const protect = [DerivationPathLevels.Purpose, DerivationPathLevels.CoinType];
+ if (undefined !== protect.find((type) => which === type)) {
+ const errorMessage = "Cannot modify a derivation path's purpose and coin type levels.";
+ console.error(errorMessage);
+ throw new Error(errorMessage);
+ }
+ }
+}
diff --git a/src/services/HarvestingService.ts b/src/services/HarvestingService.ts
new file mode 100644
index 0000000..6440ea5
--- /dev/null
+++ b/src/services/HarvestingService.ts
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { HarvestingModel } from '@/core/database/entities/HarvestingModel';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+import { HarvestingModelStorage } from '@/core/database/storage/HarvestingModelStorage';
+
+export class HarvestingService {
+ private readonly harvestingStorage = HarvestingModelStorage.INSTANCE;
+
+ public getAllHarvestingModels(): HarvestingModel[] {
+ return this.harvestingStorage.get() || [];
+ }
+
+ public getHarvestingModel(accountAddress: string): HarvestingModel {
+ return this.getAllHarvestingModels().find((h) => h.accountAddress === accountAddress);
+ }
+
+ /**
+ * Adds or Updates a HarvestingModel
+ * @param harvestingModel
+ */
+ public saveHarvestingModel(harvestingModel: HarvestingModel) {
+ const allHarvestingModels = this.getAllHarvestingModels();
+ const itemInx = allHarvestingModels.findIndex((h) => h.accountAddress === harvestingModel.accountAddress);
+ if (itemInx >= 0) {
+ allHarvestingModels[itemInx] = harvestingModel;
+ } else {
+ allHarvestingModels.push(harvestingModel);
+ }
+ this.harvestingStorage.set(allHarvestingModels);
+ return;
+ }
+
+ public updateSignedPersistentDelReqTxs(harvestingModel: HarvestingModel, signedPersistentDelReqTxs) {
+ this.saveHarvestingModel(Object.assign(harvestingModel, { signedPersistentDelReqTxs }));
+ }
+ public updateRemoteKey(harvestingModel: HarvestingModel, encRemotePrivateKey: string) {
+ this.saveHarvestingModel(Object.assign(harvestingModel, { encRemotePrivateKey }));
+ }
+ public updateVrfKey(harvestingModel: HarvestingModel, encVrfPrivateKey: string) {
+ this.saveHarvestingModel(Object.assign(harvestingModel, { encVrfPrivateKey }));
+ }
+
+ public updateIsPersistentDelReqSent(harvestingModel: HarvestingModel, isPersistentDelReqSent: boolean) {
+ this.saveHarvestingModel(Object.assign(harvestingModel, { isPersistentDelReqSent }));
+ }
+
+ public updateSelectedHarvestingNode(harvestingModel: HarvestingModel, selectedHarvestingNode: NodeModel) {
+ this.saveHarvestingModel(Object.assign(harvestingModel, { selectedHarvestingNode }));
+ }
+ public updateDelegatedHarvestingRequestFailed(harvestingModel: HarvestingModel, delegatedHarvestingRequestFailed: boolean) {
+ this.saveHarvestingModel(Object.assign(harvestingModel, { delegatedHarvestingRequestFailed }));
+ }
+}
diff --git a/src/services/LedgerService.ts b/src/services/LedgerService.ts
new file mode 100644
index 0000000..7fa03fe
--- /dev/null
+++ b/src/services/LedgerService.ts
@@ -0,0 +1,113 @@
+import { DerivationPathValidator } from '@/core/validation/validators';
+import { SymbolLedger } from '@/core/utils/Ledger';
+import TransportWebUSB from '@ledgerhq/hw-transport-webusb';
+import { NetworkType } from 'symbol-sdk/dist/src/model/network/NetworkType';
+const TransportNodeHid = window['TransportNodeHid'] && window['TransportNodeHid'].default;
+
+export class LedgerService {
+ private transport;
+
+ /**
+ * constructor
+ * @param networkType network type
+ */
+ constructor(public readonly networkType: NetworkType) {}
+
+ private async openTransport() {
+ return TransportNodeHid ? await TransportNodeHid.open() : await TransportWebUSB.create();
+ }
+
+ private async closeTransport() {
+ TransportNodeHid && this.transport && (await this.transport.close());
+ }
+
+ private formatError(error) {
+ return error.statusCode || error.id ? { errorCode: error.statusCode || error.id } : error;
+ }
+
+ public async isAppSupported() {
+ try {
+ this.transport = await this.openTransport();
+ const symbolLedger = new SymbolLedger(this.transport, 'XYM');
+ const result = await symbolLedger.isAppSupported();
+ return result;
+ } catch (error) {
+ throw this.formatError(error);
+ } finally {
+ await this.closeTransport();
+ }
+ }
+
+ public async getAccount(path: string, display: boolean, isOptinLedgerWallet: boolean) {
+ try {
+ if (!DerivationPathValidator.validate(path, this.networkType)) {
+ const errorMessage = 'Invalid derivation path: ' + path;
+ throw new Error(errorMessage);
+ }
+ this.transport = await this.openTransport();
+ const symbolLedger = new SymbolLedger(this.transport, 'XYM');
+ const result = await symbolLedger.getAccount(path, this.networkType, display, false, isOptinLedgerWallet);
+ return result;
+ } catch (error) {
+ throw this.formatError(error);
+ } finally {
+ await this.closeTransport();
+ }
+ }
+
+ public async signTransaction(
+ path: string,
+ transferTransaction: any,
+ networkGenerationHash: string,
+ signerPublicKey: string,
+ isOptinLedgerWallet: boolean,
+ ) {
+ try {
+ if (!DerivationPathValidator.validate(path, this.networkType)) {
+ const errorMessage = 'Invalid derivation path: ' + path;
+ throw new Error(errorMessage);
+ }
+ this.transport = await this.openTransport();
+ const symbolLedger = new SymbolLedger(this.transport, 'XYM');
+ const result = await symbolLedger.signTransaction(
+ path,
+ transferTransaction,
+ networkGenerationHash,
+ signerPublicKey,
+ isOptinLedgerWallet,
+ );
+ return result;
+ } catch (error) {
+ throw this.formatError(error);
+ } finally {
+ await this.closeTransport();
+ }
+ }
+
+ public async signCosignatureTransaction(
+ path: string,
+ cosignatureTransaction: any,
+ signerPublicKey: string,
+ isOptinLedgerWallet: boolean,
+ ) {
+ try {
+ if (!DerivationPathValidator.validate(path, this.networkType)) {
+ const errorMessage = 'Invalid derivation path: ' + path;
+ throw new Error(errorMessage);
+ }
+ this.transport = await this.openTransport();
+ const symbolLedger = new SymbolLedger(this.transport, 'XYM');
+ const result = await symbolLedger.signCosignatureTransaction(
+ path,
+ cosignatureTransaction,
+ signerPublicKey,
+ isOptinLedgerWallet,
+ );
+ return result;
+ } catch (error) {
+ throw this.formatError(error);
+ } finally {
+ await this.closeTransport();
+ }
+ }
+}
diff --git a/src/services/MediaService.ts b/src/services/MediaService.ts
new file mode 100644
index 0000000..5e3119c
--- /dev/null
+++ b/src/services/MediaService.ts
@@ -0,0 +1,14 @@
+//@ts-ignore
+import soundDing from '@/views/resources/audio/ding.ogg';
+//@ts-ignore
+import soundDing2 from '@/views/resources/audio/ding2.ogg';
+
+export class MediaService {
+ public static playUnconfirmedTransactionSound(): void {
+ new Audio(soundDing).play();
+ }
+
+ public static playConfirmedTransactionSound(): void {
+ new Audio(soundDing2).play();
+ }
+}
diff --git a/src/services/MetadataService.ts b/src/services/MetadataService.ts
new file mode 100644
index 0000000..147be59
--- /dev/null
+++ b/src/services/MetadataService.ts
@@ -0,0 +1,166 @@
+/**
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import {
+ Address,
+ MetadataType,
+ RepositoryFactory,
+ Transaction,
+ NetworkType,
+ Deadline,
+ UInt64,
+ KeyGenerator,
+ MosaicId,
+ NamespaceId,
+ MetadataTransactionService,
+ MetadataSearchCriteria,
+ Crypto,
+ Convert,
+} from 'symbol-sdk';
+import { from, Observable, of } from 'rxjs';
+import { map } from 'rxjs/operators';
+import { MetadataModel } from '@/core/database/entities/MetadataModel';
+import { MetadataModelStorage } from '@/core/database/storage/MetadataModelStorage';
+
+/**
+ * The service in charge of loading and caching anything related to Metadata from Rest.
+ * The cache is done by storing the payloads in SimpleObjectStorage.
+ */
+
+export class MetadataService {
+ /**
+ * The metadata information local cache.
+ */
+ private readonly metadataModelStorage = MetadataModelStorage.INSTANCE;
+
+ /**
+ * This method loads and caches the metadata information for the given accounts.
+ * The returned Observable will announce the cached information first, then the rest returned
+ * information (if possible).
+ *
+ * @param repositoryFactory the repository factory
+ * @param generationHash the current network generation hash.
+ * @param address the current address.
+ */
+ public getMetadataList(repositoryFactory: RepositoryFactory, generationHash: string, address: Address): Observable {
+ if (!address) {
+ return of([]);
+ }
+ if (!repositoryFactory) {
+ return of([]);
+ }
+ const metadataRepository = repositoryFactory.createMetadataRepository();
+
+ // search where user is target
+ const targetSearchCriteria: MetadataSearchCriteria = { targetAddress: address };
+ const uniquMetaArray: MetadataModel[] = [];
+ metadataRepository
+ .search(targetSearchCriteria)
+ .pipe(map((metadataListPage) => metadataListPage.data.map((metadata) => new MetadataModel(metadata))))
+ .subscribe((t) => {
+ t.map((value) => {
+ if (!uniquMetaArray.find((o) => o.metadataId === value.metadataId)) {
+ uniquMetaArray.push(value);
+ }
+ });
+ });
+
+ // search where user is sender of metadata
+ const sourceSearchCriteria: MetadataSearchCriteria = { sourceAddress: address };
+ metadataRepository
+ .search(sourceSearchCriteria)
+ .pipe(map((metadataListPage) => metadataListPage.data.map((metadata) => new MetadataModel(metadata))))
+ .subscribe((t) => {
+ t.map((value) => {
+ if (!uniquMetaArray.find((o) => o.metadataId === value.metadataId)) {
+ uniquMetaArray.push(value);
+ }
+ });
+ });
+ return from([uniquMetaArray]);
+ }
+
+ /**
+ * get metadata creation observable
+ * @returns {Observable}
+ */
+ public metadataTransactionObserver(
+ repositoryFactory: RepositoryFactory,
+ deadline: Deadline,
+ networkType: NetworkType,
+ sourceAddress: Address,
+ targetAddress: Address,
+ MetadataKey: string,
+ value: string,
+ targetId: string,
+ metadataType: MetadataType,
+ maxFee: UInt64,
+ ): Observable {
+ const scopedMetadataKey = MetadataKey ? UInt64.fromHex(MetadataKey) : KeyGenerator.generateUInt64Key(Crypto.randomBytes(8));
+
+ const metadataRepository = repositoryFactory.createMetadataRepository();
+ const metadataTransactionService = new MetadataTransactionService(metadataRepository);
+
+ let metadataObservable: Observable = null;
+
+ const encodedValue = Convert.utf8ToHex(value);
+ if (metadataType === MetadataType.Account) {
+ metadataObservable = metadataTransactionService.createAccountMetadataTransaction(
+ deadline,
+ networkType,
+ targetAddress,
+ scopedMetadataKey,
+ encodedValue,
+ sourceAddress,
+ maxFee,
+ );
+ } else if (metadataType === MetadataType.Mosaic) {
+ const mosaicId = new MosaicId(targetId);
+ metadataObservable = metadataTransactionService.createMosaicMetadataTransaction(
+ deadline,
+ networkType,
+ targetAddress,
+ mosaicId,
+ scopedMetadataKey,
+ encodedValue,
+ sourceAddress,
+ maxFee,
+ );
+ } else {
+ const namespaceId = new NamespaceId(targetId);
+ metadataObservable = metadataTransactionService.createNamespaceMetadataTransaction(
+ deadline,
+ networkType,
+ targetAddress,
+ namespaceId,
+ scopedMetadataKey,
+ encodedValue,
+ sourceAddress,
+ maxFee,
+ );
+ }
+
+ return metadataObservable;
+ }
+
+ /**
+ * get metadata list by target id
+ * @param metadataList
+ * @param targetId MosaicId | NamespaceId
+ */
+ public static getMosaicMetadataByTargetId(metadataList: MetadataModel[], targetId: string) {
+ return (metadataList && metadataList.filter((metadataModel) => metadataModel.targetId === targetId)) || [];
+ }
+}
diff --git a/src/services/MosaicService.ts b/src/services/MosaicService.ts
new file mode 100644
index 0000000..ab8750c
--- /dev/null
+++ b/src/services/MosaicService.ts
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// external dependencies
+import _ from 'lodash';
+import { AccountInfo, Address, Currency, MosaicId, MosaicInfo, MosaicNames, NamespaceId, RepositoryFactory, UInt64 } from 'symbol-sdk';
+import { combineLatest, from, Observable, of } from 'rxjs';
+import { map, mergeMap, tap, toArray } from 'rxjs/operators';
+// internal dependencies
+import { MosaicConfigurationModel, AccountMosaicConfigurationModel } from '@/core/database/entities/MosaicConfigurationModel';
+import { MosaicModel } from '@/core/database/entities/MosaicModel';
+import { NetworkCurrencyModel } from '@/core/database/entities/NetworkCurrencyModel';
+import { ObservableHelpers } from '@/core/utils/ObservableHelpers';
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+import { NetworkCurrenciesModel } from '@/core/database/entities/NetworkCurrenciesModel';
+import { MosaicModelStorage } from '@/core/database/storage/MosaicModelStorage';
+import { NetworkCurrenciesModelStorage } from '@/core/database/storage/NetworkCurrenciesModelStorage';
+import { MosaicConfigurationModelStorage } from '@/core/database/storage/MosaicConfigurationModelStorage';
+import { AccountModel } from '@/core/database/entities/AccountModel';
+
+// custom types
+export type ExpirationStatus = 'unlimited' | 'expired' | string | number;
+
+// TODO. Can this interface be removed?
+export interface AttachedMosaic {
+ id: MosaicId | NamespaceId;
+ mosaicHex: string;
+ /**
+ * Relative amount
+ */
+ amount: number;
+}
+
+interface MosaicBalance {
+ mosaicId: MosaicId;
+ amount: UInt64;
+ address: Address;
+}
+
+/**
+ * The service in charge of loading and caching anything related to Mosaics from Rest.
+ * The cache is done by storing the payloads in SimpleObjectStorage.
+ *
+ * The service also holds configuration about the current mosaics, for example which mosaic
+ * balances are currently hidden.
+ */
+export class MosaicService {
+ /**
+ * Store that caches the mosaic information of the current accounts when returned from rest.
+ */
+ private readonly mosaicDataStorage = MosaicModelStorage.INSTANCE;
+
+ /**
+ * The storage to keep user configuration around mosaics. For example, the balance hidden
+ * feature.
+ */
+ private readonly mosaicConfigurationsStorage = MosaicConfigurationModelStorage.INSTANCE;
+
+ /**
+ * Store that caches the information around the network currency.
+ */
+ private readonly networkCurrencyStorage = NetworkCurrenciesModelStorage.INSTANCE;
+
+ /**
+ * This method loads and caches the mosaic information for the given accounts.
+ * The returned Observable will announce the cached information first, then the rest returned
+ * information (if possible).
+ *
+ * @param {RepositoryFactory} repositoryFactory
+ * @param {string} generationHash
+ * @param {NetworkCurrencyModel} networkCurrency
+ * @param {AccountInfo[]} accountsInfo
+ * @returns {Observable}
+ */
+ public getMosaics(
+ repositoryFactory: RepositoryFactory,
+ generationHash: string,
+ networkCurrency: NetworkCurrencyModel,
+ accountsInfo: AccountInfo[],
+ ownerAddress: Address,
+ ): Observable {
+ if (!accountsInfo.length) {
+ return of([]);
+ }
+ const mosaicDataList = this.loadMosaicData(generationHash) || [];
+ const resolvedBalancesObservable = this.resolveBalances(repositoryFactory, accountsInfo);
+ const accountAddresses = accountsInfo.map((a) => a.address);
+ const mosaicsFromAccountsObservable = repositoryFactory.createMosaicRepository().search({ ownerAddress });
+
+ return combineLatest([resolvedBalancesObservable, mosaicsFromAccountsObservable])
+ .pipe(
+ mergeMap(([balances, owedMosaics]) => {
+ const mosaicIds: MosaicId[] = _.uniqBy(
+ [...balances.map((m) => m.mosaicId), ...owedMosaics.data.map((o) => o.id)],
+ (m) => m.toHex(),
+ );
+ const nameObservables = repositoryFactory.createNamespaceRepository().getMosaicsNames(mosaicIds);
+ const mosaicInfoObservable = this.loadMosaic(repositoryFactory, mosaicIds, owedMosaics.data);
+ return combineLatest([nameObservables, mosaicInfoObservable]).pipe(
+ map(([names, mosaicInfos]) => {
+ return this.toMosaicDtos(balances, mosaicInfos, names, networkCurrency, accountAddresses);
+ }),
+ );
+ }),
+ )
+ .pipe(
+ tap((d) => this.saveMosaicData(generationHash, d)),
+ ObservableHelpers.defaultFirst(mosaicDataList),
+ );
+ }
+
+ private loadMosaic(
+ repositoryFactory: RepositoryFactory,
+ mosaicIds: MosaicId[],
+ alreadyLoadedMosaics: MosaicInfo[],
+ ): Observable {
+ const toLoadMosaicIds = mosaicIds.filter((mosaicId) => !alreadyLoadedMosaics.some((info) => info.id.equals(mosaicId)));
+ if (toLoadMosaicIds.length) {
+ return repositoryFactory
+ .createMosaicRepository()
+ .getMosaics(toLoadMosaicIds)
+ .pipe(map((newMosaics) => newMosaics.concat(alreadyLoadedMosaics)));
+ } else {
+ return of(alreadyLoadedMosaics);
+ }
+ }
+
+ private getName(mosaicNames: MosaicNames[], accountMosaicDto: MosaicId): string {
+ return _.first(
+ mosaicNames
+ .filter((n) => n.mosaicId.equals(accountMosaicDto))
+ .filter((n) => n.names.length)
+ .map((n) => n.names[0].name),
+ );
+ }
+
+ private toMosaicDtos(
+ balances: MosaicBalance[],
+ mosaicDtos: MosaicInfo[],
+ mosaicNames: MosaicNames[],
+ networkCurrency: NetworkCurrencyModel,
+ accountAddresses: Address[],
+ ): MosaicModel[] {
+ return _.flatten(
+ accountAddresses.map((address) => {
+ return mosaicDtos.map((mosaicDto) => {
+ const name = this.getName(mosaicNames, mosaicDto.id);
+ const isCurrencyMosaic = mosaicDto.id.toHex() === networkCurrency.mosaicIdHex;
+ const balance = balances.find((balance) => balance.mosaicId.equals(mosaicDto.id) && balance.address.equals(address));
+ return new MosaicModel(
+ address.plain(),
+ mosaicDto.ownerAddress.plain(),
+ name,
+ isCurrencyMosaic,
+ (balance && balance.amount.compact()) || 0,
+ mosaicDto,
+ );
+ });
+ }),
+ );
+ }
+
+ private resolveBalances(repositoryFactory: RepositoryFactory, accountsInfo: AccountInfo[]): Observable {
+ const mosaicIdOrAliases = _.flatten(accountsInfo.map((a) => a.mosaics.map((m) => m.id)));
+ const mosaicIdOrAliasesUnique = _.uniqBy(mosaicIdOrAliases, (m) => m.toHex());
+ return this.resolveMosaicIds(repositoryFactory, mosaicIdOrAliasesUnique).pipe(
+ map((resolveMosaicIds) => {
+ return _.flatten(
+ accountsInfo.map((a) => {
+ return a.mosaics.map((m) => {
+ return {
+ address: a.address,
+ amount: m.amount,
+ mosaicId: resolveMosaicIds.find((pair) => pair.from.equals(m.id)).to,
+ };
+ });
+ }),
+ );
+ }),
+ );
+ }
+
+ private resolveMosaicIds(
+ repositoryFactory: RepositoryFactory,
+ ids: (NamespaceId | MosaicId)[],
+ ): Observable<{ from: NamespaceId | MosaicId; to: MosaicId }[]> {
+ const namespaceRepository = repositoryFactory.createNamespaceRepository();
+ return from(ids)
+ .pipe(
+ mergeMap((id) => {
+ if (id instanceof MosaicId) {
+ return of({ from: id, to: id as MosaicId });
+ } else {
+ const linkedMosaicIdObservable = namespaceRepository.getLinkedMosaicId(id as NamespaceId);
+ return linkedMosaicIdObservable.pipe(
+ map((to) => {
+ return { from: id, to: to };
+ }),
+ );
+ }
+ }),
+ )
+ .pipe(toArray());
+ }
+
+ /**
+ * This method returns the list of {@link NetworkCurrencyModel} of the network.
+ *
+ * The intent of this method is to resolve the configured main (like cat.currency or symbol.xym)
+ * and harvest currencies (cat.harvest) returned by the network configuration endpoint.
+ *
+ * @param {RepositoryFactory} repositoryFactory
+ * @param {generationHash} the generation hash.
+ * @returns {Observable}
+ */
+ public getNetworkCurrencies(repositoryFactory: RepositoryFactory, generationHash: string): Observable {
+ return repositoryFactory.getCurrencies().pipe(
+ map((networkMosaics) => {
+ const currency = this.getNetworkCurrency(networkMosaics.currency);
+ const harvest = this.getNetworkCurrency(networkMosaics.harvest);
+ return new NetworkCurrenciesModel(currency, harvest);
+ }),
+ tap((d) => this.networkCurrencyStorage.set(generationHash, d)),
+ );
+ }
+
+ private loadMosaicData(generationHash: string): MosaicModel[] {
+ return this.mosaicDataStorage.get(generationHash);
+ }
+
+ private saveMosaicData(generationHash: string, mosaics: MosaicModel[]) {
+ this.mosaicDataStorage.set(generationHash, mosaics);
+ }
+
+ public reset(generationHash: string) {
+ this.mosaicDataStorage.remove(generationHash);
+ this.networkCurrencyStorage.remove(generationHash);
+ }
+
+ /**
+ * Creates a network currency model given mosaic info and mosaic names
+ * @param {MosaicInfo} mosaicInfo
+ * @param {MosaicNames} mosaicName
+ * @returns {(NetworkCurrencyModel | undefined)}
+ */
+ private getNetworkCurrency(currency: Currency): NetworkCurrencyModel {
+ const mosaicId = currency.mosaicId;
+ const namespaceId = currency.namespaceId;
+ const ticker = (namespaceId && namespaceId.fullName && namespaceId.fullName.split('.').pop().toUpperCase()) || undefined;
+ return new NetworkCurrencyModel(
+ mosaicId?.toHex(),
+ namespaceId?.toHex(),
+ namespaceId.fullName,
+ currency.divisibility,
+ currency.transferable,
+ currency.supplyMutable,
+ currency.restrictable,
+ ticker,
+ );
+ }
+
+ /**
+ *
+ * Utility method that returns the mosaic expiration status
+ * @param mosaicInfo the mosaic info
+ * @param currentHeight
+ * @param blockGenerationTargetTime
+ */
+ public static getExpiration(mosaicInfo: MosaicModel, currentHeight: number, blockGenerationTargetTime: number): ExpirationStatus {
+ const duration = mosaicInfo.duration;
+ const startHeight = mosaicInfo.height;
+
+ // unlimited duration mosaics are flagged as duration == 0
+ if (duration === 0) {
+ return 'unlimited';
+ }
+
+ // get current height
+ // calculate expiration
+ const expiresIn = startHeight + duration - (currentHeight || 0);
+ if (expiresIn <= 0) {
+ return 'expired';
+ }
+ // number of blocks remaining
+ return TimeHelpers.durationToRelativeTime(expiresIn, blockGenerationTargetTime);
+ }
+
+ public getMosaicConfigurationsByAccount(account: AccountModel): AccountMosaicConfigurationModel {
+ return this.getMosaicConfigurations()[account.id] || {};
+ }
+
+ public getMosaicConfiguration(mosaicId: MosaicId, account: AccountModel): MosaicConfigurationModel {
+ return this.getMosaicConfigurationsByAccount(account)[mosaicId.toHex()] || new MosaicConfigurationModel();
+ }
+ public getMosaicConfigurations(): Record {
+ return this.mosaicConfigurationsStorage.get() || {};
+ }
+ public changeMosaicConfiguration(mosaicId: MosaicId, account: AccountModel, newConfigs: any): Record {
+ const mosaicConfigurationsStorage = this.getMosaicConfigurations();
+ mosaicConfigurationsStorage[account.id] = mosaicConfigurationsStorage[account.id] ? mosaicConfigurationsStorage[account.id] : {};
+ mosaicConfigurationsStorage[account.id][mosaicId.toHex()] = {
+ ...this.getMosaicConfiguration(mosaicId, account),
+ ...newConfigs,
+ };
+ this.mosaicConfigurationsStorage.set(mosaicConfigurationsStorage);
+ return mosaicConfigurationsStorage[account.id];
+ }
+}
diff --git a/src/services/MultisigService.ts b/src/services/MultisigService.ts
new file mode 100644
index 0000000..56643d0
--- /dev/null
+++ b/src/services/MultisigService.ts
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address, MultisigAccountGraphInfo, MultisigAccountInfo, NetworkType } from 'symbol-sdk';
+// internal dependencies
+import { AccountModel } from '@/core/database/entities/AccountModel';
+import { Signer } from '@/store/Account';
+
+export class MultisigService {
+ /**
+ * Returns all available multisig info from a multisig graph
+ * @static
+ * @param {MultisigAccountGraphInfo} multisig graph info
+ * @returns {MultisigAccountInfo[]} multisig info
+ */
+ public static getMultisigInfoFromMultisigGraphInfo(graphInfo: MultisigAccountGraphInfo): MultisigAccountInfo[] {
+ const { multisigEntries } = graphInfo;
+ return [].concat(...this.getMultisigGraphArraySorted(multisigEntries)).map((item) => item); // flatten
+ }
+
+ public static getMultisigGraphArraySorted(multisigEntries: Map): MultisigAccountInfo[][] {
+ return [...multisigEntries.keys()]
+ .sort((a, b) => b - a) // Get addresses from top to bottom
+ .map((key) => multisigEntries.get(key) || [])
+ .filter((x) => x.length > 0);
+ }
+
+ public getSigners(
+ networkType: NetworkType,
+ knownAccounts: AccountModel[],
+ currentAccount: AccountModel,
+ currentAccountMultisigInfo: MultisigAccountInfo | undefined,
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ multisigAccountsInfo: MultisigAccountInfo[] | undefined,
+ ): Signer[] {
+ if (!currentAccount) {
+ return [];
+ }
+ const self: Signer[] = [
+ {
+ address: Address.createFromRawAddress(currentAccount.address),
+ label: currentAccount.name,
+ multisig: currentAccountMultisigInfo && currentAccountMultisigInfo.isMultisig(),
+ requiredCosignatures: (currentAccountMultisigInfo && currentAccountMultisigInfo.minApproval) || 0,
+ },
+ ];
+
+ if (!currentAccountMultisigInfo) {
+ return self;
+ }
+
+ // check if other child multisig accounts are already cosigners of other accounts and add their children multisig as signers if any to the main cosignatory account
+ let addedSignerFromMutlisigAccounts: Signer[] = [].concat(self);
+ multisigAccountsInfo.map((entry) => {
+ if (
+ (entry.minApproval > 0 || entry.minRemoval > 0) &&
+ entry.multisigAddresses.length > 0 &&
+ entry.cosignatoryAddresses.some((value) => value.equals(Address.createFromRawAddress(currentAccount.address)))
+ ) {
+ entry.multisigAddresses.map((address) => {
+ if (!addedSignerFromMutlisigAccounts.some((val) => val.address.equals(address))) {
+ return (addedSignerFromMutlisigAccounts = addedSignerFromMutlisigAccounts.concat([
+ {
+ address: address,
+ multisig: true,
+ label: this.getAccountLabel(address, knownAccounts),
+ requiredCosignatures: (currentAccountMultisigInfo && currentAccountMultisigInfo.minApproval) || 0,
+ },
+ ]));
+ }
+ });
+ }
+ });
+
+ // check for next level signers and add them to the main cosignatory as signers if any
+ let addressesFromNextLevel: Signer[] = [].concat(addedSignerFromMutlisigAccounts);
+ multisigAccountsInfo.map((term) => {
+ if (
+ !term.accountAddress.equals(Address.createFromRawAddress(currentAccount.address)) &&
+ !addressesFromNextLevel.find((val) => val.address.equals(term.accountAddress))
+ ) {
+ return (addressesFromNextLevel = addressesFromNextLevel.concat([
+ {
+ address: term.accountAddress,
+ multisig: !!term.cosignatoryAddresses.length,
+ label: this.getAccountLabel(term.accountAddress, knownAccounts),
+ requiredCosignatures: (currentAccountMultisigInfo && term.minApproval) || 0,
+ },
+ ]));
+ }
+ });
+ return addressesFromNextLevel;
+ }
+
+ private getAccountLabel(address: Address, accounts: AccountModel[]): string {
+ const account = accounts.find((wlt) => address.plain() === wlt.address);
+ return (account && account.name) || address.plain();
+ }
+}
diff --git a/src/services/NamespaceService.ts b/src/services/NamespaceService.ts
new file mode 100644
index 0000000..b287dfd
--- /dev/null
+++ b/src/services/NamespaceService.ts
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NamespaceModel } from '@/core/database/entities/NamespaceModel';
+import { Address, NamespaceName, RepositoryFactory } from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+import { flatMap, map } from 'rxjs/operators';
+import * as _ from 'lodash';
+import { TimeHelpers } from '@/core/utils/TimeHelpers';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { NamespaceModelStorage } from '@/core/database/storage/NamespaceModelStorage';
+
+/**
+ * The service in charge of loading and caching anything related to Namepsaces from Rest.
+ * The cache is done by storing the payloads in SimpleObjectStorage.
+ */
+export class NamespaceService {
+ /**
+ * The namespace information local cache.
+ */
+ private readonly namespaceModelStorage = NamespaceModelStorage.INSTANCE;
+
+ /**
+ * This method loads and caches the namespace information for the given accounts.
+ * The returned Observable will announce the cached information first, then the rest returned
+ * information (if possible).
+ *
+ * @param repositoryFactory the repository factory
+ * @param generationHash the current network generation hash.
+ * @param addresses the current addresses.
+ */
+ public getNamespaces(
+ repositoryFactory: RepositoryFactory,
+ address: Address,
+ { pageSize, pageNumber }: { pageSize: number; pageNumber: number } = {
+ pageSize: 20,
+ pageNumber: 1,
+ },
+ ): Observable<{ models: NamespaceModel[]; pageInfo: { pageNumber: number; isLastPage: boolean } }> {
+ if (!address) {
+ return of({ models: [], pageInfo: { pageNumber: 1, isLastPage: true } });
+ }
+
+ const namespaceRepository = repositoryFactory.createNamespaceRepository();
+
+ return namespaceRepository.search({ ownerAddress: address, pageSize, pageNumber }).pipe(
+ flatMap((namespaceInfos) => {
+ return namespaceRepository
+ .getNamespacesNames(namespaceInfos.data.map((info) => info.id))
+ .pipe(
+ map((names) => {
+ return namespaceInfos.data.map((namespaceInfo) => {
+ const reference = _.first(names.filter((n) => n.namespaceId.toHex() === namespaceInfo.id.toHex()));
+ return new NamespaceModel(namespaceInfo, NamespaceService.getFullNameFromNamespaceNames(reference, names));
+ });
+ }),
+ )
+ .pipe(
+ map((models) => {
+ return {
+ models,
+ pageInfo: {
+ pageNumber: namespaceInfos.pageNumber,
+ isLastPage: namespaceInfos.isLastPage,
+ },
+ };
+ }),
+ );
+ }),
+ );
+ }
+
+ public static getExpiration(
+ networkConfiguration: NetworkConfigurationModel,
+ currentHeight: number,
+ endHeight: number,
+ ): { expiration: string; expired: boolean } {
+ const blockGenerationTargetTime = networkConfiguration.blockGenerationTargetTime;
+ const namespaceGracePeriodBlocks = Math.floor(networkConfiguration.namespaceGracePeriodDuration / blockGenerationTargetTime);
+ const expired = currentHeight > endHeight - namespaceGracePeriodBlocks;
+ const expiredIn = endHeight - namespaceGracePeriodBlocks - currentHeight;
+ const deletedIn = endHeight - currentHeight;
+ const expiration = expired
+ ? TimeHelpers.durationToRelativeTime(expiredIn, blockGenerationTargetTime)
+ : TimeHelpers.durationToRelativeTime(deletedIn, blockGenerationTargetTime);
+ return { expired, expiration };
+ }
+
+ /**
+ * Constructs a namespace fullName from namespace names
+ * @static
+ * @param {NamespaceName} reference
+ * @param {NamespaceName[]} namespaceNames
+ * @returns the full namespace name.
+ */
+ public static getFullNameFromNamespaceNames(reference: NamespaceName, namespaceNames: NamespaceName[]): string {
+ if (!reference) {
+ return '';
+ }
+ if (!reference.parentId) {
+ return reference.name;
+ }
+
+ const parent = namespaceNames.find((namespaceName) => namespaceName.namespaceId.toHex() === reference.parentId.toHex());
+ if (parent === undefined) {
+ return reference.name;
+ }
+ const parentName = NamespaceService.getFullNameFromNamespaceNames(parent, namespaceNames);
+ return `${parentName}.${reference.name}`;
+ }
+}
diff --git a/src/services/NetworkService.ts b/src/services/NetworkService.ts
new file mode 100644
index 0000000..35be957
--- /dev/null
+++ b/src/services/NetworkService.ts
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ * Copyright 2021-present [Using Blockchain Ltd](https://using-blockchain.org), All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { networkConfig } from '@/config';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { NetworkModel } from '@/core/database/entities/NetworkModel';
+import { NetworkModelStorage } from '@/core/database/storage/NetworkModelStorage';
+import { NetworkConfigurationHelpers } from '@/core/utils/NetworkConfigurationHelpers';
+import { ObservableHelpers } from '@/core/utils/ObservableHelpers';
+import { URLHelpers } from '@/core/utils/URLHelpers';
+import { combineLatest, defer, EMPTY, from, Observable } from 'rxjs';
+import { catchError, flatMap, map, tap } from 'rxjs/operators';
+import { NetworkConfiguration, NetworkType, RepositoryFactory, RepositoryFactoryHttp } from 'symbol-sdk';
+import { OfflineRepositoryFactory } from '@/services/offline/OfflineRepositoryFactory';
+
+/**
+ * The service in charge of loading and caching anything related to Network from Rest.
+ * The cache is done by storing the payloads in SimpleObjectStorage.
+ */
+export class NetworkService {
+ /**
+ * The network information local cache.
+ */
+ private readonly storage = NetworkModelStorage.INSTANCE;
+
+ /**
+ * The best default Url. It uses the stored configuration if possible.
+ */
+ public getDefaultUrl(): string {
+ const storedNetworkModel = this.storage.getLatest();
+ return URLHelpers.formatUrl(storedNetworkModel && storedNetworkModel.url).url;
+ }
+
+ /**
+ * This method get the network data from the provided URL. If the server in the candidateUrl is down,
+ * the next available url will be used.
+ *
+ * @param nodeUrl
+ * @param defaultNetworkType
+ * @param isOffline
+ */
+ public getNetworkModel(
+ nodeUrl: string,
+ defaultNetworkType: NetworkType = NetworkType.TEST_NET,
+ isOffline = false,
+ networkName: string = 'mainnet',
+ ): Observable<{
+ networkModel: NetworkModel;
+ repositoryFactory: RepositoryFactory;
+ }> {
+ return from(this.createRepositoryFactory(nodeUrl, isOffline, defaultNetworkType)).pipe(
+ flatMap(({ url, repositoryFactory }) => {
+ return repositoryFactory.getGenerationHash().pipe(
+ flatMap((generationHash) => {
+ const networkRepository = repositoryFactory.createNetworkRepository();
+ const nodeRepository = repositoryFactory.createNodeRepository();
+ const networkTypeObservable = repositoryFactory
+ .getNetworkType()
+ .pipe(ObservableHelpers.defaultLast(defaultNetworkType));
+ const generationHashObservable = repositoryFactory.getGenerationHash();
+
+ const networkPropertiesObservable = networkRepository
+ .getNetworkProperties()
+ .pipe(map((d) => this.toNetworkConfigurationModel(d, defaultNetworkType)));
+ const nodeInfoObservable = nodeRepository.getNodeInfo();
+
+ const transactionFeesObservable = repositoryFactory.createNetworkRepository().getTransactionFees();
+
+ return combineLatest([
+ networkTypeObservable,
+ generationHashObservable,
+ networkPropertiesObservable,
+ nodeInfoObservable,
+ transactionFeesObservable,
+ ]).pipe(
+ map(([networkType, generationHash, networkProperties, nodeInfo, transactionFees]) => {
+ return {
+ networkModel: new NetworkModel(
+ url,
+ networkType,
+ networkName,
+ generationHash,
+ networkProperties,
+ transactionFees,
+ nodeInfo,
+ ),
+ repositoryFactory,
+ };
+ }),
+ tap((p) => this.storage.set(generationHash, p.networkModel)),
+ );
+ }),
+ );
+ }),
+ );
+ }
+
+ private createRepositoryFactory(
+ url: string,
+ isOffline = false,
+ networkType = NetworkType.TEST_NET,
+ ): Observable<{ url: string; repositoryFactory: RepositoryFactory }> {
+ // console.log(`Testing ${url}`);
+ const repositoryFactory = NetworkService.createRepositoryFactory(url, isOffline, networkType);
+ return defer(() => {
+ return repositoryFactory.getGenerationHash();
+ }).pipe(
+ map(() => {
+ // console.log(`Peer ${url} seems OK`);
+ return { url, repositoryFactory };
+ }),
+ catchError((e) => {
+ console.log(`Peer ${url} seems down. Ignoring. Error: ${e.message}`, e);
+ return EMPTY;
+ }),
+ );
+ }
+
+ private toNetworkConfigurationModel(dto: NetworkConfiguration, networkType: NetworkType): NetworkConfigurationModel {
+ const fileDefaults: NetworkConfigurationModel = networkConfig[networkType].networkConfigurationDefaults;
+ const fromDto: NetworkConfigurationModel = {
+ epochAdjustment: NetworkConfigurationHelpers.epochAdjustment(dto),
+ maxMosaicDivisibility: NetworkConfigurationHelpers.maxMosaicDivisibility(dto),
+ namespaceGracePeriodDuration: NetworkConfigurationHelpers.namespaceGracePeriodDuration(dto),
+ lockedFundsPerAggregate: NetworkConfigurationHelpers.lockedFundsPerAggregate(dto),
+ maxCosignatoriesPerAccount: NetworkConfigurationHelpers.maxCosignatoriesPerAccount(dto),
+ blockGenerationTargetTime: NetworkConfigurationHelpers.blockGenerationTargetTime(dto),
+ maxNamespaceDepth: NetworkConfigurationHelpers.maxNamespaceDepth(dto),
+ maxMosaicDuration: NetworkConfigurationHelpers.maxMosaicDuration(dto),
+ minNamespaceDuration: NetworkConfigurationHelpers.minNamespaceDuration(dto),
+ maxNamespaceDuration: NetworkConfigurationHelpers.maxNamespaceDuration(dto),
+ maxTransactionsPerAggregate: NetworkConfigurationHelpers.maxTransactionsPerAggregate(dto),
+ maxCosignedAccountsPerAccount: NetworkConfigurationHelpers.maxCosignedAccountsPerAccount(dto),
+ maxMessageSize: NetworkConfigurationHelpers.maxMessageSize(dto),
+ maxMosaicAtomicUnits: NetworkConfigurationHelpers.maxMosaicAtomicUnits(dto),
+ currencyMosaicId: NetworkConfigurationHelpers.currencyMosaicId(dto),
+ harvestingMosaicId: NetworkConfigurationHelpers.harvestingMosaicId(dto),
+ defaultDynamicFeeMultiplier: NetworkConfigurationHelpers.defaultDynamicFeeMultiplier(dto),
+ totalChainImportance: NetworkConfigurationHelpers.totalChainImportance(dto),
+ };
+ return { ...fileDefaults, ...fromDto };
+ }
+
+ public reset(generationHash: string) {
+ this.storage.remove(generationHash);
+ }
+
+ /**
+ * It creates the RepositoryFactory used to build the http repository/clients and listeners.
+ * @param url the url.
+ */
+ public static createRepositoryFactory(url: string, isOffline: boolean = false, networkType = NetworkType.TEST_NET): RepositoryFactory {
+ return isOffline
+ ? new OfflineRepositoryFactory(networkType)
+ : new RepositoryFactoryHttp(url, {
+ websocketUrl: URLHelpers.httpToWsUrl(url) + '/ws',
+ websocketInjected: WebSocket,
+ });
+ }
+}
diff --git a/src/services/NodeService.ts b/src/services/NodeService.ts
new file mode 100644
index 0000000..081cb94
--- /dev/null
+++ b/src/services/NodeService.ts
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { NetworkType, NodeInfo, RepositoryFactory } from 'symbol-sdk';
+import { Observable } from 'rxjs';
+import { ObservableHelpers } from '@/core/utils/ObservableHelpers';
+import { map, tap } from 'rxjs/operators';
+import { NodeModel } from '@/core/database/entities/NodeModel';
+import * as _ from 'lodash';
+import { networkConfig } from '@/config';
+import { NodeModelStorage } from '@/core/database/storage/NodeModelStorage';
+
+/**
+ * The service in charge of loading and caching anything related to Node and Peers from Rest.
+ * The cache is done by storing the payloads in SimpleObjectStorage.
+ */
+export class NodeService {
+ /**
+ * The peer information local cache.
+ */
+ private readonly storage = NodeModelStorage.INSTANCE;
+
+ public getKnowNodesOnly(networkType: NetworkType): NodeModel[] {
+ return _.uniqBy(this.loadNodes().concat(this.loadStaticNodes(networkType)), 'url').filter((n) => n.networkType === networkType);
+ }
+
+ public getNodes(repositoryFactory: RepositoryFactory, repositoryFactoryUrl: string, networkType: NetworkType): Observable {
+ const storedNodes = this.getKnowNodesOnly(networkType);
+ const nodeRepository = repositoryFactory.createNodeRepository();
+
+ return nodeRepository.getNodeInfo().pipe(
+ map((dto: NodeInfo) =>
+ this.createNodeModel(repositoryFactoryUrl, networkType, dto.friendlyName, undefined, dto.publicKey, dto.nodePublicKey),
+ ),
+ ObservableHelpers.defaultLast(this.createNodeModel(repositoryFactoryUrl, networkType)),
+ map((currentNode) => _.uniqBy([currentNode, ...storedNodes], 'url')),
+ tap((p) => this.saveNodes(p)),
+ );
+ }
+
+ private loadStaticNodes(networkType: NetworkType): NodeModel[] {
+ return networkConfig[networkType].nodes.map((n) => {
+ return this.createNodeModel(n.url, networkType, n.friendlyName, true);
+ });
+ }
+
+ private createNodeModel(
+ url: string,
+ networkType: NetworkType,
+ friendlyName: string | undefined = undefined,
+ isDefault: boolean | undefined = undefined,
+ publicKey?: string,
+ nodePublicKey?: string,
+ ): NodeModel {
+ return new NodeModel(
+ url,
+ friendlyName || '',
+ isDefault || !!networkConfig[networkType].nodes.find((n) => n.url === url),
+ networkType,
+ publicKey,
+ nodePublicKey,
+ );
+ }
+
+ private loadNodes(): NodeModel[] {
+ return this.storage.get() || [];
+ }
+
+ public saveNodes(nodes: NodeModel[]) {
+ this.storage.set(nodes);
+ }
+
+ public reset() {
+ this.storage.remove();
+ }
+}
diff --git a/src/services/ProfileService.ts b/src/services/ProfileService.ts
new file mode 100644
index 0000000..5b88490
--- /dev/null
+++ b/src/services/ProfileService.ts
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Convert, Password, SHA3Hasher } from 'symbol-sdk';
+// internal dependencies
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { ProfileModelStorage } from '@/core/database/storage/ProfileModelStorage';
+import { AccountService } from './AccountService';
+import { AddressBookService } from './AddressBookService';
+import { SettingService } from './SettingService';
+
+/**
+ * Service in charge of loading profiles information from the wallet.
+ */
+export class ProfileService {
+ /**
+ * The storage to keep user configuration around mosaics. For example, the balance hidden
+ * feature.
+ */
+ private readonly profilesStorage = ProfileModelStorage.INSTANCE;
+ private readonly accountService = new AccountService();
+ private readonly addressBookService = new AddressBookService();
+ private readonly settingService = new SettingService();
+
+ public getProfiles(): ProfileModel[] {
+ return Object.values(this.getProfilesByProfileName());
+ }
+
+ public getProfileByName(profileName: string): ProfileModel | undefined {
+ return this.getProfilesByProfileName()[profileName];
+ }
+
+ public getProfilesByProfileName(): Record {
+ return this.profilesStorage.get() || {};
+ }
+
+ public saveProfile(profile: ProfileModel): ProfileModel {
+ const profiles = this.getProfilesByProfileName();
+ profiles[profile.profileName] = profile;
+ this.profilesStorage.set(profiles);
+ return profile;
+ }
+
+ public deleteProfile(profileName: string) {
+ const profiles = this.getProfilesByProfileName();
+ delete profiles[profileName];
+ this.profilesStorage.set(profiles);
+
+ this.accountService.deleteAccounts(profileName);
+ this.addressBookService.deleteAddressBook(profileName);
+ this.settingService.deleteProfileSettings(profileName);
+ }
+
+ public updateSeed(profile: ProfileModel, seed: string): ProfileModel {
+ return this.saveProfile(Object.assign(profile, { seed }));
+ }
+
+ public updatePassword(profile: ProfileModel, password: string, hint: string, seed: string): ProfileModel {
+ return this.saveProfile(Object.assign(profile, { password, hint, seed }));
+ }
+
+ public updateAccounts(profile: ProfileModel, accounts: string[]): ProfileModel {
+ return this.saveProfile(Object.assign(profile, { accounts }));
+ }
+ public updateProfileTermsAndConditionsStatus(profile: ProfileModel, termsAndConditionsApproved: boolean): ProfileModel {
+ return this.saveProfile(Object.assign(profile, { termsAndConditionsApproved }));
+ }
+ public updateSelectedNode(profile: ProfileModel, selectedNodeUrlToConnect: string): ProfileModel {
+ return this.saveProfile(Object.assign(profile, { selectedNodeUrlToConnect }));
+ }
+ /**
+ * Return password hash that can be compared
+ * @param password to be hashed
+ * @return the password hash
+ */
+ public static getPasswordHash(password: Password): string {
+ const hasher = SHA3Hasher.createHasher(64);
+ hasher.reset();
+ hasher.update(Convert.utf8ToHex(password.value));
+
+ const hash = new Uint8Array(64);
+ hasher.finalize(hash);
+ return Convert.uint8ToHex(hash);
+ }
+}
diff --git a/src/services/RESTService.ts b/src/services/RESTService.ts
new file mode 100644
index 0000000..d393eeb
--- /dev/null
+++ b/src/services/RESTService.ts
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { Address, Listener, TransactionStatusError } from 'symbol-sdk';
+import { Subscription } from 'rxjs';
+// internal dependencies
+import { AddressValidator } from '@/core/validation/validators';
+import { NotificationType } from '@/core/utils/NotificationType';
+import { TransactionGroupState } from '@/store/Transaction';
+import { CommonHelpers } from '@/core/utils/CommonHelpers';
+import { MediaService } from '@/services/MediaService';
+
+/**
+ * This Service is more like a static helper now. All the methods are statics. Rename and move.
+ */
+export class RESTService {
+ /**
+ * Subscribe to transactions websocket channels
+ * @param {Context} dispatch context the context
+ * @param {listener} listener the listener.
+ * @param {Address} address the listened account.
+ */
+ public static async subscribeTransactionChannels(
+ context: { dispatch: any; commit: any },
+ listener: Listener,
+ addressStr: string,
+ isMultisig: boolean,
+ ): Promise<{ listener: Listener; subscriptions: Subscription[] }> {
+ if (!AddressValidator.validate(addressStr)) {
+ throw new Error('Invalid address for subscribing to websocket connections');
+ }
+
+ context.dispatch('diagnostic/ADD_DEBUG', `Opening REST websocket channel connections with ${addressStr}`, {
+ root: true,
+ });
+
+ // open websocket connection
+ const address = Address.createFromRawAddress(addressStr);
+ if (listener) {
+ if (!listener.isOpen()) {
+ await listener.open(async (event: { client: string; code: any; reason: any }) => {
+ if (event && event.code !== 1005) {
+ await CommonHelpers.retryNTimes(listener, 3, 5000);
+ } else {
+ context.dispatch('notification/ADD_WARNING', NotificationType.WS_CONNECTION_FAILED, { root: true });
+ }
+ });
+ }
+
+ // error listener
+ const status = listener
+ .status(address)
+ .subscribe((error: TransactionStatusError) => context.dispatch('notification/ADD_ERROR', error.code, { root: true }));
+
+ // unconfirmed listeners
+ const unconfirmedAdded = listener.unconfirmedAdded(address, undefined, isMultisig).subscribe(
+ (transaction) => {
+ context.dispatch(
+ 'transaction/ADD_TRANSACTION',
+ { group: TransactionGroupState.unconfirmed, transaction },
+ { root: true },
+ );
+ context.dispatch('notification/ADD_SUCCESS', NotificationType.NEW_UNCONFIRMED_TRANSACTION, { root: true });
+ MediaService.playUnconfirmedTransactionSound();
+ },
+ (err) => context.dispatch('diagnostic/ADD_ERROR', err, { root: true }),
+ );
+
+ const unconfirmedRemoved = listener.unconfirmedRemoved(address, undefined, isMultisig).subscribe(
+ (transactionHash) =>
+ context.dispatch(
+ 'transaction/REMOVE_TRANSACTION',
+ { group: TransactionGroupState.unconfirmed, transactionHash },
+ { root: true },
+ ),
+ (err) => context.dispatch('diagnostic/ADD_ERROR', err, { root: true }),
+ );
+
+ // partial listeners
+ const cosignatureAdded = listener.cosignatureAdded(address, isMultisig).subscribe(
+ (cosignature) => {
+ context.dispatch('transaction/ADD_COSIGNATURE', cosignature, {
+ root: true,
+ });
+ context.dispatch('notification/ADD_SUCCESS', NotificationType.COSIGNATURE_ADDED, { root: true });
+ MediaService.playUnconfirmedTransactionSound();
+ },
+ (err) => context.dispatch('diagnostic/ADD_ERROR', err, { root: true }),
+ );
+
+ const partialAdded = listener.aggregateBondedAdded(address, undefined, isMultisig).subscribe(
+ (transaction) => {
+ context.dispatch('transaction/ADD_TRANSACTION', { group: TransactionGroupState.partial, transaction }, { root: true });
+ context.dispatch('notification/ADD_SUCCESS', NotificationType.NEW_AGGREGATE_BONDED, { root: true });
+ MediaService.playUnconfirmedTransactionSound();
+ },
+ (err) => context.dispatch('diagnostic/ADD_ERROR', err, { root: true }),
+ );
+
+ const partialRemoved = listener.aggregateBondedRemoved(address, undefined, isMultisig).subscribe(
+ (transactionHash) =>
+ context.dispatch(
+ 'transaction/REMOVE_TRANSACTION',
+ { group: TransactionGroupState.partial, transactionHash },
+ { root: true },
+ ),
+ (err) => context.dispatch('diagnostic/ADD_ERROR', err, { root: true }),
+ );
+
+ // confirmed listener
+ const confirmed = listener.confirmed(address, undefined, isMultisig).subscribe(
+ (transaction) => {
+ context.dispatch(
+ 'transaction/ADD_TRANSACTION',
+ { group: TransactionGroupState.confirmed, transaction },
+ { root: true },
+ );
+ context.dispatch('transaction/ON_NEW_TRANSACTION', transaction, {
+ root: true,
+ });
+ context.dispatch('notification/ADD_SUCCESS', NotificationType.NEW_CONFIRMED_TRANSACTION, { root: true });
+ MediaService.playConfirmedTransactionSound();
+ },
+ (err) => context.dispatch('diagnostic/ADD_ERROR', err, { root: true }),
+ );
+
+ return {
+ listener,
+ subscriptions: [status, unconfirmedAdded, unconfirmedRemoved, cosignatureAdded, partialAdded, partialRemoved, confirmed],
+ };
+ } else {
+ return;
+ }
+ }
+}
diff --git a/src/services/RemoteAccountService.ts b/src/services/RemoteAccountService.ts
new file mode 100644
index 0000000..a78f030
--- /dev/null
+++ b/src/services/RemoteAccountService.ts
@@ -0,0 +1,137 @@
+/**
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// external dependencies
+import { Crypto, Password, Account, AccountRepository, AccountInfo, AccountType as sdkAccountType } from 'symbol-sdk';
+
+// internal dependencies
+import { AccountService } from './AccountService';
+import { AccountModel, AccountType } from '@/core/database/entities/AccountModel';
+import { DerivationPathLevels, DerivationService } from './DerivationService';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+import { MnemonicPassPhrase } from 'symbol-hd-wallets';
+
+export class RemoteAccountService extends AccountService {
+ /**
+ * Derivation service
+ */
+ private derivationService: DerivationService;
+
+ /**
+ * Creates an instance of RemoteAccountService.
+ * @param {AccountModel} account
+ * @param {ProfileModel} profile
+ * @param {AccountRepository} accountRepository
+ */
+ public constructor(
+ private readonly account: AccountModel,
+ private readonly profile: ProfileModel,
+ private readonly accountRepository: AccountRepository,
+ ) {
+ super();
+ this.derivationService = new DerivationService(profile.networkType);
+ }
+
+ /**
+ * Gets the first available remote account
+ * @param {Password} password
+ * @returns {Promise}
+ */
+ public async getAvailableRemoteAccount(password: Password): Promise {
+ const candidates = this.getRemoteAccounts(password);
+ const addresses = candidates.map(({ address }) => address);
+ const accountsInfo = await this.accountRepository.getAccountsInfo(addresses).toPromise();
+ return this.getFirstFreeRemoteAccount(candidates, accountsInfo);
+ }
+
+ /**
+ * Gets remote account candidates from the derivation of the account seed
+ * @private
+ * @param {Password} password
+ * @param {number} [numberOfPaths=10]
+ * @returns {Account[]}
+ */
+ private getRemoteAccounts(password: Password, numberOfPaths = 10): Account[] {
+ switch (this.account.type) {
+ case AccountType.SEED:
+ return this.getRemoteAccountsFromSeed(password, numberOfPaths);
+
+ // @TODO: implement private key
+ // @TODO: show error to the user
+ case AccountType.KEYSTORE:
+ case AccountType.OPT_IN:
+ case AccountType.PRIVATE_KEY:
+ throw new Error('remote account generation from Private Key is not supported');
+ case AccountType.TREZOR:
+ throw new Error('remote account generation from Trezor wallet is not supported');
+
+ default:
+ throw new Error('Something went wrong at getRemoteAccountPrivateKey');
+ }
+ }
+
+ /**
+ * Gets remote account candidates from the derivation of the account seed
+ * @private
+ * @param {Password} password
+ * @param {number} [numberOfPaths=10]
+ * @returns {Account[]}
+ */
+ private getRemoteAccountsFromSeed(password: Password, numberOfPaths = 10): Account[] {
+ const paths = [...Array(numberOfPaths).keys()].map((i) =>
+ this.derivationService.incrementPathLevel(this.account.path, DerivationPathLevels.Remote, i),
+ );
+
+ const encSeed = this.profile.seed;
+ const passphrase = Crypto.decrypt(encSeed, password.value);
+ const mnemonic = new MnemonicPassPhrase(passphrase);
+ return this.generateAccountsFromPaths(mnemonic, this.profile.networkType, paths);
+ }
+
+ /**
+ * Query the network with the remote account candidates,
+ * Returns the first eligible account
+ * @private
+ * @param {Account[]} remoteAccounts
+ * @param {AccountInfo[]} accountsInfo
+ * @returns {Account}
+ */
+ private getFirstFreeRemoteAccount(remoteAccounts: Account[], accountsInfo: AccountInfo[]): Account {
+ if (!accountsInfo.length) {
+ return remoteAccounts[0];
+ }
+
+ const linkableRemoteAccounts = remoteAccounts.filter(({ address }) => {
+ const matchedAccountInfo = accountsInfo.find((ai) => ai.address.plain() === address.plain());
+ return matchedAccountInfo === undefined || RemoteAccountService.isLinkable(matchedAccountInfo);
+ });
+
+ if (!linkableRemoteAccounts.length) {
+ throw new Error('Could not find a free remote account');
+ }
+
+ return linkableRemoteAccounts[0];
+ }
+
+ /**
+ * Whether an account is linkable as a remote account
+ * @static
+ * @param {AccountInfo} accountInfo
+ * @returns {boolean}
+ */
+ static isLinkable(accountInfo: AccountInfo): boolean {
+ return accountInfo?.accountType === sdkAccountType.Remote_Unlinked;
+ }
+}
diff --git a/src/services/SettingService.ts b/src/services/SettingService.ts
new file mode 100644
index 0000000..9f25fc8
--- /dev/null
+++ b/src/services/SettingService.ts
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+import { SettingsModel } from '@/core/database/entities/SettingsModel';
+
+import { feesConfig } from '@/config';
+import { appConfig } from '@/config';
+import { networkConfig } from '@/config';
+import i18n from '@/language';
+import { SettingsModelStorage } from '@/core/database/storage/SettingsModelStorage';
+import { NetworkType } from 'symbol-sdk';
+
+/**
+ * Service in charge of loading and storing the SettingsModel from local storage.
+ */
+export class SettingService {
+ /**
+ * The the local storage that keeps the SettingsModel objects indexed by profileName.
+ */
+ private readonly storage = SettingsModelStorage.INSTANCE;
+
+ public getProfileSettings(profileName: string, networkType: NetworkType): SettingsModel {
+ const storedData = this.storage.get() || {};
+ return {
+ ...this.createDefaultSettingsModel(profileName, networkType),
+ ...(storedData[profileName] || {}),
+ };
+ }
+
+ public changeProfileSettings(profileName: string, newConfigs: any, networkType: NetworkType): SettingsModel {
+ const storedData = this.storage.get() || {};
+ storedData[profileName] = {
+ ...this.getProfileSettings(profileName, networkType),
+ ...newConfigs,
+ };
+ this.storage.set(storedData);
+ return storedData[profileName];
+ }
+
+ public createDefaultSettingsModel(profileName: string, networkType: NetworkType): SettingsModel {
+ const browserLocale = i18n.locale;
+ const language = appConfig.languages.find((l) => l.value == browserLocale) ? browserLocale : appConfig.languages[0].value;
+ return new SettingsModel(profileName, language, feesConfig.slowest, '', networkConfig[networkType].explorerUrl);
+ }
+
+ public deleteProfileSettings(profileName: string): void {
+ const storedData = this.storage.get();
+ if (!storedData) {
+ return;
+ }
+ delete storedData[profileName];
+ this.storage.set(storedData);
+ }
+}
diff --git a/src/services/TransactionAnnouncerService.ts b/src/services/TransactionAnnouncerService.ts
new file mode 100644
index 0000000..0bffefd
--- /dev/null
+++ b/src/services/TransactionAnnouncerService.ts
@@ -0,0 +1,278 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+// configuration
+import { appConfig } from '@/config';
+// internal dependencies
+import { BroadcastResult } from '@/core/transactions/BroadcastResult';
+import i18n from '@/language';
+import { from, Observable, of, OperatorFunction, throwError } from 'rxjs';
+import { catchError, flatMap, map, switchMap, tap, timeoutWith } from 'rxjs/operators';
+import {
+ Account,
+ CosignatureSignedTransaction,
+ CosignatureTransaction,
+ IListener,
+ NetworkType,
+ RepositoryFactory,
+ SignedTransaction,
+ Transaction,
+ TransactionGroup,
+ TransactionService,
+ TransactionType,
+} from 'symbol-sdk';
+import { TransactionAnnounceResponse } from 'symbol-sdk/dist/src/model/transaction/TransactionAnnounceResponse';
+import { Store } from 'vuex';
+import { HashLockAggregatePairModelStorage } from '@/core/database/storage/HashLockAggregatePairModelStorage';
+import { HashLockAggregatePairModel } from '@/core/database/entities/HashLockAggregatePairModel';
+import { ProfileModel } from '@/core/database/entities/ProfileModel';
+
+const { ANNOUNCE_TRANSACTION_TIMEOUT } = appConfig.constants;
+
+/// end-region custom types
+
+export interface TransactionSigner {
+ signTransaction(t: Transaction, generationHash: string): Observable;
+
+ signCosignatureTransaction(t: CosignatureTransaction): Observable;
+}
+
+export class AccountTransactionSigner implements TransactionSigner {
+ constructor(private readonly account: Account) {}
+
+ signTransaction(t: Transaction, generationHash: string): Observable {
+ return of(this.account.sign(t, generationHash));
+ }
+ signCosignatureTransaction(t: CosignatureTransaction): Observable {
+ return of(this.account.signCosignatureTransaction(t));
+ }
+}
+
+export class TransactionAnnouncerService {
+ /**
+ * Vuex Store
+ * @var {Vuex.Store}
+ */
+ public $store: Store;
+
+ private readonly transactionTimeout = ANNOUNCE_TRANSACTION_TIMEOUT;
+
+ private networkType: NetworkType;
+
+ /**
+ * The namespace information local cache.
+ */
+ private readonly hashLockAggregatePairModelStorage = HashLockAggregatePairModelStorage.INSTANCE;
+
+ /**
+ * Construct a service instance around \a store
+ * @param store
+ */
+ constructor(store: Store) {
+ this.$store = store;
+ this.networkType = this.$store.getters['network/networkType'];
+ }
+
+ public announce(signedTransaction: SignedTransaction): Observable {
+ const listener: IListener = this.$store.getters['account/listener'];
+ const service = this.createService();
+ return service
+ .announce(signedTransaction, listener)
+ .pipe(this.timeout(this.timeoutMessage(signedTransaction.type)))
+ .pipe(map((t) => this.createBroadcastResult(signedTransaction, t)));
+ }
+
+ public announceAggregateBonded(signedTransaction: SignedTransaction): Observable {
+ const listener: IListener = this.$store.getters['account/listener'];
+ const service = this.createService();
+ return service
+ .announceAggregateBonded(signedTransaction, listener)
+ .pipe(this.timeout(this.timeoutMessage(signedTransaction.type)))
+ .pipe(map((t) => this.createBroadcastResult(signedTransaction, t)));
+ }
+
+ private retrySubscribe() {
+ const address = this.$store.getters['account/currentAccountAddress'];
+ this.$store.dispatch('account/UNSUBSCRIBE', address);
+ this.$store.dispatch('account/SUBSCRIBE', address);
+ }
+
+ private timeout(message: string): OperatorFunction {
+ const listener: IListener = this.$store.getters['account/listener'];
+ if (!listener.isOpen()) {
+ this.retrySubscribe();
+ }
+ if (!this.transactionTimeout) {
+ return (o) => o;
+ }
+ const operatorFunction: any = timeoutWith(this.transactionTimeout, throwError(new Error(message)));
+ return operatorFunction as OperatorFunction;
+ }
+
+ private timeoutMessage(transactionType: TransactionType): string {
+ return `${i18n.t(`transaction_descriptor_${transactionType}`)} Transaction has timed out.`;
+ }
+
+ private createService() {
+ const repositoryFactory: RepositoryFactory = this.$store.getters['network/repositoryFactory'];
+ return new TransactionService(repositoryFactory.createTransactionRepository(), repositoryFactory.createReceiptRepository());
+ }
+
+ public announceHashAndAggregateBonded(
+ signedHashLockTransaction: SignedTransaction,
+ signedAggregateTransaction: SignedTransaction,
+ ): Observable {
+ const repositoryFactory = this.$store.getters['network/repositoryFactory'] as RepositoryFactory;
+ const hashLockListener: IListener = repositoryFactory.createListener();
+ this.addHashLockAggregateBondedPair(signedHashLockTransaction.hash, signedAggregateTransaction);
+ return from(hashLockListener.open()).pipe(
+ switchMap(() => {
+ hashLockListener.unconfirmedAdded(this.$store.getters['account/currentAccountAddress']);
+ const service = this.createService();
+ return service
+ .announceHashLockAggregateBonded(signedHashLockTransaction, signedAggregateTransaction, hashLockListener)
+ .pipe(this.timeout(this.timeoutMessage(signedHashLockTransaction.type)))
+ .pipe(
+ tap(() => {
+ hashLockListener.close();
+ console.log('hashAndAggregateBonded listener is closed!');
+ }),
+ )
+ .pipe(
+ catchError((e) => {
+ hashLockListener.close();
+ console.log('hashAndAggregateBonded listener is closed due to error!');
+ return of(e as Error);
+ }),
+ )
+ .pipe(map((t) => this.createBroadcastResult(signedAggregateTransaction, t)));
+ }),
+ );
+ }
+
+ private addHashLockAggregateBondedPair(hashLockHash: string, aggregateBonded: SignedTransaction): void {
+ const currentProfile: ProfileModel = this.$store.getters['profile/currentProfile'];
+ const hashLockAggregatePairs = this.hashLockAggregatePairModelStorage.get() || [];
+ hashLockAggregatePairs.push({
+ profileName: currentProfile.profileName,
+ hashLockHash: hashLockHash,
+ aggregateTransactionDTO: aggregateBonded.toDTO(),
+ } as HashLockAggregatePairModel);
+ this.hashLockAggregatePairModelStorage.set(hashLockAggregatePairs);
+ }
+
+ public async sendUnspentHashLockPairs(): Promise {
+ const currentProfile: ProfileModel = this.$store.getters['profile/currentProfile'];
+ if (!currentProfile) {
+ return;
+ }
+ const hashLockAggregatePairs = this.hashLockAggregatePairModelStorage.get() || [];
+ const unannouncedPairs: HashLockAggregatePairModel[] = [];
+ for (const hashLockAggregatePair of hashLockAggregatePairs) {
+ const hashLockGroup = await this.getTransactionGroup(hashLockAggregatePair.hashLockHash);
+ if (hashLockGroup === null) {
+ continue;
+ } else if (hashLockGroup === TransactionGroup.Unconfirmed) {
+ unannouncedPairs.push(hashLockAggregatePair);
+ continue;
+ }
+ const isAnnounced = await this.getTransactionGroup(hashLockAggregatePair.aggregateTransactionDTO.hash);
+ const signedTransaction = new SignedTransaction(
+ hashLockAggregatePair.aggregateTransactionDTO.payload,
+ hashLockAggregatePair.aggregateTransactionDTO.hash,
+ hashLockAggregatePair.aggregateTransactionDTO.signerPublicKey,
+ hashLockAggregatePair.aggregateTransactionDTO.type,
+ hashLockAggregatePair.aggregateTransactionDTO.networkType,
+ );
+ if (isAnnounced !== null) {
+ continue;
+ }
+ this.announceAggregateBonded(signedTransaction).subscribe(
+ (res) => {
+ if (res.success) {
+ this.$store.dispatch('notification/ADD_SUCCESS', 'success_transactions_announced');
+ } else if (res.error) {
+ this.$store.dispatch('notification/ADD_ERROR', res.error);
+ }
+ },
+ (error) => {
+ this.$store.dispatch('notification/ADD_ERROR', error);
+ },
+ );
+ }
+ this.hashLockAggregatePairModelStorage.set(unannouncedPairs);
+ }
+
+ private async getTransactionGroup(hash: string): Promise {
+ const repositoryFactory: RepositoryFactory = this.$store.getters['network/repositoryFactory'];
+ const transactionHttp = repositoryFactory.createTransactionRepository();
+ try {
+ const transaction = await transactionHttp.getTransaction(hash, TransactionGroup.Confirmed).toPromise();
+ if (transaction) {
+ return TransactionGroup.Confirmed;
+ }
+ // eslint-disable-next-line no-empty
+ } catch {}
+ try {
+ const transaction = await transactionHttp.getTransaction(hash, TransactionGroup.Partial).toPromise();
+ if (transaction) {
+ return TransactionGroup.Partial;
+ }
+ // eslint-disable-next-line no-empty
+ } catch {}
+ try {
+ const transaction = await transactionHttp.getTransaction(hash, TransactionGroup.Unconfirmed).toPromise();
+ if (transaction) {
+ return TransactionGroup.Unconfirmed;
+ }
+ // eslint-disable-next-line no-empty
+ } catch {}
+ return null;
+ }
+
+ public announceChainedBinary(first: SignedTransaction, second: SignedTransaction): Observable {
+ const listener: IListener = this.$store.getters['account/listener'];
+ const service = this.createService();
+ return service
+ .announce(first, listener)
+ .pipe(this.timeout(this.timeoutMessage(first.type)))
+ .pipe(flatMap(() => service.announce(second, listener).pipe(this.timeout(this.timeoutMessage(second.type)))))
+
+ .pipe(catchError((e) => of(e as Error)))
+ .pipe(map((t) => this.createBroadcastResult(second, t)));
+ }
+
+ public announceAggregateBondedCosignature(singedTransaction: CosignatureSignedTransaction): Observable {
+ const repositoryFactory = this.$store.getters['network/repositoryFactory'] as RepositoryFactory;
+ const transactionHttp = repositoryFactory.createTransactionRepository();
+ return transactionHttp
+ .announceAggregateBondedCosignature(singedTransaction)
+ .pipe(this.timeout('Cosignature Transaction has timed out'))
+ .pipe(map((t) => this.createBroadcastResult(singedTransaction, t)));
+ }
+
+ private createBroadcastResult(
+ signedTransaction: SignedTransaction | CosignatureSignedTransaction,
+ transactionOrError: Error | Transaction | TransactionAnnounceResponse,
+ ): BroadcastResult {
+ if (transactionOrError instanceof Error) {
+ return new BroadcastResult(signedTransaction, undefined, false, transactionOrError.message);
+ } else if (transactionOrError instanceof Transaction) {
+ return new BroadcastResult(signedTransaction, transactionOrError, true);
+ } else {
+ return new BroadcastResult(signedTransaction, undefined, true);
+ }
+ }
+}
diff --git a/src/services/TransactionCommand.ts b/src/services/TransactionCommand.ts
new file mode 100644
index 0000000..4ed939b
--- /dev/null
+++ b/src/services/TransactionCommand.ts
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import {
+ Account,
+ AggregateTransaction,
+ Deadline,
+ LockFundsTransaction,
+ Mosaic,
+ MosaicId,
+ NetworkType,
+ PublicAccount,
+ SignedTransaction,
+ Transaction,
+ TransactionFees,
+ UInt64,
+} from 'symbol-sdk';
+import { Signer } from '@/store/Account';
+import { NetworkConfigurationModel } from '@/core/database/entities/NetworkConfigurationModel';
+import { Observable, of } from 'rxjs';
+import { AccountTransactionSigner, TransactionAnnouncerService, TransactionSigner } from '@/services/TransactionAnnouncerService';
+import { BroadcastResult } from '@/core/transactions/BroadcastResult';
+import { flatMap, map } from 'rxjs/operators';
+
+export enum TransactionCommandMode {
+ SIMPLE = 'SIMPLE',
+ AGGREGATE = 'AGGREGATE',
+ MULTISIGN = 'MULTISIGN',
+ CHAINED_BINARY = 'CHAINED_BINARY',
+}
+
+export class TransactionCommand {
+ private readonly tempAccount: Account;
+ private readonly tempTransactionSigner: TransactionSigner;
+ constructor(
+ public readonly mode: TransactionCommandMode,
+ public readonly signer: Signer,
+ public readonly signerPublicKey: string,
+ public readonly stageTransactions: Transaction[],
+ public readonly networkMosaic: MosaicId,
+ public readonly generationHash: string,
+ public readonly networkType: NetworkType,
+ public readonly epochAdjustment: number,
+ public readonly networkConfiguration: NetworkConfigurationModel,
+ public readonly transactionFees: TransactionFees,
+ public readonly requiredCosignatures: number,
+ ) {
+ this.tempAccount = Account.generateNewAccount(this.networkType);
+ this.tempTransactionSigner = new AccountTransactionSigner(this.tempAccount);
+ }
+
+ public sign(service: TransactionAnnouncerService, account: TransactionSigner): Observable[]> {
+ return this.resolveTransactions(account).pipe(
+ flatMap((transactions) => {
+ return of(transactions.map((t) => account.signTransaction(t, this.generationHash)));
+ }),
+ );
+ }
+
+ public announce(service: TransactionAnnouncerService, account: TransactionSigner): Observable[]> {
+ return this.resolveTransactions(account).pipe(
+ flatMap((transactions) => {
+ const signedTransactions = transactions.map((t) => account.signTransaction(t, this.generationHash));
+ if (!signedTransactions.length) {
+ return of([]);
+ }
+ if (this.mode == TransactionCommandMode.MULTISIGN) {
+ return of([this.announceHashAndAggregateBonded(service, signedTransactions)]);
+ } else if (this.mode == TransactionCommandMode.CHAINED_BINARY) {
+ return of([this.announceChainedBinary(service, signedTransactions)]);
+ } else {
+ return of(this.announceSimple(service, signedTransactions));
+ }
+ }),
+ );
+ }
+
+ private announceChainedBinary(
+ service: TransactionAnnouncerService,
+ signedTransactions: Observable[],
+ ): Observable {
+ return signedTransactions[0].pipe(
+ flatMap((first) => {
+ return signedTransactions[1].pipe(
+ flatMap((second) => {
+ return service.announceChainedBinary(first, second);
+ }),
+ );
+ }),
+ );
+ }
+
+ public announceHashAndAggregateBonded(
+ service: TransactionAnnouncerService,
+ signedTransactions: Observable[],
+ ): Observable {
+ return signedTransactions[0].pipe(
+ flatMap((signedHashLockTransaction) => {
+ return signedTransactions[1].pipe(
+ flatMap((signedAggregateTransaction) => {
+ return service.announceHashAndAggregateBonded(signedHashLockTransaction, signedAggregateTransaction);
+ }),
+ );
+ }),
+ );
+ }
+
+ private announceSimple(
+ service: TransactionAnnouncerService,
+ signedTransactions: Observable[],
+ ): Observable[] {
+ return signedTransactions.map((o) => o.pipe(flatMap((s) => service.announce(s))));
+ }
+
+ public getTotalMaxFee(): Observable {
+ return this.resolveTransactions().pipe(
+ map((ts) => ts.reduce((partial, current) => partial.add(current.maxFee), UInt64.fromUint(0))),
+ );
+ }
+
+ public resolveTransactions(account: TransactionSigner = this.tempTransactionSigner): Observable {
+ if (!this.stageTransactions.length) {
+ return of([]);
+ }
+ const maxFee = this.stageTransactions.sort((a, b) => a.maxFee.compare(b.maxFee))[0].maxFee;
+ if (this.mode === TransactionCommandMode.SIMPLE || this.mode === TransactionCommandMode.CHAINED_BINARY) {
+ return of(this.stageTransactions.map((t) => this.calculateSuggestedMaxFee(t)));
+ } else {
+ const currentSigner = PublicAccount.createFromPublicKey(this.signerPublicKey, this.networkType);
+ if (this.mode === TransactionCommandMode.AGGREGATE) {
+ const aggregate = this.calculateSuggestedMaxFee(
+ AggregateTransaction.createComplete(
+ Deadline.create(this.epochAdjustment),
+ this.stageTransactions.map((t) => t.toAggregate(currentSigner)),
+ this.networkType,
+ [],
+ maxFee,
+ ),
+ );
+ return of([aggregate]);
+ } else {
+ // use attached signer (multisig account) if exists
+ const signedInnerTransactions = this.stageTransactions.map((t) => {
+ return t.signer === undefined ? t.toAggregate(currentSigner) : t.toAggregate(t.signer);
+ });
+
+ const aggregate = this.calculateSuggestedMaxFee(
+ AggregateTransaction.createBonded(
+ Deadline.create(this.epochAdjustment, 48),
+ signedInnerTransactions,
+ this.networkType,
+ [],
+ maxFee,
+ ),
+ );
+ return account.signTransaction(aggregate, this.generationHash).pipe(
+ map((signedAggregateTransaction) => {
+ const hashLock = this.calculateSuggestedMaxFee(
+ LockFundsTransaction.create(
+ Deadline.create(this.epochAdjustment, 6),
+ new Mosaic(this.networkMosaic, UInt64.fromNumericString(this.networkConfiguration.lockedFundsPerAggregate)),
+ UInt64.fromUint(5760),
+ signedAggregateTransaction,
+ this.networkType,
+ maxFee,
+ ),
+ );
+ return [hashLock, aggregate];
+ }),
+ );
+ }
+ }
+ }
+
+ public calculateSuggestedMaxFee(transaction: Transaction): Transaction {
+ const feeMultiplier = this.resolveFeeMultipler(transaction);
+ if (!feeMultiplier) {
+ return transaction;
+ }
+ if (transaction instanceof AggregateTransaction) {
+ return transaction.setMaxFeeForAggregate(feeMultiplier, this.requiredCosignatures);
+ } else {
+ return transaction.setMaxFee(feeMultiplier);
+ }
+ }
+
+ private resolveFeeMultipler(transaction: Transaction): number | undefined {
+ // average
+ if (transaction.maxFee.compact() === 10) {
+ const fees = this.transactionFees.minFeeMultiplier + this.transactionFees.averageFeeMultiplier * 0.65;
+ return fees || this.networkConfiguration.defaultDynamicFeeMultiplier;
+ }
+ // fast
+ if (transaction.maxFee.compact() === 20) {
+ const fees =
+ this.transactionFees.averageFeeMultiplier < this.transactionFees.minFeeMultiplier
+ ? this.transactionFees.minFeeMultiplier
+ : this.transactionFees.averageFeeMultiplier;
+ return fees || this.networkConfiguration.defaultDynamicFeeMultiplier;
+ }
+ // slowest
+ if (transaction.maxFee.compact() === 1) {
+ const fees = this.transactionFees.minFeeMultiplier;
+ return fees || this.networkConfiguration.defaultDynamicFeeMultiplier;
+ }
+ // slow
+ if (transaction.maxFee.compact() === 5) {
+ const fees = this.transactionFees.minFeeMultiplier + this.transactionFees.averageFeeMultiplier * 0.35;
+ return fees || this.networkConfiguration.defaultDynamicFeeMultiplier;
+ }
+ return undefined;
+ }
+}
diff --git a/src/services/TransactionFilterService.ts b/src/services/TransactionFilterService.ts
new file mode 100644
index 0000000..b60bc1d
--- /dev/null
+++ b/src/services/TransactionFilterService.ts
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2020 NEM (https://nem.io)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and limitations under the License.
+ *
+ */
+
+import { Transaction } from 'symbol-sdk';
+import { TransactionFilterOptionsState, TransactionState } from '@/store/Transaction';
+
+/**
+ * TransactionFilter used for filtering transactions by group and sent status.
+ */
+export class TransactionFilterService {
+ /**
+ * Filters transactions depends on selected filter options.
+ * @param state for extracting transactions filter options and list filtered by group.
+ * @param currentSignerAddress selected signer address
+ */
+ public static filter(state: TransactionState, currentSignerAddress: string): Transaction[] {
+ const { filterOptions, transactions, confirmedTransactions, unconfirmedTransactions, partialTransactions } = state;
+ if (!filterOptions.isFilterShouldBeApplied) {
+ return [...transactions];
+ }
+
+ const mainFilterGroup = [filterOptions.isConfirmedSelected, filterOptions.isUnconfirmedSelected, filterOptions.isPartialSelected];
+ // Indicates if all checkboxes in main group selected or unselected
+ const areAllGroupResultsShown = mainFilterGroup.every((option) => option) || mainFilterGroup.every((option) => !option);
+
+ let result: Transaction[] = areAllGroupResultsShown ? [...transactions] : [];
+
+ if (!areAllGroupResultsShown) {
+ if (filterOptions.isPartialSelected) {
+ result = result.concat(partialTransactions);
+ }
+ if (filterOptions.isUnconfirmedSelected) {
+ result = result.concat(unconfirmedTransactions);
+ }
+ if (filterOptions.isConfirmedSelected) {
+ result = result.concat(confirmedTransactions);
+ }
+ }
+
+ return this.filterByRecepient(result, filterOptions, currentSignerAddress);
+ }
+
+ /**
+ * Filters transactions depends on selected sent status filter options.
+ * @param transactions
+ * @param filterOptions
+ * @param currentSignerAddress selected signer address
+ */
+ private static filterByRecepient(
+ transactions: Transaction[],
+ filterOptions: TransactionFilterOptionsState,
+ currentSignerAddress: string,
+ ): Transaction[] {
+ const recepientFilterOptions = [filterOptions.isSentSelected, filterOptions.isReceivedSelected];
+ const areAllShouldBeShown: boolean = recepientFilterOptions.every((option) => !option);
+ if (areAllShouldBeShown) {
+ return transactions;
+ }
+
+ const areAllWithRecepientShouldBeShown: boolean = recepientFilterOptions.every((option) => option);
+ if (areAllWithRecepientShouldBeShown) {
+ return transactions.filter((transaction) => {
+ return (transaction as any).recipientAddress && (transaction as any).recipientAddress.address;
+ });
+ }
+
+ return transactions.filter((transaction) => {
+ if ((transaction as any).recipientAddress && (transaction as any).recipientAddress.address) {
+ if (filterOptions.isSentSelected) {
+ if ((transaction as any).signer) {
+ return (transaction as any).signer.address.plain() === currentSignerAddress;
+ }
+ }
+
+ if (filterOptions.isReceivedSelected) {
+ return (transaction as any).recipientAddress.address === currentSignerAddress;
+ }
+ }
+ });
+ }
+}
diff --git a/src/services/offline/MockModels.ts b/src/services/offline/MockModels.ts
new file mode 100644
index 0000000..3d834a9
--- /dev/null
+++ b/src/services/offline/MockModels.ts
@@ -0,0 +1,168 @@
+import {
+ AccountInfo,
+ AccountNames,
+ ChainInfo,
+ ChainProperties,
+ Currency,
+ FinalizedBlock,
+ MosaicId,
+ MultisigAccountGraphInfo,
+ NamespaceId,
+ NamespaceName,
+ NetworkConfiguration,
+ NetworkCurrencies,
+ NetworkProperties,
+ NetworkType,
+ NodeInfo,
+ PluginProperties,
+ RentalFees,
+ StorageInfo,
+ TransactionFees,
+ UInt64,
+} from 'symbol-sdk';
+import { NodeIdentityEqualityStrategy } from 'symbol-openapi-typescript-fetch-client';
+import { Address } from 'symbol-sdk';
+import { AccountType } from 'symbol-sdk';
+import { SupplementalPublicKeys } from 'symbol-sdk';
+import { networkConfig } from '@/config';
+
+export const OfflineUrl = 'http://mock:3000';
+
+export const OfflineGenerationHash = {
+ [NetworkType.TEST_NET]: networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults.generationHash,
+ [NetworkType.MAIN_NET]: networkConfig[NetworkType.MAIN_NET].networkConfigurationDefaults.generationHash,
+};
+
+export const OfflineTransactionFees = new TransactionFees(84587, 100, 1136363, 0, 0);
+
+export const OfflineNodeInfo = (networkType: NetworkType) =>
+ new NodeInfo('pubkey', OfflineGenerationHash[networkType], 3000, networkType, 0, [], 'host', 'name');
+
+export const OfflineNetworkProperties = {
+ [NetworkType.TEST_NET]: new NetworkConfiguration(
+ new NetworkProperties(
+ 'public-test',
+ NodeIdentityEqualityStrategy.Host,
+ 'B4EDD106057B631DAA45BDEF97D5E8E43C4C426B1C024086202200D72EDA988E',
+ OfflineGenerationHash[NetworkType.TEST_NET],
+ networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults.epochAdjustment + 's',
+ ),
+ new ChainProperties(
+ true,
+ true,
+ networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults.currencyMosaicId,
+ networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults.harvestingMosaicId,
+ networkConfig[NetworkType.TEST_NET].networkConfigurationDefaults.blockGenerationTargetTime + 's',
+ "3'000",
+ '180',
+ '180',
+ '5',
+ '0',
+ '60',
+ '100',
+ '6h',
+ '500ms',
+ "1'000'000'000'000'000",
+ "9'000'000'000'000'000",
+ "1'000'000'000'000'000",
+ "2'000'000'000",
+ "200'000'000'000'000",
+ "2'000'000'000'000",
+ '3',
+ '28',
+ '720',
+ '10',
+ '5',
+ 'TCOMFIBVPWGB5O5CQXHEINKYQDXNIMGBCUHNJBQ',
+ undefined,
+ "6'000",
+ ),
+ new PluginProperties(),
+ ),
+ [NetworkType.MAIN_NET]: new NetworkConfiguration(
+ new NetworkProperties(
+ 'public',
+ NodeIdentityEqualityStrategy.Host,
+ '907B74B4EAA4F8DA48162B624C933FD1F3F51714A6EE8A78BB1713F5D6959E0A',
+ OfflineGenerationHash[NetworkType.MAIN_NET],
+ networkConfig[NetworkType.MAIN_NET].networkConfigurationDefaults.epochAdjustment + 's',
+ ),
+ new ChainProperties(
+ true,
+ true,
+ networkConfig[NetworkType.MAIN_NET].networkConfigurationDefaults.currencyMosaicId,
+ networkConfig[NetworkType.MAIN_NET].networkConfigurationDefaults.harvestingMosaicId,
+ networkConfig[NetworkType.MAIN_NET].networkConfigurationDefaults.blockGenerationTargetTime + 's',
+ "3'000",
+ '180',
+ '720',
+ '5',
+ '0',
+ '60',
+ '100',
+ '6h',
+ '500ms',
+ "1'000'000'000'000'000",
+ "9'000'000'000'000'000",
+ "1'000'000'000'000'000",
+ "2'000'000'000",
+ "200'000'000'000'000",
+ "2'000'000'000'000",
+ '3',
+ '112',
+ '360',
+ '10',
+ '5',
+ 'NCOMSWYJ5E6WRQV7GBLHCIITDAVDZQ5HEMYJV6I',
+ undefined,
+ "6'000",
+ ),
+ new PluginProperties(),
+ ),
+};
+
+export const OfflineChainInfo = new ChainInfo(
+ UInt64.fromUint(1),
+ UInt64.fromUint(1),
+ UInt64.fromUint(1),
+ // mainnet nemesis block hash for dHealth
+ new FinalizedBlock(UInt64.fromUint(1), '01FBFF8ACBD0EFA47E9874882EECBC327E2B2E7076577F5A1A31FE5A358EC070', 1, 1),
+);
+
+export const OfflineAccountInfo = (address: Address) =>
+ new AccountInfo(
+ 0,
+ 'recordId',
+ address,
+ UInt64.fromUint(0),
+ '0000000000000000000000000000000000000000000000000000000000000000',
+ UInt64.fromUint(0),
+ AccountType.Unlinked,
+ new SupplementalPublicKeys(),
+ [],
+ [],
+ UInt64.fromUint(0),
+ UInt64.fromUint(0),
+ );
+
+export const OfflineStorageInfo = new StorageInfo(0, 0, 0);
+
+export const OfflineRentalFees = new RentalFees(UInt64.fromUint(1000), UInt64.fromUint(100000), UInt64.fromUint(500000));
+
+export const OfflineAccountNames = (address: Address) => new AccountNames(address, []);
+
+export const OfflineNamespaceNames = (namespaceId: NamespaceId) => new NamespaceName(namespaceId, 'mocknamespace');
+
+export const OfflineMultisigAccountGraphInfo = new MultisigAccountGraphInfo(new Map());
+
+export const OfflineNetworkCurrencies = (networkType: NetworkType): NetworkCurrencies => {
+ const publicCurrency = new Currency({
+ namespaceId: new NamespaceId('dhealth.dhp'),
+ divisibility: 6,
+ transferable: true,
+ supplyMutable: false,
+ restrictable: false,
+ mosaicId: new MosaicId(networkConfig[networkType].networkConfigurationDefaults.currencyMosaicId),
+ });
+ return new NetworkCurrencies(publicCurrency, publicCurrency);
+};
diff --git a/src/services/offline/OfflineAccountRepository.ts b/src/services/offline/OfflineAccountRepository.ts
new file mode 100644
index 0000000..388b764
--- /dev/null
+++ b/src/services/offline/OfflineAccountRepository.ts
@@ -0,0 +1,26 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import { AccountInfo, AccountRepository, AccountSearchCriteria, Address, MerkleStateInfo, Page, PaginationStreamer } from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+import { OfflineAccountInfo } from '@/services/offline/MockModels';
+
+export class OfflineAccountRepository implements AccountRepository {
+ getAccountInfo(address: Address): Observable {
+ return of(OfflineAccountInfo(address));
+ }
+
+ getAccountInfoMerkle(address: Address): Observable {
+ throw new Error(`OfflineAccountRepository: getAccountInfoMerkle not implemented`);
+ }
+
+ getAccountsInfo(addresses: Address[]): Observable {
+ return of(addresses.map(OfflineAccountInfo));
+ }
+
+ search(criteria: AccountSearchCriteria): Observable> {
+ throw new Error(`OfflineAccountRepository: search not implemented`);
+ }
+
+ streamer(): PaginationStreamer {
+ throw new Error(`OfflineAccountRepository: streamer not implemented`);
+ }
+}
diff --git a/src/services/offline/OfflineChainRepository.ts b/src/services/offline/OfflineChainRepository.ts
new file mode 100644
index 0000000..55f00a1
--- /dev/null
+++ b/src/services/offline/OfflineChainRepository.ts
@@ -0,0 +1,9 @@
+import { ChainInfo, ChainRepository } from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+import { OfflineChainInfo } from '@/services/offline/MockModels';
+
+export class OfflineChainRepository implements ChainRepository {
+ getChainInfo(): Observable {
+ return of(OfflineChainInfo);
+ }
+}
diff --git a/src/services/offline/OfflineListener.ts b/src/services/offline/OfflineListener.ts
new file mode 100644
index 0000000..cc36b0b
--- /dev/null
+++ b/src/services/offline/OfflineListener.ts
@@ -0,0 +1,81 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import {
+ Address,
+ AggregateTransaction,
+ CosignatureSignedTransaction,
+ FinalizedBlock,
+ IListener,
+ NamespaceId,
+ NewBlock,
+ Transaction,
+ TransactionStatusError,
+} from 'symbol-sdk';
+import { Observable } from 'rxjs';
+
+export class OfflineListener implements IListener {
+ url = 'mock';
+
+ aggregateBondedAdded(
+ unresolvedAddress: Address | NamespaceId,
+ transactionHash?: string,
+ subscribeMultisig?: boolean,
+ ): Observable {
+ return new Observable();
+ }
+
+ aggregateBondedRemoved(
+ unresolvedAddress: Address | NamespaceId,
+ transactionHash?: string,
+ subscribeMultisig?: boolean,
+ ): Observable {
+ return new Observable();
+ }
+
+ close(): void {
+ return;
+ }
+
+ confirmed(unresolvedAddress: Address | NamespaceId, transactionHash?: string, subscribeMultisig?: boolean): Observable {
+ return new Observable();
+ }
+
+ cosignatureAdded(unresolvedAddress: Address | NamespaceId, subscribeMultisig?: boolean): Observable {
+ return new Observable();
+ }
+
+ finalizedBlock(): Observable {
+ return new Observable();
+ }
+
+ isOpen(): boolean {
+ return true;
+ }
+
+ newBlock(): Observable {
+ return new Observable();
+ }
+
+ open(): Promise {
+ return Promise.resolve();
+ }
+
+ status(unresolvedAddress: Address | NamespaceId, transactionHash?: string): Observable {
+ return new Observable();
+ }
+
+ unconfirmedAdded(
+ unresolvedAddress: Address | NamespaceId,
+ transactionHash?: string,
+ subscribeMultisig?: boolean,
+ ): Observable {
+ return new Observable();
+ }
+
+ unconfirmedRemoved(
+ unresolvedAddress: Address | NamespaceId,
+ transactionHash?: string,
+ subscribeMultisig?: boolean,
+ ): Observable {
+ return new Observable();
+ }
+}
diff --git a/src/services/offline/OfflineMetadataRepository.ts b/src/services/offline/OfflineMetadataRepository.ts
new file mode 100644
index 0000000..236e1aa
--- /dev/null
+++ b/src/services/offline/OfflineMetadataRepository.ts
@@ -0,0 +1,21 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import { MerkleStateInfo, Metadata, MetadataRepository, MetadataSearchCriteria, Page, PaginationStreamer } from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+
+export class OfflineMetadataRepository implements MetadataRepository {
+ getMetadata(compositeHash: string): Observable {
+ throw new Error(`OfflineMetadataRepository: getMetadata not implemented`);
+ }
+
+ getMetadataMerkle(compositeHash: string): Observable {
+ throw new Error(`OfflineMetadataRepository: getMetadataMerkle not implemented`);
+ }
+
+ search(criteria: MetadataSearchCriteria): Observable> {
+ return of(new Page([], criteria.pageNumber, criteria.pageSize));
+ }
+
+ streamer(): PaginationStreamer {
+ throw new Error(`OfflineMetadataRepository: streamer not implemented`);
+ }
+}
diff --git a/src/services/offline/OfflineMosaicRepository.ts b/src/services/offline/OfflineMosaicRepository.ts
new file mode 100644
index 0000000..f02e688
--- /dev/null
+++ b/src/services/offline/OfflineMosaicRepository.ts
@@ -0,0 +1,25 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import { MerkleStateInfo, MosaicId, MosaicInfo, MosaicRepository, MosaicSearchCriteria, Page, PaginationStreamer } from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+
+export class OfflineMosaicRepository implements MosaicRepository {
+ getMosaic(mosaicId: MosaicId): Observable {
+ throw new Error(`OfflineMosaicRepository: getMosaic not implemented`);
+ }
+
+ getMosaicMerkle(mosaicId: MosaicId): Observable {
+ throw new Error(`OfflineMosaicRepository: getMosaicMerkle not implemented`);
+ }
+
+ getMosaics(mosaicIds: MosaicId[]): Observable {
+ throw new Error(`OfflineMosaicRepository: getMosaics not implemented`);
+ }
+
+ search(criteria: MosaicSearchCriteria): Observable> {
+ return of(new Page([], criteria.pageNumber, criteria.pageSize));
+ }
+
+ streamer(): PaginationStreamer {
+ throw new Error(`OfflineMosaicRepository: streamer not implemented`);
+ }
+}
diff --git a/src/services/offline/OfflineMultisigRepository.ts b/src/services/offline/OfflineMultisigRepository.ts
new file mode 100644
index 0000000..c9987a6
--- /dev/null
+++ b/src/services/offline/OfflineMultisigRepository.ts
@@ -0,0 +1,18 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import { Address, MerkleStateInfo, MultisigAccountGraphInfo, MultisigAccountInfo, MultisigRepository } from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+import { OfflineMultisigAccountGraphInfo } from '@/services/offline/MockModels';
+
+export class OfflineMultisigRepository implements MultisigRepository {
+ getMultisigAccountGraphInfo(address: Address): Observable {
+ return of(OfflineMultisigAccountGraphInfo);
+ }
+
+ getMultisigAccountInfo(address: Address): Observable {
+ throw new Error(`OfflineMultisigRepository: getMultisigAccountInfo not implemented`);
+ }
+
+ getMultisigAccountInfoMerkle(address: Address): Observable {
+ throw new Error(`OfflineMultisigRepository: getMultisigAccountInfoMerkle not implemented`);
+ }
+}
diff --git a/src/services/offline/OfflineNamespaceRepository.ts b/src/services/offline/OfflineNamespaceRepository.ts
new file mode 100644
index 0000000..3254856
--- /dev/null
+++ b/src/services/offline/OfflineNamespaceRepository.ts
@@ -0,0 +1,59 @@
+/* eslint-disable @typescript-eslint/no-unused-vars */
+import {
+ AccountNames,
+ Address,
+ MerkleStateInfo,
+ MosaicId,
+ MosaicNames,
+ NamespaceId,
+ NamespaceInfo,
+ NamespaceName,
+ NamespaceRepository,
+ NamespaceSearchCriteria,
+ Page,
+ PaginationStreamer,
+} from 'symbol-sdk';
+import { Observable, of } from 'rxjs';
+import { OfflineAccountNames, OfflineNamespaceNames } from '@/services/offline/MockModels';
+
+export class OfflineNamespaceRepository implements NamespaceRepository {
+ getAccountsNames(accountIds: Address[]): Observable {
+ return of(accountIds.map(OfflineAccountNames));
+ }
+
+ getLinkedAddress(namespaceId: NamespaceId): Observable {
+ throw new Error(`OfflineNamespaceRepository: getLinkedAddress not implemented`);
+ }
+
+ getLinkedMosaicId(namespaceId: NamespaceId): Observable {
+ throw new Error(`OfflineNamespaceRepository: getLinkedMosaicId not implemented`);
+ }
+
+ getMosaicsNames(mosaicIds: MosaicId[]): Observable {
+ throw new Error(`OfflineNamespaceRepository: getMosaicsNames not implemented`);
+ }
+
+ getNamespace(namespaceId: NamespaceId): Observable {
+ throw new Error(`OfflineNamespaceRepository: getNamespace not implemented`);
+ }
+
+ getNamespaceMerkle(namespaceId: NamespaceId): Observable {
+ throw new Error(`OfflineNamespaceRepository: getNamespaceMerkle not implemented`);
+ }
+
+ getNamespacesNames(namespaceIds: NamespaceId[]): Observable