aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.babelrc4
-rw-r--r--.env.sample17
-rw-r--r--.gitignore26
-rw-r--r--.sample.yarnrc.yml14
-rw-r--r--Caddyfile21
-rw-r--r--README.md47
-rw-r--r--apidoc/api_data.js762
-rw-r--r--apidoc/api_data.json742
-rw-r--r--apidoc/api_project.js16
-rw-r--r--apidoc/api_project.json16
-rw-r--r--apidoc/css/style.css525
-rw-r--r--apidoc/fonts/glyphicons-halflings-regular.eotbin20127 -> 0 bytes
-rw-r--r--apidoc/fonts/glyphicons-halflings-regular.svg288
-rw-r--r--apidoc/fonts/glyphicons-halflings-regular.ttfbin45404 -> 0 bytes
-rw-r--r--apidoc/fonts/glyphicons-halflings-regular.woffbin23424 -> 0 bytes
-rw-r--r--apidoc/fonts/glyphicons-halflings-regular.woff2bin18028 -> 0 bytes
-rw-r--r--apidoc/img/android-chrome-192x192.pngbin7672 -> 0 bytes
-rw-r--r--apidoc/img/android-chrome-512x512.pngbin28928 -> 0 bytes
-rw-r--r--apidoc/img/apple-touch-icon.pngbin8775 -> 0 bytes
-rw-r--r--apidoc/img/favicon-16x16.pngbin566 -> 0 bytes
-rw-r--r--apidoc/img/favicon-32x32.pngbin1154 -> 0 bytes
-rw-r--r--apidoc/img/favicon.icobin24838 -> 0 bytes
-rw-r--r--apidoc/index.html816
-rw-r--r--apidoc/locales/ca.js25
-rw-r--r--apidoc/locales/cs.js25
-rw-r--r--apidoc/locales/de.js25
-rw-r--r--apidoc/locales/es.js25
-rw-r--r--apidoc/locales/fr.js25
-rw-r--r--apidoc/locales/it.js25
-rw-r--r--apidoc/locales/locale.js51
-rw-r--r--apidoc/locales/nl.js25
-rw-r--r--apidoc/locales/pl.js25
-rw-r--r--apidoc/locales/pt_br.js25
-rw-r--r--apidoc/locales/ro.js25
-rw-r--r--apidoc/locales/ru.js25
-rw-r--r--apidoc/locales/tr.js25
-rw-r--r--apidoc/locales/vi.js25
-rw-r--r--apidoc/locales/zh.js25
-rw-r--r--apidoc/locales/zh_cn.js27
-rw-r--r--apidoc/main.js1146
-rw-r--r--apidoc/utils/handlebars_helper.js416
-rw-r--r--apidoc/utils/send_sample_request.js272
-rw-r--r--apidoc/utils/send_sample_request_utils.js97
-rw-r--r--apidoc/vendor/bootstrap.min.css6
-rw-r--r--apidoc/vendor/bootstrap.min.js6
-rw-r--r--apidoc/vendor/diff_match_patch.min.js49
-rw-r--r--apidoc/vendor/handlebars.min.js29
-rw-r--r--apidoc/vendor/jquery.min.js2
-rw-r--r--apidoc/vendor/list.min.js2
-rw-r--r--apidoc/vendor/lodash.custom.min.js41
-rw-r--r--apidoc/vendor/path-to-regexp/LICENSE21
-rw-r--r--apidoc/vendor/path-to-regexp/index.js204
-rw-r--r--apidoc/vendor/polyfill.js96
-rw-r--r--apidoc/vendor/prism.css125
-rw-r--r--apidoc/vendor/prism.js21
-rw-r--r--apidoc/vendor/require.min.js37
-rw-r--r--apidoc/vendor/semver.min.js1
-rw-r--r--apidoc/vendor/webfontloader.js17
-rw-r--r--app.js4
-rw-r--r--db/db.js5
-rw-r--r--db/index.js158
-rw-r--r--db/init/prodschema.sql312
-rw-r--r--db/migrations/20210612181508_init_referrals.js24
-rw-r--r--db/migrations/20210612192804_init_waiting_list.js.js24
-rw-r--r--db/migrations/20210612203333_schema_diff_merges.js39
-rw-r--r--db/migrations/20210625232223_add_invoice_id_to_payments.js13
-rw-r--r--db/migrations/20210628221727_add_webhook_to_invoices.js11
-rw-r--r--db/migrations/20210713174217_add_admin_to_users.js16
-rw-r--r--db/migrations/20210714123455_data_fixes_merge.js22
-rw-r--r--db/migrations/20210714123456_add_fks_merge.js45
-rw-r--r--db/migrations/s2/user_adjustments.js67
-rw-r--r--db/models/accounts.js217
-rw-r--r--db/models/codes.js32
-rw-r--r--db/models/deposits.js76
-rw-r--r--db/models/invoices.js202
-rw-r--r--db/models/keys.js40
-rw-r--r--db/models/orders.js112
-rw-r--r--db/models/payments.js220
-rw-r--r--db/models/referrals.js90
-rw-r--r--db/models/requests.js67
-rw-r--r--db/models/users.js250
-rw-r--r--db/models/waiting_list.js45
-rw-r--r--db/models/withdrawals.js103
-rw-r--r--db/normalized/README.md48
-rw-r--r--db/normalized/accounts.js231
-rw-r--r--db/normalized/bank_accounts.js24
-rw-r--r--db/normalized/credits.js236
-rw-r--r--db/normalized/debits.js236
-rw-r--r--db/normalized/deposits.js100
-rw-r--r--db/normalized/exchanges.js232
-rw-r--r--db/normalized/invoices.js206
-rw-r--r--db/normalized/liquid_assets.js21
-rw-r--r--db/normalized/ln_keys.js16
-rw-r--r--db/normalized/lnurl_codes.js14
-rw-r--r--db/normalized/non_custodial_accounts.js91
-rw-r--r--db/normalized/orders.js29
-rw-r--r--db/normalized/referrals.js20
-rw-r--r--db/normalized/transactions.js41
-rw-r--r--db/normalized/transfers.js243
-rw-r--r--db/normalized/user_preferences.js20
-rw-r--r--db/normalized/user_security.js22
-rw-r--r--db/normalized/users.js18
-rw-r--r--db/normalized/vouchers.js18
-rw-r--r--db/normalized/waiting_list.js60
-rw-r--r--db/normalized/withdrawals.js128
-rw-r--r--db/schema.sql479
-rw-r--r--doc/PAYMENTS.md52
-rw-r--r--doc/fund-server-bitcoin-cli.md44
-rw-r--r--doc/img/50-bitcoin-server-balance.gifbin7791 -> 0 bytes
-rw-r--r--docker-compose.yml205
-rw-r--r--fx.sample1
-rw-r--r--git_hooks/pre-commit11
-rw-r--r--index.js121
-rw-r--r--k8s/app-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/app-deployment.yaml44
-rw-r--r--k8s/app-service.yaml19
-rw-r--r--k8s/bitcoin-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/bitcoin-deployment.yaml42
-rw-r--r--k8s/bitcoin-service.yaml22
-rw-r--r--k8s/docker-compose-resolved.yaml118
-rw-r--r--k8s/electrs-liquid-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/electrs-liquid-deployment.yaml62
-rw-r--r--k8s/electrs-liquid-service.yaml22
-rw-r--r--k8s/esplora-liquid-deployment.yaml40
-rw-r--r--k8s/esplora-liquid-service.yaml19
-rw-r--r--k8s/la-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/la-deployment.yaml42
-rw-r--r--k8s/lb-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/lb-deployment.yaml42
-rw-r--r--k8s/liquid-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/liquid-deployment.yaml44
-rw-r--r--k8s/liquid-service.yaml28
-rw-r--r--k8s/maria-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/maria-deployment.yaml44
-rw-r--r--k8s/maria-service.yaml19
-rw-r--r--k8s/ui-claim0-persistentvolumeclaim.yaml14
-rw-r--r--k8s/ui-deployment.yaml44
-rw-r--r--k8s/ui-service.yaml19
-rw-r--r--lib/account.js49
-rw-r--r--lib/app.js40
-rw-r--r--lib/auth.js37
-rw-r--r--lib/binance.js36
-rw-r--r--lib/bitcoin.js2
-rw-r--r--lib/buildliquidtx.js160
-rw-r--r--lib/buildtx.js90
-rw-r--r--lib/db.js33
-rw-r--r--lib/invoices.js75
-rw-r--r--lib/lightning.js39
-rw-r--r--lib/liquid.js3
-rw-r--r--lib/ln.js2
-rw-r--r--lib/lnd.js1
-rw-r--r--lib/locations.js18
-rw-r--r--lib/logo.js1
-rw-r--r--lib/mail.js34
-rw-r--r--lib/nostr.js164
-rw-r--r--lib/passport.js84
-rw-r--r--lib/payments.js155
-rw-r--r--lib/persist.js22
-rw-r--r--lib/rates.js108
-rw-r--r--lib/read.js25
-rw-r--r--lib/redis.js11
-rw-r--r--lib/register.js76
-rw-r--r--lib/rpc.js26
-rw-r--r--lib/send.js215
-rw-r--r--lib/sendInternal.js224
-rw-r--r--lib/sockets.js148
-rw-r--r--lib/store.js10
-rw-r--r--lib/sync.js384
-rw-r--r--lib/upload.js64
-rw-r--r--lib/utils.js187
-rw-r--r--lib/webhooks.js13
-rw-r--r--lib/whitelist.js15
-rw-r--r--lib/wretch.js4
-rwxr-xr-xmine.sh8
-rw-r--r--nodemon.json3
-rw-r--r--package.json37
-rw-r--r--pnpm-lock.yaml1958
-rw-r--r--prod.yml96
-rw-r--r--routes/admin.js566
-rw-r--r--routes/assets.js536
-rw-r--r--routes/bitcoin/broadcast.js56
-rw-r--r--routes/bitcoin/conversionFee.js12
-rw-r--r--routes/bitcoin/fee.js73
-rw-r--r--routes/bitcoin/generate.js5
-rw-r--r--routes/bitcoin/index.js13
-rw-r--r--routes/bitcoin/receive.js281
-rw-r--r--routes/bitcoin/send.js193
-rw-r--r--routes/bitcoin/sweep.js87
-rw-r--r--routes/email.js24
-rw-r--r--routes/funding.js96
-rw-r--r--routes/info.js90
-rw-r--r--routes/invoices.js226
-rw-r--r--routes/lightning/channel.js29
-rw-r--r--routes/lightning/channelRequest.js24
-rw-r--r--routes/lightning/conversionFee.js12
-rw-r--r--routes/lightning/index.js13
-rw-r--r--routes/lightning/invoice.js25
-rw-r--r--routes/lightning/parse.js19
-rw-r--r--routes/lightning/query.js20
-rw-r--r--routes/lightning/receive.js162
-rw-r--r--routes/lightning/send.js17
-rw-r--r--routes/liquid/broadcast.js58
-rw-r--r--routes/liquid/conversionFee.js12
-rw-r--r--routes/liquid/fee.js89
-rw-r--r--routes/liquid/generate.js5
-rw-r--r--routes/liquid/index.js11
-rw-r--r--routes/liquid/receive.js406
-rw-r--r--routes/liquid/send.js276
-rw-r--r--routes/lnurl.js610
-rw-r--r--routes/locations.js24
-rw-r--r--routes/nostr.js157
-rw-r--r--routes/payments.js351
-rw-r--r--routes/rates.js11
-rw-r--r--routes/referrals.js272
-rw-r--r--routes/requests.js158
-rw-r--r--routes/send.js14
-rw-r--r--routes/swaps.js587
-rw-r--r--routes/tickets.js22
-rw-r--r--routes/users.js883
-rw-r--r--sampleconfig.js22
-rw-r--r--sampleconfig/certbot/.gitkeep1
-rw-r--r--sampleconfig/index.js78
-rw-r--r--sampleconfig/liquid/elements.conf17
-rw-r--r--sampleconfig/lnd/lnd.conf25
-rw-r--r--sampleconfig/lnd/pwd1
-rw-r--r--sampleconfig/lnurl.js36
-rw-r--r--sampleconfig/nginx/default.conf.template38
-rw-r--r--sampledata/bitcoin/bitcoin.conf (renamed from sampleconfig/bitcoin/bitcoin.conf)2
-rwxr-xr-xsampledata/bitcoin/transaction.sh2
-rw-r--r--sampledata/conversions.json2
-rw-r--r--sampledata/emails.json4
-rw-r--r--sampledata/index.js16
-rw-r--r--sampledata/lightning/config (renamed from sampleconfig/lightning/config)0
-rw-r--r--sampledata/logins.json1
-rw-r--r--sampledata/payments.json2
-rw-r--r--sampledata/recipients.json2
-rw-r--r--sampledata/withdrawals.json1
-rw-r--r--scripts/apiParse.js46
-rw-r--r--scripts/check.js24
-rwxr-xr-xscripts/purge-except-git.sh31
-rw-r--r--secret0
-rw-r--r--setup.sh7
242 files changed, 1936 insertions, 21857 deletions
diff --git a/.babelrc b/.babelrc
deleted file mode 100644
index babbfa2d..00000000
--- a/.babelrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "presets": ["env"],
- "plugins": ["transform-object-rest-spread"],
-}
diff --git a/.env.sample b/.env.sample
deleted file mode 100644
index 9fedb2dc..00000000
--- a/.env.sample
+++ /dev/null
@@ -1,17 +0,0 @@
-NGINX_PORT=8080
-APP_SERVER_PORT=3220
-BITCOIN_PEER_PORT=18442
-BITCOIN_NODE_PORT=18443
-LIQUID_PEER_PORT=18444
-LIQUID_NODE_PORT=7040
-BITCOIN_ELECTRS_RPC_PORT=51401
-BITCOIN_ELECTRS_PORT=3002
-LIQUID_ELECTRS_RPC_PORT=60401
-LIQUID_ELECTRS_PORT=3012
-LIQUID_BLOCK_PORT=18606
-LIQUID_TX_PORT=18607
-LIQUID_ESPLORA_URL=http://localhost:5005
-LIQUID_ESPLORA_PORT=5005
-LIQUID_ELECTRS_URL=http://localhost:3012
-ROOT_PASSWORD=password
-HOST=dev.coinos.io
diff --git a/.gitignore b/.gitignore
index 3b6aa213..7bbd2455 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,26 +1,4 @@
node_modules/
-.env
-yarn-error.log
-.pnp*
-.yarn*
-tls.*
-leveldb
-swaps
-exceptions
-fx
-uploads
-verified
+.pnpm*
data
-lnurl-server.sqlite3
-watcher.log
-config
-mysql
-build.json
-build.sh
-watcher.sh
-logs
-docker-compose.mainnet.yml
-assets.json
-lm.yml
-lt.yml
-caddy
+config.js
diff --git a/.sample.yarnrc.yml b/.sample.yarnrc.yml
deleted file mode 100644
index 80aeac20..00000000
--- a/.sample.yarnrc.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-yarnPath: ".yarn/releases/yarn-berry.js"
-packageExtensions:
- "@protobufjs/inquire@*":
- dependencies:
- long: "^4.0.0"
- "lnurl@*":
- dependencies:
- knex: "^0.21.1"
- "knex@*":
- dependencies:
- mysql: "^2.18.1"
- "sequelize@*":
- dependencies:
- mariadb: "^2.4.0"
diff --git a/Caddyfile b/Caddyfile
deleted file mode 100644
index 3e41ca11..00000000
--- a/Caddyfile
+++ /dev/null
@@ -1,21 +0,0 @@
-:80 {
- handle_path /api* {
- reverse_proxy app:3119
- }
-
- handle_path /.well-known* {
- reverse_proxy app:3119
- }
-
- handle /lnurl* {
- reverse_proxy app:3118
- }
-
- handle /ws* {
- reverse_proxy app:3119
- }
-
- handle {
- reverse_proxy ui:3000
- }
-}
diff --git a/README.md b/README.md
index 699bd928..9215afae 100644
--- a/README.md
+++ b/README.md
@@ -1,49 +1,14 @@
-# coinos-server
+# Coinos
-Coinos is a bitcoin wallet app that supports payments over the <a href="https://bitcoin.org">bitcoin</a>, <a href="https://blockstream.com/liquid/">liquid</a> and <a href="http://lightning.network/">lightning</a> networks. Try it out at <a href="https://coinos.io/">coinos.io</a>.
+Coinos is a web-based bitcoin and nostr client. You can use it as a front end to your personal bitcoin and lightning nodes or host a public instance that allows anyone to register with a username and password. Try ours at https://coinos.io
-This repository contains the code for the backend API server which is implemented as a NodeJS application. The code for the frontend UI is tracked separately <a href="https://github.com/asoltys/coinos.io">here</a>.
+This repository contains the code for the API server. The frontend code is at <a href="https://github.com/coinos/coinos-ui">https://github.com/coinos/coinos-ui</a>
## Install
-The follow commands will set up bitcoin, liquid and lightning nodes in regtest mode, along with a coinos app server, database, and front end UI. You'll need to have <a href="https://docs.docker.com/get-docker/">docker</a> installed as a pre-requisite.
+Make sure you have <a href="https://docs.docker.com/get-docker/">docker</a> then run the setup script:
```bash
-git clone https://github.com/coinos/coinos-server
-cd coinos-server
-cp -r sampleconfig config
-cp -r sampledata data
-mkdir uploads
-sudo chown $(id -u):$(id -g) config/liquid
-sudo chown $(id -u):$(id -g) config/bitcoin
-cp .env.sample .env
-cp fx.sample fx
-docker network create net --gateway 172.18.0.1 --subnet 172.18.0.0/16
-docker run -it -v $(pwd):/app --entrypoint pnpm asoltys/coinos-server i
-docker-compose up -d
-docker exec -i maria mysql -u root -ppassword < db/schema.sql
-docker exec -it bitcoin bitcoin-cli createwallet coinos
-docker exec -it bitcoin bitcoin-cli rescanblockchain
-docker exec -it bitcoin bitcoin-cli generatetoaddress 500 $(docker exec -it bitcoin bitcoin-cli getnewaddress "" "p2sh-segwit")
-docker exec -it liquid elements-cli createwallet coinos
-docker exec -it liquid elements-cli rescanblockchain
-docker exec -it liquid elements-cli sendtoaddress AzpsKhC6xE9FEK4aWAzMnbvueMLiSa5ym1xpuYogFkHzWgMHSt8B79aNNbFppQzCSQ2yZ9E4nL6RQJU7 1000000
-docker exec -it liquid elements-cli generatetoaddress 1 AzpsKhC6xE9FEK4aWAzMnbvueMLiSa5ym1xpuYogFkHzWgMHSt8B79aNNbFppQzCSQ2yZ9E4nL6RQJU7
-curl localhost:3119/register -H "content-type: application/json" -d '{"user": { "username": "coinosfees", "password": "password"}}'
+chmod +x setup.sh
+./setup.sh
```
-
-After successful creation of all docker containers coinos ui will be available at http://localhost:8085 and coinos server will be available at http://localhost:3119
-
-### License
-
-This code is [licensed]. Coinos is free for personal use. Anyone can fork as long as it stays AGPLv3.
-
-To purchase a commercial license or to inquire about customized, managed instances - please reach out to us at [[email protected]]
-
-
-[Config changes]:(#config-changes)
-[config/lnd/lnd.conf]:./sampleconfig/lnd/lnd.conf
-[pwd file]:./sampleconfig/lnd/pwd
-[licensed]:./LICENSE.md
-[generate some BTC]:./doc/fund-server-bitcoin-cli.md
diff --git a/apidoc/api_data.js b/apidoc/api_data.js
deleted file mode 100644
index 44a2a9c4..00000000
--- a/apidoc/api_data.js
+++ /dev/null
@@ -1,762 +0,0 @@
-define({
- api: [
- {
- type: "get",
- url: "/accounts",
- title: "Retrieve list of accounts",
- name: "accounts",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of accounts</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "accounts" : [\n { "user": \'Adam\', "account_id": \'123\', balance: 500 ... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/deposits",
- title: "Retrieve summary of deposits",
- name: "deposits",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of deposits</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "deposits" : [\n { "seller": \'Adam\', "buyer": \'bob\' ... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/users",
- title: "Retrieve user list",
- name: "getUsers",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- type: "Object",
- optional: false,
- field: "users",
- description: "<p>List of users</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "users" : [\n { "username": \'John Doe\', "email": \'[email protected]\', ...},\n { "username": \'Jane Doe\', "email": \'[email protected]\', ...}\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/invoices",
- title: "Retrieve summary of invoices",
- name: "invoices",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of invoices</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "invoices" : [\n { "seller": \'Adam\', "buyer": \'bob\' ... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/orders",
- title: "Retrieve summary of orders",
- name: "orders",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of orders</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "orders" : [\n { "seller": \'Adam\', "buyer": \'bob\' ... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/payments",
- title: "Retrieve summary of payments",
- name: "payments",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of payments</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "payments" : [\n { "seller": \'Adam\', "buyer": \'bob\' ... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/referrals",
- title: "Retrieve list of referral tokens",
- name: "referrals",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of referral tokens</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- "HTTP/1.1 200 OK\n{\n \"referrals\" : [\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername1', expiry: null },\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername2', expiry: null },\n ]\n}",
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/referrals",
- title: "Retrieve list of referral tokens",
- name: "referrals",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of referral tokens</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- "HTTP/1.1 200 OK\n{\n \"referrals\" : [\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername1', expiry: null },\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername2', expiry: null },\n ]\n}",
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/user_kyc",
- title: "Retrieve user kyc details",
- name: "user_kyc",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of kyc details for each user</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "users" : [\n { "username": \'Adam\', "email": \'[email protected]\', ... kyc_data... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/transactions",
- title: "Retrieve summary of user transactions",
- name: "user_transactions",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of invoices, payments, orders for users</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "transactions" : [\n { "username": \'Adam\', "email": \'[email protected]\', invoices: 1, orders: 0, payments: 2 },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/withdrawals",
- title: "Retrieve summary of withdrawals",
- name: "withdrawals",
- group: "Admin",
- permission: [
- {
- name: "admin"
- }
- ],
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "returns",
- description: "<p>list of withdrawals</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "withdrawals" : [\n { "seller": \'Adam\', "buyer": \'bob\' ... },\n ...\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/admin.js",
- groupTitle: "Admin"
- },
- {
- type: "get",
- url: "/info",
- title: "Request server information",
- name: "GetInfo",
- group: "Info",
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- type: "Object",
- optional: false,
- field: "fx",
- description:
- "<p>Exchange rates relative to USD - fx.CUR is the value of one CUR in USD.</p>"
- },
- {
- group: "Success 200",
- type: "String[]",
- optional: false,
- field: "networks",
- description:
- "<p>Array of supported networks; possible values are &quot;bitcoin&quot;, &quot;liquid&quot; and &quot;lightning&quot;.</p>"
- },
- {
- group: "Success 200",
- type: "String",
- optional: false,
- field: "clientVersion",
- description: "<p>the current git commit of the ui</p>"
- }
- ]
- }
- },
- version: "0.0.0",
- filename: "routes/info.js",
- groupTitle: "Info"
- },
- {
- type: "post",
- url: "/grant",
- title: "Grant Referral code",
- name: "Grant",
- group: "Referrals",
- permission: [
- {
- name: "member"
- }
- ],
- parameter: {
- fields: {
- Parameter: [
- {
- group: "Parameter",
- type: "sponsor_id",
- optional: false,
- field: "user_id",
- description: "<p>of member generating referral code.</p>"
- },
- {
- group: "Parameter",
- type: "expiry",
- optional: false,
- field: "optional",
- description: "<p>expiry date for token.</p>"
- }
- ]
- }
- },
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- type: "String",
- optional: false,
- field: "token",
- description: "<p>referral token</p>"
- },
- {
- group: "Success 200",
- type: "Date",
- optional: false,
- field: "expiry",
- description: "<p>optional expiry</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "token": "*********", \n "status": "available", \n "expiry": null\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/referrals.js",
- groupTitle: "Referrals"
- },
- {
- type: "get",
- url: "/grant",
- title: "Grant Referral code (variation using get)",
- name: "Grant",
- group: "Referrals",
- permission: [
- {
- name: "member"
- },
- {
- name: "member"
- }
- ],
- parameter: {
- fields: {
- Parameter: [
- {
- group: "Parameter",
- type: "sponsor_id",
- optional: false,
- field: "user_id",
- description: "<p>of member generating referral code.</p>"
- },
- {
- group: "Parameter",
- type: "expiry",
- optional: false,
- field: "optional",
- description: "<p>expiry date for token.</p>"
- }
- ]
- }
- },
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- type: "String",
- optional: false,
- field: "token",
- description: "<p>referral token</p>"
- },
- {
- group: "Success 200",
- type: "Status",
- optional: false,
- field: "status",
- description: "<p>referral status</p>"
- },
- {
- group: "Success 200",
- type: "Date",
- optional: false,
- field: "expiry",
- description: "<p>optional expiry</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "token": "*********", \n "status": "available", \n "expiry": null\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/referrals.js",
- groupTitle: "Referrals"
- },
- {
- type: "get",
- url: "/checkTokens/:sponsor_id",
- title: "Retrieve list of referral tokens generated by this user",
- name: "checkTokens",
- group: "Referrals",
- permission: [
- {
- name: "member"
- }
- ],
- parameter: {
- fields: {
- Parameter: [
- {
- group: "Parameter",
- type: "sponsor_id",
- optional: false,
- field: "user_id",
- description: "<p>of member generating referral code.</p>"
- },
- {
- group: "Parameter",
- type: "status",
- optional: false,
- field: "optional",
- description: "<p>token status.</p>"
- }
- ]
- }
- },
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "tokens",
- description: "<p>array of token objects</p>"
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "tokens": [\n {"token": "*********", "status": "available", "expiry": null}\n ]\n}',
- type: "json"
- }
- ]
- },
- version: "0.0.0",
- filename: "routes/referrals.js",
- groupTitle: "Referrals"
- },
- {
- type: "get",
- url: "/isReferred/:user_id",
- title: "Check if user is referred",
- name: "isReferred",
- group: "Referrals",
- parameter: {
- fields: {
- Parameter: [
- {
- group: "Parameter",
- type: "user_id",
- optional: false,
- field: "user",
- description: "<p>id</p>"
- }
- ]
- }
- },
- success: {
- examples: [
- {
- title: "Success-Response:",
- content: "HTTP/1.1 200 OK\n{\n true\n}",
- type: "json"
- }
- ]
- },
- description:
- "<p>returns boolean indicating if user is referred or not</p>",
- version: "0.0.0",
- filename: "routes/referrals.js",
- groupTitle: "Referrals"
- },
- {
- type: "post",
- url: "/joinQueue",
- title: "Join waiting list (track email & phone)",
- name: "joinQueue",
- group: "Referrals",
- parameter: {
- fields: {
- Parameter: [
- {
- group: "Parameter",
- type: "email",
- optional: false,
- field: "email",
- description: "<p>address</p>"
- },
- {
- group: "Parameter",
- type: "phone",
- optional: false,
- field: "phone",
- description: "<p>number</p>"
- }
- ]
- }
- },
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "verified",
- defaultValue: "true",
- description: ""
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content:
- 'HTTP/1.1 200 OK\n{\n "success": true\n "message": \'Added to waiting list\'\n}',
- type: "json"
- }
- ]
- },
- description: "<p>referral token is updated with existing user_id</p>",
- version: "0.0.0",
- filename: "routes/referrals.js",
- groupTitle: "Referrals"
- },
- {
- type: "get",
- url: "/verify/:user_id",
- title: "Verify token and apply to existing user",
- name: "verify",
- group: "Referrals",
- permission: [
- {
- name: "member"
- }
- ],
- parameter: {
- fields: {
- Parameter: [
- {
- group: "Parameter",
- type: "user_id",
- optional: false,
- field: "Current",
- description: "<p>user</p>"
- },
- {
- group: "Parameter",
- type: "token",
- optional: false,
- field: "Token",
- description: "<p>to validate</p>"
- }
- ]
- }
- },
- success: {
- fields: {
- "Success 200": [
- {
- group: "Success 200",
- optional: false,
- field: "verified",
- defaultValue: "true",
- description: ""
- }
- ]
- },
- examples: [
- {
- title: "Success-Response:",
- content: 'HTTP/1.1 200 OK\n{\n "verified": true\n}',
- type: "json"
- }
- ]
- },
- description: "<p>referral token is updated with existing user_id</p>",
- version: "0.0.0",
- filename: "routes/referrals.js",
- groupTitle: "Referrals"
- }
- ]
-});
diff --git a/apidoc/api_data.json b/apidoc/api_data.json
deleted file mode 100644
index 5bab3ee7..00000000
--- a/apidoc/api_data.json
+++ /dev/null
@@ -1,742 +0,0 @@
-[
- {
- "type": "get",
- "url": "/accounts",
- "title": "Retrieve list of accounts",
- "name": "accounts",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of accounts</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"accounts\" : [\n { \"user\": 'Adam', \"account_id\": '123', balance: 500 ... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/deposits",
- "title": "Retrieve summary of deposits",
- "name": "deposits",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of deposits</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"deposits\" : [\n { \"seller\": 'Adam', \"buyer\": 'bob' ... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/users",
- "title": "Retrieve user list",
- "name": "getUsers",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "type": "Object",
- "optional": false,
- "field": "users",
- "description": "<p>List of users</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"users\" : [\n { \"username\": 'John Doe', \"email\": '[email protected]', ...},\n { \"username\": 'Jane Doe', \"email\": '[email protected]', ...}\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/invoices",
- "title": "Retrieve summary of invoices",
- "name": "invoices",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of invoices</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"invoices\" : [\n { \"seller\": 'Adam', \"buyer\": 'bob' ... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/orders",
- "title": "Retrieve summary of orders",
- "name": "orders",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of orders</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"orders\" : [\n { \"seller\": 'Adam', \"buyer\": 'bob' ... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/payments",
- "title": "Retrieve summary of payments",
- "name": "payments",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of payments</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"payments\" : [\n { \"seller\": 'Adam', \"buyer\": 'bob' ... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/referrals",
- "title": "Retrieve list of referral tokens",
- "name": "referrals",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of referral tokens</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"referrals\" : [\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername1', expiry: null },\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername2', expiry: null },\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/referrals",
- "title": "Retrieve list of referral tokens",
- "name": "referrals",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of referral tokens</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"referrals\" : [\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername1', expiry: null },\n { \"token\": '***', \"status\": 'pending', sponsor: 'Adam', user: 'newUsername2', expiry: null },\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/user_kyc",
- "title": "Retrieve user kyc details",
- "name": "user_kyc",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of kyc details for each user</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"users\" : [\n { \"username\": 'Adam', \"email\": '[email protected]', ... kyc_data... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/transactions",
- "title": "Retrieve summary of user transactions",
- "name": "user_transactions",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of invoices, payments, orders for users</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"transactions\" : [\n { \"username\": 'Adam', \"email\": '[email protected]', invoices: 1, orders: 0, payments: 2 },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/withdrawals",
- "title": "Retrieve summary of withdrawals",
- "name": "withdrawals",
- "group": "Admin",
- "permission": [
- {
- "name": "admin"
- }
- ],
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "returns",
- "description": "<p>list of withdrawals</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"withdrawals\" : [\n { \"seller\": 'Adam', \"buyer\": 'bob' ... },\n ...\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/admin.js",
- "groupTitle": "Admin"
- },
- {
- "type": "get",
- "url": "/info",
- "title": "Request server information",
- "name": "GetInfo",
- "group": "Info",
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "type": "Object",
- "optional": false,
- "field": "fx",
- "description": "<p>Exchange rates relative to USD - fx.CUR is the value of one CUR in USD.</p>"
- },
- {
- "group": "Success 200",
- "type": "String[]",
- "optional": false,
- "field": "networks",
- "description": "<p>Array of supported networks; possible values are &quot;bitcoin&quot;, &quot;liquid&quot; and &quot;lightning&quot;.</p>"
- },
- {
- "group": "Success 200",
- "type": "String",
- "optional": false,
- "field": "clientVersion",
- "description": "<p>the current git commit of the ui</p>"
- }
- ]
- }
- },
- "version": "0.0.0",
- "filename": "routes/info.js",
- "groupTitle": "Info"
- },
- {
- "type": "post",
- "url": "/grant",
- "title": "Grant Referral code",
- "name": "Grant",
- "group": "Referrals",
- "permission": [
- {
- "name": "member"
- }
- ],
- "parameter": {
- "fields": {
- "Parameter": [
- {
- "group": "Parameter",
- "type": "sponsor_id",
- "optional": false,
- "field": "user_id",
- "description": "<p>of member generating referral code.</p>"
- },
- {
- "group": "Parameter",
- "type": "expiry",
- "optional": false,
- "field": "optional",
- "description": "<p>expiry date for token.</p>"
- }
- ]
- }
- },
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "type": "String",
- "optional": false,
- "field": "token",
- "description": "<p>referral token</p>"
- },
- {
- "group": "Success 200",
- "type": "Date",
- "optional": false,
- "field": "expiry",
- "description": "<p>optional expiry</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"token\": \"*********\", \n \"status\": \"available\", \n \"expiry\": null\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/referrals.js",
- "groupTitle": "Referrals"
- },
- {
- "type": "get",
- "url": "/grant",
- "title": "Grant Referral code (variation using get)",
- "name": "Grant",
- "group": "Referrals",
- "permission": [
- {
- "name": "member"
- },
- {
- "name": "member"
- }
- ],
- "parameter": {
- "fields": {
- "Parameter": [
- {
- "group": "Parameter",
- "type": "sponsor_id",
- "optional": false,
- "field": "user_id",
- "description": "<p>of member generating referral code.</p>"
- },
- {
- "group": "Parameter",
- "type": "expiry",
- "optional": false,
- "field": "optional",
- "description": "<p>expiry date for token.</p>"
- }
- ]
- }
- },
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "type": "String",
- "optional": false,
- "field": "token",
- "description": "<p>referral token</p>"
- },
- {
- "group": "Success 200",
- "type": "Status",
- "optional": false,
- "field": "status",
- "description": "<p>referral status</p>"
- },
- {
- "group": "Success 200",
- "type": "Date",
- "optional": false,
- "field": "expiry",
- "description": "<p>optional expiry</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"token\": \"*********\", \n \"status\": \"available\", \n \"expiry\": null\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/referrals.js",
- "groupTitle": "Referrals"
- },
- {
- "type": "get",
- "url": "/checkTokens/:sponsor_id",
- "title": "Retrieve list of referral tokens generated by this user",
- "name": "checkTokens",
- "group": "Referrals",
- "permission": [
- {
- "name": "member"
- }
- ],
- "parameter": {
- "fields": {
- "Parameter": [
- {
- "group": "Parameter",
- "type": "sponsor_id",
- "optional": false,
- "field": "user_id",
- "description": "<p>of member generating referral code.</p>"
- },
- {
- "group": "Parameter",
- "type": "status",
- "optional": false,
- "field": "optional",
- "description": "<p>token status.</p>"
- }
- ]
- }
- },
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "tokens",
- "description": "<p>array of token objects</p>"
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"tokens\": [\n {\"token\": \"*********\", \"status\": \"available\", \"expiry\": null}\n ]\n}",
- "type": "json"
- }
- ]
- },
- "version": "0.0.0",
- "filename": "routes/referrals.js",
- "groupTitle": "Referrals"
- },
- {
- "type": "get",
- "url": "/isReferred/:user_id",
- "title": "Check if user is referred",
- "name": "isReferred",
- "group": "Referrals",
- "parameter": {
- "fields": {
- "Parameter": [
- {
- "group": "Parameter",
- "type": "user_id",
- "optional": false,
- "field": "user",
- "description": "<p>id</p>"
- }
- ]
- }
- },
- "success": {
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n true\n}",
- "type": "json"
- }
- ]
- },
- "description": "<p>returns boolean indicating if user is referred or not</p>",
- "version": "0.0.0",
- "filename": "routes/referrals.js",
- "groupTitle": "Referrals"
- },
- {
- "type": "post",
- "url": "/joinQueue",
- "title": "Join waiting list (track email & phone)",
- "name": "joinQueue",
- "group": "Referrals",
- "parameter": {
- "fields": {
- "Parameter": [
- {
- "group": "Parameter",
- "type": "email",
- "optional": false,
- "field": "email",
- "description": "<p>address</p>"
- },
- {
- "group": "Parameter",
- "type": "phone",
- "optional": false,
- "field": "phone",
- "description": "<p>number</p>"
- }
- ]
- }
- },
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "verified",
- "defaultValue": "true",
- "description": ""
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"success\": true\n \"message\": 'Added to waiting list'\n}",
- "type": "json"
- }
- ]
- },
- "description": "<p>referral token is updated with existing user_id</p>",
- "version": "0.0.0",
- "filename": "routes/referrals.js",
- "groupTitle": "Referrals"
- },
- {
- "type": "get",
- "url": "/verify/:user_id",
- "title": "Verify token and apply to existing user",
- "name": "verify",
- "group": "Referrals",
- "permission": [
- {
- "name": "member"
- }
- ],
- "parameter": {
- "fields": {
- "Parameter": [
- {
- "group": "Parameter",
- "type": "user_id",
- "optional": false,
- "field": "Current",
- "description": "<p>user</p>"
- },
- {
- "group": "Parameter",
- "type": "token",
- "optional": false,
- "field": "Token",
- "description": "<p>to validate</p>"
- }
- ]
- }
- },
- "success": {
- "fields": {
- "Success 200": [
- {
- "group": "Success 200",
- "optional": false,
- "field": "verified",
- "defaultValue": "true",
- "description": ""
- }
- ]
- },
- "examples": [
- {
- "title": "Success-Response:",
- "content": "HTTP/1.1 200 OK\n{\n \"verified\": true\n}",
- "type": "json"
- }
- ]
- },
- "description": "<p>referral token is updated with existing user_id</p>",
- "version": "0.0.0",
- "filename": "routes/referrals.js",
- "groupTitle": "Referrals"
- }
-]
diff --git a/apidoc/api_project.js b/apidoc/api_project.js
deleted file mode 100644
index 3c0eb6aa..00000000
--- a/apidoc/api_project.js
+++ /dev/null
@@ -1,16 +0,0 @@
-define({
- title: "CoinOS Server API Documentation",
- url: "https://coinos.io/api",
- name: "coinos",
- version: "0.0.1",
- description: "",
- sampleUrl: false,
- defaultVersion: "0.0.0",
- apidoc: "0.3.0",
- generator: {
- name: "apidoc",
- time: "2021-08-18T19:13:24.486Z",
- url: "https://apidocjs.com",
- version: "0.29.0"
- }
-});
diff --git a/apidoc/api_project.json b/apidoc/api_project.json
deleted file mode 100644
index 42943876..00000000
--- a/apidoc/api_project.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "title": "CoinOS Server API Documentation",
- "url": "https://coinos.io/api",
- "name": "coinos",
- "version": "0.0.1",
- "description": "",
- "sampleUrl": false,
- "defaultVersion": "0.0.0",
- "apidoc": "0.3.0",
- "generator": {
- "name": "apidoc",
- "time": "2021-08-18T19:13:24.486Z",
- "url": "https://apidocjs.com",
- "version": "0.29.0"
- }
-}
diff --git a/apidoc/css/style.css b/apidoc/css/style.css
deleted file mode 100644
index 9f3c88ac..00000000
--- a/apidoc/css/style.css
+++ /dev/null
@@ -1,525 +0,0 @@
-/* ------------------------------------------------------------------------------------------
- * Content
- * ------------------------------------------------------------------------------------------ */
-body {
- max-width: 1280px;
-}
-
-body, p, a, div, th, td {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 400;
- font-size: 16px;
-}
-
-@media (min-width: 1200px) {
- body.container-fluid {
- padding-right: 0px;
- padding-left: 0px;
- margin-right: 0px;
- margin-left: 0px;
- }
-}
-
-td.code {
- font-size: 14px;
- font-family: "Source Code Pro", monospace;
- font-style: normal;
- font-weight: 400;
-}
-
-#content {
- padding-top: 16px;
- z-Index: -1;
- margin-left: 270px;
-}
-
-p {
- color: #808080;
-}
-
-h1 {
- font-family: "Source Sans Pro Semibold", sans-serif;
- font-weight: normal;
- font-size: 44px;
- line-height: 50px;
- margin: 0 0 10px 0;
- padding: 0;
-}
-
-h2 {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: normal;
- font-size: 24px;
- line-height: 40px;
- margin: 0 0 20px 0;
- padding: 0;
-}
-
-section {
- border-top: 1px solid #ebebeb;
- padding: 30px 0;
-}
-
-section h1 {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 700;
- font-size: 32px;
- line-height: 40px;
- margin: 0 0 20px 0;
- padding: 0;
-}
-
-article {
- padding: 14px 0 30px 0;
-}
-
-article h1 {
- font-family: "Source Sans Pro Bold", sans-serif;
- font-weight: 600;
- font-size: 24px;
- line-height: 26px;
-}
-
-article h2 {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 600;
- font-size: 18px;
- line-height: 24px;
- margin: 0 0 10px 0;
-}
-
-article h3 {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 600;
- font-size: 16px;
- line-height: 18px;
- margin: 0 0 10px 0;
-}
-
-article h4 {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 600;
- font-size: 14px;
- line-height: 16px;
- margin: 0 0 8px 0;
-}
-
-table {
- border-collapse: collapse;
- width: 100%;
- margin: 0 0 20px 0;
-}
-
-th {
- background-color: #f5f5f5;
- text-align: left;
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 700;
- padding: 4px 8px;
- border: #e0e0e0 1px solid;
-}
-
-td {
- vertical-align: top;
- padding: 10px 8px 0 8px;
- border: #e0e0e0 1px solid;
-}
-
-#generator .content {
- color: #b0b0b0;
- border-top: 1px solid #ebebeb;
- padding: 10px 0;
-}
-
-.label-optional {
- float: right;
- background-color: grey;
- margin-top: 4px;
- user-select: none;
-}
-
-.open-left {
- right: 0;
- left: auto;
-}
-
-/* ------------------------------------------------------------------------------------------
- * apidoc - intro
- * ------------------------------------------------------------------------------------------ */
-
-#apidoc .apidoc {
- border-top: 1px solid #ebebeb;
- padding: 30px 0;
-}
-
-#apidoc h1 {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 700;
- font-size: 32px;
- line-height: 40px;
- margin: 0 0 20px 0;
- padding: 0;
-}
-
-#apidoc h2 {
- font-family: "Source Sans Pro Bold", sans-serif;
- font-weight: 600;
- font-size: 22px;
- line-height: 26px;
- padding-top: 14px;
-}
-
-/* ------------------------------------------------------------------------------------------
- * Request type
- * ------------------------------------------------------------------------------------------ */
-.type {
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 600;
- font-size: 15px;
- display: inline-block;
- margin: 0 0 5px 0;
- padding: 4px 5px;
- border-radius: 6px;
- text-transform: uppercase;
- background-color: #3387CC;
- color: #ffffff;
-}
-
-.type__get {
- background-color: green;
-}
-
-.type__put {
- background-color: #e5c500;
-}
-
-.type__post {
- background-color: #4070ec;
-}
-
-.type__delete {
- background-color: #ed0039;
-}
-
-/* ------------------------------------------------------------------------------------------
- * Sidenav
- * ------------------------------------------------------------------------------------------ */
-.sidenav {
- width: 228px;
- margin: 0;
- padding: 0 20px 20px 20px;
- position: fixed;
- top: 50px;
- left: 0;
- bottom: 0;
- overflow-x: hidden;
- overflow-y: auto;
- background-color: #f5f5f5;
- z-index: 10;
-}
-
-.sidenav > li > a {
- display: block;
- width: 192px;
- margin: 0;
- padding: 2px 11px;
- border: 0;
- border-left: transparent 4px solid;
- border-right: transparent 4px solid;
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 400;
- font-size: 14px;
-}
-
-.sidenav > li.nav-header {
- margin-top: 8px;
- margin-bottom: 8px;
-}
-
-.sidenav > li.nav-header > a {
- padding: 5px 15px;
- border: 1px solid #e5e5e5;
- width: 190px;
- font-family: "Source Sans Pro", sans-serif;
- font-weight: 700;
- font-size: 16px;
- background-color: #ffffff;
-}
-
-.sidenav > li.active > a {
- position: relative;
- z-index: 2;
- background-color: #0088cc;
- color: #ffffff;
-}
-
-.sidenav > li.has-modifications a {
- border-right: #60d060 4px solid;
-}
-
-.sidenav > li.is-new a {
- border-left: #e5e5e5 4px solid;
-}
-
-/* ------------------------------------------------------------------------------------------
- * Side nav search
- * ------------------------------------------------------------------------------------------ */
-.sidenav-search {
- width: 228px;
- left: 0px;
- position: fixed;
- padding: 16px 20px 10px 20px;
- background-color: #F5F5F5;
- z-index: 11;
-}
-
-.sidenav-search .search {
- height: 26px;
-}
-
-.search-reset {
- position: absolute;
- display: block;
- cursor: pointer;
- width: 20px;
- height: 20px;
- text-align: center;
- right: 28px;
- top: 17px;
- background-color: #fff;
-}
-
-/* ------------------------------------------------------------------------------------------
- * Compare
- * ------------------------------------------------------------------------------------------ */
-
-ins {
- background: #60d060;
- text-decoration: none;
- color: #000000;
-}
-
-del {
- background: #f05050;
- color: #000000;
-}
-
-.label-ins {
- background-color: #60d060;
-}
-
-.label-del {
- background-color: #f05050;
- text-decoration: line-through;
-}
-
-pre.ins {
- background-color: #60d060;
-}
-
-pre.del {
- background-color: #f05050;
- text-decoration: line-through;
-}
-
-table.ins th,
-table.ins td {
- background-color: #60d060;
-}
-
-table.del th,
-table.del td {
- background-color: #f05050;
- text-decoration: line-through;
-}
-
-tr.ins td {
- background-color: #60d060;
-}
-
-tr.del td {
- background-color: #f05050;
- text-decoration: line-through;
-}
-
-/* ------------------------------------------------------------------------------------------
- * Spinner
- * ------------------------------------------------------------------------------------------ */
-
-#loader {
- position: absolute;
- width: 100%;
-}
-
-#loader p {
- padding-top: 80px;
- margin-left: -4px;
-}
-
-.spinner {
- margin: 200px auto;
- width: 60px;
- height: 60px;
- position: relative;
-}
-
-.container1 > div, .container2 > div, .container3 > div {
- width: 14px;
- height: 14px;
- background-color: #0088cc;
-
- border-radius: 100%;
- position: absolute;
- -webkit-animation: bouncedelay 1.2s infinite ease-in-out;
- animation: bouncedelay 1.2s infinite ease-in-out;
- /* Prevent first frame from flickering when animation starts */
- -webkit-animation-fill-mode: both;
- animation-fill-mode: both;
-}
-
-.spinner .spinner-container {
- position: absolute;
- width: 100%;
- height: 100%;
-}
-
-.container2 {
- -webkit-transform: rotateZ(45deg);
- transform: rotateZ(45deg);
-}
-
-.container3 {
- -webkit-transform: rotateZ(90deg);
- transform: rotateZ(90deg);
-}
-
-.circle1 { top: 0; left: 0; }
-.circle2 { top: 0; right: 0; }
-.circle3 { right: 0; bottom: 0; }
-.circle4 { left: 0; bottom: 0; }
-
-.container2 .circle1 {
- -webkit-animation-delay: -1.1s;
- animation-delay: -1.1s;
-}
-
-.container3 .circle1 {
- -webkit-animation-delay: -1.0s;
- animation-delay: -1.0s;
-}
-
-.container1 .circle2 {
- -webkit-animation-delay: -0.9s;
- animation-delay: -0.9s;
-}
-
-.container2 .circle2 {
- -webkit-animation-delay: -0.8s;
- animation-delay: -0.8s;
-}
-
-.container3 .circle2 {
- -webkit-animation-delay: -0.7s;
- animation-delay: -0.7s;
-}
-
-.container1 .circle3 {
- -webkit-animation-delay: -0.6s;
- animation-delay: -0.6s;
-}
-
-.container2 .circle3 {
- -webkit-animation-delay: -0.5s;
- animation-delay: -0.5s;
-}
-
-.container3 .circle3 {
- -webkit-animation-delay: -0.4s;
- animation-delay: -0.4s;
-}
-
-.container1 .circle4 {
- -webkit-animation-delay: -0.3s;
- animation-delay: -0.3s;
-}
-
-.container2 .circle4 {
- -webkit-animation-delay: -0.2s;
- animation-delay: -0.2s;
-}
-
-.container3 .circle4 {
- -webkit-animation-delay: -0.1s;
- animation-delay: -0.1s;
-}
-
-@-webkit-keyframes bouncedelay {
- 0%, 80%, 100% { -webkit-transform: scale(0.0) }
- 40% { -webkit-transform: scale(1.0) }
-}
-
-@keyframes bouncedelay {
- 0%, 80%, 100% {
- transform: scale(0.0);
- -webkit-transform: scale(0.0);
- } 40% {
- transform: scale(1.0);
- -webkit-transform: scale(1.0);
- }
-}
-
-/* ------------------------------------------------------------------------------------------
- * Tabs
- * ------------------------------------------------------------------------------------------ */
-ul.nav-tabs {
- margin: 0;
-}
-
-p.deprecated span{
- color: #ff0000;
- font-weight: bold;
- text-decoration: underline;
-}
-
-/* ------------------------------------------------------------------------------------------
- * Print
- * ------------------------------------------------------------------------------------------ */
-
-@media print {
-
- #sidenav,
- #version,
- #versions,
- section .version,
- section .versions {
- display: none;
- }
-
- #content {
- margin-left: 0;
- }
-
- a {
- text-decoration: none;
- color: inherit;
- }
-
- a:after {
- content: " [" attr(href) "] ";
- }
-
- p {
- color: #000000
- }
-
- pre {
- background-color: #ffffff;
- color: #000000;
- padding: 10px;
- border: #808080 1px solid;
- border-radius: 6px;
- position: relative;
- margin: 10px 0 20px 0;
- }
-
-} /* /@media print */
diff --git a/apidoc/fonts/glyphicons-halflings-regular.eot b/apidoc/fonts/glyphicons-halflings-regular.eot
deleted file mode 100644
index b93a4953..00000000
--- a/apidoc/fonts/glyphicons-halflings-regular.eot
+++ /dev/null
Binary files differ
diff --git a/apidoc/fonts/glyphicons-halflings-regular.svg b/apidoc/fonts/glyphicons-halflings-regular.svg
deleted file mode 100644
index 94fb5490..00000000
--- a/apidoc/fonts/glyphicons-halflings-regular.svg
+++ /dev/null
@@ -1,288 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
-<svg xmlns="http://www.w3.org/2000/svg">
-<metadata></metadata>
-<defs>
-<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
-<font-face units-per-em="1200" ascent="960" descent="-240" />
-<missing-glyph horiz-adv-x="500" />
-<glyph horiz-adv-x="0" />
-<glyph horiz-adv-x="400" />
-<glyph unicode=" " />
-<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
-<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xa0;" />
-<glyph unicode="&#xa5;" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
-<glyph unicode="&#x2000;" horiz-adv-x="650" />
-<glyph unicode="&#x2001;" horiz-adv-x="1300" />
-<glyph unicode="&#x2002;" horiz-adv-x="650" />
-<glyph unicode="&#x2003;" horiz-adv-x="1300" />
-<glyph unicode="&#x2004;" horiz-adv-x="433" />
-<glyph unicode="&#x2005;" horiz-adv-x="325" />
-<glyph unicode="&#x2006;" horiz-adv-x="216" />
-<glyph unicode="&#x2007;" horiz-adv-x="216" />
-<glyph unicode="&#x2008;" horiz-adv-x="162" />
-<glyph unicode="&#x2009;" horiz-adv-x="260" />
-<glyph unicode="&#x200a;" horiz-adv-x="72" />
-<glyph unicode="&#x202f;" horiz-adv-x="260" />
-<glyph unicode="&#x205f;" horiz-adv-x="325" />
-<glyph unicode="&#x20ac;" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
-<glyph unicode="&#x20bd;" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
-<glyph unicode="&#x2212;" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#x231b;" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
-<glyph unicode="&#x25fc;" horiz-adv-x="500" d="M0 0z" />
-<glyph unicode="&#x2601;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
-<glyph unicode="&#x26fa;" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
-<glyph unicode="&#x2709;" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
-<glyph unicode="&#x270f;" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
-<glyph unicode="&#xe001;" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
-<glyph unicode="&#xe002;" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
-<glyph unicode="&#xe003;" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
-<glyph unicode="&#xe005;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
-<glyph unicode="&#xe006;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
-<glyph unicode="&#xe007;" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
-<glyph unicode="&#xe008;" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
-<glyph unicode="&#xe009;" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
-<glyph unicode="&#xe010;" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe011;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
-<glyph unicode="&#xe012;" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe013;" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
-<glyph unicode="&#xe014;" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
-<glyph unicode="&#xe015;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe016;" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe017;" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
-<glyph unicode="&#xe018;" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe019;" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
-<glyph unicode="&#xe020;" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
-<glyph unicode="&#xe021;" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
-<glyph unicode="&#xe022;" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
-<glyph unicode="&#xe023;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe024;" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
-<glyph unicode="&#xe025;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe026;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
-<glyph unicode="&#xe027;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
-<glyph unicode="&#xe028;" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
-<glyph unicode="&#xe029;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
-<glyph unicode="&#xe030;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
-<glyph unicode="&#xe031;" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
-<glyph unicode="&#xe032;" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe033;" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
-<glyph unicode="&#xe034;" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
-<glyph unicode="&#xe035;" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
-<glyph unicode="&#xe036;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
-<glyph unicode="&#xe037;" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
-<glyph unicode="&#xe038;" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
-<glyph unicode="&#xe039;" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
-<glyph unicode="&#xe040;" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
-<glyph unicode="&#xe041;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
-<glyph unicode="&#xe042;" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
-<glyph unicode="&#xe043;" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
-<glyph unicode="&#xe044;" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe045;" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
-<glyph unicode="&#xe046;" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
-<glyph unicode="&#xe047;" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
-<glyph unicode="&#xe048;" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
-<glyph unicode="&#xe049;" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
-<glyph unicode="&#xe050;" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
-<glyph unicode="&#xe051;" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
-<glyph unicode="&#xe052;" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe053;" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe054;" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
-<glyph unicode="&#xe055;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe056;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe057;" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe058;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe059;" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
-<glyph unicode="&#xe060;" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
-<glyph unicode="&#xe062;" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
-<glyph unicode="&#xe063;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
-<glyph unicode="&#xe064;" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
-<glyph unicode="&#xe065;" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
-<glyph unicode="&#xe066;" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
-<glyph unicode="&#xe067;" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
-<glyph unicode="&#xe068;" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
-<glyph unicode="&#xe069;" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe070;" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe071;" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
-<glyph unicode="&#xe072;" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
-<glyph unicode="&#xe073;" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe074;" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
-<glyph unicode="&#xe075;" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
-<glyph unicode="&#xe076;" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe077;" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe078;" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe079;" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
-<glyph unicode="&#xe080;" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
-<glyph unicode="&#xe081;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
-<glyph unicode="&#xe082;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
-<glyph unicode="&#xe083;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
-<glyph unicode="&#xe084;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
-<glyph unicode="&#xe085;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
-<glyph unicode="&#xe086;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
-<glyph unicode="&#xe087;" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
-<glyph unicode="&#xe088;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
-<glyph unicode="&#xe089;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
-<glyph unicode="&#xe090;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
-<glyph unicode="&#xe091;" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
-<glyph unicode="&#xe092;" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
-<glyph unicode="&#xe093;" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
-<glyph unicode="&#xe094;" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe095;" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
-<glyph unicode="&#xe096;" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
-<glyph unicode="&#xe097;" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
-<glyph unicode="&#xe101;" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
-<glyph unicode="&#xe102;" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
-<glyph unicode="&#xe103;" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
-<glyph unicode="&#xe104;" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
-<glyph unicode="&#xe105;" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
-<glyph unicode="&#xe106;" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
-<glyph unicode="&#xe107;" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
-<glyph unicode="&#xe108;" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
-<glyph unicode="&#xe109;" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
-<glyph unicode="&#xe110;" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
-<glyph unicode="&#xe111;" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
-<glyph unicode="&#xe112;" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
-<glyph unicode="&#xe113;" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
-<glyph unicode="&#xe114;" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
-<glyph unicode="&#xe115;" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
-<glyph unicode="&#xe116;" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
-<glyph unicode="&#xe117;" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
-<glyph unicode="&#xe118;" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
-<glyph unicode="&#xe119;" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
-<glyph unicode="&#xe120;" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
-<glyph unicode="&#xe121;" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
-<glyph unicode="&#xe122;" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
-<glyph unicode="&#xe123;" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
-<glyph unicode="&#xe124;" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
-<glyph unicode="&#xe125;" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe126;" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
-<glyph unicode="&#xe127;" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe128;" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe129;" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe130;" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
-<glyph unicode="&#xe131;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
-<glyph unicode="&#xe132;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
-<glyph unicode="&#xe133;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
-<glyph unicode="&#xe134;" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
-<glyph unicode="&#xe135;" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
-<glyph unicode="&#xe136;" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
-<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
-<glyph unicode="&#xe138;" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
-<glyph unicode="&#xe139;" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
-<glyph unicode="&#xe140;" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
-<glyph unicode="&#xe141;" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
-<glyph unicode="&#xe142;" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
-<glyph unicode="&#xe143;" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
-<glyph unicode="&#xe144;" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
-<glyph unicode="&#xe145;" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
-<glyph unicode="&#xe146;" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
-<glyph unicode="&#xe148;" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
-<glyph unicode="&#xe149;" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
-<glyph unicode="&#xe150;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
-<glyph unicode="&#xe151;" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
-<glyph unicode="&#xe152;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
-<glyph unicode="&#xe153;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
-<glyph unicode="&#xe154;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
-<glyph unicode="&#xe155;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
-<glyph unicode="&#xe156;" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
-<glyph unicode="&#xe157;" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
-<glyph unicode="&#xe158;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
-<glyph unicode="&#xe159;" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
-<glyph unicode="&#xe160;" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
-<glyph unicode="&#xe161;" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
-<glyph unicode="&#xe162;" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
-<glyph unicode="&#xe163;" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
-<glyph unicode="&#xe164;" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
-<glyph unicode="&#xe165;" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
-<glyph unicode="&#xe166;" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
-<glyph unicode="&#xe167;" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
-<glyph unicode="&#xe168;" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
-<glyph unicode="&#xe169;" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
-<glyph unicode="&#xe170;" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
-<glyph unicode="&#xe171;" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
-<glyph unicode="&#xe172;" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
-<glyph unicode="&#xe173;" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
-<glyph unicode="&#xe174;" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
-<glyph unicode="&#xe175;" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe176;" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
-<glyph unicode="&#xe177;" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
-<glyph unicode="&#xe178;" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
-<glyph unicode="&#xe179;" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
-<glyph unicode="&#xe180;" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
-<glyph unicode="&#xe181;" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
-<glyph unicode="&#xe182;" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
-<glyph unicode="&#xe183;" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
-<glyph unicode="&#xe184;" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe185;" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
-<glyph unicode="&#xe186;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
-<glyph unicode="&#xe187;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
-<glyph unicode="&#xe188;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
-<glyph unicode="&#xe189;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
-<glyph unicode="&#xe190;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
-<glyph unicode="&#xe191;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
-<glyph unicode="&#xe192;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
-<glyph unicode="&#xe193;" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
-<glyph unicode="&#xe194;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
-<glyph unicode="&#xe195;" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
-<glyph unicode="&#xe197;" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe198;" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
-<glyph unicode="&#xe199;" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
-<glyph unicode="&#xe200;" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
-<glyph unicode="&#xe201;" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
-<glyph unicode="&#xe202;" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
-<glyph unicode="&#xe203;" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
-<glyph unicode="&#xe204;" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
-<glyph unicode="&#xe205;" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
-<glyph unicode="&#xe206;" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
-<glyph unicode="&#xe209;" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
-<glyph unicode="&#xe210;" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe211;" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe212;" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe213;" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe214;" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe215;" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe216;" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
-<glyph unicode="&#xe218;" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
-<glyph unicode="&#xe219;" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
-<glyph unicode="&#xe221;" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe223;" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
-<glyph unicode="&#xe224;" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
-<glyph unicode="&#xe225;" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
-<glyph unicode="&#xe226;" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
-<glyph unicode="&#xe227;" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
-<glyph unicode="&#xe230;" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
-<glyph unicode="&#xe231;" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
-<glyph unicode="&#xe232;" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
-<glyph unicode="&#xe233;" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
-<glyph unicode="&#xe234;" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
-<glyph unicode="&#xe235;" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
-<glyph unicode="&#xe236;" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
-<glyph unicode="&#xe237;" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
-<glyph unicode="&#xe238;" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe239;" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
-<glyph unicode="&#xe240;" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
-<glyph unicode="&#xe241;" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
-<glyph unicode="&#xe242;" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
-<glyph unicode="&#xe243;" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
-<glyph unicode="&#xe244;" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
-<glyph unicode="&#xe245;" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
-<glyph unicode="&#xe246;" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
-<glyph unicode="&#xe247;" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe248;" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
-<glyph unicode="&#xe249;" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
-<glyph unicode="&#xe250;" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
-<glyph unicode="&#xe251;" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
-<glyph unicode="&#xe252;" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
-<glyph unicode="&#xe253;" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
-<glyph unicode="&#xe254;" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
-<glyph unicode="&#xe255;" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
-<glyph unicode="&#xe256;" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
-<glyph unicode="&#xe257;" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
-<glyph unicode="&#xe258;" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
-<glyph unicode="&#xe259;" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
-<glyph unicode="&#xe260;" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
-<glyph unicode="&#xf8ff;" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
-<glyph unicode="&#x1f511;" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
-<glyph unicode="&#x1f6aa;" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
-</font>
-</defs></svg> \ No newline at end of file
diff --git a/apidoc/fonts/glyphicons-halflings-regular.ttf b/apidoc/fonts/glyphicons-halflings-regular.ttf
deleted file mode 100644
index 1413fc60..00000000
--- a/apidoc/fonts/glyphicons-halflings-regular.ttf
+++ /dev/null
Binary files differ
diff --git a/apidoc/fonts/glyphicons-halflings-regular.woff b/apidoc/fonts/glyphicons-halflings-regular.woff
deleted file mode 100644
index 9e612858..00000000
--- a/apidoc/fonts/glyphicons-halflings-regular.woff
+++ /dev/null
Binary files differ
diff --git a/apidoc/fonts/glyphicons-halflings-regular.woff2 b/apidoc/fonts/glyphicons-halflings-regular.woff2
deleted file mode 100644
index 64539b54..00000000
--- a/apidoc/fonts/glyphicons-halflings-regular.woff2
+++ /dev/null
Binary files differ
diff --git a/apidoc/img/android-chrome-192x192.png b/apidoc/img/android-chrome-192x192.png
deleted file mode 100644
index 5c3d085d..00000000
--- a/apidoc/img/android-chrome-192x192.png
+++ /dev/null
Binary files differ
diff --git a/apidoc/img/android-chrome-512x512.png b/apidoc/img/android-chrome-512x512.png
deleted file mode 100644
index 2381b094..00000000
--- a/apidoc/img/android-chrome-512x512.png
+++ /dev/null
Binary files differ
diff --git a/apidoc/img/apple-touch-icon.png b/apidoc/img/apple-touch-icon.png
deleted file mode 100644
index 10a12dcc..00000000
--- a/apidoc/img/apple-touch-icon.png
+++ /dev/null
Binary files differ
diff --git a/apidoc/img/favicon-16x16.png b/apidoc/img/favicon-16x16.png
deleted file mode 100644
index 8d7a6dc8..00000000
--- a/apidoc/img/favicon-16x16.png
+++ /dev/null
Binary files differ
diff --git a/apidoc/img/favicon-32x32.png b/apidoc/img/favicon-32x32.png
deleted file mode 100644
index 361d8bce..00000000
--- a/apidoc/img/favicon-32x32.png
+++ /dev/null
Binary files differ
diff --git a/apidoc/img/favicon.ico b/apidoc/img/favicon.ico
deleted file mode 100644
index 8cc49dd4..00000000
--- a/apidoc/img/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/apidoc/index.html b/apidoc/index.html
deleted file mode 100644
index 88b0f86d..00000000
--- a/apidoc/index.html
+++ /dev/null
@@ -1,816 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <meta http-equiv="X-UA-Compatible" content="IE=edge" />
- <title>Loading...</title>
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link href="vendor/bootstrap.min.css" rel="stylesheet" media="screen">
- <link href="vendor/prism.css" rel="stylesheet" />
- <link href="css/style.css" rel="stylesheet" media="screen, print">
- <link href="img/favicon.ico" rel="icon" type="image/x-icon">
- <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
- <link rel="icon" type="image/png" sizes="32x32" href="img/favicon-32x32.png">
- <link rel="icon" type="image/png" sizes="16x16" href="img/favicon-16x16.png">
- <script src="vendor/polyfill.js"></script>
-</head>
-<body class="container-fluid">
-
-<script id="template-sidenav" type="text/x-handlebars-template">
-<nav id="scrollingNav">
- <div class="sidenav-search">
- <input class="form-control search" type="text" placeholder="{{__ "Filter..."}}">
- <span class="search-reset">x</span>
- </div>
- <ul class="sidenav nav nav-list list">
- {{#each nav}}
- {{#if title}}
- {{#if isHeader}}
- {{#if isFixed}}
- <li class="nav-fixed nav-header navbar-btn nav-list-item" data-group="{{group}}"><a href="#api-{{group}}" data-name="show-api-{{group}}" class="show-api api-{{group}}-init">{{underscoreToSpace title}}</a></li>
- {{else}}
- <li class="nav-header nav-list-item" data-group="{{group}}"><a href="#api-{{group}}" data-group="show-api-{{group}}" class="show-group api-{{group}}-init">{{underscoreToSpace title}}</a></li>
- {{/if}}
- {{else}}
- <li class="{{#if hidden}}hide {{/if}}" data-group="{{group}}" data-name="{{name}}" data-version="{{version}}">
- <a href="#api-{{group}}-{{name}}" title="{{url}}" data-group="show-api-{{group}}" data-name="show-api-{{group}}-{{name}}" class="nav-list-item show-api api-{{group}}-{{name}}-init">{{title}}<div class="nav-list-url-item hide">{{url}}</div></a>
- </li>
- {{/if}}
- {{/if}}
- {{/each}}
- </ul>
-</nav>
-</script>
-
-<script id="template-project" type="text/x-handlebars-template">
- <div class="pull-left">
- <h1>{{name}}</h1>
- {{#if description}}<h2>{{{nl2br description}}}</h2>{{/if}}
- </div>
- <div class="pull-right">
- {{#if template.withCompare}}
- <div class="btn-group">
- <button id="version" class="btn btn-lg btn-default dropdown-toggle" data-toggle="dropdown">
- <strong>{{version}}</strong>&nbsp;<span class="caret"></span>
- </button>
- <ul id="versions" class="dropdown-menu open-left">
- <li><a id="compareAllWithPredecessor" href="#">{{__ "Compare all with predecessor"}}</a></li>
- <li class="divider"></li>
- <li class="disabled"><a href="#">{{__ "show up to version:"}}</a></li>
- {{#each versions}}
- <li class="version"><a href="#">{{this}}</a></li>
- {{/each}}
- </ul>
- </div>
- {{else}}
- <div id="version" class="well well-sm">
- <strong>{{version}}</strong>
- </div>
- {{/if}}
- </div>
- <div class="clearfix"></div>
-</script>
-
-<script id="template-header" type="text/x-handlebars-template">
- {{#if content}}
- <div id="api-_" class="show-api-article show-api-_-article">{{{content}}}</div>
- {{/if}}
-</script>
-
-<script id="template-footer" type="text/x-handlebars-template">
- {{#if content}}
- <div id="api-_footer" class="show-api-article show-api-_-article">{{{content}}}</div>
- {{/if}}
-</script>
-
-<script id="template-generator" type="text/x-handlebars-template">
- {{#if template.withGenerator}}
- {{#if generator}}
- <div class="content">
- {{__ "Generated with"}} <a href="{{{generator.url}}}">{{{generator.name}}}</a> {{{generator.version}}} - {{{generator.time}}}
- </div>
- {{/if}}
- {{/if}}
-</script>
-
-<script id="template-sections" type="text/x-handlebars-template">
- <section id="api-{{group}}" class="show-api-group show-api-{{group}}-group {{#if aloneDisplay}} hide{{/if}}">
- <h1>{{underscoreToSpace title}}</h1>
- {{#if description}}
- <p>{{{nl2br description}}}</p>
- {{/if}}
- {{#each articles}}
- <div id="api-{{group}}-{{name}}" class="show-api-article show-api-{{group}}-article show-api-{{group}}-{{name}}-article {{#if aloneDisplay}} hide{{/if}}">
- {{{article}}}
- </div>
- {{/each}}
- </section>
-</script>
-
-<script id="template-article" type="text/x-handlebars-template">
- <article id="api-{{article.group}}-{{article.name}}-{{article.version}}" {{#if hidden}}class="hide"{{/if}} data-group="{{article.group}}" data-name="{{article.name}}" data-version="{{article.version}}">
- <div class="pull-left">
- <h1>{{underscoreToSpace article.groupTitle}}{{#if article.title}} - {{article.title}}{{/if}}</h1>
- </div>
- {{#if template.withCompare}}
- <div class="pull-right">
- <div class="btn-group">
- <button class="version btn btn-default dropdown-toggle" data-toggle="dropdown">
- <strong>{{article.version}}</strong>&nbsp;<span class="caret"></span>
- </button>
- <ul class="versions dropdown-menu open-left">
- <li class="disabled"><a href="#">{{__ "compare changes to:"}}</a></li>
- {{#each versions}}
- <li class="version"><a href="#">{{this}}</a></li>
- {{/each}}
- </ul>
- </div>
- </div>
- {{/if}}
- <div class="clearfix"></div>
-
- {{#if article.author}}<h4 class="muted">Authored by: {{article.author}}</h4>{{/if}}
-
- {{#if article.deprecated}}
- <p class="deprecated"><span>{{__ "DEPRECATED"}}</span>
- {{{markdown article.deprecated.content}}}
- </p>
- {{/if}}
-
- {{#if article.description}}
- <p>{{{nl2br article.description}}}</p>
- {{/if}}
- <span class="type type__{{toLowerCase article.type}}">{{toLowerCase article.type}}</span>
- <pre data-type="{{toLowerCase article.type}}"><code class="language-http">{{article.url}}</code></pre>
-
- {{#if article.permission}}
- <p>
- {{__ "Permission:"}}
- {{#each article.permission}}
- {{name}}
- {{#if title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{title}}" data-content="{{nl2br description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{/if}}
- {{/each}}
- </p>
- {{/if}}
-
- {{!-- CODE EXAMPLES IN TABS --}}
- {{#if_gt article.examples.length compare=0}}
- <ul class="nav nav-tabs nav-tabs-examples">
- {{#each article.examples}}
- <li{{#if_eq @index compare=0}} class="active"{{/if_eq}}>
- <a href="#examples-{{../id}}-{{@index}}">{{title}}</a>
- </li>
- {{/each}}
- </ul>
-
- <div class="tab-content">
- {{#each article.examples}}
- <div class="tab-pane{{#if_eq @index compare=0}} active{{/if_eq}}" id="examples-{{../id}}-{{@index}}">
- <pre data-type="{{type}}"><code class="language-{{type}}">{{content}}</code></pre>
- </div>
- {{/each}}
- </div>
- {{/if_gt}}
-
- {{subTemplate "article-param-block" params=article.header _hasType=_hasTypeInHeaderFields section="header"}}
- {{subTemplate "article-param-block" params=article.parameter _hasType=_hasTypeInParameterFields section="parameter"}}
- {{subTemplate "article-param-block" params=article.success _hasType=_hasTypeInSuccessFields section="success"}}
- {{subTemplate "article-query-block" params=article.query _hasType=_hasTypeInParameterFields section="query"}}
- {{subTemplate "article-param-block" params=article.body _hasType=_hasTypeInSuccessFields section="body"}}
- {{subTemplate "article-param-block" params=article.error _col1="Name" _hasType=_hasTypeInErrorFields section="error"}}
-
- {{subTemplate "article-sample-request" article=article id=id}}
- </article>
-</script>
-
-<script id="template-article-query-block" type="text/x-handlebars-template">
- {{#if article.query}}
- <h2>Query Parameter(s)</h2>
- <table>
- <thead>
- <tr>
- <th style="width: 30%">{{#if ../_col1}}{{__ ../_col1}}{{else}}{{__ "Field"}}{{/if}}</th>
- {{#unless this.Type compare=null}}
- <th style="width: 10%">{{__ "Type"}}</th>
- {{/unless}}
- <th style="width: {{#if ../_hasType}}60%{{else}}70%{{/if}}">{{__ "Description"}}</th>
- </tr>
- </thead>
- <tbody>
- {{#each params}}
- <tr>
- <td class="code">{{this.field}}</td>
- {{#unless this.Type compare=null}}
- <td>{{this.type}}</td>
- {{/unless}}
- <td>{{{nl2br this.description}}}</td>
- </tr>
- {{/each}}
- </tbody>
- </table>
- {{/if}}
-</script>
-
-<script id="template-article-body-block" type="text/x-handlebars-template">
- {{#if article.body}}
- <h2>Request Body</h2>
- <table>
- <thead>
- <tr>
- <th style="width: 30%">{{#if ../_col1}}{{__ ../_col1}}{{else}}{{__ "Field"}}{{/if}}</th>
- {{#unless this.Type compare=null}}
- <th style="width: 10%">{{__ "Type"}}</th>
- {{/unless}}
- <th style="width: {{#if ../_hasType}}60%{{else}}70%{{/if}}">{{__ "Description"}}</th>
- </tr>
- </thead>
- <tbody>
- {{#each params}}
- <tr>
- <td class="code">{{this.field}}</td>
- {{#unless this.Type compare=null}}
- <td>{{this.type}}</td>
- {{/unless}}
- <td>
- {{{nl2br this.description}}}
- {{#if defaultValue}}
- <p class="default-value">{{__ "Default value:"}} <code>{{{defaultValue}}}</code></p>
- {{/if}}
- {{#if size}}
- <p class="type-size">{{__ "Size range:"}} <code>{{{size}}}</code></p>
- {{/if}}
- {{#if allowedValues}}
- <p class="type-size">{{__ "Allowed values:"}}
- {{#each allowedValues}}
- <code>{{{this}}}</code>{{#unless @last}}, {{/unless}}
- {{/each}}
- </p>
- {{/if}}
- </td>
- </tr>
- {{/each}}
- </tbody>
- </table>
- {{/if}}
-</script>
-
-<script id="template-article-param-block" type="text/x-handlebars-template">
- {{#if params}}
- {{#each params.fields}}
- <h2>{{__ @key}}</h2>
- <table>
- <thead>
- <tr>
- <th style="width: 30%">{{#if ../_col1}}{{__ ../_col1}}{{else}}{{__ "Field"}}{{/if}}</th>
- {{#if ../_hasType}}<th style="width: 10%">{{__ "Type"}}</th>{{/if}}
- <th style="width: {{#if ../_hasType}}60%{{else}}70%{{/if}}">{{__ "Description"}}</th>
- </tr>
- </thead>
- <tbody>
- {{#each this}}
- <tr>
- <td class="code">{{{splitFill field "." "&nbsp;&nbsp;"}}}{{#if optional}}<span class="label label-optional">{{__ "optional"}}</span>{{/if}}</td>
- {{#if ../../_hasType}}
- <td>
- {{{type}}}
- </td>
- {{/if}}
- <td>
- {{{nl2br description}}}
- {{#if defaultValue}}<p class="default-value">{{__ "Default value:"}} <code>{{{defaultValue}}}</code></p>{{/if}}
- {{#if size}}<p class="type-size">{{__ "Size range:"}} <code>{{{size}}}</code></p>{{/if}}
- {{#if allowedValues}}<p class="type-size">{{__ "Allowed values:"}}
- {{#each allowedValues}}
- <code>{{{this}}}</code>{{#unless @last}}, {{/unless}}
- {{/each}}
- </p>
- {{/if}}
- </td>
- </tr>
- {{/each}}
- </tbody>
- </table>
- {{/each}}
- {{#if_gt params.examples.length compare=0}}
- <ul class="nav nav-tabs nav-tabs-examples">
- {{#each params.examples}}
- <li{{#if_eq @index compare=0}} class="active"{{/if_eq}}>
- <a href="#{{../section}}-examples-{{../id}}-{{@index}}">{{title}}</a>
- </li>
- {{/each}}
- </ul>
-
- <div class="tab-content">
- {{#each params.examples}}
- <div class="tab-pane{{#if_eq @index compare=0}} active{{/if_eq}}" id="{{../section}}-examples-{{../id}}-{{@index}}">
- <pre data-type="{{type}}"><code class="language-{{type}}">{{reformat content type}}</code></pre>
- </div>
- {{/each}}
- </div>
- {{/if_gt}}
- {{/if}}
-</script>
-
-<script id="template-article-sample-request" type="text/x-handlebars-template">
- {{#if article.sampleRequest}}
- <h2>{{__ "Send a Sample Request"}}</h2>
- <form class="form-horizontal">
- <fieldset>
- <div class="form-group">
- <label class="col-md-3 control-label" for="{{../id}}-sample-request-url"></label>
- <div class="input-group">
- <input id="{{../id}}-sample-request-url" type="text" class="form-control sample-request-url" value="{{article.sampleRequest.0.url}}" />
- <span class="input-group-addon">{{__ "url"}}</span>
- </div>
- </div>
-
- {{#if article.header}}
- {{#if article.header.fields}}
- <h3>{{__ "Headers"}}</h3>
- {{#each article.header.fields}}
- <h4><input type="checkbox" data-sample-request-header-group-id="sample-request-header-{{@index}}" name="{{../id}}-sample-request-header" value="{{@index}}" class="sample-request-header sample-request-switch" checked />{{__ @key}}</h4>
- <div class="{{../id}}-sample-request-header-fields">
- {{#each this}}
- <div class="form-group">
- <label class="col-md-3 control-label" for="sample-request-header-field-{{field}}">{{field}}</label>
- <div class="input-group">
- <input type="text" placeholder="{{field}}" value="{{defaultValue}}" id="sample-request-header-field-{{field}}" class="form-control sample-request-header" data-sample-request-header-name="{{field}}" data-sample-request-header-group="sample-request-header-{{@../index}}">
- <span class="input-group-addon">{{{type}}}</span>
- </div>
- </div>
- {{/each}}
- </div>
- {{/each}}
- {{/if}}
- {{/if}}
-
- {{#if article.parameter}}
- {{#if article.parameter.fields}}
- <h3>{{__ "Parameters"}}</h3>
- {{#each article.parameter.fields}}
- <h4><input type="checkbox" data-sample-request-param-group-id="sample-request-param-{{@index}}" name="{{../id}}-sample-request-param" value="{{@index}}" class="sample-request-param sample-request-switch" checked/>{{__ @key}}
- <select name="{{../id}}-sample-header-content-type" class="{{../id}}-sample-request-param-select sample-header-content-type sample-header-content-type-switch">
- <option value="undefined" selected>ajax-auto</option>
- <option value="body-json" >body/json</option>
- <option value="body-form-data" >body/form-data</option>
- </select>
- </h4>
- <div class="{{../id}}-sample-request-param-body {{../id}}-sample-header-content-type-body hide">
- <div class="form-group">
- <div class="input-group">
- <textarea id="sample-request-body-json" class="form-control sample-request-body" data-sample-request-body-group="sample-request-param-{{@./index}}" rows="6" style="OVERFLOW: visible" {{#if optional}}data-sample-request-param-optional="true"{{/if}}></textarea>
- <div class="input-group-addon">json</div>
- </div>
- </div>
- </div>
- <div class="{{../id}}-sample-request-param-fields {{../id}}-sample-header-content-type-fields">
- {{#each this}}
- <div class="form-group">
- <label class="col-md-3 control-label" for="sample-request-param-field-{{field}}">{{field}}</label>
- <div class="input-group">
- <input id="sample-request-param-field-{{field}}" type="{{setInputType type}}" placeholder="{{field}}" class="form-control sample-request-param" data-sample-request-param-name="{{field}}" data-sample-request-param-group="sample-request-param-{{@../index}}" {{#if optional}}data-sample-request-param-optional="true"{{/if}}>
- <div class="input-group-addon">{{{type}}}</div>
- </div>
- </div>
- {{/each}}
- </div>
- {{/each}}
- {{/if}}
- {{/if}}
-
- {{#if article.query}}
- <h3>{{__ "Query Parameters"}}</h3>
- <div class="{{../id}}-sample-request-param-fields {{../id}}-sample-header-content-type-fields">
- {{#each article.query}}
- <div class="form-group">
- <label class="col-md-3 control-label" for="sample-request-param-field-{{field}}">{{field}}</label>
- <div class="input-group">
- <input id="sample-request-param-field-{{field}}" type="{{setInputType type}}" placeholder="{{field}}" class="form-control sample-request-param" data-sample-request-param-name="{{field}}"
- data-sample-request-param-group="sample-request-param-{{@../index}}" {{#if optional}}data-sample-request-param-optional="true" {{/if}}>
- <div class="input-group-addon">{{{type}}}</div>
- </div>
- </div>
- {{/each}}
- </div>
- {{/if}}
-
- {{#if article.body}}
- {{log this}}
- <h3>{{__ "Body"}}</h3>
- <h4><input type="checkbox" data-sample-request-param-group-id="sample-request-param-{{@index}}" name="{{this.id}}-sample-request-param" value="{{@index}}" class="sample-request-param sample-request-switch" checked />{{__ @key}}
- <select name="{{this.id}}-sample-header-content-type" class="{{this.id}}-sample-request-param-select sample-header-content-type sample-header-content-type-switch">
- <option value="body-json" selected>body/json</option>
- <option value="body-form-data">body/form-data</option>
- </select>
- </h4>
- <div class="{{this.id}}-sample-request-param-body {{this.id}}-sample-header-content-type-body">
- <div class="form-group">
- <div class="input-group">
- <textarea id="sample-request-body-json" class="form-control sample-request-body" data-sample-request-body-group="sample-request-param-{{@./index}}" rows="6" style="OVERFLOW: visible"
- {{#if optional}}data-sample-request-param-optional="true" {{/if}}>{{gen_body article.body}}</textarea>
- <div class="input-group-addon">json</div>
- </div>
- </div>
- </div>
- <div class="{{this.id}}-sample-request-param-fields {{this.id}}-sample-header-content-type-fields hide">
- {{#each article.body}}
- <div class="form-group">
- <label class="col-md-3 control-label" for="sample-request-param-field-{{field}}">{{field}}</label>
- <div class="input-group">
- <input id="sample-request-param-field-{{field}}" type="{{setInputType type}}" placeholder="{{field}}" class="form-control sample-request-param" data-sample-request-param-name="{{field}}"
- data-sample-request-param-group="sample-request-param-{{@../index}}" {{#if optional}}data-sample-request-param-optional="true" {{/if}}>
- <div class="input-group-addon">{{{type}}}</div>
- </div>
- </div>
- {{/each}}
- </div>
- {{/if}}
-
- <div class="form-group">
- <div class="controls pull-right">
- <button class="btn btn-primary sample-request-send" data-sample-request-type="{{article.type}}">{{__ "Send"}}</button>
- </div>
- </div>
- <div class="form-group sample-request-response" style="display: none;">
- <h3>
- {{__ "Response"}}
- <button class="btn btn-default btn-xs pull-right sample-request-clear">X</button>
- </h3>
- <pre data-type="json"><code class="language-json sample-request-response-json"></code></pre>
- </div>
- </fieldset>
- </form>
- {{/if}}
-</script>
-
-<script id="template-compare-article" type="text/x-handlebars-template">
- <article id="api-{{article.group}}-{{article.name}}-{{article.version}}" {{#if hidden}}class="hide"{{/if}} data-group="{{article.group}}" data-name="{{article.name}}" data-version="{{article.version}}" data-compare-version="{{compare.version}}">
- <div class="pull-left">
- <h1>{{underscoreToSpace article.group}} - {{{showDiff article.title compare.title}}}</h1>
- </div>
-
- <div class="pull-right">
- <div class="btn-group">
- <button class="btn btn-success" disabled>
- <strong>{{article.version}}</strong> {{__ "compared to"}}
- </button>
- <button class="version btn btn-danger dropdown-toggle" data-toggle="dropdown">
- <strong>{{compare.version}}</strong>&nbsp;<span class="caret"></span>
- </button>
- <ul class="versions dropdown-menu open-left">
- <li class="disabled"><a href="#">{{__ "compare changes to:"}}</a></li>
- <li class="divider"></li>
- {{#each versions}}
- <li class="version"><a href="#">{{this}}</a></li>
- {{/each}}
- </ul>
- </div>
- </div>
- <div class="clearfix"></div>
-
- {{#if article.description}}
- <p>{{{showDiff article.description compare.description "nl2br"}}}</p>
- {{else}}
- {{#if compare.description}}
- <p>{{{showDiff "" compare.description "nl2br"}}}</p>
- {{/if}}
- {{/if}}
-
- <pre data-type="{{toLowerCase article.type}}"><code class="language-html">{{{showDiff article.url compare.url}}}</code></pre>
-
- {{subTemplate "article-compare-permission" article=article compare=compare}}
-
- <ul class="nav nav-tabs nav-tabs-examples">
- {{#each_compare_title article.examples compare.examples}}
- {{#if typeSame}}
- <li{{#if_eq index compare=0}} class="active"{{/if_eq}}>
- <a href="#compare-examples-{{../../article.id}}-{{index}}">{{{showDiff source.title compare.title}}}</a>
- </li>
- {{/if}}
-
- {{#if typeIns}}
- <li{{#if_eq index compare=0}} class="active"{{/if_eq}}>
- <a href="#compare-examples-{{../../article.id}}-{{index}}"><ins>{{{source.title}}}</ins></a>
- </li>
- {{/if}}
-
- {{#if typeDel}}
- <li{{#if_eq index compare=0}} class="active"{{/if_eq}}>
- <a href="#compare-examples-{{../../article.id}}-{{index}}"><del>{{{compare.title}}}</del></a>
- </li>
- {{/if}}
- {{/each_compare_title}}
- </ul>
-
- <div class="tab-content">
- {{#each_compare_title article.examples compare.examples}}
-
- {{#if typeSame}}
- <div class="tab-pane{{#if_eq index compare=0}} active{{/if_eq}}" id="compare-examples-{{../../article.id}}-{{index}}">
- <pre data-type="{{source.type}}"><code class="language-{{source.type}}">{{{showDiff source.content compare.content}}}</code></pre>
- </div>
- {{/if}}
-
- {{#if typeIns}}
- <div class="tab-pane{{#if_eq index compare=0}} active{{/if_eq}}" id="compare-examples-{{../../article.id}}-{{index}}">
- <pre data-type="{{source.type}}"><code class="language-{{source.type}}">{{{source.content}}}</code></pre>
- </div>
- {{/if}}
-
- {{#if typeDel}}
- <div class="tab-pane{{#if_eq index compare=0}} active{{/if_eq}}" id="compare-examples-{{../../article.id}}-{{index}}">
- <pre data-type="{{compare.type}}"><code class="language-{{source.type}}">{{{compare.content}}}</code></pre>
- </div>
- {{/if}}
-
- {{/each_compare_title}}
- </div>
-
- {{subTemplate "article-compare-param-block" source=article.parameter compare=compare.parameter _hasType=_hasTypeInParameterFields section="parameter"}}
- {{subTemplate "article-compare-param-block" source=article.success compare=compare.success _hasType=_hasTypeInSuccessFields section="success"}}
- {{subTemplate "article-compare-param-block" source=article.error compare=compare.error _col1="Name" _hasType=_hasTypeInErrorFields section="error"}}
-
- {{subTemplate "article-sample-request" article=article id=id}}
-
- </article>
-</script>
-
-<script id="template-article-compare-permission" type="text/x-handlebars-template">
- <p>
- {{__ "Permission:"}}
- {{#each_compare_list_field article.permission compare.permission field="name"}}
- {{#if source}}
- {{#if typeSame}}
- {{source.name}}
- {{#if source.title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{source.title}}" data-content="{{nl2br source.description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{#unless _last}}, {{/unless}}
- {{/if}}
- {{/if}}
-
- {{#if typeIns}}
- <ins>{{source.name}}</ins>
- {{#if source.title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{source.title}}" data-content="{{nl2br source.description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{#unless _last}}, {{/unless}}
- {{/if}}
- {{/if}}
-
- {{#if typeDel}}
- <del>{{source.name}}</del>
- {{#if source.title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{source.title}}" data-content="{{nl2br source.description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{#unless _last}}, {{/unless}}
- {{/if}}
- {{/if}}
- {{else}}
- {{#if typeSame}}
- {{compare.name}}
- {{#if compare.title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{compare.title}}" data-content="{{nl2br compare.description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{#unless _last}}, {{/unless}}
- {{/if}}
- {{/if}}
-
- {{#if typeIns}}
- <ins>{{compare.name}}</ins>
- {{#if compare.title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{compare.title}}" data-content="{{nl2br compare.description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{#unless _last}}, {{/unless}}
- {{/if}}
- {{/if}}
-
- {{#if typeDel}}
- <del>{{compare.name}}</del>
- {{#if compare.title}}
- <button type="button" class="btn btn-info btn-xs" data-title="{{compare.title}}" data-content="{{nl2br compare.description}}" data-html="true" data-toggle="popover" data-placement="right" data-trigger="hover">
- <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
- </button>
- {{#unless _last}}, {{/unless}}
- {{/if}}
- {{/if}}
- {{/if}}
- {{/each_compare_list_field}}
- </p>
-</script>
-
-<script id="template-article-compare-param-block" type="text/x-handlebars-template">
- {{#if source}}
- {{#each_compare_keys source.fields compare.fields}}
- {{#if typeSame}}
- <h2>{{__ source.key}}</h2>
- <table>
- <thead>
- <tr>
- <th style="width: 30%">{{#if ../_col1}}{{__ ../_col1}}{{else}}{{__ "Field"}}{{/if}}</th>
- {{#if ../_hasType}}<th style="width: 10%">{{__ "Type"}}</th>{{/if}}
- <th style="width: {{#if ../_hasType}}60%{{else}}70%{{/if}}">{{__ "Description"}}</th>
- </tr>
- </thead>
- {{subTemplate "article-compare-param-block-body" source=source.value compare=compare.value _hasType=../_hasType}}
- </table>
- {{/if}}
-
- {{#if typeIns}}
- <h2><ins>{{__ source.key}}</ins></h2>
- <table class="ins">
- <thead>
- <tr>
- <th style="width: 30%">{{#if ../_col1}}{{__ ../_col1}}{{else}}{{__ "Field"}}{{/if}}</th>
- {{#if ../_hasType}}<th style="width: 10%">{{__ "Type"}}</th>{{/if}}
- <th style="width: {{#if ../_hasType}}60%{{else}}70%{{/if}}">{{__ "Description"}}</th>
- </tr>
- </thead>
- {{subTemplate "article-compare-param-block-body" source=source.value compare=source.value _hasType=../_hasType}}
- </table>
- {{/if}}
-
- {{#if typeDel}}
- <h2><del>{{__ compare.key}}</del></h2>
- <table class="del">
- <thead>
- <tr>
- <th style="width: 30%">{{#if ../_col1}}{{__ ../_col1}}{{else}}{{__ "Field"}}{{/if}}</th>
- {{#if ../_hasType}}<th style="width: 10%">{{__ "Type"}}</th>{{/if}}
- <th style="width: {{#if ../_hasType}}60%{{else}}70%{{/if}}">{{__ "Description"}}</th>
- </tr>
- </thead>
- {{subTemplate "article-compare-param-block-body" source=compare.value compare=compare.value _hasType=../_hasType}}
- </table>
- {{/if}}
- {{/each_compare_keys}}
-
- {{#if source.examples}}
- <ul class="nav nav-tabs nav-tabs-examples">
- {{#each_compare_title source.examples compare.examples}}
- {{#if typeSame}}
- <li{{#if_eq index compare=0}} class="active"{{/if_eq}}>
- <a href="#{{../../section}}-compare-examples-{{../../article.id}}-{{index}}">{{{showDiff source.title compare.title}}}</a>
- </li>
- {{/if}}
-
- {{#if typeIns}}
- <li{{#if_eq index compare=0}} class="active"{{/if_eq}}>
- <a href="#{{../../section}}-compare-examples-{{../../article.id}}-{{index}}"><ins>{{{source.title}}}</ins></a>
- </li>
- {{/if}}
-
- {{#if typeDel}}
- <li{{#if_eq index compare=0}} class="active"{{/if_eq}}>
- <a href="#{{../../section}}-compare-examples-{{../../article.id}}-{{index}}"><del>{{{compare.title}}}</del></a>
- </li>
- {{/if}}
- {{/each_compare_title}}
- </ul>
-
- <div class="tab-content">
- {{#each_compare_title source.examples compare.examples}}
-
- {{#if typeSame}}
- <div class="tab-pane{{#if_eq index compare=0}} active{{/if_eq}}" id="{{../../section}}-compare-examples-{{../../article.id}}-{{index}}">
- <pre data-type="{{source.type}}"><code class="language-{{source.type}}">{{{showDiff source.content compare.content}}}</code></pre>
- </div>
- {{/if}}
-
- {{#if typeIns}}
- <div class="tab-pane{{#if_eq index compare=0}} active{{/if_eq}}" id="{{../../section}}-compare-examples-{{../../article.id}}-{{index}}">
- <pre data-type="{{source.type}}"><code class="language-{{source.type}}">{{{source.content}}}</code></pre>
- </div>
- {{/if}}
-
- {{#if typeDel}}
- <div class="tab-pane{{#if_eq index compare=0}} active{{/if_eq}}" id="{{../../section}}-compare-examples-{{../../article.id}}-{{index}}">
- <pre data-type="{{compare.type}}"><code class="language-{{source.type}}">{{{compare.content}}}</code></pre>
- </div>
- {{/if}}
- {{/each_compare_title}}
- </div>
- {{/if}}
- {{/if}}
-</script>
-
-<script id="template-article-compare-param-block-body" type="text/x-handlebars-template">
- <tbody>
- {{#each_compare_field source compare}}
- {{#if typeSame}}
- <tr>
- <td class="code">
- {{{splitFill source.field "." "&nbsp;&nbsp;"}}}
- {{#if source.optional}}
- {{#if compare.optional}} <span class="label label-optional">{{__ "optional"}}</span>
- {{else}} <span class="label label-optional label-ins">{{__ "optional"}}</span>
- {{/if}}
- {{else}}
- {{#if compare.optional}} <span class="label label-optional label-del">{{__ "optional"}}</span>{{/if}}
- {{/if}}
- </td>
-
- {{#if source.type}}
- {{#if compare.type}}
- <td>{{{showDiff source.type compare.type}}}</td>
- {{else}}
- <td>{{{source.type}}}</td>
- {{/if}}
- {{else}}
- {{#if compare.type}}
- <td>{{{compare.type}}}</td>
- {{else}}
- {{#if ../../../../_hasType}}<td></td>{{/if}}
- {{/if}}
- {{/if}}
- <td>
- {{{showDiff source.description compare.description "nl2br"}}}
- {{#if source.defaultValue}}<p class="default-value">{{__ "Default value:"}} <code>{{{showDiff source.defaultValue compare.defaultValue}}}</code><p>{{/if}}
- </td>
- </tr>
- {{/if}}
-
- {{#if typeIns}}
- <tr class="ins">
- <td class="code">
- {{{splitFill source.field "." "&nbsp;&nbsp;"}}}
- {{#if source.optional}} <span class="label label-optional label-ins">{{__ "optional"}}</span>{{/if}}
- </td>
-
- {{#if source.type}}
- <td>{{{source.type}}}</td>
- {{else}}
- {{{typRowTd}}}
- {{/if}}
-
- <td>
- {{{nl2br source.description}}}
- {{#if source.defaultValue}}<p class="default-value">{{__ "Default value:"}} <code>{{{source.defaultValue}}}</code><p>{{/if}}
- </td>
- </tr>
- {{/if}}
-
- {{#if typeDel}}
- <tr class="del">
- <td class="code">
- {{{splitFill compare.field "." "&nbsp;&nbsp;"}}}
- {{#if compare.optional}} <span class="label label-optional label-del">{{__ "optional"}}</span>{{/if}}
- </td>
-
- {{#if compare.type}}
- <td>{{{compare.type}}}</td>
- {{else}}
- {{{typRowTd}}}
- {{/if}}
-
- <td>
- {{{nl2br compare.description}}}
- {{#if compare.defaultValue}}<p class="default-value">{{__ "Default value:"}} <code>{{{compare.defaultValue}}}</code><p>{{/if}}
- </td>
- </tr>
- {{/if}}
-
- {{/each_compare_field}}
- </tbody>
-</script>
-
-<div class="container-fluid">
- <div class="row">
- <div id="sidenav" class="span2"></div>
- <div id="content">
- <div id="project"></div>
- <div id="header"></div>
- <div id="sections"></div>
- <div id="footer"></div>
- <div id="generator"></div>
- </div>
- </div>
-</div>
-
-<div id="loader">
- <div class="spinner">
- <div class="spinner-container container1">
- <div class="circle1"></div><div class="circle2"></div><div class="circle3"></div><div class="circle4"></div>
- </div>
- <div class="spinner-container container2">
- <div class="circle1"></div><div class="circle2"></div><div class="circle3"></div><div class="circle4"></div>
- </div>
- <div class="spinner-container container3">
- <div class="circle1"></div><div class="circle2"></div><div class="circle3"></div><div class="circle4"></div>
- </div>
- <p>Loading...</p>
- </div>
-</div>
-
-<script data-main="main.js" src="vendor/require.min.js"></script>
-</body>
-</html>
diff --git a/apidoc/locales/ca.js b/apidoc/locales/ca.js
deleted file mode 100644
index 65af5df2..00000000
--- a/apidoc/locales/ca.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- ca: {
- 'Allowed values:' : 'Valors permesos:',
- 'Compare all with predecessor': 'Comparar tot amb versió anterior',
- 'compare changes to:' : 'comparar canvis amb:',
- 'compared to' : 'comparat amb',
- 'Default value:' : 'Valor per defecte:',
- 'Description' : 'Descripció',
- 'Field' : 'Camp',
- 'General' : 'General',
- 'Generated with' : 'Generat amb',
- 'Name' : 'Nom',
- 'No response values.' : 'Sense valors en la resposta.',
- 'optional' : 'opcional',
- 'Parameter' : 'Paràmetre',
- 'Permission:' : 'Permisos:',
- 'Response' : 'Resposta',
- 'Send' : 'Enviar',
- 'Send a Sample Request' : 'Enviar una petició d\'exemple',
- 'show up to version:' : 'mostrar versió:',
- 'Size range:' : 'Tamany de rang:',
- 'Type' : 'Tipus',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/cs.js b/apidoc/locales/cs.js
deleted file mode 100644
index b7796d8f..00000000
--- a/apidoc/locales/cs.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- cs: {
- 'Allowed values:' : 'Povolené hodnoty:',
- 'Compare all with predecessor': 'Porovnat vše s předchozími verzemi',
- 'compare changes to:' : 'porovnat změny s:',
- 'compared to' : 'porovnat s',
- 'Default value:' : 'Výchozí hodnota:',
- 'Description' : 'Popis',
- 'Field' : 'Pole',
- 'General' : 'Obecné',
- 'Generated with' : 'Vygenerováno pomocí',
- 'Name' : 'Název',
- 'No response values.' : 'Nebyly vráceny žádné hodnoty.',
- 'optional' : 'volitelné',
- 'Parameter' : 'Parametr',
- 'Permission:' : 'Oprávnění:',
- 'Response' : 'Odpověď',
- 'Send' : 'Odeslat',
- 'Send a Sample Request' : 'Odeslat ukázkový požadavek',
- 'show up to version:' : 'zobrazit po verzi:',
- 'Size range:' : 'Rozsah velikosti:',
- 'Type' : 'Typ',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/de.js b/apidoc/locales/de.js
deleted file mode 100644
index f66420d0..00000000
--- a/apidoc/locales/de.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- de: {
- 'Allowed values:' : 'Erlaubte Werte:',
- 'Compare all with predecessor': 'Vergleiche alle mit ihren Vorgängern',
- 'compare changes to:' : 'vergleiche Änderungen mit:',
- 'compared to' : 'verglichen mit',
- 'Default value:' : 'Standardwert:',
- 'Description' : 'Beschreibung',
- 'Field' : 'Feld',
- 'General' : 'Allgemein',
- 'Generated with' : 'Erstellt mit',
- 'Name' : 'Name',
- 'No response values.' : 'Keine Rückgabewerte.',
- 'optional' : 'optional',
- 'Parameter' : 'Parameter',
- 'Permission:' : 'Berechtigung:',
- 'Response' : 'Antwort',
- 'Send' : 'Senden',
- 'Send a Sample Request' : 'Eine Beispielanfrage senden',
- 'show up to version:' : 'zeige bis zur Version:',
- 'Size range:' : 'Größenbereich:',
- 'Type' : 'Typ',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/es.js b/apidoc/locales/es.js
deleted file mode 100644
index 3d47e800..00000000
--- a/apidoc/locales/es.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- es: {
- 'Allowed values:' : 'Valores permitidos:',
- 'Compare all with predecessor': 'Comparar todo con versión anterior',
- 'compare changes to:' : 'comparar cambios con:',
- 'compared to' : 'comparado con',
- 'Default value:' : 'Valor por defecto:',
- 'Description' : 'Descripción',
- 'Field' : 'Campo',
- 'General' : 'General',
- 'Generated with' : 'Generado con',
- 'Name' : 'Nombre',
- 'No response values.' : 'Sin valores en la respuesta.',
- 'optional' : 'opcional',
- 'Parameter' : 'Parámetro',
- 'Permission:' : 'Permisos:',
- 'Response' : 'Respuesta',
- 'Send' : 'Enviar',
- 'Send a Sample Request' : 'Enviar una petición de ejemplo',
- 'show up to version:' : 'mostrar a versión:',
- 'Size range:' : 'Tamaño de rango:',
- 'Type' : 'Tipo',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/fr.js b/apidoc/locales/fr.js
deleted file mode 100644
index 100a6429..00000000
--- a/apidoc/locales/fr.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- fr: {
- 'Allowed values:' : 'Valeurs autorisées :',
- 'Compare all with predecessor': 'Tout comparer avec ...',
- 'compare changes to:' : 'comparer les changements à :',
- 'compared to' : 'comparer à',
- 'Default value:' : 'Valeur par défaut :',
- 'Description' : 'Description',
- 'Field' : 'Champ',
- 'General' : 'Général',
- 'Generated with' : 'Généré avec',
- 'Name' : 'Nom',
- 'No response values.' : 'Aucune valeur de réponse.',
- 'optional' : 'optionnel',
- 'Parameter' : 'Paramètre',
- 'Permission:' : 'Permission :',
- 'Response' : 'Réponse',
- 'Send' : 'Envoyer',
- 'Send a Sample Request' : 'Envoyer une requête représentative',
- 'show up to version:' : 'Montrer à partir de la version :',
- 'Size range:' : 'Ordre de grandeur :',
- 'Type' : 'Type',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/it.js b/apidoc/locales/it.js
deleted file mode 100644
index 8117108c..00000000
--- a/apidoc/locales/it.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- it: {
- 'Allowed values:' : 'Valori permessi:',
- 'Compare all with predecessor': 'Confronta tutto con versioni precedenti',
- 'compare changes to:' : 'confronta modifiche con:',
- 'compared to' : 'confrontato con',
- 'Default value:' : 'Valore predefinito:',
- 'Description' : 'Descrizione',
- 'Field' : 'Campo',
- 'General' : 'Generale',
- 'Generated with' : 'Creato con',
- 'Name' : 'Nome',
- 'No response values.' : 'Nessun valore di risposta.',
- 'optional' : 'opzionale',
- 'Parameter' : 'Parametro',
- 'Permission:' : 'Permessi:',
- 'Response' : 'Risposta',
- 'Send' : 'Invia',
- 'Send a Sample Request' : 'Invia una richiesta di esempio',
- 'show up to version:' : 'mostra alla versione:',
- 'Size range:' : 'Intervallo dimensione:',
- 'Type' : 'Tipo',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/locale.js b/apidoc/locales/locale.js
deleted file mode 100644
index 3530705e..00000000
--- a/apidoc/locales/locale.js
+++ /dev/null
@@ -1,51 +0,0 @@
-define([
- './locales/ca.js',
- './locales/cs.js',
- './locales/de.js',
- './locales/es.js',
- './locales/fr.js',
- './locales/it.js',
- './locales/nl.js',
- './locales/pl.js',
- './locales/pt_br.js',
- './locales/ro.js',
- './locales/ru.js',
- './locales/tr.js',
- './locales/vi.js',
- './locales/zh.js',
- './locales/zh_cn.js'
-], function() {
- var langId = (navigator.language || navigator.userLanguage).toLowerCase().replace('-', '_');
- var language = langId.substr(0, 2);
- var locales = {};
-
- for (index in arguments) {
- for (property in arguments[index])
- locales[property] = arguments[index][property];
- }
- if ( ! locales['en'])
- locales['en'] = {};
-
- if ( ! locales[langId] && ! locales[language])
- language = 'en';
-
- var locale = (locales[langId] ? locales[langId] : locales[language]);
-
- function __(text) {
- var index = locale[text];
- if (index === undefined)
- return text;
- return index;
- };
-
- function setLanguage(language) {
- locale = locales[language];
- }
-
- return {
- __ : __,
- locales : locales,
- locale : locale,
- setLanguage: setLanguage
- };
-});
diff --git a/apidoc/locales/nl.js b/apidoc/locales/nl.js
deleted file mode 100644
index bddfeeb1..00000000
--- a/apidoc/locales/nl.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- nl: {
- 'Allowed values:' : 'Toegestane waarden:',
- 'Compare all with predecessor': 'Vergelijk alle met voorgaande versie',
- 'compare changes to:' : 'vergelijk veranderingen met:',
- 'compared to' : 'vergelijk met',
- 'Default value:' : 'Standaard waarde:',
- 'Description' : 'Omschrijving',
- 'Field' : 'Veld',
- 'General' : 'Algemeen',
- 'Generated with' : 'Gegenereerd met',
- 'Name' : 'Naam',
- 'No response values.' : 'Geen response waardes.',
- 'optional' : 'optioneel',
- 'Parameter' : 'Parameter',
- 'Permission:' : 'Permissie:',
- 'Response' : 'Antwoorden',
- 'Send' : 'Sturen',
- 'Send a Sample Request' : 'Stuur een sample aanvragen',
- 'show up to version:' : 'toon tot en met versie:',
- 'Size range:' : 'Maatbereik:',
- 'Type' : 'Type',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/pl.js b/apidoc/locales/pl.js
deleted file mode 100644
index db645ee1..00000000
--- a/apidoc/locales/pl.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- pl: {
- 'Allowed values:' : 'Dozwolone wartości:',
- 'Compare all with predecessor': 'Porównaj z poprzednimi wersjami',
- 'compare changes to:' : 'porównaj zmiany do:',
- 'compared to' : 'porównaj do:',
- 'Default value:' : 'Wartość domyślna:',
- 'Description' : 'Opis',
- 'Field' : 'Pole',
- 'General' : 'Generalnie',
- 'Generated with' : 'Wygenerowano z',
- 'Name' : 'Nazwa',
- 'No response values.' : 'Brak odpowiedzi.',
- 'optional' : 'opcjonalny',
- 'Parameter' : 'Parametr',
- 'Permission:' : 'Uprawnienia:',
- 'Response' : 'Odpowiedź',
- 'Send' : 'Wyślij',
- 'Send a Sample Request' : 'Wyślij przykładowe żądanie',
- 'show up to version:' : 'pokaż do wersji:',
- 'Size range:' : 'Zakres rozmiaru:',
- 'Type' : 'Typ',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/pt_br.js b/apidoc/locales/pt_br.js
deleted file mode 100644
index 2bd78b0d..00000000
--- a/apidoc/locales/pt_br.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- 'pt_br': {
- 'Allowed values:' : 'Valores permitidos:',
- 'Compare all with predecessor': 'Compare todos com antecessores',
- 'compare changes to:' : 'comparar alterações com:',
- 'compared to' : 'comparado com',
- 'Default value:' : 'Valor padrão:',
- 'Description' : 'Descrição',
- 'Field' : 'Campo',
- 'General' : 'Geral',
- 'Generated with' : 'Gerado com',
- 'Name' : 'Nome',
- 'No response values.' : 'Sem valores de resposta.',
- 'optional' : 'opcional',
- 'Parameter' : 'Parâmetro',
- 'Permission:' : 'Permissão:',
- 'Response' : 'Resposta',
- 'Send' : 'Enviar',
- 'Send a Sample Request' : 'Enviar um Exemplo de Pedido',
- 'show up to version:' : 'aparecer para a versão:',
- 'Size range:' : 'Faixa de tamanho:',
- 'Type' : 'Tipo',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/ro.js b/apidoc/locales/ro.js
deleted file mode 100644
index 8d4e4ed8..00000000
--- a/apidoc/locales/ro.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- ro: {
- 'Allowed values:' : 'Valori permise:',
- 'Compare all with predecessor': 'Compară toate cu versiunea precedentă',
- 'compare changes to:' : 'compară cu versiunea:',
- 'compared to' : 'comparat cu',
- 'Default value:' : 'Valoare implicită:',
- 'Description' : 'Descriere',
- 'Field' : 'Câmp',
- 'General' : 'General',
- 'Generated with' : 'Generat cu',
- 'Name' : 'Nume',
- 'No response values.' : 'Nici o valoare returnată.',
- 'optional' : 'opțional',
- 'Parameter' : 'Parametru',
- 'Permission:' : 'Permisiune:',
- 'Response' : 'Răspuns',
- 'Send' : 'Trimite',
- 'Send a Sample Request' : 'Trimite o cerere de probă',
- 'show up to version:' : 'arată până la versiunea:',
- 'Size range:' : 'Interval permis:',
- 'Type' : 'Tip',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/ru.js b/apidoc/locales/ru.js
deleted file mode 100644
index c5f33821..00000000
--- a/apidoc/locales/ru.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- ru: {
- 'Allowed values:' : 'Допустимые значения:',
- 'Compare all with predecessor': 'Сравнить с предыдущей версией',
- 'compare changes to:' : 'сравнить с:',
- 'compared to' : 'в сравнении с',
- 'Default value:' : 'По умолчанию:',
- 'Description' : 'Описание',
- 'Field' : 'Название',
- 'General' : 'Общая информация',
- 'Generated with' : 'Сгенерировано с помощью',
- 'Name' : 'Название',
- 'No response values.' : 'Нет значений для ответа.',
- 'optional' : 'необязательный',
- 'Parameter' : 'Параметр',
- 'Permission:' : 'Разрешено:',
- 'Response' : 'Ответ',
- 'Send' : 'Отправить',
- 'Send a Sample Request' : 'Отправить тестовый запрос',
- 'show up to version:' : 'показать версию:',
- 'Size range:' : 'Ограничения:',
- 'Type' : 'Тип',
- 'url' : 'URL'
- }
-});
diff --git a/apidoc/locales/tr.js b/apidoc/locales/tr.js
deleted file mode 100644
index 5c64e52d..00000000
--- a/apidoc/locales/tr.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- tr: {
- 'Allowed values:' : 'İzin verilen değerler:',
- 'Compare all with predecessor': 'Tümünü öncekiler ile karşılaştır',
- 'compare changes to:' : 'değişiklikleri karşılaştır:',
- 'compared to' : 'karşılaştır',
- 'Default value:' : 'Varsayılan değer:',
- 'Description' : 'Açıklama',
- 'Field' : 'Alan',
- 'General' : 'Genel',
- 'Generated with' : 'Oluşturan',
- 'Name' : 'İsim',
- 'No response values.' : 'Dönüş verisi yok.',
- 'optional' : 'opsiyonel',
- 'Parameter' : 'Parametre',
- 'Permission:' : 'İzin:',
- 'Response' : 'Dönüş',
- 'Send' : 'Gönder',
- 'Send a Sample Request' : 'Örnek istek gönder',
- 'show up to version:' : 'bu versiyona kadar göster:',
- 'Size range:' : 'Boyut aralığı:',
- 'Type' : 'Tip',
- 'url' : 'url'
- }
-});
diff --git a/apidoc/locales/vi.js b/apidoc/locales/vi.js
deleted file mode 100644
index 7ce77050..00000000
--- a/apidoc/locales/vi.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- vi: {
- 'Allowed values:' : 'Giá trị chấp nhận:',
- 'Compare all with predecessor': 'So sánh với tất cả phiên bản trước',
- 'compare changes to:' : 'so sánh sự thay đổi với:',
- 'compared to' : 'so sánh với',
- 'Default value:' : 'Giá trị mặc định:',
- 'Description' : 'Chú thích',
- 'Field' : 'Trường dữ liệu',
- 'General' : 'Tổng quan',
- 'Generated with' : 'Được tạo bởi',
- 'Name' : 'Tên',
- 'No response values.' : 'Không có kết quả trả về.',
- 'optional' : 'Tùy chọn',
- 'Parameter' : 'Tham số',
- 'Permission:' : 'Quyền hạn:',
- 'Response' : 'Kết quả',
- 'Send' : 'Gửi',
- 'Send a Sample Request' : 'Gửi một yêu cầu mẫu',
- 'show up to version:' : 'hiển thị phiên bản:',
- 'Size range:' : 'Kích cỡ:',
- 'Type' : 'Kiểu',
- 'url' : 'liên kết'
- }
-});
diff --git a/apidoc/locales/zh.js b/apidoc/locales/zh.js
deleted file mode 100644
index ca5042fe..00000000
--- a/apidoc/locales/zh.js
+++ /dev/null
@@ -1,25 +0,0 @@
-define({
- zh: {
- 'Allowed values​​:' : '允許值:',
- 'Compare all with predecessor': '預先比較所有',
- 'compare changes to:' : '比較變更:',
- 'compared to' : '對比',
- 'Default value:' : '預設值:',
- 'Description' : '描述',
- 'Field' : '欄位',
- 'General' : '概括',
- 'Generated with' : '生成工具',
- 'Name' : '名稱',
- 'No response values​​.' : '無對應資料.',
- 'optional' : '選填',
- 'Parameter' : '參數',
- 'Permission:' : '權限:',
- 'Response' : '回應',
- 'Send' : '發送',
- 'Send a Sample Request' : '發送試用需求',
- 'show up to version:' : '顯示到版本:',
- 'Size range:' : '區間:',
- 'Type' : '類型',
- 'url' : '網址'
- }
-});
diff --git a/apidoc/locales/zh_cn.js b/apidoc/locales/zh_cn.js
deleted file mode 100644
index 50913e25..00000000
--- a/apidoc/locales/zh_cn.js
+++ /dev/null
@@ -1,27 +0,0 @@
-define({
- 'zh_cn': {
- 'Allowed values:' : '允许值:',
- 'Compare all with predecessor': '与所有较早的比较',
- 'compare changes to:' : '将当前版本与指定版本比较:',
- 'compared to' : '相比于',
- 'Default value:' : '默认值:',
- 'Description' : '描述',
- 'Field' : '字段',
- 'General' : '概要',
- 'Generated with' : '基于',
- 'Name' : '名称',
- 'No response values.' : '无返回值.',
- 'optional' : '可选',
- 'Parameter' : '参数',
- 'Parameters' : '参数',
- 'Headers' : '头部参数',
- 'Permission:' : '权限:',
- 'Response' : '返回',
- 'Send' : '发送',
- 'Send a Sample Request' : '发送示例请求',
- 'show up to version:' : '显示到指定版本:',
- 'Size range:' : '取值范围:',
- 'Type' : '类型',
- 'url' : '网址'
- }
-});
diff --git a/apidoc/main.js b/apidoc/main.js
deleted file mode 100644
index bdcf58cb..00000000
--- a/apidoc/main.js
+++ /dev/null
@@ -1,1146 +0,0 @@
-require.config({
- paths: {
- bootstrap: "./vendor/bootstrap.min",
- diffMatchPatch: "./vendor/diff_match_patch.min",
- handlebars: "./vendor/handlebars.min",
- handlebarsExtended: "./utils/handlebars_helper",
- jquery: "./vendor/jquery.min",
- locales: "./locales/locale",
- lodash: "./vendor/lodash.custom.min",
- pathToRegexp: "./vendor/path-to-regexp/index",
- prismjs: "./vendor/prism",
- semver: "./vendor/semver.min",
- utilsSampleRequest: "./utils/send_sample_request",
- webfontloader: "./vendor/webfontloader",
- list: "./vendor/list.min",
- apiData: "./api_data",
- apiProject: "./api_project"
- },
- shim: {
- bootstrap: {
- deps: ["jquery"]
- },
- diffMatchPatch: {
- exports: "diff_match_patch"
- },
- handlebars: {
- exports: "Handlebars"
- },
- handlebarsExtended: {
- deps: ["jquery", "handlebars"],
- exports: "Handlebars"
- },
- prismjs: {
- exports: "Prism"
- }
- },
- urlArgs: "v=" + new Date().getTime(),
- waitSeconds: 150
-});
-
-require([
- "jquery",
- "lodash",
- "locales",
- "handlebarsExtended",
- "apiProject",
- "apiData",
- "prismjs",
- "utilsSampleRequest",
- "semver",
- "webfontloader",
- "bootstrap",
- "pathToRegexp",
- "list"
-], function(
- $,
- _,
- locale,
- Handlebars,
- apiProject,
- apiData,
- Prism,
- sampleRequest,
- semver,
- WebFont
-) {
- // Load google web fonts.
- WebFont.load({
- active: function() {
- // Only init after fonts are loaded.
- init(
- $,
- _,
- locale,
- Handlebars,
- apiProject,
- apiData,
- Prism,
- sampleRequest,
- semver
- );
- },
- inactive: function() {
- // Run init, even if loading fonts fails
- init(
- $,
- _,
- locale,
- Handlebars,
- apiProject,
- apiData,
- Prism,
- sampleRequest,
- semver
- );
- },
- google: {
- families: ["Source Code Pro", "Source Sans Pro:n4,n6,n7"]
- }
- });
-});
-
-function init(
- $,
- _,
- locale,
- Handlebars,
- apiProject,
- apiData,
- Prism,
- sampleRequest,
- semver
-) {
- var api = apiData.api;
-
- //
- // Templates
- //
- var templateHeader = Handlebars.compile($("#template-header").html());
- var templateFooter = Handlebars.compile($("#template-footer").html());
- var templateArticle = Handlebars.compile($("#template-article").html());
- var templateCompareArticle = Handlebars.compile(
- $("#template-compare-article").html()
- );
- var templateGenerator = Handlebars.compile($("#template-generator").html());
- var templateProject = Handlebars.compile($("#template-project").html());
- var templateSections = Handlebars.compile($("#template-sections").html());
- var templateSidenav = Handlebars.compile($("#template-sidenav").html());
-
- //
- // Default host url used if no sampleUrl is present in config
- //
- var baseURL = window.location.origin;
-
- //
- // apiProject defaults
- //
- if (!apiProject.template) apiProject.template = {};
-
- if (apiProject.template.withCompare == null)
- apiProject.template.withCompare = true;
-
- if (apiProject.template.withGenerator == null)
- apiProject.template.withGenerator = true;
-
- if (apiProject.template.forceLanguage)
- locale.setLanguage(apiProject.template.forceLanguage);
-
- if (apiProject.template.aloneDisplay == null)
- apiProject.template.aloneDisplay = false;
-
- // Setup jQuery Ajax
- $.ajaxSetup(apiProject.template.jQueryAjaxSetup);
-
- //
- // Data transform
- //
- // grouped by group
- var apiByGroup = _.groupBy(api, function(entry) {
- return entry.group;
- });
-
- // grouped by group and name
- var apiByGroupAndName = {};
- $.each(apiByGroup, function(index, entries) {
- apiByGroupAndName[index] = _.groupBy(entries, function(entry) {
- return entry.name;
- });
- });
-
- //
- // sort api within a group by title ASC and custom order
- //
- var newList = [];
- var umlauts = { ä: "ae", ü: "ue", ö: "oe", ß: "ss" }; // TODO: remove in version 1.0
- $.each(apiByGroupAndName, function(index, groupEntries) {
- // get titles from the first entry of group[].name[] (name has versioning)
- var titles = [];
- $.each(groupEntries, function(titleName, entries) {
- var title = entries[0].title;
- if (title !== undefined) {
- title.toLowerCase().replace(/[äöüß]/g, function($0) {
- return umlauts[$0];
- });
- titles.push(title + "#~#" + titleName); // '#~#' keep reference to titleName after sorting
- }
- });
- // sort by name ASC
- titles.sort();
-
- // custom order
- if (apiProject.order) titles = sortByOrder(titles, apiProject.order, "#~#");
-
- // add single elements to the new list
- titles.forEach(function(name) {
- var values = name.split("#~#");
- var key = values[1];
- groupEntries[key].forEach(function(entry) {
- newList.push(entry);
- });
- });
- });
- // api overwrite with ordered list
- api = newList;
-
- //
- // Group- and Versionlists
- //
- var apiGroups = {};
- var apiGroupTitles = {};
- var apiVersions = {};
- apiVersions[apiProject.version] = 1;
-
- $.each(api, function(index, entry) {
- apiGroups[entry.group] = 1;
- apiGroupTitles[entry.group] = entry.groupTitle || entry.group;
- apiVersions[entry.version] = 1;
- });
-
- // sort groups
- apiGroups = Object.keys(apiGroups);
- apiGroups.sort();
-
- // custom order
- if (apiProject.order) apiGroups = sortByOrder(apiGroups, apiProject.order);
-
- // sort versions DESC
- apiVersions = Object.keys(apiVersions);
- apiVersions.sort(semver.compare);
- apiVersions.reverse();
-
- //
- // create Navigationlist
- //
- var nav = [];
- apiGroups.forEach(function(group) {
- // Mainmenu entry
- nav.push({
- group: group,
- isHeader: true,
- title: apiGroupTitles[group]
- });
-
- // Submenu
- var oldName = "";
- api.forEach(function(entry) {
- if (entry.group === group) {
- if (oldName !== entry.name) {
- nav.push({
- title: entry.title,
- group: group,
- name: entry.name,
- type: entry.type,
- version: entry.version,
- url: entry.url
- });
- } else {
- nav.push({
- title: entry.title,
- group: group,
- hidden: true,
- name: entry.name,
- type: entry.type,
- version: entry.version,
- url: entry.url
- });
- }
- oldName = entry.name;
- }
- });
- });
-
- /**
- * Add navigation items by analyzing the HTML content and searching for h1 and h2 tags
- * @param nav Object the navigation array
- * @param content string the compiled HTML content
- * @param index where to insert items
- * @return boolean true if any good-looking (i.e. with a group identifier) <h1> tag was found
- */
- function add_nav(nav, content, index) {
- var found_level1 = false;
- if (!content) {
- return found_level1;
- }
- var topics = content.match(/<h(1|2).*?>(.+?)<\/h(1|2)>/gi);
- if (topics) {
- topics.forEach(function(entry) {
- var level = entry.substring(2, 3);
- var title = entry.replace(/<.+?>/g, ""); // Remove all HTML tags for the title
- var entry_tags = entry.match(/id="api-([^\-]+)(?:-(.+))?"/); // Find the group and name in the id property
- var group = entry_tags ? entry_tags[1] : null;
- var name = entry_tags ? entry_tags[2] : null;
- if (level == 1 && title && group) {
- nav.splice(index, 0, {
- group: group,
- isHeader: true,
- title: title,
- isFixed: true
- });
- index++;
- found_level1 = true;
- }
- if (level == 2 && title && group && name) {
- nav.splice(index, 0, {
- group: group,
- name: name,
- isHeader: false,
- title: title,
- isFixed: false,
- version: "1.0"
- });
- index++;
- }
- });
- }
- return found_level1;
- }
-
- // Mainmenu Header entry
- if (apiProject.header) {
- var found_level1 = add_nav(nav, apiProject.header.content, 0); // Add level 1 and 2 titles
- if (!found_level1) {
- // If no Level 1 tags were found, make a title
- nav.unshift({
- group: "_",
- isHeader: true,
- title:
- apiProject.header.title == null
- ? locale.__("General")
- : apiProject.header.title,
- isFixed: true
- });
- }
- }
-
- // Mainmenu Footer entry
- if (apiProject.footer) {
- var last_nav_index = nav.length;
- var found_level1 = add_nav(nav, apiProject.footer.content, nav.length); // Add level 1 and 2 titles
- if (!found_level1 && apiProject.footer.title != null) {
- // If no Level 1 tags were found, make a title
- nav.splice(last_nav_index, 0, {
- group: "_footer",
- isHeader: true,
- title: apiProject.footer.title,
- isFixed: true
- });
- }
- }
-
- // render pagetitle
- var title = apiProject.title
- ? apiProject.title
- : "apiDoc: " + apiProject.name + " - " + apiProject.version;
- $(document).attr("title", title);
-
- // remove loader
- $("#loader").remove();
-
- // render sidenav
- var fields = {
- nav: nav
- };
- $("#sidenav").append(templateSidenav(fields));
-
- // render Generator
- $("#generator").append(templateGenerator(apiProject));
-
- // render Project
- _.extend(apiProject, { versions: apiVersions });
- $("#project").append(templateProject(apiProject));
-
- // render apiDoc, header/footer documentation
- if (apiProject.header) $("#header").append(templateHeader(apiProject.header));
-
- if (apiProject.footer) $("#footer").append(templateFooter(apiProject.footer));
-
- //
- // Render Sections and Articles
- //
- var articleVersions = {};
- var content = "";
- apiGroups.forEach(function(groupEntry) {
- var articles = [];
- var oldName = "";
- var fields = {};
- var title = groupEntry;
- var description = "";
- articleVersions[groupEntry] = {};
-
- // render all articles of a group
- api.forEach(function(entry) {
- if (groupEntry === entry.group) {
- if (oldName !== entry.name) {
- // determine versions
- api.forEach(function(versionEntry) {
- if (
- groupEntry === versionEntry.group &&
- entry.name === versionEntry.name
- ) {
- if (!articleVersions[entry.group].hasOwnProperty(entry.name)) {
- articleVersions[entry.group][entry.name] = [];
- }
- articleVersions[entry.group][entry.name].push(
- versionEntry.version
- );
- }
- });
- fields = {
- article: entry,
- versions: articleVersions[entry.group][entry.name]
- };
- } else {
- fields = {
- article: entry,
- hidden: true,
- versions: articleVersions[entry.group][entry.name]
- };
- }
-
- if (apiProject.sampleUrl == false) {
- fields.article.sampleRequest = [
- {
- url: baseURL + fields.article.url
- }
- ];
- }
-
- // add prefix URL for endpoint unless it's already absolute
- if (apiProject.url) {
- if (fields.article.url.substr(0, 4).toLowerCase() !== "http") {
- fields.article.url = apiProject.url + fields.article.url;
- }
- }
-
- addArticleSettings(fields, entry);
-
- if (entry.groupTitle) title = entry.groupTitle;
-
- // TODO: make groupDescription compareable with older versions (not important for the moment)
- if (entry.groupDescription) description = entry.groupDescription;
-
- articles.push({
- article: templateArticle(fields),
- group: entry.group,
- name: entry.name,
- aloneDisplay: apiProject.template.aloneDisplay
- });
- oldName = entry.name;
- }
- });
-
- // render Section with Articles
- var fields = {
- group: groupEntry,
- title: title,
- description: description,
- articles: articles,
- aloneDisplay: apiProject.template.aloneDisplay
- };
- content += templateSections(fields);
- });
- $("#sections").append(content);
-
- // Bootstrap Scrollspy
- $(this).scrollspy({ target: "#scrollingNav" });
-
- // Content-Scroll on Navigation click.
- $(".sidenav")
- .find("a")
- .on("click", function(e) {
- e.preventDefault();
- var id = $(this).attr("href");
- if ($(id).length > 0)
- $("html,body").animate(
- { scrollTop: parseInt($(id).offset().top) },
- 400
- );
- window.location.hash = $(this).attr("href");
- });
-
- /**
- * Check if Parameter (sub) List has a type Field.
- * Example: @apiSuccess varname1 No type.
- * @apiSuccess {String} varname2 With type.
- *
- * @param {Object} fields
- */
- function _hasTypeInFields(fields) {
- var result = false;
- $.each(fields, function(name) {
- result =
- result ||
- _.some(fields[name], function(item) {
- return item.type;
- });
- });
- return result;
- }
-
- /**
- * On Template changes, recall plugins.
- */
- function initDynamic() {
- // Bootstrap popover
- $('button[data-toggle="popover"]')
- .popover()
- .click(function(e) {
- e.preventDefault();
- });
-
- var version = $("#version strong").html();
- $("#sidenav li").removeClass("is-new");
- if (apiProject.template.withCompare) {
- $("#sidenav li[data-version='" + version + "']").each(function() {
- var group = $(this).data("group");
- var name = $(this).data("name");
- var length = $(
- "#sidenav li[data-group='" + group + "'][data-name='" + name + "']"
- ).length;
- var index = $(
- "#sidenav li[data-group='" + group + "'][data-name='" + name + "']"
- ).index($(this));
- if (length === 1 || index === length - 1) $(this).addClass("is-new");
- });
- }
-
- // tabs
- $(".nav-tabs-examples a").click(function(e) {
- e.preventDefault();
- $(this).tab("show");
- });
- $(".nav-tabs-examples")
- .find("a:first")
- .tab("show");
-
- // sample header-content-type switch
- $(".sample-header-content-type-switch").change(function() {
- var paramName = "." + $(this).attr("name") + "-fields";
- var bodyName = "." + $(this).attr("name") + "-body";
- var selectName = "select[name=" + $(this).attr("name") + "]";
- if ($(this).val() == "body-json") {
- $(selectName).val("undefined");
- $(this).val("body-json");
- $(paramName).removeClass("hide");
- $(this)
- .parent()
- .nextAll(paramName)
- .first()
- .addClass("hide");
- $(bodyName).addClass("hide");
- $(this)
- .parent()
- .nextAll(bodyName)
- .first()
- .removeClass("hide");
- } else if ($(this).val() == "body-form-data") {
- $(selectName).val("undefined");
- $(this).val("body-form-data");
- $(bodyName).addClass("hide");
- $(paramName).removeClass("hide");
- } else {
- $(this)
- .parent()
- .nextAll(paramName)
- .first()
- .removeClass("hide");
- $(this)
- .parent()
- .nextAll(bodyName)
- .first()
- .addClass("hide");
- }
- $(this)
- .prev(".sample-request-switch")
- .prop("checked", true);
- });
-
- // sample request switch
- $(".sample-request-switch").click(function(e) {
- var paramName = "." + $(this).attr("name") + "-fields";
- var bodyName = "." + $(this).attr("name") + "-body";
- var select = $(this)
- .next("." + $(this).attr("name") + "-select")
- .val();
- if ($(this).prop("checked")) {
- if (select == "body-json") {
- $(this)
- .parent()
- .nextAll(bodyName)
- .first()
- .removeClass("hide");
- } else {
- $(this)
- .parent()
- .nextAll(paramName)
- .first()
- .removeClass("hide");
- }
- } else {
- if (select == "body-json") {
- $(this)
- .parent()
- .nextAll(bodyName)
- .first()
- .addClass("hide");
- } else {
- $(this)
- .parent()
- .nextAll(paramName)
- .first()
- .addClass("hide");
- }
- }
- });
-
- if (apiProject.template.aloneDisplay) {
- //show group
- $(".show-group").click(function() {
- var apiGroup = "." + $(this).attr("data-group") + "-group";
- var apiGroupArticle = "." + $(this).attr("data-group") + "-article";
- $(".show-api-group").addClass("hide");
- $(apiGroup).removeClass("hide");
- $(".show-api-article").addClass("hide");
- $(apiGroupArticle).removeClass("hide");
- });
-
- //show api
- $(".show-api").click(function() {
- var apiName = "." + $(this).attr("data-name") + "-article";
- var apiGroup = "." + $(this).attr("data-group") + "-group";
- $(".show-api-group").addClass("hide");
- $(apiGroup).removeClass("hide");
- $(".show-api-article").addClass("hide");
- $(apiName).removeClass("hide");
- });
- }
-
- // call scrollspy refresh method
- $(window).scrollspy("refresh");
-
- // init modules
- sampleRequest.initDynamic();
- Prism.highlightAll();
- }
- initDynamic();
-
- if (apiProject.template.aloneDisplay) {
- var hashVal = window.location.hash;
- if (hashVal != null && hashVal.length !== 0) {
- $("." + hashVal.slice(1) + "-init").click();
- }
- }
-
- //
- // HTML-Template specific jQuery-Functions
- //
- // Change Main Version
- function setMainVersion(selectedVersion) {
- if (typeof selectedVersion === "undefined") {
- selectedVersion = $("#version strong").html();
- } else {
- $("#version strong").html(selectedVersion);
- }
-
- // hide all
- $("article").addClass("hide");
- $("#sidenav li:not(.nav-fixed)").addClass("hide");
-
- // show 1st equal or lower Version of each entry
- $("article[data-version]").each(function(index) {
- var group = $(this).data("group");
- var name = $(this).data("name");
- var version = $(this).data("version");
-
- if (semver.lte(version, selectedVersion)) {
- if (
- $(
- "article[data-group='" +
- group +
- "'][data-name='" +
- name +
- "']:visible"
- ).length === 0
- ) {
- // enable Article
- $(
- "article[data-group='" +
- group +
- "'][data-name='" +
- name +
- "'][data-version='" +
- version +
- "']"
- ).removeClass("hide");
- // enable Navigation
- $(
- "#sidenav li[data-group='" +
- group +
- "'][data-name='" +
- name +
- "'][data-version='" +
- version +
- "']"
- ).removeClass("hide");
- $("#sidenav li.nav-header[data-group='" + group + "']").removeClass(
- "hide"
- );
- }
- }
- });
-
- // show 1st equal or lower Version of each entry
- $("article[data-version]").each(function(index) {
- var group = $(this).data("group");
- $("section#api-" + group).removeClass("hide");
- if ($("section#api-" + group + " article:visible").length === 0) {
- $("section#api-" + group).addClass("hide");
- } else {
- $("section#api-" + group).removeClass("hide");
- }
- });
-
- initDynamic();
- return;
- }
- setMainVersion();
-
- $("#versions li.version a").on("click", function(e) {
- e.preventDefault();
-
- setMainVersion($(this).html());
- });
-
- // compare all article with their predecessor
- $("#compareAllWithPredecessor").on("click", changeAllVersionCompareTo);
-
- // change version of an article
- $("article .versions li.version a").on("click", changeVersionCompareTo);
-
- // compare url-parameter
- $.urlParam = function(name) {
- var results = new RegExp("[\\?&amp;]" + name + "=([^&amp;#]*)").exec(
- window.location.href
- );
- return results && results[1] ? results[1] : null;
- };
-
- if ($.urlParam("compare")) {
- // URL Paramter ?compare=1 is set
- $("#compareAllWithPredecessor").trigger("click");
- }
-
- // Quick jump on page load to hash position.
- // Should happen after setting the main version
- // and after triggering the click on the compare button,
- // as these actions modify the content
- // and would make it jump to the wrong position or not jump at all.
- if (window.location.hash) {
- var id = decodeURI(window.location.hash);
- if ($(id).length > 0)
- $("html,body").animate({ scrollTop: parseInt($(id).offset().top) }, 0);
- }
-
- /**
- * Initialize search
- */
- var options = {
- valueNames: ["nav-list-item", "nav-list-url-item"]
- };
- var endpointsList = new List("scrollingNav", options);
-
- /**
- * Set initial focus to search input
- */
- $("#scrollingNav .sidenav-search input.search").focus();
-
- /**
- * Detect ESC key to reset search
- */
- $(document).keyup(function(e) {
- if (e.keyCode === 27) $("span.search-reset").click();
- });
-
- /**
- * Search reset
- */
- $("span.search-reset").on("click", function() {
- $("#scrollingNav .sidenav-search input.search")
- .val("")
- .focus();
- endpointsList.search();
- });
-
- /**
- * Change version of an article to compare it to an other version.
- */
- function changeVersionCompareTo(e) {
- e.preventDefault();
-
- var $root = $(this).parents("article");
- var selectedVersion = $(this).html();
- var $button = $root.find(".version");
- var currentVersion = $button.find("strong").html();
- $button.find("strong").html(selectedVersion);
-
- var group = $root.data("group");
- var name = $root.data("name");
- var version = $root.data("version");
-
- var compareVersion = $root.data("compare-version");
-
- if (compareVersion === selectedVersion) return;
-
- if (!compareVersion && version == selectedVersion) return;
-
- if (
- (compareVersion && articleVersions[group][name][0] === selectedVersion) ||
- version === selectedVersion
- ) {
- // the version of the entry is set to the highest version (reset)
- resetArticle(group, name, version);
- } else {
- var $compareToArticle = $(
- "article[data-group='" +
- group +
- "'][data-name='" +
- name +
- "'][data-version='" +
- selectedVersion +
- "']"
- );
-
- var sourceEntry = {};
- var compareEntry = {};
- $.each(apiByGroupAndName[group][name], function(index, entry) {
- if (entry.version === version) sourceEntry = entry;
- if (entry.version === selectedVersion) compareEntry = entry;
- });
-
- var fields = {
- article: sourceEntry,
- compare: compareEntry,
- versions: articleVersions[group][name]
- };
-
- // add unique id
- // TODO: replace all group-name-version in template with id.
- fields.article.id =
- fields.article.group +
- "-" +
- fields.article.name +
- "-" +
- fields.article.version;
- fields.article.id = fields.article.id.replace(/\./g, "_");
-
- fields.compare.id =
- fields.compare.group +
- "-" +
- fields.compare.name +
- "-" +
- fields.compare.version;
- fields.compare.id = fields.compare.id.replace(/\./g, "_");
-
- var entry = sourceEntry;
- if (entry.parameter && entry.parameter.fields)
- fields._hasTypeInParameterFields = _hasTypeInFields(
- entry.parameter.fields
- );
-
- if (entry.error && entry.error.fields)
- fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields);
-
- if (entry.success && entry.success.fields)
- fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields);
-
- if (entry.info && entry.info.fields)
- fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields);
-
- var entry = compareEntry;
- if (
- fields._hasTypeInParameterFields !== true &&
- entry.parameter &&
- entry.parameter.fields
- )
- fields._hasTypeInParameterFields = _hasTypeInFields(
- entry.parameter.fields
- );
-
- if (
- fields._hasTypeInErrorFields !== true &&
- entry.error &&
- entry.error.fields
- )
- fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields);
-
- if (
- fields._hasTypeInSuccessFields !== true &&
- entry.success &&
- entry.success.fields
- )
- fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields);
-
- if (
- fields._hasTypeInInfoFields !== true &&
- entry.info &&
- entry.info.fields
- )
- fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields);
-
- var content = templateCompareArticle(fields);
- $root.after(content);
- var $content = $root.next();
-
- // Event on.click re-assign
- $content
- .find(".versions li.version a")
- .on("click", changeVersionCompareTo);
-
- // select navigation
- $(
- "#sidenav li[data-group='" +
- group +
- "'][data-name='" +
- name +
- "'][data-version='" +
- currentVersion +
- "']"
- ).addClass("has-modifications");
-
- $root.remove();
- // TODO: on change main version or select the highest version re-render
- }
-
- initDynamic();
- }
-
- /**
- * Compare all currently selected Versions with their predecessor.
- */
- function changeAllVersionCompareTo(e) {
- e.preventDefault();
- $("article:visible .versions").each(function() {
- var $root = $(this).parents("article");
- var currentVersion = $root.data("version");
- var $foundElement = null;
- $(this)
- .find("li.version a")
- .each(function() {
- var selectVersion = $(this).html();
- if (selectVersion < currentVersion && !$foundElement)
- $foundElement = $(this);
- });
-
- if ($foundElement) $foundElement.trigger("click");
- });
- initDynamic();
- }
-
- /**
- * Sort the fields.
- */
- function sortFields(fields_object) {
- $.each(fields_object, function(key, fields) {
- // Find only object fields
- var objects = fields.filter(function(item) {
- return item.type === "Object";
- });
-
- // Check if has any object
- if (objects.length === 0) {
- return;
- }
-
- // Iterate over all objects
- for (var object of objects) {
- // Retrieve the index
- var index = fields.indexOf(object);
-
- // Find all child fields for this object
- var objectFields = fields.filter(function(item) {
- return item.field.indexOf(object.field + ".") > -1;
- });
-
- // Get the child index
- var firstIndex = fields.indexOf(objectFields[0]);
-
- // Put the object it before the first child index
- fields.splice(index, 1);
- fields.splice(firstIndex, 0, object);
-
- // Startup the last index with the object index
- var lastIndex = firstIndex;
-
- // Iterate over all children
- for (var child of objectFields) {
- lastIndex++;
-
- // Retrieve the index
- var childIndex = fields.indexOf(child);
-
- // Put it after the object declaration
- fields.splice(childIndex, 1);
- fields.splice(lastIndex, 0, child);
- }
- }
-
- // Retrieve the first object field index
- var firstObjectIndex = fields.indexOf(objects[0]);
-
- // Find all non-object fields that doesn't contain dot notation
- var nonObjects = fields.filter(function(item) {
- return item.field.indexOf(".") === -1 && item.type !== "Object";
- });
-
- // Iterate over all non-objects
- for (var nonObject of nonObjects) {
- // Put it before the first object field
- var index = fields.indexOf(nonObject);
- fields.splice(index, 1);
- fields.splice(firstObjectIndex, 0, nonObject);
- }
- });
- }
-
- /**
- * Add article settings.
- */
- function addArticleSettings(fields, entry) {
- // add unique id
- // TODO: replace all group-name-version in template with id.
- fields.id =
- fields.article.group +
- "-" +
- fields.article.name +
- "-" +
- fields.article.version;
- fields.id = fields.id.replace(/\./g, "_");
-
- if (entry.header && entry.header.fields) {
- sortFields(entry.header.fields);
- fields._hasTypeInHeaderFields = _hasTypeInFields(entry.header.fields);
- }
-
- if (entry.parameter && entry.parameter.fields) {
- sortFields(entry.parameter.fields);
- fields._hasTypeInParameterFields = _hasTypeInFields(
- entry.parameter.fields
- );
- }
-
- if (entry.error && entry.error.fields) {
- sortFields(entry.error.fields);
- fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields);
- }
-
- if (entry.success && entry.success.fields) {
- sortFields(entry.success.fields);
- fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields);
- }
-
- if (entry.info && entry.info.fields) {
- sortFields(entry.info.fields);
- fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields);
- }
-
- // add template settings
- fields.template = apiProject.template;
- }
-
- /**
- * Render Article.
- */
- function renderArticle(group, name, version) {
- var entry = {};
- $.each(apiByGroupAndName[group][name], function(index, currentEntry) {
- if (currentEntry.version === version) entry = currentEntry;
- });
- var fields = {
- article: entry,
- versions: articleVersions[group][name]
- };
-
- addArticleSettings(fields, entry);
-
- return templateArticle(fields);
- }
-
- /**
- * Render original Article and remove the current visible Article.
- */
- function resetArticle(group, name, version) {
- var $root = $(
- "article[data-group='" + group + "'][data-name='" + name + "']:visible"
- );
- var content = renderArticle(group, name, version);
-
- $root.after(content);
- var $content = $root.next();
-
- // Event on.click needs to be reassigned (should actually work with on ... automatically)
- $content.find(".versions li.version a").on("click", changeVersionCompareTo);
-
- $(
- "#sidenav li[data-group='" +
- group +
- "'][data-name='" +
- name +
- "'][data-version='" +
- version +
- "']"
- ).removeClass("has-modifications");
-
- $root.remove();
- return;
- }
-
- /**
- * Return ordered entries by custom order and append not defined entries to the end.
- * @param {String[]} elements
- * @param {String[]} order
- * @param {String} splitBy
- * @return {String[]} Custom ordered list.
- */
- function sortByOrder(elements, order, splitBy) {
- var results = [];
- order.forEach(function(name) {
- if (splitBy)
- elements.forEach(function(element) {
- var parts = element.split(splitBy);
- var key = parts[0]; // reference keep for sorting
- if (key == name || parts[1] == name) results.push(element);
- });
- else
- elements.forEach(function(key) {
- if (key == name) results.push(name);
- });
- });
- // Append all other entries that ar not defined in order
- elements.forEach(function(element) {
- if (results.indexOf(element) === -1) results.push(element);
- });
- return results;
- }
- Prism.highlightAll();
-}
diff --git a/apidoc/utils/handlebars_helper.js b/apidoc/utils/handlebars_helper.js
deleted file mode 100644
index ed1dc1da..00000000
--- a/apidoc/utils/handlebars_helper.js
+++ /dev/null
@@ -1,416 +0,0 @@
-define([
- 'locales',
- 'handlebars',
- 'diffMatchPatch'
-], function(locale, Handlebars, DiffMatchPatch) {
-
- /**
- * Return a text as markdown.
- * Currently only a little helper to replace apidoc-inline Links (#Group:Name).
- * Should be replaced with a full markdown lib.
- * @param string text
- */
- Handlebars.registerHelper('markdown', function(text) {
- if ( ! text ) {
- return text;
- }
- text = text.replace(/((\[(.*?)\])?\(#)((.+?):(.+?))(\))/mg, function(match, p1, p2, p3, p4, p5, p6) {
- var link = p3 || p5 + '/' + p6;
- return '<a href="#api-' + p5 + '-' + p6 + '">' + link + '</a>';
- });
- return text;
- });
-
- /**
- * set paramater type.
- */
- Handlebars.registerHelper("setInputType", function(text) {
- if (text === "File") {
- return "file";
- }
- return "text";
- });
-
- /**
- * start/stop timer for simple performance check.
- */
- var timer;
- Handlebars.registerHelper('startTimer', function(text) {
- timer = new Date();
- return '';
- });
-
- Handlebars.registerHelper('stopTimer', function(text) {
- console.log(new Date() - timer);
- return '';
- });
-
- /**
- * Return localized Text.
- * @param string text
- */
- Handlebars.registerHelper('__', function(text) {
- return locale.__(text);
- });
-
- /**
- * Console log.
- * @param mixed obj
- */
- Handlebars.registerHelper('cl', function(obj) {
- console.log(obj);
- return '';
- });
-
- /**
- * Replace underscore with space.
- * @param string text
- */
- Handlebars.registerHelper('underscoreToSpace', function(text) {
- return text.replace(/(_+)/g, ' ');
- });
-
- /**
- *
- */
- Handlebars.registerHelper('assign', function(name) {
- if(arguments.length > 0) {
- var type = typeof(arguments[1]);
- var arg = null;
- if(type === 'string' || type === 'number' || type === 'boolean') arg = arguments[1];
- Handlebars.registerHelper(name, function() { return arg; });
- }
- return '';
- });
-
- /**
- *
- */
- Handlebars.registerHelper('nl2br', function(text) {
- return _handlebarsNewlineToBreak(text);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('if_eq', function(context, options) {
- var compare = context;
- // Get length if context is an object
- if (context instanceof Object && ! (options.hash.compare instanceof Object))
- compare = Object.keys(context).length;
-
- if (compare === options.hash.compare)
- return options.fn(this);
-
- return options.inverse(this);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('if_gt', function(context, options) {
- var compare = context;
- // Get length if context is an object
- if (context instanceof Object && ! (options.hash.compare instanceof Object))
- compare = Object.keys(context).length;
-
- if(compare > options.hash.compare)
- return options.fn(this);
-
- return options.inverse(this);
- });
-
- /**
- *
- */
- var templateCache = {};
- Handlebars.registerHelper('subTemplate', function(name, sourceContext) {
- if ( ! templateCache[name])
- templateCache[name] = Handlebars.compile($('#template-' + name).html());
-
- var template = templateCache[name];
- var templateContext = $.extend({}, this, sourceContext.hash);
- return new Handlebars.SafeString( template(templateContext) );
- });
-
- /**
- *
- */
- Handlebars.registerHelper('toLowerCase', function(value) {
- return (value && typeof value === 'string') ? value.toLowerCase() : '';
- });
-
- /**
- *
- */
- Handlebars.registerHelper('splitFill', function(value, splitChar, fillChar) {
- var splits = value.split(splitChar);
- return new Array(splits.length).join(fillChar) + splits[splits.length - 1];
- });
-
- /**
- * Convert Newline to HTML-Break (nl2br).
- *
- * @param {String} text
- * @returns {String}
- */
- function _handlebarsNewlineToBreak(text) {
- return ('' + text).replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + '<br>' + '$2');
- }
-
- /**
- *
- */
- Handlebars.registerHelper('each_compare_list_field', function(source, compare, options) {
- var fieldName = options.hash.field;
- var newSource = [];
- if (source) {
- source.forEach(function(entry) {
- var values = entry;
- values['key'] = entry[fieldName];
- newSource.push(values);
- });
- }
-
- var newCompare = [];
- if (compare) {
- compare.forEach(function(entry) {
- var values = entry;
- values['key'] = entry[fieldName];
- newCompare.push(values);
- });
- }
- return _handlebarsEachCompared('key', newSource, newCompare, options);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('each_compare_keys', function(source, compare, options) {
- var newSource = [];
- if (source) {
- var sourceFields = Object.keys(source);
- sourceFields.forEach(function(name) {
- var values = {};
- values['value'] = source[name];
- values['key'] = name;
- newSource.push(values);
- });
- }
-
- var newCompare = [];
- if (compare) {
- var compareFields = Object.keys(compare);
- compareFields.forEach(function(name) {
- var values = {};
- values['value'] = compare[name];
- values['key'] = name;
- newCompare.push(values);
- });
- }
- return _handlebarsEachCompared('key', newSource, newCompare, options);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('gen_body', function(context, options) {
- let strBody = {};
- context.forEach(element => {
- element.field = element.field.replace("]", "");
- switch (element.type.toLowerCase()) {
- case "string":
- if (element.field.includes('[')) {
- if (strBody[element.field.split("[")[0]] === undefined) {
- strBody[element.field.split("[")[0]] = {};
- }
- strBody[element.field.split("[")[0]][element.field.split("[")[1]] = (element.defaultValue || "");
- break;
- }
- strBody[element.field] = (element.defaultValue || "");
- break;
- case "number":
- if (element.field.includes('[')) {
- if (strBody[element.field.split("[")[0]] === undefined) {
- strBody[element.field.split("[")[0]] = {};
- }
- strBody[element.field.split("[")[0]][element.field.split("[")[1]] = (element.defaultValue || 0);
- break;
- }
- strBody[element.field] = (element.defaultValue || 0);
- break;
- case "object":
- if (strBody[element.field] === undefined) {
- strBody[element.field] = {};
- }
- break;
- default:
- strBody[element.field] = null;
- }
- });
- return JSON.stringify(strBody, null, 4);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('each_compare_field', function(source, compare, options) {
- return _handlebarsEachCompared('field', source, compare, options);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('each_compare_title', function(source, compare, options) {
- return _handlebarsEachCompared('title', source, compare, options);
- });
-
- /**
- *
- */
- Handlebars.registerHelper('reformat', function(source, type){
- if (type == 'json')
- try {
- return JSON.stringify(JSON.parse(source.trim()),null, " ");
- } catch(e) {
-
- }
- return source
- });
-
- /**
- *
- */
- Handlebars.registerHelper('showDiff', function(source, compare, options) {
- var ds = '';
- if(source === compare) {
- ds = source;
- } else {
- if( ! source)
- return compare;
-
- if( ! compare)
- return source;
-
- var d = diffMatchPatch.diff_main(stripHtml(compare), stripHtml(source));
- diffMatchPatch.diff_cleanupSemantic(d);
- ds = diffMatchPatch.diff_prettyHtml(d);
- ds = ds.replace(/&para;/gm, '');
- }
- if(options === 'nl2br')
- ds = _handlebarsNewlineToBreak(ds);
-
- return ds;
- });
-
- /**
- *
- */
- function _handlebarsEachCompared(fieldname, source, compare, options)
- {
- var dataList = [];
- var index = 0;
- if(source) {
- source.forEach(function(sourceEntry) {
- var found = false;
- if (compare) {
- compare.forEach(function(compareEntry) {
- if(sourceEntry[fieldname] === compareEntry[fieldname]) {
- var data = {
- typeSame: true,
- source: sourceEntry,
- compare: compareEntry,
- index: index
- };
- dataList.push(data);
- found = true;
- index++;
- }
- });
- }
- if ( ! found) {
- var data = {
- typeIns: true,
- source: sourceEntry,
- index: index
- };
- dataList.push(data);
- index++;
- }
- });
- }
-
- if (compare) {
- compare.forEach(function(compareEntry) {
- var found = false;
- if (source) {
- source.forEach(function(sourceEntry) {
- if(sourceEntry[fieldname] === compareEntry[fieldname])
- found = true;
- });
- }
- if ( ! found) {
- var data = {
- typeDel: true,
- compare: compareEntry,
- index: index
- };
- dataList.push(data);
- index++;
- }
- });
- }
-
- var ret = '';
- var length = dataList.length;
- for (var index in dataList) {
- if(index == (length - 1))
- dataList[index]['_last'] = true;
- ret = ret + options.fn(dataList[index]);
- }
- return ret;
- }
-
- var diffMatchPatch = new DiffMatchPatch();
-
- /**
- * Overwrite Colors
- */
- DiffMatchPatch.prototype.diff_prettyHtml = function(diffs) {
- var html = [];
- var pattern_amp = /&/g;
- var pattern_lt = /</g;
- var pattern_gt = />/g;
- var pattern_para = /\n/g;
- for (var x = 0; x < diffs.length; x++) {
- var op = diffs[x][0]; // Operation (insert, delete, equal)
- var data = diffs[x][1]; // Text of change.
- var text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;')
- .replace(pattern_gt, '&gt;').replace(pattern_para, '&para;<br>');
- switch (op) {
- case DIFF_INSERT:
- html[x] = '<ins>' + text + '</ins>';
- break;
- case DIFF_DELETE:
- html[x] = '<del>' + text + '</del>';
- break;
- case DIFF_EQUAL:
- html[x] = '<span>' + text + '</span>';
- break;
- }
- }
- return html.join('');
- };
-
- /**
- * Fixes html after comparison (#506, #538, #616, #825)
- */
- function stripHtml(html){
- var div = document.createElement("div");
- div.innerHTML = html;
- return div.textContent || div.innerText || "";
- }
-
- // Exports
- return Handlebars;
-});
diff --git a/apidoc/utils/send_sample_request.js b/apidoc/utils/send_sample_request.js
deleted file mode 100644
index 4d695d14..00000000
--- a/apidoc/utils/send_sample_request.js
+++ /dev/null
@@ -1,272 +0,0 @@
-define([
- 'jquery',
- 'lodash',
- './utils/send_sample_request_utils'
-], function($, _, utils) {
-
- var initDynamic = function() {
- // Button send
- $(".sample-request-send").off("click");
- $(".sample-request-send").on("click", function(e) {
- e.preventDefault();
- var $root = $(this).parents("article");
- var group = $root.data("group");
- var name = $root.data("name");
- var version = $root.data("version");
- sendSampleRequest(group, name, version, $(this).data("sample-request-type"));
- });
-
- // Button clear
- $(".sample-request-clear").off("click");
- $(".sample-request-clear").on("click", function(e) {
- e.preventDefault();
- var $root = $(this).parents("article");
- var group = $root.data("group");
- var name = $root.data("name");
- var version = $root.data("version");
- clearSampleRequest(group, name, version);
- });
- }; // initDynamic
-
- function sendSampleRequest(group, name, version, type)
- {
- var $root = $('article[data-group="' + group + '"][data-name="' + name + '"][data-version="' + version + '"]');
-
- // Optional header
- var header = {};
- $root.find(".sample-request-header:checked").each(function(i, element) {
- var group = $(element).data("sample-request-header-group-id");
- $root.find("[data-sample-request-header-group=\"" + group + "\"]").each(function(i, element) {
- var key = $(element).data("sample-request-header-name");
- var value = element.value;
- if (typeof element.optional === 'undefined') {
- element.optional = true;
- }
- if ( ! element.optional && element.defaultValue !== '') {
- value = element.defaultValue;
- }
- header[key] = value;
- });
- });
-
-
- // create JSON dictionary of parameters
- var param = {};
- var paramType = {};
- var bodyFormData = new FormData();
- var bodyJson = '';
- $root.find(".sample-request-param:checked").each(function(i, element) {
- var group = $(element).data("sample-request-param-group-id");
- var contentType = $(element).nextAll('.sample-header-content-type-switch').first().val();
- if (contentType == "body-json"){
- $root.find("[data-sample-request-body-group=\"" + group + "\"]").not(function(){
- return $(this).val() == "" && $(this).is("[data-sample-request-param-optional='true']");
- }).each(function(i, element) {
- if (isJson(element.value)){
- header['Content-Type'] = 'application/json';
- bodyJson = element.value;
- }
- });
- }else {
- $root.find("[data-sample-request-param-group=\"" + group + "\"]").not(function(){
- return $(this).val() == "" && $(this).is("[data-sample-request-param-optional='true']");
- }).each(function(i, element) {
- var key = $(element).data("sample-request-param-name");
- var value = element.value;
- if ( ! element.optional && element.defaultValue !== '') {
- value = element.defaultValue;
- }
- if (contentType == "body-form-data"){
- header['Content-Type'] = 'multipart/form-data'
- if (element.type == "file") {
- value = element.files[0];
- }
- bodyFormData.append(key,value);
- }else {
- param[key] = value;
- paramType[key] = $(element).next().text();
- }
- });
- }
- });
-
- // grab user-inputted URL
- var url = $root.find(".sample-request-url").val();
-
- //Convert {param} form to :param
- url = utils.convertPathParams(url);
-
- // Insert url parameter
- var pattern = pathToRegexp(url, null);
- var matches = pattern.exec(url);
- for (var i = 1; i < matches.length; i++) {
- var key = matches[i].substr(1);
- var optional = false
- if (key[key.length - 1] === '?') {
- optional = true;
- key = key.substr(0, key.length - 1);
- }
- if (param[key] !== undefined) {
- url = url.replace(matches[i], encodeURIComponent(param[key]));
-
- // remove URL parameters from list
- delete param[key];
- } else if (optional) {
- // if parameter is optional denoted by ending '?' in param (:param?)
- // and no parameter is given, replace parameter with empty string instead
- url = url.replace(matches[i], '');
- delete param[key];
- }
- } // for
-
- //handle nested objects and parsing fields
- param = utils.handleNestedAndParsingFields(param, paramType);
-
- //add url search parameter
- if (header['Content-Type'] == 'application/json') {
- if (bodyJson) {
- // bodyJson is set to value if request body: 'body/json' was selected and manual json was input
- // in this case, use the given bodyJson and add other params in query string
- url = url + encodeSearchParams(param);
- param = bodyJson;
- } else {
- // bodyJson not set, but Content-Type: application/json header was set. In this case, send parameters
- // as JSON body. First, try parsing fields of object with given paramType definition so that the json
- // is valid against the parameter spec (e.g. Boolean params are boolean instead of strings in final json)
- param = utils.tryParsingWithTypes(param, paramType);
- param = JSON.stringify(param);
- }
- }else if (header['Content-Type'] == 'multipart/form-data'){
- url = url + encodeSearchParams(param);
- param = bodyFormData;
- }
-
- $root.find(".sample-request-response").fadeTo(250, 1);
- $root.find(".sample-request-response-json").html("Loading...");
- refreshScrollSpy();
-
- // send AJAX request, catch success or error callback
- var ajaxRequest = {
- url : url,
- headers : header,
- data : param,
- type : type.toUpperCase(),
- success : displaySuccess,
- error : displayError
- };
-
- if(header['Content-Type'] == 'multipart/form-data'){
- delete ajaxRequest.headers['Content-Type'];
- ajaxRequest.contentType=false;
- ajaxRequest.processData=false;
- }
- $.ajax(ajaxRequest);
-
-
- function displaySuccess(data, status, jqXHR) {
- var jsonResponse;
- try {
- jsonResponse = JSON.parse(jqXHR.responseText);
- jsonResponse = JSON.stringify(jsonResponse, null, 4);
- } catch (e) {
- jsonResponse = jqXHR.responseText;
- }
- $root.find(".sample-request-response-json").text(jsonResponse);
- refreshScrollSpy();
- };
-
- function displayError(jqXHR, textStatus, error) {
- var message = "Error " + jqXHR.status + ": " + error;
- var jsonResponse;
- try {
- jsonResponse = JSON.parse(jqXHR.responseText);
- jsonResponse = JSON.stringify(jsonResponse, null, 4);
- } catch (e) {
- jsonResponse = jqXHR.responseText;
- }
-
- if (jsonResponse)
- message += "\n" + jsonResponse;
-
- // flicker on previous error to make clear that there is a new response
- if($root.find(".sample-request-response").is(":visible"))
- $root.find(".sample-request-response").fadeTo(1, 0.1);
-
- $root.find(".sample-request-response").fadeTo(250, 1);
- $root.find(".sample-request-response-json").text(message);
- refreshScrollSpy();
- };
- }
-
- function clearSampleRequest(group, name, version)
- {
- var $root = $('article[data-group="' + group + '"][data-name="' + name + '"][data-version="' + version + '"]');
-
- // hide sample response
- $root.find(".sample-request-response-json").html("");
- $root.find(".sample-request-response").hide();
-
- // reset value of parameters
- $root.find(".sample-request-param").each(function(i, element) {
- element.value = "";
- });
-
- // restore default URL
- var $urlElement = $root.find(".sample-request-url");
- $urlElement.val($urlElement.prop("defaultValue"));
-
- refreshScrollSpy();
- }
-
- function refreshScrollSpy()
- {
- $('[data-spy="scroll"]').each(function () {
- $(this).scrollspy("refresh");
- });
- }
-
- function escapeHtml(str) {
- var div = document.createElement("div");
- div.appendChild(document.createTextNode(str));
- return div.innerHTML;
- }
-
-
- /**
- * is Json
- */
- function isJson(str) {
- if (typeof str == 'string') {
- try {
- var obj=JSON.parse(str);
- if(typeof obj == 'object' && obj ){
- return true;
- }else{
- return false;
- }
- } catch(e) {
- return false;
- }
- }
- }
-
- /**
- * encode Search Params
- */
- function encodeSearchParams(obj) {
- const params = [];
- Object.keys(obj).forEach((key) => {
- let value = obj[key];
- params.push([key, encodeURIComponent(value)].join('='));
- })
- return params.length === 0 ? '' : '?' + params.join('&');
- }
-
- /**
- * Exports.
- */
- return {
- initDynamic: initDynamic
- };
-
-});
diff --git a/apidoc/utils/send_sample_request_utils.js b/apidoc/utils/send_sample_request_utils.js
deleted file mode 100644
index fbda1ffd..00000000
--- a/apidoc/utils/send_sample_request_utils.js
+++ /dev/null
@@ -1,97 +0,0 @@
-//this block is used to make this module works with Node (CommonJS module format)
-if (typeof define !== 'function') {
- var define = require('amdefine')(module)
-}
-
-define(['lodash'], function (_) {
-
- var log = console;
-
- function handleNestedFields(object, key, params, paramType) {
- var attributes = key.split('.');
- var field = attributes[0];
- params.push(field);
- if (attributes.length > 1 && paramType[params.join('.')] == 'Object') {
- var nestedField = attributes.slice(1).join('.');
- if (!object[field])
- object[field] = {};
- if (typeof object[field] == 'object') {
- object[field][nestedField] = object[key];
- delete object[key];
- handleNestedFields(object[field], nestedField, params, paramType);
- }
- }
- }
-
- function handleNestedFieldsForAllParams(param, paramType) {
- var result = Object.assign({}, param);
- Object.keys(result).forEach(function (key) {
- handleNestedFields(result, key, [], paramType);
- });
- return result
- }
-
- function handleArraysAndObjectFields(param, paramType) {
- var result = Object.assign({}, param);
- Object.keys(paramType).forEach(function (key) {
- if (result[key] && (paramType[key].endsWith('[]') || paramType[key] === 'Object')) {
- try {
- result[key] = JSON.parse(result[key]);
- } catch (e) {;}
- }
- });
- return result
- }
-
- function tryParsingAsType(object, path, type) {
- var val = _.get(object, path);
- if (val !== undefined) {
- if (type === 'Boolean') {
- if (val === 'true') {
- _.set(object, path, true);
- } else if (val === 'false') {
- _.set(object, path, false);
- } else {
- log.warn('Failed to parse object value at path [' + path + ']. Value: (' + val + '). Type: (' + type + ')');
- }
- } else if (type === 'Number') {
- var parsedInt = parseInt(val, 10);
- if (!_.isNaN(parsedInt)) {
- _.set(object, path, parsedInt);
- } else {
- log.warn('Failed to parse object value at path [' + path + ']. Value: (' + val + '). Type: (' + type + ')');
- }
- }
- }
- }
-
- function handleNestedAndParsingFields(param, paramType) {
- var result = handleArraysAndObjectFields(param, paramType);
- result = handleNestedFieldsForAllParams(result, paramType);
- return result;
- }
-
- function tryParsingWithTypes(param, paramType) {
- var result = Object.assign({}, param);
- Object.keys(paramType).forEach(function (key) {
- tryParsingAsType(result, key, paramType[key]);
- });
- return result;
- }
-
- // Converts path params in the {param} format to the accepted :param format, used before inserting the URL params.
- function convertPathParams(url) {
- return url.replace(/{(.+?)}/g, ':$1');
- }
-
- function setLogger(logger) {
- log = logger;
- }
-
- return {
- handleNestedAndParsingFields,
- convertPathParams,
- tryParsingWithTypes,
- setLogger
- };
-});
diff --git a/apidoc/vendor/bootstrap.min.css b/apidoc/vendor/bootstrap.min.css
deleted file mode 100644
index 5b96335f..00000000
--- a/apidoc/vendor/bootstrap.min.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
- * Bootstrap v3.4.1 (https://getbootstrap.com/)
- * Copyright 2011-2019 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;-moz-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:"Glyphicons Halflings";src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format("embedded-opentype"),url(../fonts/glyphicons-halflings-regular.woff2) format("woff2"),url(../fonts/glyphicons-halflings-regular.woff) format("woff"),url(../fonts/glyphicons-halflings-regular.ttf) format("truetype"),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format("svg")}.glyphicon{position:relative;top:1px;display:inline-block;font-family:"Glyphicons Halflings";font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:"\2014 \00A0"}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:""}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:"\00A0 \2014"}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.row-no-gutters{margin-right:0;margin-left:0}.row-no-gutters [class*=col-]{padding-right:0;padding-left:0}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s,-webkit-box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],.input-group-sm input[type=time],input[type=date].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm,input[type=time].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],.input-group-lg input[type=time],input[type=date].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg,input[type=time].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);opacity:.65;-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;background-image:none;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;background-image:none;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;background-image:none;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;background-image:none;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;background-image:none;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;background-image:none;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-right:15px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-right:-15px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out,-o-transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:12px;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:400;line-height:1.42857143;line-break:auto;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;font-size:14px;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover>.arrow{border-width:11px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out,-o-transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);left:0}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);left:0}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;outline:0;filter:alpha(opacity=90);opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:"\2039"}.carousel-control .icon-next:before{content:"\203a"}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
-/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file
diff --git a/apidoc/vendor/bootstrap.min.js b/apidoc/vendor/bootstrap.min.js
deleted file mode 100644
index 6290896a..00000000
--- a/apidoc/vendor/bootstrap.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/*!
- * Bootstrap v3.4.1 (https://getbootstrap.com/)
- * Copyright 2011-2019 Twitter, Inc.
- * Licensed under the MIT license
- */
-if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");!function(t){"use strict";var e=jQuery.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1||3<e[0])throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(),function(n){"use strict";n.fn.emulateTransitionEnd=function(t){var e=!1,i=this;n(this).one("bsTransitionEnd",function(){e=!0});return setTimeout(function(){e||n(i).trigger(n.support.transition.end)},t),this},n(function(){n.support.transition=function o(){var t=document.createElement("bootstrap"),e={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var i in e)if(t.style[i]!==undefined)return{end:e[i]};return!1}(),n.support.transition&&(n.event.special.bsTransitionEnd={bindType:n.support.transition.end,delegateType:n.support.transition.end,handle:function(t){if(n(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}})})}(jQuery),function(s){"use strict";var e='[data-dismiss="alert"]',a=function(t){s(t).on("click",e,this.close)};a.VERSION="3.4.1",a.TRANSITION_DURATION=150,a.prototype.close=function(t){var e=s(this),i=e.attr("data-target");i||(i=(i=e.attr("href"))&&i.replace(/.*(?=#[^\s]*$)/,"")),i="#"===i?[]:i;var o=s(document).find(i);function n(){o.detach().trigger("closed.bs.alert").remove()}t&&t.preventDefault(),o.length||(o=e.closest(".alert")),o.trigger(t=s.Event("close.bs.alert")),t.isDefaultPrevented()||(o.removeClass("in"),s.support.transition&&o.hasClass("fade")?o.one("bsTransitionEnd",n).emulateTransitionEnd(a.TRANSITION_DURATION):n())};var t=s.fn.alert;s.fn.alert=function o(i){return this.each(function(){var t=s(this),e=t.data("bs.alert");e||t.data("bs.alert",e=new a(this)),"string"==typeof i&&e[i].call(t)})},s.fn.alert.Constructor=a,s.fn.alert.noConflict=function(){return s.fn.alert=t,this},s(document).on("click.bs.alert.data-api",e,a.prototype.close)}(jQuery),function(s){"use strict";var n=function(t,e){this.$element=s(t),this.options=s.extend({},n.DEFAULTS,e),this.isLoading=!1};function i(o){return this.each(function(){var t=s(this),e=t.data("bs.button"),i="object"==typeof o&&o;e||t.data("bs.button",e=new n(this,i)),"toggle"==o?e.toggle():o&&e.setState(o)})}n.VERSION="3.4.1",n.DEFAULTS={loadingText:"loading..."},n.prototype.setState=function(t){var e="disabled",i=this.$element,o=i.is("input")?"val":"html",n=i.data();t+="Text",null==n.resetText&&i.data("resetText",i[o]()),setTimeout(s.proxy(function(){i[o](null==n[t]?this.options[t]:n[t]),"loadingText"==t?(this.isLoading=!0,i.addClass(e).attr(e,e).prop(e,!0)):this.isLoading&&(this.isLoading=!1,i.removeClass(e).removeAttr(e).prop(e,!1))},this),0)},n.prototype.toggle=function(){var t=!0,e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var i=this.$element.find("input");"radio"==i.prop("type")?(i.prop("checked")&&(t=!1),e.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==i.prop("type")&&(i.prop("checked")!==this.$element.hasClass("active")&&(t=!1),this.$element.toggleClass("active")),i.prop("checked",this.$element.hasClass("active")),t&&i.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var t=s.fn.button;s.fn.button=i,s.fn.button.Constructor=n,s.fn.button.noConflict=function(){return s.fn.button=t,this},s(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(t){var e=s(t.target).closest(".btn");i.call(e,"toggle"),s(t.target).is('input[type="radio"], input[type="checkbox"]')||(t.preventDefault(),e.is("input,button")?e.trigger("focus"):e.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(t){s(t.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(t.type))})}(jQuery),function(p){"use strict";var c=function(t,e){this.$element=p(t),this.$indicators=this.$element.find(".carousel-indicators"),this.options=e,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",p.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",p.proxy(this.pause,this)).on("mouseleave.bs.carousel",p.proxy(this.cycle,this))};function r(n){return this.each(function(){var t=p(this),e=t.data("bs.carousel"),i=p.extend({},c.DEFAULTS,t.data(),"object"==typeof n&&n),o="string"==typeof n?n:i.slide;e||t.data("bs.carousel",e=new c(this,i)),"number"==typeof n?e.to(n):o?e[o]():i.interval&&e.pause().cycle()})}c.VERSION="3.4.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},c.prototype.cycle=function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(p.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},c.prototype.getItemForDirection=function(t,e){var i=this.getItemIndex(e);if(("prev"==t&&0===i||"next"==t&&i==this.$items.length-1)&&!this.options.wrap)return e;var o=(i+("prev"==t?-1:1))%this.$items.length;return this.$items.eq(o)},c.prototype.to=function(t){var e=this,i=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(t>this.$items.length-1||t<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(i<t?"next":"prev",this.$items.eq(t))},c.prototype.pause=function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&p.support.transition&&(this.$element.trigger(p.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(t,e){var i=this.$element.find(".item.active"),o=e||this.getItemForDirection(t,i),n=this.interval,s="next"==t?"left":"right",a=this;if(o.hasClass("active"))return this.sliding=!1;var r=o[0],l=p.Event("slide.bs.carousel",{relatedTarget:r,direction:s});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,n&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var h=p(this.$indicators.children()[this.getItemIndex(o)]);h&&h.addClass("active")}var d=p.Event("slid.bs.carousel",{relatedTarget:r,direction:s});return p.support.transition&&this.$element.hasClass("slide")?(o.addClass(t),"object"==typeof o&&o.length&&o[0].offsetWidth,i.addClass(s),o.addClass(s),i.one("bsTransitionEnd",function(){o.removeClass([t,s].join(" ")).addClass("active"),i.removeClass(["active",s].join(" ")),a.sliding=!1,setTimeout(function(){a.$element.trigger(d)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(i.removeClass("active"),o.addClass("active"),this.sliding=!1,this.$element.trigger(d)),n&&this.cycle(),this}};var t=p.fn.carousel;p.fn.carousel=r,p.fn.carousel.Constructor=c,p.fn.carousel.noConflict=function(){return p.fn.carousel=t,this};var e=function(t){var e=p(this),i=e.attr("href");i&&(i=i.replace(/.*(?=#[^\s]+$)/,""));var o=e.attr("data-target")||i,n=p(document).find(o);if(n.hasClass("carousel")){var s=p.extend({},n.data(),e.data()),a=e.attr("data-slide-to");a&&(s.interval=!1),r.call(n,s),a&&n.data("bs.carousel").to(a),t.preventDefault()}};p(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),p(window).on("load",function(){p('[data-ride="carousel"]').each(function(){var t=p(this);r.call(t,t.data())})})}(jQuery),function(a){"use strict";var r=function(t,e){this.$element=a(t),this.options=a.extend({},r.DEFAULTS,e),this.$trigger=a('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};function n(t){var e,i=t.attr("data-target")||(e=t.attr("href"))&&e.replace(/.*(?=#[^\s]+$)/,"");return a(document).find(i)}function l(o){return this.each(function(){var t=a(this),e=t.data("bs.collapse"),i=a.extend({},r.DEFAULTS,t.data(),"object"==typeof o&&o);!e&&i.toggle&&/show|hide/.test(o)&&(i.toggle=!1),e||t.data("bs.collapse",e=new r(this,i)),"string"==typeof o&&e[o]()})}r.VERSION="3.4.1",r.TRANSITION_DURATION=350,r.DEFAULTS={toggle:!0},r.prototype.dimension=function(){return this.$element.hasClass("width")?"width":"height"},r.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var t,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(t=e.data("bs.collapse"))&&t.transitioning)){var i=a.Event("show.bs.collapse");if(this.$element.trigger(i),!i.isDefaultPrevented()){e&&e.length&&(l.call(e,"hide"),t||e.data("bs.collapse",null));var o=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[o](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var n=function(){this.$element.removeClass("collapsing").addClass("collapse in")[o](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return n.call(this);var s=a.camelCase(["scroll",o].join("-"));this.$element.one("bsTransitionEnd",a.proxy(n,this)).emulateTransitionEnd(r.TRANSITION_DURATION)[o](this.$element[0][s])}}}},r.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var t=a.Event("hide.bs.collapse");if(this.$element.trigger(t),!t.isDefaultPrevented()){var e=this.dimension();this.$element[e](this.$element[e]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var i=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};if(!a.support.transition)return i.call(this);this.$element[e](0).one("bsTransitionEnd",a.proxy(i,this)).emulateTransitionEnd(r.TRANSITION_DURATION)}}},r.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},r.prototype.getParent=function(){return a(document).find(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(t,e){var i=a(e);this.addAriaAndCollapsedClass(n(i),i)},this)).end()},r.prototype.addAriaAndCollapsedClass=function(t,e){var i=t.hasClass("in");t.attr("aria-expanded",i),e.toggleClass("collapsed",!i).attr("aria-expanded",i)};var t=a.fn.collapse;a.fn.collapse=l,a.fn.collapse.Constructor=r,a.fn.collapse.noConflict=function(){return a.fn.collapse=t,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(t){var e=a(this);e.attr("data-target")||t.preventDefault();var i=n(e),o=i.data("bs.collapse")?"toggle":e.data();l.call(i,o)})}(jQuery),function(a){"use strict";var r='[data-toggle="dropdown"]',o=function(t){a(t).on("click.bs.dropdown",this.toggle)};function l(t){var e=t.attr("data-target");e||(e=(e=t.attr("href"))&&/#[A-Za-z]/.test(e)&&e.replace(/.*(?=#[^\s]*$)/,""));var i="#"!==e?a(document).find(e):null;return i&&i.length?i:t.parent()}function s(o){o&&3===o.which||(a(".dropdown-backdrop").remove(),a(r).each(function(){var t=a(this),e=l(t),i={relatedTarget:this};e.hasClass("open")&&(o&&"click"==o.type&&/input|textarea/i.test(o.target.tagName)&&a.contains(e[0],o.target)||(e.trigger(o=a.Event("hide.bs.dropdown",i)),o.isDefaultPrevented()||(t.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",i)))))})}o.VERSION="3.4.1",o.prototype.toggle=function(t){var e=a(this);if(!e.is(".disabled, :disabled")){var i=l(e),o=i.hasClass("open");if(s(),!o){"ontouchstart"in document.documentElement&&!i.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",s);var n={relatedTarget:this};if(i.trigger(t=a.Event("show.bs.dropdown",n)),t.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),i.toggleClass("open").trigger(a.Event("shown.bs.dropdown",n))}return!1}},o.prototype.keydown=function(t){if(/(38|40|27|32)/.test(t.which)&&!/input|textarea/i.test(t.target.tagName)){var e=a(this);if(t.preventDefault(),t.stopPropagation(),!e.is(".disabled, :disabled")){var i=l(e),o=i.hasClass("open");if(!o&&27!=t.which||o&&27==t.which)return 27==t.which&&i.find(r).trigger("focus"),e.trigger("click");var n=i.find(".dropdown-menu li:not(.disabled):visible a");if(n.length){var s=n.index(t.target);38==t.which&&0<s&&s--,40==t.which&&s<n.length-1&&s++,~s||(s=0),n.eq(s).trigger("focus")}}}};var t=a.fn.dropdown;a.fn.dropdown=function e(i){return this.each(function(){var t=a(this),e=t.data("bs.dropdown");e||t.data("bs.dropdown",e=new o(this)),"string"==typeof i&&e[i].call(t)})},a.fn.dropdown.Constructor=o,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=t,this},a(document).on("click.bs.dropdown.data-api",s).on("click.bs.dropdown.data-api",".dropdown form",function(t){t.stopPropagation()}).on("click.bs.dropdown.data-api",r,o.prototype.toggle).on("keydown.bs.dropdown.data-api",r,o.prototype.keydown).on("keydown.bs.dropdown.data-api",".dropdown-menu",o.prototype.keydown)}(jQuery),function(a){"use strict";var s=function(t,e){this.options=e,this.$body=a(document.body),this.$element=a(t),this.$dialog=this.$element.find(".modal-dialog"),this.$backdrop=null,this.isShown=null,this.originalBodyPad=null,this.scrollbarWidth=0,this.ignoreBackdropClick=!1,this.fixedContent=".navbar-fixed-top, .navbar-fixed-bottom",this.options.remote&&this.$element.find(".modal-content").load(this.options.remote,a.proxy(function(){this.$element.trigger("loaded.bs.modal")},this))};function r(o,n){return this.each(function(){var t=a(this),e=t.data("bs.modal"),i=a.extend({},s.DEFAULTS,t.data(),"object"==typeof o&&o);e||t.data("bs.modal",e=new s(this,i)),"string"==typeof o?e[o](n):i.show&&e.show(n)})}s.VERSION="3.4.1",s.TRANSITION_DURATION=300,s.BACKDROP_TRANSITION_DURATION=150,s.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},s.prototype.toggle=function(t){return this.isShown?this.hide():this.show(t)},s.prototype.show=function(i){var o=this,t=a.Event("show.bs.modal",{relatedTarget:i});this.$element.trigger(t),this.isShown||t.isDefaultPrevented()||(this.isShown=!0,this.checkScrollbar(),this.setScrollbar(),this.$body.addClass("modal-open"),this.escape(),this.resize(),this.$element.on("click.dismiss.bs.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.$dialog.on("mousedown.dismiss.bs.modal",function(){o.$element.one("mouseup.dismiss.bs.modal",function(t){a(t.target).is(o.$element)&&(o.ignoreBackdropClick=!0)})}),this.backdrop(function(){var t=a.support.transition&&o.$element.hasClass("fade");o.$element.parent().length||o.$element.appendTo(o.$body),o.$element.show().scrollTop(0),o.adjustDialog(),t&&o.$element[0].offsetWidth,o.$element.addClass("in"),o.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:i});t?o.$dialog.one("bsTransitionEnd",function(){o.$element.trigger("focus").trigger(e)}).emulateTransitionEnd(s.TRANSITION_DURATION):o.$element.trigger("focus").trigger(e)})},s.prototype.hide=function(t){t&&t.preventDefault(),t=a.Event("hide.bs.modal"),this.$element.trigger(t),this.isShown&&!t.isDefaultPrevented()&&(this.isShown=!1,this.escape(),this.resize(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").off("click.dismiss.bs.modal").off("mouseup.dismiss.bs.modal"),this.$dialog.off("mousedown.dismiss.bs.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one("bsTransitionEnd",a.proxy(this.hideModal,this)).emulateTransitionEnd(s.TRANSITION_DURATION):this.hideModal())},s.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(t){document===t.target||this.$element[0]===t.target||this.$element.has(t.target).length||this.$element.trigger("focus")},this))},s.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keydown.dismiss.bs.modal",a.proxy(function(t){27==t.which&&this.hide()},this)):this.isShown||this.$element.off("keydown.dismiss.bs.modal")},s.prototype.resize=function(){this.isShown?a(window).on("resize.bs.modal",a.proxy(this.handleUpdate,this)):a(window).off("resize.bs.modal")},s.prototype.hideModal=function(){var t=this;this.$element.hide(),this.backdrop(function(){t.$body.removeClass("modal-open"),t.resetAdjustments(),t.resetScrollbar(),t.$element.trigger("hidden.bs.modal")})},s.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},s.prototype.backdrop=function(t){var e=this,i=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var o=a.support.transition&&i;if(this.$backdrop=a(document.createElement("div")).addClass("modal-backdrop "+i).appendTo(this.$body),this.$element.on("click.dismiss.bs.modal",a.proxy(function(t){this.ignoreBackdropClick?this.ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus():this.hide())},this)),o&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!t)return;o?this.$backdrop.one("bsTransitionEnd",t).emulateTransitionEnd(s.BACKDROP_TRANSITION_DURATION):t()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var n=function(){e.removeBackdrop(),t&&t()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",n).emulateTransitionEnd(s.BACKDROP_TRANSITION_DURATION):n()}else t&&t()},s.prototype.handleUpdate=function(){this.adjustDialog()},s.prototype.adjustDialog=function(){var t=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},s.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},s.prototype.checkScrollbar=function(){var t=window.innerWidth;if(!t){var e=document.documentElement.getBoundingClientRect();t=e.right-Math.abs(e.left)}this.bodyIsOverflowing=document.body.clientWidth<t,this.scrollbarWidth=this.measureScrollbar()},s.prototype.setScrollbar=function(){var t=parseInt(this.$body.css("padding-right")||0,10);this.originalBodyPad=document.body.style.paddingRight||"";var n=this.scrollbarWidth;this.bodyIsOverflowing&&(this.$body.css("padding-right",t+n),a(this.fixedContent).each(function(t,e){var i=e.style.paddingRight,o=a(e).css("padding-right");a(e).data("padding-right",i).css("padding-right",parseFloat(o)+n+"px")})},s.prototype.resetScrollbar=function(){this.$body.css("padding-right",this.originalBodyPad),a(this.fixedContent).each(function(t,e){var i=a(e).data("padding-right");a(e).removeData("padding-right"),e.style.paddingRight=i||""})},s.prototype.measureScrollbar=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",this.$body.append(t);var e=t.offsetWidth-t.clientWidth;return this.$body[0].removeChild(t),e};var t=a.fn.modal;a.fn.modal=r,a.fn.modal.Constructor=s,a.fn.modal.noConflict=function(){return a.fn.modal=t,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(t){var e=a(this),i=e.attr("href"),o=e.attr("data-target")||i&&i.replace(/.*(?=#[^\s]+$)/,""),n=a(document).find(o),s=n.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(i)&&i},n.data(),e.data());e.is("a")&&t.preventDefault(),n.one("show.bs.modal",function(t){t.isDefaultPrevented()||n.one("hidden.bs.modal",function(){e.is(":visible")&&e.trigger("focus")})}),r.call(n,s,this)})}(jQuery),function(g){"use strict";var o=["sanitize","whiteList","sanitizeFn"],a=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],t={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},r=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,l=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function u(t,e){var i=t.nodeName.toLowerCase();if(-1!==g.inArray(i,e))return-1===g.inArray(i,a)||Boolean(t.nodeValue.match(r)||t.nodeValue.match(l));for(var o=g(e).filter(function(t,e){return e instanceof RegExp}),n=0,s=o.length;n<s;n++)if(i.match(o[n]))return!0;return!1}function n(t,e,i){if(0===t.length)return t;if(i&&"function"==typeof i)return i(t);if(!document.implementation||!document.implementation.createHTMLDocument)return t;var o=document.implementation.createHTMLDocument("sanitization");o.body.innerHTML=t;for(var n=g.map(e,function(t,e){return e}),s=g(o.body).find("*"),a=0,r=s.length;a<r;a++){var l=s[a],h=l.nodeName.toLowerCase();if(-1!==g.inArray(h,n))for(var d=g.map(l.attributes,function(t){return t}),p=[].concat(e["*"]||[],e[h]||[]),c=0,f=d.length;c<f;c++)u(d[c],p)||l.removeAttribute(d[c].nodeName);else l.parentNode.removeChild(l)}return o.body.innerHTML}var m=function(t,e){this.type=null,this.options=null,this.enabled=null,this.timeout=null,this.hoverState=null,this.$element=null,this.inState=null,this.init("tooltip",t,e)};m.VERSION="3.4.1",m.TRANSITION_DURATION=150,m.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0},sanitize:!0,sanitizeFn:null,whiteList:t},m.prototype.init=function(t,e,i){if(this.enabled=!0,this.type=t,this.$element=g(e),this.options=this.getOptions(i),this.$viewport=this.options.viewport&&g(document).find(g.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var o=this.options.trigger.split(" "),n=o.length;n--;){var s=o[n];if("click"==s)this.$element.on("click."+this.type,this.options.selector,g.proxy(this.toggle,this));else if("manual"!=s){var a="hover"==s?"mouseenter":"focusin",r="hover"==s?"mouseleave":"focusout";this.$element.on(a+"."+this.type,this.options.selector,g.proxy(this.enter,this)),this.$element.on(r+"."+this.type,this.options.selector,g.proxy(this.leave,this))}}this.options.selector?this._options=g.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},m.prototype.getDefaults=function(){return m.DEFAULTS},m.prototype.getOptions=function(t){var e=this.$element.data();for(var i in e)e.hasOwnProperty(i)&&-1!==g.inArray(i,o)&&delete e[i];return(t=g.extend({},this.getDefaults(),e,t)).delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t.sanitize&&(t.template=n(t.template,t.whiteList,t.sanitizeFn)),t},m.prototype.getDelegateOptions=function(){var i={},o=this.getDefaults();return this._options&&g.each(this._options,function(t,e){o[t]!=e&&(i[t]=e)}),i},m.prototype.enter=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusin"==t.type?"focus":"hover"]=!0),e.tip().hasClass("in")||"in"==e.hoverState)e.hoverState="in";else{if(clearTimeout(e.timeout),e.hoverState="in",!e.options.delay||!e.options.delay.show)return e.show();e.timeout=setTimeout(function(){"in"==e.hoverState&&e.show()},e.options.delay.show)}},m.prototype.isInStateTrue=function(){for(var t in this.inState)if(this.inState[t])return!0;return!1},m.prototype.leave=function(t){var e=t instanceof this.constructor?t:g(t.currentTarget).data("bs."+this.type);if(e||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e)),t instanceof g.Event&&(e.inState["focusout"==t.type?"focus":"hover"]=!1),!e.isInStateTrue()){if(clearTimeout(e.timeout),e.hoverState="out",!e.options.delay||!e.options.delay.hide)return e.hide();e.timeout=setTimeout(function(){"out"==e.hoverState&&e.hide()},e.options.delay.hide)}},m.prototype.show=function(){var t=g.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(t);var e=g.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(t.isDefaultPrevented()||!e)return;var i=this,o=this.tip(),n=this.getUID(this.type);this.setContent(),o.attr("id",n),this.$element.attr("aria-describedby",n),this.options.animation&&o.addClass("fade");var s="function"==typeof this.options.placement?this.options.placement.call(this,o[0],this.$element[0]):this.options.placement,a=/\s?auto?\s?/i,r=a.test(s);r&&(s=s.replace(a,"")||"top"),o.detach().css({top:0,left:0,display:"block"}).addClass(s).data("bs."+this.type,this),this.options.container?o.appendTo(g(document).find(this.options.container)):o.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var l=this.getPosition(),h=o[0].offsetWidth,d=o[0].offsetHeight;if(r){var p=s,c=this.getPosition(this.$viewport);s="bottom"==s&&l.bottom+d>c.bottom?"top":"top"==s&&l.top-d<c.top?"bottom":"right"==s&&l.right+h>c.width?"left":"left"==s&&l.left-h<c.left?"right":s,o.removeClass(p).addClass(s)}var f=this.getCalculatedOffset(s,l,h,d);this.applyPlacement(f,s);var u=function(){var t=i.hoverState;i.$element.trigger("shown.bs."+i.type),i.hoverState=null,"out"==t&&i.leave(i)};g.support.transition&&this.$tip.hasClass("fade")?o.one("bsTransitionEnd",u).emulateTransitionEnd(m.TRANSITION_DURATION):u()}},m.prototype.applyPlacement=function(t,e){var i=this.tip(),o=i[0].offsetWidth,n=i[0].offsetHeight,s=parseInt(i.css("margin-top"),10),a=parseInt(i.css("margin-left"),10);isNaN(s)&&(s=0),isNaN(a)&&(a=0),t.top+=s,t.left+=a,g.offset.setOffset(i[0],g.extend({using:function(t){i.css({top:Math.round(t.top),left:Math.round(t.left)})}},t),0),i.addClass("in");var r=i[0].offsetWidth,l=i[0].offsetHeight;"top"==e&&l!=n&&(t.top=t.top+n-l);var h=this.getViewportAdjustedDelta(e,t,r,l);h.left?t.left+=h.left:t.top+=h.top;var d=/top|bottom/.test(e),p=d?2*h.left-o+r:2*h.top-n+l,c=d?"offsetWidth":"offsetHeight";i.offset(t),this.replaceArrow(p,i[0][c],d)},m.prototype.replaceArrow=function(t,e,i){this.arrow().css(i?"left":"top",50*(1-t/e)+"%").css(i?"top":"left","")},m.prototype.setContent=function(){var t=this.tip(),e=this.getTitle();this.options.html?(this.options.sanitize&&(e=n(e,this.options.whiteList,this.options.sanitizeFn)),t.find(".tooltip-inner").html(e)):t.find(".tooltip-inner").text(e),t.removeClass("fade in top bottom left right")},m.prototype.hide=function(t){var e=this,i=g(this.$tip),o=g.Event("hide.bs."+this.type);function n(){"in"!=e.hoverState&&i.detach(),e.$element&&e.$element.removeAttr("aria-describedby").trigger("hidden.bs."+e.type),t&&t()}if(this.$element.trigger(o),!o.isDefaultPrevented())return i.removeClass("in"),g.support.transition&&i.hasClass("fade")?i.one("bsTransitionEnd",n).emulateTransitionEnd(m.TRANSITION_DURATION):n(),this.hoverState=null,this},m.prototype.fixTitle=function(){var t=this.$element;(t.attr("title")||"string"!=typeof t.attr("data-original-title"))&&t.attr("data-original-title",t.attr("title")||"").attr("title","")},m.prototype.hasContent=function(){return this.getTitle()},m.prototype.getPosition=function(t){var e=(t=t||this.$element)[0],i="BODY"==e.tagName,o=e.getBoundingClientRect();null==o.width&&(o=g.extend({},o,{width:o.right-o.left,height:o.bottom-o.top});var n=window.SVGElement&&e instanceof window.SVGElement,s=i?{top:0,left:0}:n?null:t.offset(),a={scroll:i?document.documentElement.scrollTop||document.body.scrollTop:t.scrollTop()},r=i?{width:g(window).width(),height:g(window).height()}:null;return g.extend({},o,a,r,s)},m.prototype.getCalculatedOffset=function(t,e,i,o){return"bottom"==t?{top:e.top+e.height,left:e.left+e.width/2-i/2}:"top"==t?{top:e.top-o,left:e.left+e.width/2-i/2}:"left"==t?{top:e.top+e.height/2-o/2,left:e.left-i}:{top:e.top+e.height/2-o/2,left:e.left+e.width}},m.prototype.getViewportAdjustedDelta=function(t,e,i,o){var n={top:0,left:0};if(!this.$viewport)return n;var s=this.options.viewport&&this.options.viewport.padding||0,a=this.getPosition(this.$viewport);if(/right|left/.test(t)){var r=e.top-s-a.scroll,l=e.top+s-a.scroll+o;r<a.top?n.top=a.top-r:l>a.top+a.height&&(n.top=a.top+a.height-l)}else{var h=e.left-s,d=e.left+s+i;h<a.left?n.left=a.left-h:d>a.right&&(n.left=a.left+a.width-d)}return n},m.prototype.getTitle=function(){var t=this.$element,e=this.options;return t.attr("data-original-title")||("function"==typeof e.title?e.title.call(t[0]):e.title)},m.prototype.getUID=function(t){for(;t+=~~(1e6*Math.random()),document.getElementById(t););return t},m.prototype.tip=function(){if(!this.$tip&&(this.$tip=g(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},m.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},m.prototype.enable=function(){this.enabled=!0},m.prototype.disable=function(){this.enabled=!1},m.prototype.toggleEnabled=function(){this.enabled=!this.enabled},m.prototype.toggle=function(t){var e=this;t&&((e=g(t.currentTarget).data("bs."+this.type))||(e=new this.constructor(t.currentTarget,this.getDelegateOptions()),g(t.currentTarget).data("bs."+this.type,e))),t?(e.inState.click=!e.inState.click,e.isInStateTrue()?e.enter(e):e.leave(e)):e.tip().hasClass("in")?e.leave(e):e.enter(e)},m.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type),t.$tip&&t.$tip.detach(),t.$tip=null,t.$arrow=null,t.$viewport=null,t.$element=null})},m.prototype.sanitizeHtml=function(t){return n(t,this.options.whiteList,this.options.sanitizeFn)};var e=g.fn.tooltip;g.fn.tooltip=function i(o){return this.each(function(){var t=g(this),e=t.data("bs.tooltip"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.tooltip",e=new m(this,i)),"string"==typeof o&&e[o]())})},g.fn.tooltip.Constructor=m,g.fn.tooltip.noConflict=function(){return g.fn.tooltip=e,this}}(jQuery),function(n){"use strict";var s=function(t,e){this.init("popover",t,e)};if(!n.fn.tooltip)throw new Error("Popover requires tooltip.js");s.VERSION="3.4.1",s.DEFAULTS=n.extend({},n.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),((s.prototype=n.extend({},n.fn.tooltip.Constructor.prototype)).constructor=s).prototype.getDefaults=function(){return s.DEFAULTS},s.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();if(this.options.html){var o=typeof i;this.options.sanitize&&(e=this.sanitizeHtml(e),"string"===o&&(i=this.sanitizeHtml(i))),t.find(".popover-title").html(e),t.find(".popover-content").children().detach().end()["string"===o?"html":"append"](i)}else t.find(".popover-title").text(e),t.find(".popover-content").children().detach().end().text(i);t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},s.prototype.hasContent=function(){return this.getTitle()||this.getContent()},s.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},s.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var t=n.fn.popover;n.fn.popover=function e(o){return this.each(function(){var t=n(this),e=t.data("bs.popover"),i="object"==typeof o&&o;!e&&/destroy|hide/.test(o)||(e||t.data("bs.popover",e=new s(this,i)),"string"==typeof o&&e[o]())})},n.fn.popover.Constructor=s,n.fn.popover.noConflict=function(){return n.fn.popover=t,this}}(jQuery),function(s){"use strict";function n(t,e){this.$body=s(document.body),this.$scrollElement=s(t).is(document.body)?s(window):s(t),this.options=s.extend({},n.DEFAULTS,e),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",s.proxy(this.process,this)),this.refresh(),this.process()}function e(o){return this.each(function(){var t=s(this),e=t.data("bs.scrollspy"),i="object"==typeof o&&o;e||t.data("bs.scrollspy",e=new n(this,i)),"string"==typeof o&&e[o]()})}n.VERSION="3.4.1",n.DEFAULTS={offset:10},n.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},n.prototype.refresh=function(){var t=this,o="offset",n=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),s.isWindow(this.$scrollElement[0])||(o="position",n=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var t=s(this),e=t.data("target")||t.attr("href"),i=/^#./.test(e)&&s(e);return i&&i.length&&i.is(":visible")&&[[i[o]().top+n,e]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){t.offsets.push(this[0]),t.targets.push(this[1])})},n.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),n=this.offsets,s=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),o<=e)return a!=(t=s[s.length-1])&&this.activate(t);if(a&&e<n[0])return this.activeTarget=null,this.clear();for(t=n.length;t--;)a!=s[t]&&e>=n[t]&&(n[t+1]===undefined||e<n[t+1])&&this.activate(s[t])},n.prototype.activate=function(t){this.activeTarget=t,this.clear();var e=this.selector+'[data-target="'+t+'"],'+this.selector+'[href="'+t+'"]',i=s(e).parents("li").addClass("active");i.parent(".dropdown-menu").length&&(i=i.closest("li.dropdown").addClass("active")),i.trigger("activate.bs.scrollspy")},n.prototype.clear=function(){s(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var t=s.fn.scrollspy;s.fn.scrollspy=e,s.fn.scrollspy.Constructor=n,s.fn.scrollspy.noConflict=function(){return s.fn.scrollspy=t,this},s(window).on("load.bs.scrollspy.data-api",function(){s('[data-spy="scroll"]').each(function(){var t=s(this);e.call(t,t.data())})})}(jQuery),function(r){"use strict";var a=function(t){this.element=r(t)};function e(i){return this.each(function(){var t=r(this),e=t.data("bs.tab");e||t.data("bs.tab",e=new a(this)),"string"==typeof i&&e[i]()})}a.VERSION="3.4.1",a.TRANSITION_DURATION=150,a.prototype.show=function(){var t=this.element,e=t.closest("ul:not(.dropdown-menu)"),i=t.data("target");if(i||(i=(i=t.attr("href"))&&i.replace(/.*(?=#[^\s]*$)/,"")),!t.parent("li").hasClass("active")){var o=e.find(".active:last a"),n=r.Event("hide.bs.tab",{relatedTarget:t[0]}),s=r.Event("show.bs.tab",{relatedTarget:o[0]});if(o.trigger(n),t.trigger(s),!s.isDefaultPrevented()&&!n.isDefaultPrevented()){var a=r(document).find(i);this.activate(t.closest("li"),e),this.activate(a,a.parent(),function(){o.trigger({type:"hidden.bs.tab",relatedTarget:t[0]}),t.trigger({type:"shown.bs.tab",relatedTarget:o[0]})})}}},a.prototype.activate=function(t,e,i){var o=e.find("> .active"),n=i&&r.support.transition&&(o.length&&o.hasClass("fade")||!!e.find("> .fade").length);function s(){o.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),t.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),n?(t[0].offsetWidth,t.addClass("in")):t.removeClass("fade"),t.parent(".dropdown-menu").length&&t.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),i&&i()}o.length&&n?o.one("bsTransitionEnd",s).emulateTransitionEnd(a.TRANSITION_DURATION):s(),o.removeClass("in")};var t=r.fn.tab;r.fn.tab=e,r.fn.tab.Constructor=a,r.fn.tab.noConflict=function(){return r.fn.tab=t,this};var i=function(t){t.preventDefault(),e.call(r(this),"show")};r(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',i).on("click.bs.tab.data-api",'[data-toggle="pill"]',i)}(jQuery),function(l){"use strict";var h=function(t,e){this.options=l.extend({},h.DEFAULTS,e);var i=this.options.target===h.DEFAULTS.target?l(this.options.target):l(document).find(this.options.target);this.$target=i.on("scroll.bs.affix.data-api",l.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",l.proxy(this.checkPositionWithEventLoop,this)),this.$element=l(t),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};function i(o){return this.each(function(){var t=l(this),e=t.data("bs.affix"),i="object"==typeof o&&o;e||t.data("bs.affix",e=new h(this,i)),"string"==typeof o&&e[o]()})}h.VERSION="3.4.1",h.RESET="affix affix-top affix-bottom",h.DEFAULTS={offset:0,target:window},h.prototype.getState=function(t,e,i,o){var n=this.$target.scrollTop(),s=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return n<i&&"top";if("bottom"==this.affixed)return null!=i?!(n+this.unpin<=s.top)&&"bottom":!(n+a<=t-o)&&"bottom";var r=null==this.affixed,l=r?n:s.top;return null!=i&&n<=i?"top":null!=o&&t-o<=l+(r?a:e)&&"bottom"},h.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(h.RESET).addClass("affix");var t=this.$target.scrollTop(),e=this.$element.offset();return this.pinnedOffset=e.top-t},h.prototype.checkPositionWithEventLoop=function(){setTimeout(l.proxy(this.checkPosition,this),1)},h.prototype.checkPosition=function(){if(this.$element.is(":visible")){var t=this.$element.height(),e=this.options.offset,i=e.top,o=e.bottom,n=Math.max(l(document).height(),l(document.body).height());"object"!=typeof e&&(o=i=e),"function"==typeof i&&(i=e.top(this.$element)),"function"==typeof o&&(o=e.bottom(this.$element));var s=this.getState(n,t,i,o);if(this.affixed!=s){null!=this.unpin&&this.$element.css("top","");var a="affix"+(s?"-"+s:""),r=l.Event(a+".bs.affix");if(this.$element.trigger(r),r.isDefaultPrevented())return;this.affixed=s,this.unpin="bottom"==s?this.getPinnedOffset():null,this.$element.removeClass(h.RESET).addClass(a).trigger(a.replace("affix","affixed")+".bs.affix")}"bottom"==s&&this.$element.offset({top:n-t-o})}};var t=l.fn.affix;l.fn.affix=i,l.fn.affix.Constructor=h,l.fn.affix.noConflict=function(){return l.fn.affix=t,this},l(window).on("load",function(){l('[data-spy="affix"]').each(function(){var t=l(this),e=t.data();e.offset=e.offset||{},null!=e.offsetBottom&&(e.offset.bottom=e.offsetBottom),null!=e.offsetTop&&(e.offset.top=e.offsetTop),i.call(t,e)})})}(jQuery); \ No newline at end of file
diff --git a/apidoc/vendor/diff_match_patch.min.js b/apidoc/vendor/diff_match_patch.min.js
deleted file mode 100644
index c41b5132..00000000
--- a/apidoc/vendor/diff_match_patch.min.js
+++ /dev/null
@@ -1,49 +0,0 @@
-(function(){function diff_match_patch(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=0.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=0.5;this.Patch_Margin=4;this.Match_MaxBits=32}
-diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[[0,a]]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);var f=this.diff_commonSuffix(a,b),g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,b.length-f);a=this.diff_compute_(a,
-b,e,d);c&&a.unshift([0,c]);g&&a.push([0,g]);this.diff_cleanupMerge(a);return a};
-diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[[1,b]];if(!b)return[[-1,a]];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[[1,e.substring(0,g)],[0,f],[1,e.substring(g+f.length)]],a.length>b.length&&(c[0][0]=c[2][0]=-1),c):1==f.length?[[-1,a],[1,b]]:(e=this.diff_halfMatch_(a,b))?(f=e[0],a=e[1],g=e[2],b=e[3],e=e[4],f=this.diff_main(f,g,c,d),c=this.diff_main(a,b,c,d),f.concat([[0,e]],c)):c&&100<a.length&&100<b.length?this.diff_lineMode_(a,b,
-d):this.diff_bisect_(a,b,d)};
-diff_match_patch.prototype.diff_lineMode_=function(a,b,c){var d=this.diff_linesToChars_(a,b);a=d.chars1;b=d.chars2;d=d.lineArray;a=this.diff_main(a,b,!1,c);this.diff_charsToLines_(a,d);this.diff_cleanupSemantic(a);a.push([0,""]);for(var e=d=b=0,f="",g="";b<a.length;){switch(a[b][0]){case 1:e++;g+=a[b][1];break;case -1:d++;f+=a[b][1];break;case 0:if(1<=d&&1<=e){a.splice(b-d-e,d+e);b=b-d-e;d=this.diff_main(f,g,!1,c);for(e=d.length-1;0<=e;e--)a.splice(b,0,d[e]);b+=d.length}d=e=0;g=f=""}b++}a.pop();return a};
-diff_match_patch.prototype.diff_bisect_=function(a,b,c){for(var d=a.length,e=b.length,f=Math.ceil((d+e)/2),g=f,h=2*f,j=Array(h),i=Array(h),k=0;k<h;k++)j[k]=-1,i[k]=-1;j[g+1]=0;i[g+1]=0;for(var k=d-e,q=0!=k%2,r=0,t=0,p=0,w=0,v=0;v<f&&!((new Date).getTime()>c);v++){for(var n=-v+r;n<=v-t;n+=2){var l=g+n,m;m=n==-v||n!=v&&j[l-1]<j[l+1]?j[l+1]:j[l-1]+1;for(var s=m-n;m<d&&s<e&&a.charAt(m)==b.charAt(s);)m++,s++;j[l]=m;if(m>d)t+=2;else if(s>e)r+=2;else if(q&&(l=g+k-n,0<=l&&l<h&&-1!=i[l])){var u=d-i[l];if(m>=
-u)return this.diff_bisectSplit_(a,b,m,s,c)}}for(n=-v+p;n<=v-w;n+=2){l=g+n;u=n==-v||n!=v&&i[l-1]<i[l+1]?i[l+1]:i[l-1]+1;for(m=u-n;u<d&&m<e&&a.charAt(d-u-1)==b.charAt(e-m-1);)u++,m++;i[l]=u;if(u>d)w+=2;else if(m>e)p+=2;else if(!q&&(l=g+k-n,0<=l&&(l<h&&-1!=j[l])&&(m=j[l],s=g+m-l,u=d-u,m>=u)))return this.diff_bisectSplit_(a,b,m,s,c)}}return[[-1,a],[1,b]]};
-diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
-diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,f=-1,g=d.length;f<a.length-1;){f=a.indexOf("\n",c);-1==f&&(f=a.length-1);var r=a.substring(c,f+1),c=f+1;(e.hasOwnProperty?e.hasOwnProperty(r):void 0!==e[r])?b+=String.fromCharCode(e[r]):(b+=String.fromCharCode(g),e[r]=g,d[g++]=r)}return b}var d=[],e={};d[0]="";var f=c(a),g=c(b);return{chars1:f,chars2:g,lineArray:d}};
-diff_match_patch.prototype.diff_charsToLines_=function(a,b){for(var c=0;c<a.length;c++){for(var d=a[c][1],e=[],f=0;f<d.length;f++)e[f]=b[d.charCodeAt(f)];a[c][1]=e.join("")}};diff_match_patch.prototype.diff_commonPrefix=function(a,b){if(!a||!b||a.charAt(0)!=b.charAt(0))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(f,e)==b.substring(f,e)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
-diff_match_patch.prototype.diff_commonSuffix=function(a,b){if(!a||!b||a.charAt(a.length-1)!=b.charAt(b.length-1))return 0;for(var c=0,d=Math.min(a.length,b.length),e=d,f=0;c<e;)a.substring(a.length-e,a.length-f)==b.substring(b.length-e,b.length-f)?f=c=e:d=e,e=Math.floor((d-c)/2+c);return e};
-diff_match_patch.prototype.diff_commonOverlap_=function(a,b){var c=a.length,d=b.length;if(0==c||0==d)return 0;c>d?a=a.substring(c-d):c<d&&(b=b.substring(0,c));c=Math.min(c,d);if(a==b)return c;for(var d=0,e=1;;){var f=a.substring(c-e),f=b.indexOf(f);if(-1==f)return d;e+=f;if(0==f||a.substring(c-e)==b.substring(0,e))d=e,e++}};
-diff_match_patch.prototype.diff_halfMatch_=function(a,b){function c(a,b,c){for(var d=a.substring(c,c+Math.floor(a.length/4)),e=-1,g="",h,j,n,l;-1!=(e=b.indexOf(d,e+1));){var m=f.diff_commonPrefix(a.substring(c),b.substring(e)),s=f.diff_commonSuffix(a.substring(0,c),b.substring(0,e));g.length<s+m&&(g=b.substring(e-s,e)+b.substring(e,e+m),h=a.substring(0,c-s),j=a.substring(c+m),n=b.substring(0,e-s),l=b.substring(e+m))}return 2*g.length>=a.length?[h,j,n,l,g]:null}if(0>=this.Diff_Timeout)return null;
-var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.length<d.length)return null;var f=this,g=c(d,e,Math.ceil(d.length/4)),d=c(d,e,Math.ceil(d.length/2)),h;if(!g&&!d)return null;h=d?g?g[4].length>d[4].length?g:d:d:g;var j;a.length>b.length?(g=h[0],d=h[1],e=h[2],j=h[3]):(e=h[0],j=h[1],g=h[2],d=h[3]);h=h[4];return[g,d,e,j,h]};
-diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,j=0,i=0;f<a.length;)0==a[f][0]?(c[d++]=f,g=j,h=i,i=j=0,e=a[f][1]):(1==a[f][0]?j+=a[f][1].length:i+=a[f][1].length,e&&(e.length<=Math.max(g,h)&&e.length<=Math.max(j,i))&&(a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,d--,f=0<d?c[d-1]:-1,i=j=h=g=0,e=null,b=!0)),f++;b&&this.diff_cleanupMerge(a);this.diff_cleanupSemanticLossless(a);for(f=1;f<a.length;){if(-1==a[f-1][0]&&1==a[f][0]){b=a[f-1][1];c=a[f][1];
-d=this.diff_commonOverlap_(b,c);e=this.diff_commonOverlap_(c,b);if(d>=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,[0,c.substring(0,d)]),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,[0,b.substring(0,e)]),a[f-1][0]=1,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=-1,a[f+1][1]=b.substring(e),f++;f++}f++}};
-diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_),c=g&&c.match(diff_match_patch.linebreakRegex_),d=h&&d.match(diff_match_patch.linebreakRegex_),i=c&&a.match(diff_match_patch.blanklineEndRegex_),j=d&&b.match(diff_match_patch.blanklineStartRegex_);
-return i||j?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c<a.length-1;){if(0==a[c-1][0]&&0==a[c+1][0]){var d=a[c-1][1],e=a[c][1],f=a[c+1][1],g=this.diff_commonSuffix(d,e);if(g)var h=e.substring(e.length-g),d=d.substring(0,d.length-g),e=h+e.substring(0,e.length-g),f=h+f;for(var g=d,h=e,j=f,i=b(d,e)+b(e,f);e.charAt(0)===f.charAt(0);){var d=d+e.charAt(0),e=e.substring(1)+f.charAt(0),f=f.substring(1),k=b(d,e)+b(e,f);k>=i&&(i=k,g=d,h=e,j=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-1,1),c--),a[c][1]=
-h,j?a[c+1][1]=j:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
-diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,j=!1,i=!1;f<a.length;){if(0==a[f][0])a[f][1].length<this.Diff_EditCost&&(j||i)?(c[d++]=f,g=j,h=i,e=a[f][1]):(d=0,e=null),j=i=!1;else if(-1==a[f][0]?i=!0:j=!0,e&&(g&&h&&j&&i||e.length<this.Diff_EditCost/2&&3==g+h+j+i))a.splice(c[d-1],0,[-1,e]),a[c[d-1]+1][0]=1,d--,e=null,g&&h?(j=i=!0,d=0):(d--,f=0<d?c[d-1]:-1,j=i=!1),b=!0;f++}b&&this.diff_cleanupMerge(a)};
-diff_match_patch.prototype.diff_cleanupMerge=function(a){a.push([0,""]);for(var b=0,c=0,d=0,e="",f="",g;b<a.length;)switch(a[b][0]){case 1:d++;f+=a[b][1];b++;break;case -1:c++;e+=a[b][1];b++;break;case 0:1<c+d?(0!==c&&0!==d&&(g=this.diff_commonPrefix(f,e),0!==g&&(0<b-c-d&&0==a[b-c-d-1][0]?a[b-c-d-1][1]+=f.substring(0,g):(a.splice(0,0,[0,f.substring(0,g)]),b++),f=f.substring(g),e=e.substring(g)),g=this.diff_commonSuffix(f,e),0!==g&&(a[b][1]=f.substring(f.length-g)+a[b][1],f=f.substring(0,f.length-
-g),e=e.substring(0,e.length-g))),0===c?a.splice(b-d,c+d,[1,f]):0===d?a.splice(b-c,c+d,[-1,e]):a.splice(b-c-d,c+d,[-1,e],[1,f]),b=b-c-d+(c?1:0)+(d?1:0)+1):0!==b&&0==a[b-1][0]?(a[b-1][1]+=a[b][1],a.splice(b,1)):b++,c=d=0,f=e=""}""===a[a.length-1][1]&&a.pop();c=!1;for(b=1;b<a.length-1;)0==a[b-1][0]&&0==a[b+1][0]&&(a[b][1].substring(a[b][1].length-a[b-1][1].length)==a[b-1][1]?(a[b][1]=a[b-1][1]+a[b][1].substring(0,a[b][1].length-a[b-1][1].length),a[b+1][1]=a[b-1][1]+a[b+1][1],a.splice(b-1,1),c=!0):a[b][1].substring(0,
-a[b+1][1].length)==a[b+1][1]&&(a[b-1][1]+=a[b+1][1],a[b][1]=a[b][1].substring(a[b+1][1].length)+a[b+1][1],a.splice(b+1,1),c=!0)),b++;c&&this.diff_cleanupMerge(a)};diff_match_patch.prototype.diff_xIndex=function(a,b){var c=0,d=0,e=0,f=0,g;for(g=0;g<a.length;g++){1!==a[g][0]&&(c+=a[g][1].length);-1!==a[g][0]&&(d+=a[g][1].length);if(c>b)break;e=c;f=d}return a.length!=g&&-1===a[g][0]?f:f+(b-e)};
-diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=/</g,e=/>/g,f=/\n/g,g=0;g<a.length;g++){var h=a[g][0],j=a[g][1],j=j.replace(c,"&amp;").replace(d,"&lt;").replace(e,"&gt;").replace(f,"&para;<br>");switch(h){case 1:b[g]='<ins style="background:#e6ffe6;">'+j+"</ins>";break;case -1:b[g]='<del style="background:#ffe6e6;">'+j+"</del>";break;case 0:b[g]="<span>"+j+"</span>"}}return b.join("")};
-diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;c<a.length;c++)1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_text2=function(a){for(var b=[],c=0;c<a.length;c++)-1!==a[c][0]&&(b[c]=a[c][1]);return b.join("")};diff_match_patch.prototype.diff_levenshtein=function(a){for(var b=0,c=0,d=0,e=0;e<a.length;e++){var f=a[e][0],g=a[e][1];switch(f){case 1:c+=g.length;break;case -1:d+=g.length;break;case 0:b+=Math.max(c,d),d=c=0}}return b+=Math.max(c,d)};
-diff_match_patch.prototype.diff_toDelta=function(a){for(var b=[],c=0;c<a.length;c++)switch(a[c][0]){case 1:b[c]="+"+encodeURI(a[c][1]);break;case -1:b[c]="-"+a[c][1].length;break;case 0:b[c]="="+a[c][1].length}return b.join("\t").replace(/%20/g," ")};
-diff_match_patch.prototype.diff_fromDelta=function(a,b){for(var c=[],d=0,e=0,f=b.split(/\t/g),g=0;g<f.length;g++){var h=f[g].substring(1);switch(f[g].charAt(0)){case "+":try{c[d++]=[1,decodeURI(h)]}catch(j){throw Error("Illegal escape in diff_fromDelta: "+h);}break;case "-":case "=":var i=parseInt(h,10);if(isNaN(i)||0>i)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=i);"="==f[g].charAt(0)?c[d++]=[0,h]:c[d++]=[-1,h];break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+
-f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
-diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return!f.Match_Distance?g?1:e:e+g/f.Match_Distance}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));for(var j=1<<b.length-1,h=-1,i,k,q=b.length+a.length,r,t=0;t<b.length;t++){i=0;for(k=q;i<k;)d(t,c+
-k)<=g?i=k:q=k,k=Math.floor((q-i)/2+i);q=k;i=Math.max(1,c-k+1);var p=Math.min(c+k,a.length)+b.length;k=Array(p+2);for(k[p+1]=(1<<t)-1;p>=i;p--){var w=e[a.charAt(p-1)];k[p]=0===t?(k[p+1]<<1|1)&w:(k[p+1]<<1|1)&w|((r[p+1]|r[p])<<1|1)|r[p+1];if(k[p]&j&&(w=d(t,p-1),w<=g))if(g=w,h=p-1,h>c)i=Math.max(1,2*c-h);else break}if(d(t+1,c)>g)break;r=k}return h};
-diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c<a.length;c++)b[a.charAt(c)]=0;for(c=0;c<a.length;c++)b[a.charAt(c)]|=1<<a.length-c-1;return b};
-diff_match_patch.prototype.patch_addContext_=function(a,b){if(0!=b.length){for(var c=b.substring(a.start2,a.start2+a.length1),d=0;b.indexOf(c)!=b.lastIndexOf(c)&&c.length<this.Match_MaxBits-this.Patch_Margin-this.Patch_Margin;)d+=this.Patch_Margin,c=b.substring(a.start2-d,a.start2+a.length1+d);d+=this.Patch_Margin;(c=b.substring(a.start2-d,a.start2))&&a.diffs.unshift([0,c]);(d=b.substring(a.start2+a.length1,a.start2+a.length1+d))&&a.diffs.push([0,d]);a.start1-=c.length;a.start2-=c.length;a.length1+=
-c.length+d.length;a.length2+=c.length+d.length}};
-diff_match_patch.prototype.patch_make=function(a,b,c){var d;if("string"==typeof a&&"string"==typeof b&&"undefined"==typeof c)d=a,b=this.diff_main(d,b,!0),2<b.length&&(this.diff_cleanupSemantic(b),this.diff_cleanupEfficiency(b));else if(a&&"object"==typeof a&&"undefined"==typeof b&&"undefined"==typeof c)b=a,d=this.diff_text1(b);else if("string"==typeof a&&b&&"object"==typeof b&&"undefined"==typeof c)d=a;else if("string"==typeof a&&"string"==typeof b&&c&&"object"==typeof c)d=a,b=c;else throw Error("Unknown call format to patch_make.");
-if(0===b.length)return[];c=[];a=new diff_match_patch.patch_obj;for(var e=0,f=0,g=0,h=d,j=0;j<b.length;j++){var i=b[j][0],k=b[j][1];!e&&0!==i&&(a.start1=f,a.start2=g);switch(i){case 1:a.diffs[e++]=b[j];a.length2+=k.length;d=d.substring(0,g)+k+d.substring(g);break;case -1:a.length1+=k.length;a.diffs[e++]=b[j];d=d.substring(0,g)+d.substring(g+k.length);break;case 0:k.length<=2*this.Patch_Margin&&e&&b.length!=j+1?(a.diffs[e++]=b[j],a.length1+=k.length,a.length2+=k.length):k.length>=2*this.Patch_Margin&&
-e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}1!==i&&(f+=k.length);-1!==i&&(g+=k.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;c<a.length;c++){var d=a[c],e=new diff_match_patch.patch_obj;e.diffs=[];for(var f=0;f<d.diffs.length;f++)e.diffs[f]=d.diffs[f].slice();e.start1=d.start1;e.start2=d.start2;e.length1=d.length1;e.length2=d.length2;b[c]=e}return b};
-diff_match_patch.prototype.patch_apply=function(a,b){if(0==a.length)return[b,[]];a=this.patch_deepCopy(a);var c=this.patch_addPadding(a);b=c+b+c;this.patch_splitMax(a);for(var d=0,e=[],f=0;f<a.length;f++){var g=a[f].start2+d,h=this.diff_text1(a[f].diffs),j,i=-1;if(h.length>this.Match_MaxBits){if(j=this.match_main(b,h.substring(0,this.Match_MaxBits),g),-1!=j&&(i=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==i||j>=i))j=-1}else j=this.match_main(b,h,g);
-if(-1==j)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=j-g,g=-1==i?b.substring(j,j+h.length):b.substring(j,i+this.Match_MaxBits),h==g)b=b.substring(0,j)+this.diff_text2(a[f].diffs)+b.substring(j+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);for(var h=0,k,i=0;i<a[f].diffs.length;i++){var q=a[f].diffs[i];0!==q[0]&&(k=this.diff_xIndex(g,h));1===q[0]?b=b.substring(0,
-j+k)+q[1]+b.substring(j+k):-1===q[0]&&(b=b.substring(0,j+k)+b.substring(j+this.diff_xIndex(g,h+q[1].length)));-1!==q[0]&&(h+=q[1].length)}}}b=b.substring(c.length,b.length-c.length);return[b,e]};
-diff_match_patch.prototype.patch_addPadding=function(a){for(var b=this.Patch_Margin,c="",d=1;d<=b;d++)c+=String.fromCharCode(d);for(d=0;d<a.length;d++)a[d].start1+=b,a[d].start2+=b;var d=a[0],e=d.diffs;if(0==e.length||0!=e[0][0])e.unshift([0,c]),d.start1-=b,d.start2-=b,d.length1+=b,d.length2+=b;else if(b>e[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;0==e.length||0!=e[e.length-1][0]?(e.push([0,
-c]),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
-diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c<a.length;c++)if(!(a[c].length1<=b)){var d=a[c];a.splice(c--,1);for(var e=d.start1,f=d.start2,g="";0!==d.diffs.length;){var h=new diff_match_patch.patch_obj,j=!0;h.start1=e-g.length;h.start2=f-g.length;""!==g&&(h.length1=h.length2=g.length,h.diffs.push([0,g]));for(;0!==d.diffs.length&&h.length1<b-this.Patch_Margin;){var g=d.diffs[0][0],i=d.diffs[0][1];1===g?(h.length2+=i.length,f+=i.length,h.diffs.push(d.diffs.shift()),
-j=!1):-1===g&&1==h.diffs.length&&0==h.diffs[0][0]&&i.length>2*b?(h.length1+=i.length,e+=i.length,j=!1,h.diffs.push([g,i]),d.diffs.shift()):(i=i.substring(0,b-h.length1-this.Patch_Margin),h.length1+=i.length,e+=i.length,0===g?(h.length2+=i.length,f+=i.length):j=!1,h.diffs.push([g,i]),i==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(i.length))}g=this.diff_text2(h.diffs);g=g.substring(g.length-this.Patch_Margin);i=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==i&&
-(h.length1+=i.length,h.length2+=i.length,0!==h.diffs.length&&0===h.diffs[h.diffs.length-1][0]?h.diffs[h.diffs.length-1][1]+=i:h.diffs.push([0,i]));j||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c<a.length;c++)b[c]=a[c];return b.join("")};
-diff_match_patch.prototype.patch_fromText=function(a){var b=[];if(!a)return b;a=a.split("\n");for(var c=0,d=/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@$/;c<a.length;){var e=a[c].match(d);if(!e)throw Error("Invalid patch string: "+a[c]);var f=new diff_match_patch.patch_obj;b.push(f);f.start1=parseInt(e[1],10);""===e[2]?(f.start1--,f.length1=1):"0"==e[2]?f.length1=0:(f.start1--,f.length1=parseInt(e[2],10));f.start2=parseInt(e[3],10);""===e[4]?(f.start2--,f.length2=1):"0"==e[4]?f.length2=0:(f.start2--,f.length2=
-parseInt(e[4],10));for(c++;c<a.length;){e=a[c].charAt(0);try{var g=decodeURI(a[c].substring(1))}catch(h){throw Error("Illegal escape in patch_fromText: "+g);}if("-"==e)f.diffs.push([-1,g]);else if("+"==e)f.diffs.push([1,g]);else if(" "==e)f.diffs.push([0,g]);else if("@"==e)break;else if(""!==e)throw Error('Invalid patch mode "'+e+'" in: '+g);c++}}return b};diff_match_patch.patch_obj=function(){this.diffs=[];this.start2=this.start1=null;this.length2=this.length1=0};
-diff_match_patch.patch_obj.prototype.toString=function(){var a,b;a=0===this.length1?this.start1+",0":1==this.length1?this.start1+1:this.start1+1+","+this.length1;b=0===this.length2?this.start2+",0":1==this.length2?this.start2+1:this.start2+1+","+this.length2;a=["@@ -"+a+" +"+b+" @@\n"];var c;for(b=0;b<this.diffs.length;b++){switch(this.diffs[b][0]){case 1:c="+";break;case -1:c="-";break;case 0:c=" "}a[b+1]=c+encodeURI(this.diffs[b][1])+"\n"}return a.join("").replace(/%20/g," ")};
-this.diff_match_patch=diff_match_patch;this.DIFF_DELETE=-1;this.DIFF_INSERT=1;this.DIFF_EQUAL=0;})()
diff --git a/apidoc/vendor/handlebars.min.js b/apidoc/vendor/handlebars.min.js
deleted file mode 100644
index a2b2cd5e..00000000
--- a/apidoc/vendor/handlebars.min.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/**!
-
- @license
- handlebars v4.7.7
-
-Copyright (C) 2011-2019 by Yehuda Katz
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-*/
-!function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?exports.Handlebars=b():a.Handlebars=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){"use strict";function d(){var a=r();return a.compile=function(b,c){return k.compile(b,c,a)},a.precompile=function(b,c){return k.precompile(b,c,a)},a.AST=i["default"],a.Compiler=k.Compiler,a.JavaScriptCompiler=m["default"],a.Parser=j.parser,a.parse=j.parse,a.parseWithoutProcessing=j.parseWithoutProcessing,a}var e=c(1)["default"];b.__esModule=!0;var f=c(2),g=e(f),h=c(45),i=e(h),j=c(46),k=c(51),l=c(52),m=e(l),n=c(49),o=e(n),p=c(44),q=e(p),r=g["default"].create,s=d();s.create=d,q["default"](s),s.Visitor=o["default"],s["default"]=s,b["default"]=s,a.exports=b["default"]},function(a,b){"use strict";b["default"]=function(a){return a&&a.__esModule?a:{"default":a}},b.__esModule=!0},function(a,b,c){"use strict";function d(){var a=new h.HandlebarsEnvironment;return n.extend(a,h),a.SafeString=j["default"],a.Exception=l["default"],a.Utils=n,a.escapeExpression=n.escapeExpression,a.VM=p,a.template=function(b){return p.template(b,a)},a}var e=c(3)["default"],f=c(1)["default"];b.__esModule=!0;var g=c(4),h=e(g),i=c(37),j=f(i),k=c(6),l=f(k),m=c(5),n=e(m),o=c(38),p=e(o),q=c(44),r=f(q),s=d();s.create=d,r["default"](s),s["default"]=s,b["default"]=s,a.exports=b["default"]},function(a,b){"use strict";b["default"]=function(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b},b.__esModule=!0},function(a,b,c){"use strict";function d(a,b,c){this.helpers=a||{},this.partials=b||{},this.decorators=c||{},i.registerDefaultHelpers(this),j.registerDefaultDecorators(this)}var e=c(1)["default"];b.__esModule=!0,b.HandlebarsEnvironment=d;var f=c(5),g=c(6),h=e(g),i=c(10),j=c(30),k=c(32),l=e(k),m=c(33),n="4.7.7";b.VERSION=n;var o=8;b.COMPILER_REVISION=o;var p=7;b.LAST_COMPATIBLE_COMPILER_REVISION=p;var q={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1",7:">= 4.0.0 <4.3.0",8:">= 4.3.0"};b.REVISION_CHANGES=q;var r="[object Object]";d.prototype={constructor:d,logger:l["default"],log:l["default"].log,registerHelper:function(a,b){if(f.toString.call(a)===r){if(b)throw new h["default"]("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){if(f.toString.call(a)===r)f.extend(this.partials,a);else{if("undefined"==typeof b)throw new h["default"]('Attempting to register a partial called "'+a+'" as undefined');this.partials[a]=b}},unregisterPartial:function(a){delete this.partials[a]},registerDecorator:function(a,b){if(f.toString.call(a)===r){if(b)throw new h["default"]("Arg not supported with multiple decorators");f.extend(this.decorators,a)}else this.decorators[a]=b},unregisterDecorator:function(a){delete this.decorators[a]},resetLoggedPropertyAccesses:function(){m.resetLoggedProperties()}};var s=l["default"].log;b.log=s,b.createFrame=f.createFrame,b.logger=l["default"]},function(a,b){"use strict";function c(a){return k[a]}function d(a){for(var b=1;b<arguments.length;b++)for(var c in arguments[b])Object.prototype.hasOwnProperty.call(arguments[b],c)&&(a[c]=arguments[b][c]);return a}function e(a,b){for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1}function f(a){if("string"!=typeof a){if(a&&a.toHTML)return a.toHTML();if(null==a)return"";if(!a)return a+"";a=""+a}return m.test(a)?a.replace(l,c):a}function g(a){return!a&&0!==a||!(!p(a)||0!==a.length)}function h(a){var b=d({},a);return b._parent=a,b}function i(a,b){return a.path=b,a}function j(a,b){return(a?a+".":"")+b}b.__esModule=!0,b.extend=d,b.indexOf=e,b.escapeExpression=f,b.isEmpty=g,b.createFrame=h,b.blockParams=i,b.appendContextPath=j;var k={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;","=":"&#x3D;"},l=/[&<>"'`=]/g,m=/[&<>"'`=]/,n=Object.prototype.toString;b.toString=n;var o=function(a){return"function"==typeof a};o(/x/)&&(b.isFunction=o=function(a){return"function"==typeof a&&"[object Function]"===n.call(a)}),b.isFunction=o;var p=Array.isArray||function(a){return!(!a||"object"!=typeof a)&&"[object Array]"===n.call(a)};b.isArray=p},function(a,b,c){"use strict";function d(a,b){var c=b&&b.loc,g=void 0,h=void 0,i=void 0,j=void 0;c&&(g=c.start.line,h=c.end.line,i=c.start.column,j=c.end.column,a+=" - "+g+":"+i);for(var k=Error.prototype.constructor.call(this,a),l=0;l<f.length;l++)this[f[l]]=k[f[l]];Error.captureStackTrace&&Error.captureStackTrace(this,d);try{c&&(this.lineNumber=g,this.endLineNumber=h,e?(Object.defineProperty(this,"column",{value:i,enumerable:!0}),Object.defineProperty(this,"endColumn",{value:j,enumerable:!0}):(this.column=i,this.endColumn=j))}catch(m){}}var e=c(7)["default"];b.__esModule=!0;var f=["description","fileName","lineNumber","endLineNumber","message","name","number","stack"];d.prototype=new Error,b["default"]=d,a.exports=b["default"]},function(a,b,c){a.exports={"default":c(8),__esModule:!0}},function(a,b,c){var d=c(9);a.exports=function(a,b,c){return d.setDesc(a,b,c)}},function(a,b){var c=Object;a.exports={create:c.create,getProto:c.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:c.getOwnPropertyDescriptor,setDesc:c.defineProperty,setDescs:c.defineProperties,getKeys:c.keys,getNames:c.getOwnPropertyNames,getSymbols:c.getOwnPropertySymbols,each:[].forEach}},function(a,b,c){"use strict";function d(a){h["default"](a),j["default"](a),l["default"](a),n["default"](a),p["default"](a),r["default"](a),t["default"](a)}function e(a,b,c){a.helpers[b]&&(a.hooks[b]=a.helpers[b],c||delete a.helpers[b])}var f=c(1)["default"];b.__esModule=!0,b.registerDefaultHelpers=d,b.moveHelperToHooks=e;var g=c(11),h=f(g),i=c(12),j=f(i),k=c(25),l=f(k),m=c(26),n=f(m),o=c(27),p=f(o),q=c(28),r=f(q),s=c(29),t=f(s)},function(a,b,c){"use strict";b.__esModule=!0;var d=c(5);b["default"]=function(a){a.registerHelper("blockHelperMissing",function(b,c){var e=c.inverse,f=c.fn;if(b===!0)return f(this);if(b===!1||null==b)return e(this);if(d.isArray(b))return b.length>0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):e(this);if(c.data&&c.ids){var g=d.createFrame(c.data);g.contextPath=d.appendContextPath(c.data.contextPath,c.name),c={data:g}}return f(b,c)})},a.exports=b["default"]},function(a,b,c){(function(d){"use strict";var e=c(13)["default"],f=c(1)["default"];b.__esModule=!0;var g=c(5),h=c(6),i=f(h);b["default"]=function(a){a.registerHelper("each",function(a,b){function c(b,c,d){l&&(l.key=b,l.index=c,l.first=0===c,l.last=!!d,m&&(l.contextPath=m+b)),k+=f(a[b],{data:l,blockParams:g.blockParams([a[b],b],[m+b,null])})}if(!b)throw new i["default"]("Must pass iterator to #each");var f=b.fn,h=b.inverse,j=0,k="",l=void 0,m=void 0;if(b.data&&b.ids&&(m=g.appendContextPath(b.data.contextPath,b.ids[0])+"."),g.isFunction(a)&&(a=a.call(this)),b.data&&(l=g.createFrame(b.data)),a&&"object"==typeof a)if(g.isArray(a))for(var n=a.length;j<n;j++)j in a&&c(j,j,j===a.length-1);else if(d.Symbol&&a[d.Symbol.iterator]){for(var o=[],p=a[d.Symbol.iterator](),q=p.next();!q.done;q=p.next())o.push(q.value);a=o;for(var n=a.length;j<n;j++)c(j,j,j===a.length-1)}else!function(){var b=void 0;e(a).forEach(function(a){void 0!==b&&c(b,j-1),b=a,j++}),void 0!==b&&c(b,j-1,!0)}();return 0===j&&(k=h(this)),k})},a.exports=b["default"]}).call(b,function(){return this}())},function(a,b,c){a.exports={"default":c(14),__esModule:!0}},function(a,b,c){c(15),a.exports=c(21).Object.keys},function(a,b,c){var d=c(16);c(18)("keys",function(a){return function(b){return a(d(b))}})},function(a,b,c){var d=c(17);a.exports=function(a){return Object(d(a))}},function(a,b){a.exports=function(a){if(void 0==a)throw TypeError("Can't call method on "+a);return a}},function(a,b,c){var d=c(19),e=c(21),f=c(24);a.exports=function(a,b){var c=(e.Object||{})[a]||Object[a],g={};g[a]=b(c),d(d.S+d.F*f(function(){c(1)}),"Object",g)}},function(a,b,c){var d=c(20),e=c(21),f=c(22),g="prototype",h=function(a,b,c){var i,j,k,l=a&h.F,m=a&h.G,n=a&h.S,o=a&h.P,p=a&h.B,q=a&h.W,r=m?e:e[b]||(e[b]={}),s=m?d:n?d[b]:(d[b]||{})[g];m&&(c=b);for(i in c)j=!l&&s&&i in s,j&&i in r||(k=j?s[i]:c[i],r[i]=m&&"function"!=typeof s[i]?c[i]:p&&j?f(k,d):q&&s[i]==k?function(a){var b=function(b){return this instanceof a?new a(b):a(b)};return b[g]=a[g],b}(k):o&&"function"==typeof k?f(Function.call,k):k,o&&((r[g]||(r[g]={})[i]=k))};h.F=1,h.G=2,h.S=4,h.P=8,h.B=16,h.W=32,a.exports=h},function(a,b){var c=a.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=c)},function(a,b){var c=a.exports={version:"1.2.6"};"number"==typeof __e&&(__e=c)},function(a,b,c){var d=c(23);a.exports=function(a,b,c){if(d(a),void 0===b)return a;switch(c){case 1:return function(c){return a.call(b,c)};case 2:return function(c,d){return a.call(b,c,d)};case 3:return function(c,d,e){return a.call(b,c,d,e)}}return function(){return a.apply(b,arguments)}}},function(a,b){a.exports=function(a){if("function"!=typeof a)throw TypeError(a+" is not a function!");return a}},function(a,b){a.exports=function(a){try{return!!a()}catch(b){return!0}}},function(a,b,c){"use strict";var d=c(1)["default"];b.__esModule=!0;var e=c(6),f=d(e);b["default"]=function(a){a.registerHelper("helperMissing",function(){if(1!==arguments.length)throw new f["default"]('Missing helper: "'+arguments[arguments.length-1].name+'"')})},a.exports=b["default"]},function(a,b,c){"use strict";var d=c(1)["default"];b.__esModule=!0;var e=c(5),f=c(6),g=d(f);b["default"]=function(a){a.registerHelper("if",function(a,b){if(2!=arguments.length)throw new g["default"]("#if requires exactly one argument");return e.isFunction(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||e.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper("unless",function(b,c){if(2!=arguments.length)throw new g["default"]("#unless requires exactly one argument");return a.helpers["if"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})})},a.exports=b["default"]},function(a,b){"use strict";b.__esModule=!0,b["default"]=function(a){a.registerHelper("log",function(){for(var b=[void 0],c=arguments[arguments.length-1],d=0;d<arguments.length-1;d++)b.push(arguments[d]);var e=1;null!=c.hash.level?e=c.hash.level:c.data&&null!=c.data.level&&(e=c.data.level),b[0]=e,a.log.apply(a,b)})},a.exports=b["default"]},function(a,b){"use strict";b.__esModule=!0,b["default"]=function(a){a.registerHelper("lookup",function(a,b,c){return a?c.lookupProperty(a,b):a})},a.exports=b["default"]},function(a,b,c){"use strict";var d=c(1)["default"];b.__esModule=!0;var e=c(5),f=c(6),g=d(f);b["default"]=function(a){a.registerHelper("with",function(a,b){if(2!=arguments.length)throw new g["default"]("#with requires exactly one argument");e.isFunction(a)&&(a=a.call(this));var c=b.fn;if(e.isEmpty(a))return b.inverse(this);var d=b.data;return b.data&&b.ids&&(d=e.createFrame(b.data),d.contextPath=e.appendContextPath(b.data.contextPath,b.ids[0])),c(a,{data:d,blockParams:e.blockParams([a],[d&&d.contextPath])})})},a.exports=b["default"]},function(a,b,c){"use strict";function d(a){g["default"](a)}var e=c(1)["default"];b.__esModule=!0,b.registerDefaultDecorators=d;var f=c(31),g=e(f)},function(a,b,c){"use strict";b.__esModule=!0;var d=c(5);b["default"]=function(a){a.registerDecorator("inline",function(a,b,c,e){var f=a;return b.partials||(b.partials={},f=function(e,f){var g=c.partials;c.partials=d.extend({},g,b.partials);var h=a(e,f);return c.partials=g,h}),b.partials[e.args[0]]=e.fn,f})},a.exports=b["default"]},function(a,b,c){"use strict";b.__esModule=!0;var d=c(5),e={methodMap:["debug","info","warn","error"],level:"info",lookupLevel:function(a){if("string"==typeof a){var b=d.indexOf(e.methodMap,a.toLowerCase());a=b>=0?b:parseInt(a,10)}return a},log:function(a){if(a=e.lookupLevel(a),"undefined"!=typeof console&&e.lookupLevel(e.level)<=a){var b=e.methodMap[a];console[b]||(b="log");for(var c=arguments.length,d=Array(c>1?c-1:0),f=1;f<c;f++)d[f-1]=arguments[f];console[b].apply(console,d)}}};b["default"]=e,a.exports=b["default"]},function(a,b,c){"use strict";function d(a){var b=i(null);b.constructor=!1,b.__defineGetter__=!1,b.__defineSetter__=!1,b.__lookupGetter__=!1;var c=i(null);return c.__proto__=!1,{properties:{whitelist:l.createNewLookupObject(c,a.allowedProtoProperties),defaultValue:a.allowProtoPropertiesByDefault},methods:{whitelist:l.createNewLookupObject(b,a.allowedProtoMethods),defaultValue:a.allowProtoMethodsByDefault}}}function e(a,b,c){return"function"==typeof a?f(b.methods,c):f(b.properties,c)}function f(a,b){return void 0!==a.whitelist[b]?a.whitelist[b]===!0:void 0!==a.defaultValue?a.defaultValue:(g(b),!1)}function g(a){o[a]!==!0&&(o[a]=!0,n.log("error",'Handlebars: Access has been denied to resolve the property "'+a+'" because it is not an "own property" of its parent.\nYou can add a runtime option to disable the check or this warning:\nSee https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details'))}function h(){j(o).forEach(function(a){delete o[a]})}var i=c(34)["default"],j=c(13)["default"],k=c(3)["default"];b.__esModule=!0,b.createProtoAccessControl=d,b.resultIsAllowed=e,b.resetLoggedProperties=h;var l=c(36),m=c(32),n=k(m),o=i(null)},function(a,b,c){a.exports={"default":c(35),__esModule:!0}},function(a,b,c){var d=c(9);a.exports=function(a,b){return d.create(a,b)}},function(a,b,c){"use strict";function d(){for(var a=arguments.length,b=Array(a),c=0;c<a;c++)b[c]=arguments[c];return f.extend.apply(void 0,[e(null)].concat(b))}var e=c(34)["default"];b.__esModule=!0,b.createNewLookupObject=d;var f=c(5)},function(a,b){"use strict";function c(a){this.string=a}b.__esModule=!0,c.prototype.toString=c.prototype.toHTML=function(){return""+this.string},b["default"]=c,a.exports=b["default"]},function(a,b,c){"use strict";function d(a){var b=a&&a[0]||1,c=v.COMPILER_REVISION;if(!(b>=v.LAST_COMPATIBLE_COMPILER_REVISION&&b<=v.COMPILER_REVISION)){if(b<v.LAST_COMPATIBLE_COMPILER_REVISION){var d=v.REVISION_CHANGES[c],e=v.REVISION_CHANGES[b];throw new u["default"]("Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version ("+d+") or downgrade your runtime to an older version ("+e+").")}throw new u["default"]("Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version ("+a[1]+").")}}function e(a,b){function c(c,d,e){e.hash&&(d=s.extend({},d,e.hash),e.ids&&(e.ids[0]=!0)),c=b.VM.resolvePartial.call(this,c,d,e);var f=s.extend({},e,{hooks:this.hooks,protoAccessControl:this.protoAccessControl}),g=b.VM.invokePartial.call(this,c,d,f);if(null==g&&b.compile&&(e.partials[e.name]=b.compile(c,a.compilerOptions,b),g=e.partials[e.name](d,f)),null!=g){if(e.indent){for(var h=g.split("\n"),i=0,j=h.length;i<j&&(h[i]||i+1!==j);i++)h[i]=e.indent+h[i];g=h.join("\n")}return g}throw new u["default"]("The partial "+e.name+" could not be compiled when running in runtime-only mode")}function d(b){function c(b){return""+a.main(g,b,g.helpers,g.partials,f,i,h)}var e=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],f=e.data;d._setup(e),!e.partial&&a.useData&&(f=j(b,f));var h=void 0,i=a.useBlockParams?[]:void 0;return a.useDepths&&(h=e.depths?b!=e.depths[0]?[b].concat(e.depths):e.depths:[b]),(c=k(a.main,c,g,e.depths||[],f,i))(b,e)}if(!b)throw new u["default"]("No environment passed to template");if(!a||!a.main)throw new u["default"]("Unknown template object: "+typeof a);a.main.decorator=a.main_d,b.VM.checkRevision(a.compiler);var e=a.compiler&&7===a.compiler[0],g={strict:function(a,b,c){if(!(a&&b in a))throw new u["default"]('"'+b+'" not defined in '+a,{loc:c});return g.lookupProperty(a,b)},lookupProperty:function(a,b){var c=a[b];return null==c?c:Object.prototype.hasOwnProperty.call(a,b)?c:y.resultIsAllowed(c,g.protoAccessControl,b)?c:void 0},lookup:function(a,b){for(var c=a.length,d=0;d<c;d++){var e=a[d]&&g.lookupProperty(a[d],b);if(null!=e)return a[d][b]}},lambda:function(a,b){return"function"==typeof a?a.call(b):a},escapeExpression:s.escapeExpression,invokePartial:c,fn:function(b){var c=a[b];return c.decorator=a[b+"_d"],c},programs:[],program:function(a,b,c,d,e){var g=this.programs[a],h=this.fn(a);return b||e||d||c?g=f(this,a,h,b,c,d,e):g||(g=this.programs[a]=f(this,a,h)),g},data:function(a,b){for(;a&&b--;)a=a._parent;return a},mergeIfNeeded:function(a,b){var c=a||b;return a&&b&&a!==b&&(c=s.extend({},b,a)),c},nullContext:n({}),noop:b.VM.noop,compilerInfo:a.compiler};return d.isTop=!0,d._setup=function(c){if(c.partial)g.protoAccessControl=c.protoAccessControl,g.helpers=c.helpers,g.partials=c.partials,g.decorators=c.decorators,g.hooks=c.hooks;else{var d=s.extend({},b.helpers,c.helpers);l(d,g),g.helpers=d,a.usePartial&&(g.partials=g.mergeIfNeeded(c.partials,b.partials)),(a.usePartial||a.useDecorators)&&(g.decorators=s.extend({},b.decorators,c.decorators)),g.hooks={},g.protoAccessControl=y.createProtoAccessControl(c);var f=c.allowCallsToHelperMissing||e;w.moveHelperToHooks(g,"helperMissing",f),w.moveHelperToHooks(g,"blockHelperMissing",f)}},d._child=function(b,c,d,e){if(a.useBlockParams&&!d)throw new u["default"]("must pass block params");if(a.useDepths&&!e)throw new u["default"]("must pass parent depths");return f(g,b,a[b],c,0,d,e)},d}function f(a,b,c,d,e,f,g){function h(b){var e=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],h=g;return!g||b==g[0]||b===a.nullContext&&null===g[0]||(h=[b].concat(g)),c(a,b,a.helpers,a.partials,e.data||d,f&&[e.blockParams].concat(f),h)}return h=k(c,h,a,g,d,f),h.program=b,h.depth=g?g.length:0,h.blockParams=e||0,h}function g(a,b,c){return a?a.call||c.name||(c.name=a,a=c.partials[a]):a="@partial-block"===c.name?c.data["partial-block"]:c.partials[c.name],a}function h(a,b,c){var d=c.data&&c.data["partial-block"];c.partial=!0,c.ids&&(c.data.contextPath=c.ids[0]||c.data.contextPath);var e=void 0;if(c.fn&&c.fn!==i&&!function(){c.data=v.createFrame(c.data);var a=c.fn;e=c.data["partial-block"]=function(b){var c=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];return c.data=v.createFrame(c.data),c.data["partial-block"]=d,a(b,c)},a.partials&&(c.partials=s.extend({},c.partials,a.partials))}(),void 0===a&&e&&(a=e),void 0===a)throw new u["default"]("The partial "+c.name+" could not be found");if(a instanceof Function)return a(b,c)}function i(){return""}function j(a,b){return b&&"root"in b||(b=b?v.createFrame(b):{},b.root=a),b}function k(a,b,c,d,e,f){if(a.decorator){var g={};b=a.decorator(b,g,c,d&&d[0],e,f,d),s.extend(b,g)}return b}function l(a,b){o(a).forEach(function(c){var d=a[c];a[c]=m(d,b)})}function m(a,b){var c=b.lookupProperty;return x.wrapHelper(a,function(a){return s.extend({lookupProperty:c},a)})}var n=c(39)["default"],o=c(13)["default"],p=c(3)["default"],q=c(1)["default"];b.__esModule=!0,b.checkRevision=d,b.template=e,b.wrapProgram=f,b.resolvePartial=g,b.invokePartial=h,b.noop=i;var r=c(5),s=p(r),t=c(6),u=q(t),v=c(4),w=c(10),x=c(43),y=c(33)},function(a,b,c){a.exports={"default":c(40),__esModule:!0}},function(a,b,c){c(41),a.exports=c(21).Object.seal},function(a,b,c){var d=c(42);c(18)("seal",function(a){return function(b){return a&&d(b)?a(b):b}})},function(a,b){a.exports=function(a){return"object"==typeof a?null!==a:"function"==typeof a}},function(a,b){"use strict";function c(a,b){if("function"!=typeof a)return a;var c=function(){var c=arguments[arguments.length-1];return arguments[arguments.length-1]=b(c),a.apply(this,arguments)};return c}b.__esModule=!0,b.wrapHelper=c},function(a,b){(function(c){"use strict";b.__esModule=!0,b["default"]=function(a){var b="undefined"!=typeof c?c:window,d=b.Handlebars;a.noConflict=function(){return b.Handlebars===a&&(b.Handlebars=d),a}},a.exports=b["default"]}).call(b,function(){return this}())},function(a,b){"use strict";b.__esModule=!0;var c={helpers:{helperExpression:function(a){return"SubExpression"===a.type||("MustacheStatement"===a.type||"BlockStatement"===a.type)&&!!(a.params&&a.params.length||a.hash)},scopedId:function(a){return/^\.|this\b/.test(a.original)},simpleId:function(a){return 1===a.parts.length&&!c.helpers.scopedId(a)&&!a.depth}}};b["default"]=c,a.exports=b["default"]},function(a,b,c){"use strict";function d(a,b){if("Program"===a.type)return a;i["default"].yy=o,o.locInfo=function(a){return new o.SourceLocation(b&&b.srcName,a)};var c=i["default"].parse(a);return c}function e(a,b){var c=d(a,b),e=new k["default"](b);return e.accept(c)}var f=c(1)["default"],g=c(3)["default"];b.__esModule=!0,b.parseWithoutProcessing=d,b.parse=e;var h=c(47),i=f(h),j=c(48),k=f(j),l=c(50),m=g(l),n=c(5);b.parser=i["default"];var o={};n.extend(o,m)},function(a,b){"use strict";b.__esModule=!0;var c=function(){function a(){this.yy={}}var b={trace:function(){},yy:{},symbols_:{error:2,root:3,program:4,EOF:5,program_repetition0:6,statement:7,mustache:8,block:9,rawBlock:10,partial:11,partialBlock:12,content:13,COMMENT:14,CONTENT:15,openRawBlock:16,rawBlock_repetition0:17,END_RAW_BLOCK:18,OPEN_RAW_BLOCK:19,helperName:20,openRawBlock_repetition0:21,openRawBlock_option0:22,CLOSE_RAW_BLOCK:23,openBlock:24,block_option0:25,closeBlock:26,openInverse:27,block_option1:28,OPEN_BLOCK:29,openBlock_repetition0:30,openBlock_option0:31,openBlock_option1:32,CLOSE:33,OPEN_INVERSE:34,openInverse_repetition0:35,openInverse_option0:36,openInverse_option1:37,openInverseChain:38,OPEN_INVERSE_CHAIN:39,openInverseChain_repetition0:40,openInverseChain_option0:41,openInverseChain_option1:42,inverseAndProgram:43,INVERSE:44,inverseChain:45,inverseChain_option0:46,OPEN_ENDBLOCK:47,OPEN:48,mustache_repetition0:49,mustache_option0:50,OPEN_UNESCAPED:51,mustache_repetition1:52,mustache_option1:53,CLOSE_UNESCAPED:54,OPEN_PARTIAL:55,partialName:56,partial_repetition0:57,partial_option0:58,openPartialBlock:59,OPEN_PARTIAL_BLOCK:60,openPartialBlock_repetition0:61,openPartialBlock_option0:62,param:63,sexpr:64,OPEN_SEXPR:65,sexpr_repetition0:66,sexpr_option0:67,CLOSE_SEXPR:68,hash:69,hash_repetition_plus0:70,hashSegment:71,ID:72,EQUALS:73,blockParams:74,OPEN_BLOCK_PARAMS:75,blockParams_repetition_plus0:76,CLOSE_BLOCK_PARAMS:77,path:78,dataName:79,STRING:80,NUMBER:81,BOOLEAN:82,UNDEFINED:83,NULL:84,DATA:85,pathSegments:86,SEP:87,$accept:0,$end:1},terminals_:{2:"error",5:"EOF",14:"COMMENT",15:"CONTENT",18:"END_RAW_BLOCK",19:"OPEN_RAW_BLOCK",23:"CLOSE_RAW_BLOCK",29:"OPEN_BLOCK",33:"CLOSE",34:"OPEN_INVERSE",39:"OPEN_INVERSE_CHAIN",44:"INVERSE",47:"OPEN_ENDBLOCK",48:"OPEN",51:"OPEN_UNESCAPED",54:"CLOSE_UNESCAPED",55:"OPEN_PARTIAL",60:"OPEN_PARTIAL_BLOCK",65:"OPEN_SEXPR",68:"CLOSE_SEXPR",72:"ID",73:"EQUALS",75:"OPEN_BLOCK_PARAMS",77:"CLOSE_BLOCK_PARAMS",80:"STRING",81:"NUMBER",82:"BOOLEAN",83:"UNDEFINED",84:"NULL",85:"DATA",87:"SEP"},productions_:[0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[13,1],[10,3],[16,5],[9,4],[9,4],[24,6],[27,6],[38,6],[43,2],[45,3],[45,1],[26,3],[8,5],[8,5],[11,5],[12,3],[59,5],[63,1],[63,1],[64,5],[69,1],[71,3],[74,3],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[20,1],[56,1],[56,1],[79,2],[78,1],[86,3],[86,1],[6,0],[6,2],[17,0],[17,2],[21,0],[21,2],[22,0],[22,1],[25,0],[25,1],[28,0],[28,1],[30,0],[30,2],[31,0],[31,1],[32,0],[32,1],[35,0],[35,2],[36,0],[36,1],[37,0],[37,1],[40,0],[40,2],[41,0],[41,1],[42,0],[42,1],[46,0],[46,1],[49,0],[49,2],[50,0],[50,1],[52,0],[52,2],[53,0],[53,1],[57,0],[57,2],[58,0],[58,1],[61,0],[61,2],[62,0],[62,1],[66,0],[66,2],[67,0],[67,1],[70,1],[70,2],[76,1],[76,2]],performAction:function(a,b,c,d,e,f,g){var h=f.length-1;switch(e){case 1:return f[h-1];case 2:this.$=d.prepareProgram(f[h]);break;case 3:this.$=f[h];break;case 4:this.$=f[h];break;case 5:this.$=f[h];break;case 6:this.$=f[h];break;case 7:this.$=f[h];break;case 8:this.$=f[h];break;case 9:this.$={type:"CommentStatement",value:d.stripComment(f[h]),strip:d.stripFlags(f[h],f[h]),loc:d.locInfo(this._$)};break;case 10:this.$={type:"ContentStatement",original:f[h],value:f[h],loc:d.locInfo(this._$)};break;case 11:this.$=d.prepareRawBlock(f[h-2],f[h-1],f[h],this._$);break;case 12:this.$={path:f[h-3],params:f[h-2],hash:f[h-1]};break;case 13:this.$=d.prepareBlock(f[h-3],f[h-2],f[h-1],f[h],!1,this._$);break;case 14:this.$=d.prepareBlock(f[h-3],f[h-2],f[h-1],f[h],!0,this._$);break;case 15:this.$={open:f[h-5],path:f[h-4],params:f[h-3],hash:f[h-2],blockParams:f[h-1],strip:d.stripFlags(f[h-5],f[h])};break;case 16:this.$={path:f[h-4],params:f[h-3],hash:f[h-2],blockParams:f[h-1],strip:d.stripFlags(f[h-5],f[h])};break;case 17:this.$={path:f[h-4],params:f[h-3],hash:f[h-2],blockParams:f[h-1],strip:d.stripFlags(f[h-5],f[h])};break;case 18:this.$={strip:d.stripFlags(f[h-1],f[h-1]),program:f[h]};break;case 19:var i=d.prepareBlock(f[h-2],f[h-1],f[h],f[h],!1,this._$),j=d.prepareProgram([i],f[h-1].loc);j.chained=!0,this.$={strip:f[h-2].strip,program:j,chain:!0};break;case 20:this.$=f[h];break;case 21:this.$={path:f[h-1],strip:d.stripFlags(f[h-2],f[h])};break;case 22:this.$=d.prepareMustache(f[h-3],f[h-2],f[h-1],f[h-4],d.stripFlags(f[h-4],f[h]),this._$);break;case 23:this.$=d.prepareMustache(f[h-3],f[h-2],f[h-1],f[h-4],d.stripFlags(f[h-4],f[h]),this._$);break;case 24:this.$={type:"PartialStatement",name:f[h-3],params:f[h-2],hash:f[h-1],indent:"",strip:d.stripFlags(f[h-4],f[h]),loc:d.locInfo(this._$)};break;case 25:this.$=d.preparePartialBlock(f[h-2],f[h-1],f[h],this._$);break;case 26:this.$={path:f[h-3],params:f[h-2],hash:f[h-1],strip:d.stripFlags(f[h-4],f[h])};break;case 27:this.$=f[h];break;case 28:this.$=f[h];break;case 29:this.$={type:"SubExpression",path:f[h-3],params:f[h-2],hash:f[h-1],loc:d.locInfo(this._$)};break;case 30:this.$={type:"Hash",pairs:f[h],loc:d.locInfo(this._$)};break;case 31:this.$={type:"HashPair",key:d.id(f[h-2]),value:f[h],loc:d.locInfo(this._$)};break;case 32:this.$=d.id(f[h-1]);break;case 33:this.$=f[h];break;case 34:this.$=f[h];break;case 35:this.$={type:"StringLiteral",value:f[h],original:f[h],loc:d.locInfo(this._$)};break;case 36:this.$={type:"NumberLiteral",value:Number(f[h]),original:Number(f[h]),loc:d.locInfo(this._$)};break;case 37:this.$={type:"BooleanLiteral",value:"true"===f[h],original:"true"===f[h],loc:d.locInfo(this._$)};break;case 38:this.$={type:"UndefinedLiteral",original:void 0,value:void 0,loc:d.locInfo(this._$)};break;case 39:this.$={type:"NullLiteral",original:null,value:null,loc:d.locInfo(this._$)};break;case 40:this.$=f[h];break;case 41:this.$=f[h];break;case 42:this.$=d.preparePath(!0,f[h],this._$);break;case 43:this.$=d.preparePath(!1,f[h],this._$);break;case 44:f[h-2].push({part:d.id(f[h]),original:f[h],separator:f[h-1]}),this.$=f[h-2];break;case 45:this.$=[{part:d.id(f[h]),original:f[h]}];break;case 46:this.$=[];break;case 47:f[h-1].push(f[h]);break;case 48:this.$=[];break;case 49:f[h-1].push(f[h]);break;case 50:this.$=[];break;case 51:f[h-1].push(f[h]);break;case 58:this.$=[];break;case 59:f[h-1].push(f[h]);break;case 64:this.$=[];break;case 65:f[h-1].push(f[h]);break;case 70:this.$=[];break;case 71:f[h-1].push(f[h]);break;case 78:this.$=[];break;case 79:f[h-1].push(f[h]);break;case 82:this.$=[];break;case 83:f[h-1].push(f[h]);break;case 86:this.$=[];break;case 87:f[h-1].push(f[h]);break;case 90:this.$=[];break;case 91:f[h-1].push(f[h]);break;case 94:this.$=[];break;case 95:f[h-1].push(f[h]);break;case 98:this.$=[f[h]];break;case 99:f[h-1].push(f[h]);break;case 100:this.$=[f[h]];break;case 101:f[h-1].push(f[h])}},table:[{3:1,4:2,5:[2,46],6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:10,13:11,14:[1,12],15:[1,20],16:17,19:[1,23],24:15,27:16,29:[1,21],34:[1,22],39:[2,2],44:[2,2],47:[2,2],48:[1,13],51:[1,14],55:[1,18],59:19,60:[1,24]},{1:[2,1]},{5:[2,47],14:[2,47],15:[2,47],19:[2,47],29:[2,47],34:[2,47],39:[2,47],44:[2,47],47:[2,47],48:[2,47],51:[2,47],55:[2,47],60:[2,47]},{5:[2,3],14:[2,3],15:[2,3],19:[2,3],29:[2,3],34:[2,3],39:[2,3],44:[2,3],47:[2,3],48:[2,3],51:[2,3],55:[2,3],60:[2,3]},{5:[2,4],14:[2,4],15:[2,4],19:[2,4],29:[2,4],34:[2,4],39:[2,4],44:[2,4],47:[2,4],48:[2,4],51:[2,4],55:[2,4],60:[2,4]},{5:[2,5],14:[2,5],15:[2,5],19:[2,5],29:[2,5],34:[2,5],39:[2,5],44:[2,5],47:[2,5],48:[2,5],51:[2,5],55:[2,5],60:[2,5]},{5:[2,6],14:[2,6],15:[2,6],19:[2,6],29:[2,6],34:[2,6],39:[2,6],44:[2,6],47:[2,6],48:[2,6],51:[2,6],55:[2,6],60:[2,6]},{5:[2,7],14:[2,7],15:[2,7],19:[2,7],29:[2,7],34:[2,7],39:[2,7],44:[2,7],47:[2,7],48:[2,7],51:[2,7],55:[2,7],60:[2,7]},{5:[2,8],14:[2,8],15:[2,8],19:[2,8],29:[2,8],34:[2,8],39:[2,8],44:[2,8],47:[2,8],48:[2,8],51:[2,8],55:[2,8],60:[2,8]},{5:[2,9],14:[2,9],15:[2,9],19:[2,9],29:[2,9],34:[2,9],39:[2,9],44:[2,9],47:[2,9],48:[2,9],51:[2,9],55:[2,9],60:[2,9]},{20:25,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:36,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:37,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],39:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{4:38,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{15:[2,48],17:39,18:[2,48]},{20:41,56:40,64:42,65:[1,43],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:44,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{5:[2,10],14:[2,10],15:[2,10],18:[2,10],19:[2,10],29:[2,10],34:[2,10],39:[2,10],44:[2,10],47:[2,10],48:[2,10],51:[2,10],55:[2,10],60:[2,10]},{20:45,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:46,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:47,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:41,56:48,64:42,65:[1,43],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[2,78],49:49,65:[2,78],72:[2,78],80:[2,78],81:[2,78],82:[2,78],83:[2,78],84:[2,78],85:[2,78]},{23:[2,33],33:[2,33],54:[2,33],65:[2,33],68:[2,33],72:[2,33],75:[2,33],80:[2,33],81:[2,33],82:[2,33],83:[2,33],84:[2,33],85:[2,33]},{23:[2,34],33:[2,34],54:[2,34],65:[2,34],68:[2,34],72:[2,34],75:[2,34],80:[2,34],81:[2,34],82:[2,34],83:[2,34],84:[2,34],85:[2,34]},{23:[2,35],33:[2,35],54:[2,35],65:[2,35],68:[2,35],72:[2,35],75:[2,35],80:[2,35],81:[2,35],82:[2,35],83:[2,35],84:[2,35],85:[2,35]},{23:[2,36],33:[2,36],54:[2,36],65:[2,36],68:[2,36],72:[2,36],75:[2,36],80:[2,36],81:[2,36],82:[2,36],83:[2,36],84:[2,36],85:[2,36]},{23:[2,37],33:[2,37],54:[2,37],65:[2,37],68:[2,37],72:[2,37],75:[2,37],80:[2,37],81:[2,37],82:[2,37],83:[2,37],84:[2,37],85:[2,37]},{23:[2,38],33:[2,38],54:[2,38],65:[2,38],68:[2,38],72:[2,38],75:[2,38],80:[2,38],81:[2,38],82:[2,38],83:[2,38],84:[2,38],85:[2,38]},{23:[2,39],33:[2,39],54:[2,39],65:[2,39],68:[2,39],72:[2,39],75:[2,39],80:[2,39],81:[2,39],82:[2,39],83:[2,39],84:[2,39],85:[2,39]},{23:[2,43],33:[2,43],54:[2,43],65:[2,43],68:[2,43],72:[2,43],75:[2,43],80:[2,43],81:[2,43],82:[2,43],83:[2,43],84:[2,43],85:[2,43],87:[1,50]},{72:[1,35],86:51},{23:[2,45],33:[2,45],54:[2,45],65:[2,45],68:[2,45],72:[2,45],75:[2,45],80:[2,45],81:[2,45],82:[2,45],83:[2,45],84:[2,45],85:[2,45],87:[2,45]},{52:52,54:[2,82],65:[2,82],72:[2,82],80:[2,82],81:[2,82],82:[2,82],83:[2,82],84:[2,82],85:[2,82]},{25:53,38:55,39:[1,57],43:56,44:[1,58],45:54,47:[2,54]},{28:59,43:60,44:[1,58],47:[2,56]},{13:62,15:[1,20],18:[1,61]},{33:[2,86],57:63,65:[2,86],72:[2,86],80:[2,86],81:[2,86],82:[2,86],83:[2,86],84:[2,86],85:[2,86]},{33:[2,40],65:[2,40],72:[2,40],80:[2,40],81:[2,40],82:[2,40],83:[2,40],84:[2,40],85:[2,40]},{
-33:[2,41],65:[2,41],72:[2,41],80:[2,41],81:[2,41],82:[2,41],83:[2,41],84:[2,41],85:[2,41]},{20:64,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{26:65,47:[1,66]},{30:67,33:[2,58],65:[2,58],72:[2,58],75:[2,58],80:[2,58],81:[2,58],82:[2,58],83:[2,58],84:[2,58],85:[2,58]},{33:[2,64],35:68,65:[2,64],72:[2,64],75:[2,64],80:[2,64],81:[2,64],82:[2,64],83:[2,64],84:[2,64],85:[2,64]},{21:69,23:[2,50],65:[2,50],72:[2,50],80:[2,50],81:[2,50],82:[2,50],83:[2,50],84:[2,50],85:[2,50]},{33:[2,90],61:70,65:[2,90],72:[2,90],80:[2,90],81:[2,90],82:[2,90],83:[2,90],84:[2,90],85:[2,90]},{20:74,33:[2,80],50:71,63:72,64:75,65:[1,43],69:73,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{72:[1,79]},{23:[2,42],33:[2,42],54:[2,42],65:[2,42],68:[2,42],72:[2,42],75:[2,42],80:[2,42],81:[2,42],82:[2,42],83:[2,42],84:[2,42],85:[2,42],87:[1,50]},{20:74,53:80,54:[2,84],63:81,64:75,65:[1,43],69:82,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{26:83,47:[1,66]},{47:[2,55]},{4:84,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],39:[2,46],44:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{47:[2,20]},{20:85,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{4:86,6:3,14:[2,46],15:[2,46],19:[2,46],29:[2,46],34:[2,46],47:[2,46],48:[2,46],51:[2,46],55:[2,46],60:[2,46]},{26:87,47:[1,66]},{47:[2,57]},{5:[2,11],14:[2,11],15:[2,11],19:[2,11],29:[2,11],34:[2,11],39:[2,11],44:[2,11],47:[2,11],48:[2,11],51:[2,11],55:[2,11],60:[2,11]},{15:[2,49],18:[2,49]},{20:74,33:[2,88],58:88,63:89,64:75,65:[1,43],69:90,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{65:[2,94],66:91,68:[2,94],72:[2,94],80:[2,94],81:[2,94],82:[2,94],83:[2,94],84:[2,94],85:[2,94]},{5:[2,25],14:[2,25],15:[2,25],19:[2,25],29:[2,25],34:[2,25],39:[2,25],44:[2,25],47:[2,25],48:[2,25],51:[2,25],55:[2,25],60:[2,25]},{20:92,72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,31:93,33:[2,60],63:94,64:75,65:[1,43],69:95,70:76,71:77,72:[1,78],75:[2,60],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,33:[2,66],36:96,63:97,64:75,65:[1,43],69:98,70:76,71:77,72:[1,78],75:[2,66],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,22:99,23:[2,52],63:100,64:75,65:[1,43],69:101,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{20:74,33:[2,92],62:102,63:103,64:75,65:[1,43],69:104,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[1,105]},{33:[2,79],65:[2,79],72:[2,79],80:[2,79],81:[2,79],82:[2,79],83:[2,79],84:[2,79],85:[2,79]},{33:[2,81]},{23:[2,27],33:[2,27],54:[2,27],65:[2,27],68:[2,27],72:[2,27],75:[2,27],80:[2,27],81:[2,27],82:[2,27],83:[2,27],84:[2,27],85:[2,27]},{23:[2,28],33:[2,28],54:[2,28],65:[2,28],68:[2,28],72:[2,28],75:[2,28],80:[2,28],81:[2,28],82:[2,28],83:[2,28],84:[2,28],85:[2,28]},{23:[2,30],33:[2,30],54:[2,30],68:[2,30],71:106,72:[1,107],75:[2,30]},{23:[2,98],33:[2,98],54:[2,98],68:[2,98],72:[2,98],75:[2,98]},{23:[2,45],33:[2,45],54:[2,45],65:[2,45],68:[2,45],72:[2,45],73:[1,108],75:[2,45],80:[2,45],81:[2,45],82:[2,45],83:[2,45],84:[2,45],85:[2,45],87:[2,45]},{23:[2,44],33:[2,44],54:[2,44],65:[2,44],68:[2,44],72:[2,44],75:[2,44],80:[2,44],81:[2,44],82:[2,44],83:[2,44],84:[2,44],85:[2,44],87:[2,44]},{54:[1,109]},{54:[2,83],65:[2,83],72:[2,83],80:[2,83],81:[2,83],82:[2,83],83:[2,83],84:[2,83],85:[2,83]},{54:[2,85]},{5:[2,13],14:[2,13],15:[2,13],19:[2,13],29:[2,13],34:[2,13],39:[2,13],44:[2,13],47:[2,13],48:[2,13],51:[2,13],55:[2,13],60:[2,13]},{38:55,39:[1,57],43:56,44:[1,58],45:111,46:110,47:[2,76]},{33:[2,70],40:112,65:[2,70],72:[2,70],75:[2,70],80:[2,70],81:[2,70],82:[2,70],83:[2,70],84:[2,70],85:[2,70]},{47:[2,18]},{5:[2,14],14:[2,14],15:[2,14],19:[2,14],29:[2,14],34:[2,14],39:[2,14],44:[2,14],47:[2,14],48:[2,14],51:[2,14],55:[2,14],60:[2,14]},{33:[1,113]},{33:[2,87],65:[2,87],72:[2,87],80:[2,87],81:[2,87],82:[2,87],83:[2,87],84:[2,87],85:[2,87]},{33:[2,89]},{20:74,63:115,64:75,65:[1,43],67:114,68:[2,96],69:116,70:76,71:77,72:[1,78],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{33:[1,117]},{32:118,33:[2,62],74:119,75:[1,120]},{33:[2,59],65:[2,59],72:[2,59],75:[2,59],80:[2,59],81:[2,59],82:[2,59],83:[2,59],84:[2,59],85:[2,59]},{33:[2,61],75:[2,61]},{33:[2,68],37:121,74:122,75:[1,120]},{33:[2,65],65:[2,65],72:[2,65],75:[2,65],80:[2,65],81:[2,65],82:[2,65],83:[2,65],84:[2,65],85:[2,65]},{33:[2,67],75:[2,67]},{23:[1,123]},{23:[2,51],65:[2,51],72:[2,51],80:[2,51],81:[2,51],82:[2,51],83:[2,51],84:[2,51],85:[2,51]},{23:[2,53]},{33:[1,124]},{33:[2,91],65:[2,91],72:[2,91],80:[2,91],81:[2,91],82:[2,91],83:[2,91],84:[2,91],85:[2,91]},{33:[2,93]},{5:[2,22],14:[2,22],15:[2,22],19:[2,22],29:[2,22],34:[2,22],39:[2,22],44:[2,22],47:[2,22],48:[2,22],51:[2,22],55:[2,22],60:[2,22]},{23:[2,99],33:[2,99],54:[2,99],68:[2,99],72:[2,99],75:[2,99]},{73:[1,108]},{20:74,63:125,64:75,65:[1,43],72:[1,35],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{5:[2,23],14:[2,23],15:[2,23],19:[2,23],29:[2,23],34:[2,23],39:[2,23],44:[2,23],47:[2,23],48:[2,23],51:[2,23],55:[2,23],60:[2,23]},{47:[2,19]},{47:[2,77]},{20:74,33:[2,72],41:126,63:127,64:75,65:[1,43],69:128,70:76,71:77,72:[1,78],75:[2,72],78:26,79:27,80:[1,28],81:[1,29],82:[1,30],83:[1,31],84:[1,32],85:[1,34],86:33},{5:[2,24],14:[2,24],15:[2,24],19:[2,24],29:[2,24],34:[2,24],39:[2,24],44:[2,24],47:[2,24],48:[2,24],51:[2,24],55:[2,24],60:[2,24]},{68:[1,129]},{65:[2,95],68:[2,95],72:[2,95],80:[2,95],81:[2,95],82:[2,95],83:[2,95],84:[2,95],85:[2,95]},{68:[2,97]},{5:[2,21],14:[2,21],15:[2,21],19:[2,21],29:[2,21],34:[2,21],39:[2,21],44:[2,21],47:[2,21],48:[2,21],51:[2,21],55:[2,21],60:[2,21]},{33:[1,130]},{33:[2,63]},{72:[1,132],76:131},{33:[1,133]},{33:[2,69]},{15:[2,12],18:[2,12]},{14:[2,26],15:[2,26],19:[2,26],29:[2,26],34:[2,26],47:[2,26],48:[2,26],51:[2,26],55:[2,26],60:[2,26]},{23:[2,31],33:[2,31],54:[2,31],68:[2,31],72:[2,31],75:[2,31]},{33:[2,74],42:134,74:135,75:[1,120]},{33:[2,71],65:[2,71],72:[2,71],75:[2,71],80:[2,71],81:[2,71],82:[2,71],83:[2,71],84:[2,71],85:[2,71]},{33:[2,73],75:[2,73]},{23:[2,29],33:[2,29],54:[2,29],65:[2,29],68:[2,29],72:[2,29],75:[2,29],80:[2,29],81:[2,29],82:[2,29],83:[2,29],84:[2,29],85:[2,29]},{14:[2,15],15:[2,15],19:[2,15],29:[2,15],34:[2,15],39:[2,15],44:[2,15],47:[2,15],48:[2,15],51:[2,15],55:[2,15],60:[2,15]},{72:[1,137],77:[1,136]},{72:[2,100],77:[2,100]},{14:[2,16],15:[2,16],19:[2,16],29:[2,16],34:[2,16],44:[2,16],47:[2,16],48:[2,16],51:[2,16],55:[2,16],60:[2,16]},{33:[1,138]},{33:[2,75]},{33:[2,32]},{72:[2,101],77:[2,101]},{14:[2,17],15:[2,17],19:[2,17],29:[2,17],34:[2,17],39:[2,17],44:[2,17],47:[2,17],48:[2,17],51:[2,17],55:[2,17],60:[2,17]}],defaultActions:{4:[2,1],54:[2,55],56:[2,20],60:[2,57],73:[2,81],82:[2,85],86:[2,18],90:[2,89],101:[2,53],104:[2,93],110:[2,19],111:[2,77],116:[2,97],119:[2,63],122:[2,69],135:[2,75],136:[2,32]},parseError:function(a,b){throw new Error(a)},parse:function(a){function b(){var a;return a=c.lexer.lex()||1,"number"!=typeof a&&(a=c.symbols_[a]||a),a}var c=this,d=[0],e=[null],f=[],g=this.table,h="",i=0,j=0,k=0;this.lexer.setInput(a),this.lexer.yy=this.yy,this.yy.lexer=this.lexer,this.yy.parser=this,"undefined"==typeof this.lexer.yylloc&&(this.lexer.yylloc={});var l=this.lexer.yylloc;f.push(l);var m=this.lexer.options&&this.lexer.options.ranges;"function"==typeof this.yy.parseError&&(this.parseError=this.yy.parseError);for(var n,o,p,q,r,s,t,u,v,w={};;){if(p=d[d.length-1],this.defaultActions[p]?q=this.defaultActions[p]:(null!==n&&"undefined"!=typeof n||(n=b()),q=g[p]&&g[p][n]),"undefined"==typeof q||!q.length||!q[0]){var x="";if(!k){v=[];for(s in g[p])this.terminals_[s]&&s>2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},c=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;g<f.length&&(c=this._input.match(this.rules[f[g]]),!c||b&&!(c[0].length>b[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substring(a,b.yyleng-c+a)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 15;break;case 1:return 15;case 2:return this.popState(),15;case 3:return this.begin("raw"),15;case 4:return this.popState(),"raw"===this.conditionStack[this.conditionStack.length-1]?15:(e(5,9),"END_RAW_BLOCK");case 5:return 15;case 6:return this.popState(),14;case 7:return 65;case 8:return 68;case 9:return 19;case 10:return this.popState(),this.begin("raw"),23;case 11:return 55;case 12:return 60;case 13:return 29;case 14:return 47;case 15:return this.popState(),44;case 16:return this.popState(),44;case 17:return 34;case 18:return 39;case 19:return 51;case 20:return 48;case 21:this.unput(b.yytext),this.popState(),this.begin("com");break;case 22:return this.popState(),14;case 23:return 48;case 24:return 73;case 25:return 72;case 26:return 72;case 27:return 87;case 28:break;case 29:return this.popState(),54;case 30:return this.popState(),33;case 31:return b.yytext=e(1,2).replace(/\\"/g,'"'),80;case 32:return b.yytext=e(1,2).replace(/\\'/g,"'"),80;case 33:return 85;case 34:return 82;case 35:return 82;case 36:return 83;case 37:return 84;case 38:return 81;case 39:return 75;case 40:return 77;case 41:return 72;case 42:return b.yytext=b.yytext.replace(/\\([\\\]])/g,"$1"),72;case 43:return"INVALID";case 44:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{(?=[^\/]))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]+?(?=(\{\{\{\{)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#>)/,/^(?:\{\{(~)?#\*?)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?\*?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:undefined(?=([~}\s)])))/,/^(?:null(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[(\\\]|[^\]])*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[6],inclusive:!1},raw:{rules:[3,4,5],inclusive:!1},INITIAL:{rules:[0,1,44],inclusive:!0}},a}();return b.lexer=c,a.prototype=b,b.Parser=a,new a}();b["default"]=c,a.exports=b["default"]},function(a,b,c){"use strict";function d(){var a=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.options=a}function e(a,b,c){void 0===b&&(b=a.length);var d=a[b-1],e=a[b-2];return d?"ContentStatement"===d.type?(e||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(d.original):void 0:c}function f(a,b,c){void 0===b&&(b=-1);var d=a[b+1],e=a[b+2];return d?"ContentStatement"===d.type?(e||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(d.original):void 0:c}function g(a,b,c){var d=a[null==b?0:b+1];if(d&&"ContentStatement"===d.type&&(c||!d.rightStripped)){var e=d.value;d.value=d.value.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),d.rightStripped=d.value!==e}}function h(a,b,c){var d=a[null==b?a.length-1:b-1];if(d&&"ContentStatement"===d.type&&(c||!d.leftStripped)){var e=d.value;return d.value=d.value.replace(c?/\s+$/:/[ \t]+$/,""),d.leftStripped=d.value!==e,d.leftStripped}}var i=c(1)["default"];b.__esModule=!0;var j=c(49),k=i(j);d.prototype=new k["default"],d.prototype.Program=function(a){var b=!this.options.ignoreStandalone,c=!this.isRootSeen;this.isRootSeen=!0;for(var d=a.body,i=0,j=d.length;i<j;i++){var k=d[i],l=this.accept(k);if(l){var m=e(d,i,c),n=f(d,i,c),o=l.openStandalone&&m,p=l.closeStandalone&&n,q=l.inlineStandalone&&m&&n;l.close&&g(d,i,!0),l.open&&h(d,i,!0),b&&q&&(g(d,i),h(d,i)&&"PartialStatement"===k.type&&(k.indent=/([ \t]+$)/.exec(d[i-1].original)[1])),b&&o&&(g((k.program||k.inverse).body),h(d,i)),b&&p&&(g(d,i),h((k.inverse||k.program).body))}}return a},d.prototype.BlockStatement=d.prototype.DecoratorBlock=d.prototype.PartialBlockStatement=function(a){this.accept(a.program),this.accept(a.inverse);var b=a.program||a.inverse,c=a.program&&a.inverse,d=c,i=c;if(c&&c.chained)for(d=c.body[0].program;i.chained;)i=i.body[i.body.length-1].program;var j={open:a.openStrip.open,close:a.closeStrip.close,openStandalone:f(b.body),closeStandalone:e((d||b).body)};if(a.openStrip.close&&g(b.body,null,!0),c){var k=a.inverseStrip;k.open&&h(b.body,null,!0),k.close&&g(d.body,null,!0),a.closeStrip.open&&h(i.body,null,!0),!this.options.ignoreStandalone&&e(b.body)&&f(d.body)&&(h(b.body),g(d.body))}else a.closeStrip.open&&h(b.body,null,!0);return j},d.prototype.Decorator=d.prototype.MustacheStatement=function(a){return a.strip},d.prototype.PartialStatement=d.prototype.CommentStatement=function(a){var b=a.strip||{};return{inlineStandalone:!0,open:b.open,close:b.close}},b["default"]=d,a.exports=b["default"]},function(a,b,c){"use strict";function d(){this.parents=[]}function e(a){this.acceptRequired(a,"path"),this.acceptArray(a.params),this.acceptKey(a,"hash")}function f(a){e.call(this,a),this.acceptKey(a,"program"),this.acceptKey(a,"inverse")}function g(a){this.acceptRequired(a,"name"),this.acceptArray(a.params),this.acceptKey(a,"hash")}var h=c(1)["default"];b.__esModule=!0;var i=c(6),j=h(i);d.prototype={constructor:d,mutating:!1,acceptKey:function(a,b){var c=this.accept(a[b]);if(this.mutating){if(c&&!d.prototype[c.type])throw new j["default"]('Unexpected node type "'+c.type+'" found when accepting '+b+" on "+a.type);a[b]=c}},acceptRequired:function(a,b){if(this.acceptKey(a,b),!a[b])throw new j["default"](a.type+" requires "+b)},acceptArray:function(a){for(var b=0,c=a.length;b<c;b++)this.acceptKey(a,b),a[b]||(a.splice(b,1),b--,c--)},accept:function(a){if(a){if(!this[a.type])throw new j["default"]("Unknown type: "+a.type,a);this.current&&this.parents.unshift(this.current),this.current=a;var b=this[a.type](a);return this.current=this.parents.shift(),!this.mutating||b?b:b!==!1?a:void 0}},Program:function(a){this.acceptArray(a.body)},MustacheStatement:e,Decorator:e,BlockStatement:f,DecoratorBlock:f,PartialStatement:g,PartialBlockStatement:function(a){g.call(this,a),this.acceptKey(a,"program")},ContentStatement:function(){},CommentStatement:function(){},SubExpression:e,PathExpression:function(){},StringLiteral:function(){},NumberLiteral:function(){},BooleanLiteral:function(){},UndefinedLiteral:function(){},NullLiteral:function(){},Hash:function(a){this.acceptArray(a.pairs)},HashPair:function(a){this.acceptRequired(a,"value")}},b["default"]=d,a.exports=b["default"]},function(a,b,c){"use strict";function d(a,b){if(b=b.path?b.path.original:b,a.path.original!==b){var c={loc:a.path.loc};throw new q["default"](a.path.original+" doesn't match "+b,c)}}function e(a,b){this.source=a,this.start={line:b.first_line,column:b.first_column},this.end={line:b.last_line,column:b.last_column}}function f(a){return/^\[.*\]$/.test(a)?a.substring(1,a.length-1):a}function g(a,b){return{open:"~"===a.charAt(2),close:"~"===b.charAt(b.length-3)}}function h(a){return a.replace(/^\{\{~?!-?-?/,"").replace(/-?-?~?\}\}$/,"")}function i(a,b,c){c=this.locInfo(c);for(var d=a?"@":"",e=[],f=0,g=0,h=b.length;g<h;g++){var i=b[g].part,j=b[g].original!==i;if(d+=(b[g].separator||"")+i,j||".."!==i&&"."!==i&&"this"!==i)e.push(i);else{if(e.length>0)throw new q["default"]("Invalid path: "+d,{loc:c});".."===i&&f++}}return{type:"PathExpression",data:a,depth:f,parts:e,original:d,loc:c}}function j(a,b,c,d,e,f){var g=d.charAt(3)||d.charAt(2),h="{"!==g&&"&"!==g,i=/\*/.test(d);return{type:i?"Decorator":"MustacheStatement",path:a,params:b,hash:c,escaped:h,strip:e,loc:this.locInfo(f)}}function k(a,b,c,e){d(a,c),e=this.locInfo(e);var f={type:"Program",body:b,strip:{},loc:e};return{type:"BlockStatement",path:a.path,params:a.params,hash:a.hash,program:f,openStrip:{},inverseStrip:{},closeStrip:{},loc:e}}function l(a,b,c,e,f,g){e&&e.path&&d(a,e);var h=/\*/.test(a.open);b.blockParams=a.blockParams;var i=void 0,j=void 0;if(c){if(h)throw new q["default"]("Unexpected inverse block on decorator",c);c.chain&&(c.program.body[0].closeStrip=e.strip),j=c.strip,i=c.program}return f&&(f=i,i=b,b=f),{type:h?"DecoratorBlock":"BlockStatement",path:a.path,params:a.params,hash:a.hash,program:b,inverse:i,openStrip:a.strip,inverseStrip:j,closeStrip:e&&e.strip,loc:this.locInfo(g)}}function m(a,b){if(!b&&a.length){var c=a[0].loc,d=a[a.length-1].loc;c&&d&&(b={source:c.source,start:{line:c.start.line,column:c.start.column},end:{line:d.end.line,column:d.end.column}})}return{type:"Program",body:a,strip:{},loc:b}}function n(a,b,c,e){return d(a,c),{type:"PartialBlockStatement",name:a.path,params:a.params,hash:a.hash,program:b,openStrip:a.strip,closeStrip:c&&c.strip,loc:this.locInfo(e)}}var o=c(1)["default"];b.__esModule=!0,b.SourceLocation=e,b.id=f,b.stripFlags=g,b.stripComment=h,b.preparePath=i,b.prepareMustache=j,b.prepareRawBlock=k,b.prepareBlock=l,b.prepareProgram=m,b.preparePartialBlock=n;var p=c(6),q=o(p)},function(a,b,c){"use strict";function d(){}function e(a,b,c){if(null==a||"string"!=typeof a&&"Program"!==a.type)throw new l["default"]("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var d=c.parse(a,b),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function f(a,b,c){function d(){var d=c.parse(a,b),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}function e(a,b){return f||(f=d()),f.call(this,a,b)}if(void 0===b&&(b={}),null==a||"string"!=typeof a&&"Program"!==a.type)throw new l["default"]("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=m.extend({},b),"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var f=void 0;return e._setup=function(a){return f||(f=d()),f._setup(a)},e._child=function(a,b,c,e){return f||(f=d()),f._child(a,b,c,e)},e}function g(a,b){if(a===b)return!0;if(m.isArray(a)&&m.isArray(b)&&a.length===b.length){for(var c=0;c<a.length;c++)if(!g(a[c],b[c]))return!1;return!0}}function h(a){if(!a.path.parts){var b=a.path;a.path={type:"PathExpression",data:!1,depth:0,parts:[b.original+""],original:b.original+"",loc:b.loc}}}var i=c(34)["default"],j=c(1)["default"];b.__esModule=!0,b.Compiler=d,b.precompile=e,b.compile=f;var k=c(6),l=j(k),m=c(5),n=c(45),o=j(n),p=[].slice;d.prototype={compiler:d,equals:function(a){var b=this.opcodes.length;if(a.opcodes.length!==b)return!1;for(var c=0;c<b;c++){var d=this.opcodes[c],e=a.opcodes[c];if(d.opcode!==e.opcode||!g(d.args,e.args))return!1}b=this.children.length;for(var c=0;c<b;c++)if(!this.children[c].equals(a.children[c]))return!1;return!0},guid:0,compile:function(a,b){return this.sourceNode=[],this.opcodes=[],this.children=[],this.options=b,this.stringParams=b.stringParams,this.trackIds=b.trackIds,b.blockParams=b.blockParams||[],b.knownHelpers=m.extend(i(null),{helperMissing:!0,blockHelperMissing:!0,each:!0,"if":!0,unless:!0,"with":!0,log:!0,lookup:!0},b.knownHelpers),this.accept(a)},compileProgram:function(a){var b=new this.compiler,c=b.compile(a,this.options),d=this.guid++;return this.usePartial=this.usePartial||c.usePartial,this.children[d]=c,this.useDepths=this.useDepths||c.useDepths,d},accept:function(a){if(!this[a.type])throw new l["default"]("Unknown type: "+a.type,a);this.sourceNode.unshift(a);var b=this[a.type](a);return this.sourceNode.shift(),b},Program:function(a){this.options.blockParams.unshift(a.blockParams);for(var b=a.body,c=b.length,d=0;d<c;d++)this.accept(b[d]);return this.options.blockParams.shift(),this.isSimple=1===c,this.blockParams=a.blockParams?a.blockParams.length:0,this},BlockStatement:function(a){h(a);var b=a.program,c=a.inverse;b=b&&this.compileProgram(b),c=c&&this.compileProgram(c);var d=this.classifySexpr(a);"helper"===d?this.helperSexpr(a,b,c):"simple"===d?(this.simpleSexpr(a),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.opcode("emptyHash"),this.opcode("blockValue",a.path.original)):(this.ambiguousSexpr(a,b,c),this.opcode("pushProgram",b),this.opcode("pushProgram",c),this.opcode("emptyHash"),this.opcode("ambiguousBlockValue")),this.opcode("append")},DecoratorBlock:function(a){var b=a.program&&this.compileProgram(a.program),c=this.setupFullMustacheParams(a,b,void 0),d=a.path;this.useDecorators=!0,this.opcode("registerDecorator",c.length,d.original)},PartialStatement:function(a){this.usePartial=!0;var b=a.program;b&&(b=this.compileProgram(a.program));var c=a.params;if(c.length>1)throw new l["default"]("Unsupported number of partial arguments: "+c.length,a);c.length||(this.options.explicitPartialContext?this.opcode("pushLiteral","undefined"):c.push({type:"PathExpression",parts:[],depth:0});var d=a.name.original,e="SubExpression"===a.name.type;e&&this.accept(a.name),this.setupFullMustacheParams(a,b,void 0,!0);var f=a.indent||"";this.options.preventIndent&&f&&(this.opcode("appendContent",f),f=""),this.opcode("invokePartial",e,d,f),this.opcode("append")},PartialBlockStatement:function(a){this.PartialStatement(a)},MustacheStatement:function(a){this.SubExpression(a),a.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},Decorator:function(a){this.DecoratorBlock(a)},ContentStatement:function(a){a.value&&this.opcode("appendContent",a.value)},CommentStatement:function(){},SubExpression:function(a){h(a);var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ambiguousSexpr:function(a,b,c){var d=a.path,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),d.strict=!0,this.accept(d),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){var b=a.path;b.strict=!0,this.accept(b),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.path,f=e.parts[0];if(this.options.knownHelpers[f])this.opcode("invokeKnownHelper",d.length,f);else{if(this.options.knownHelpersOnly)throw new l["default"]("You specified knownHelpersOnly, but used the unknown helper "+f,a);e.strict=!0,e.falsy=!0,this.accept(e),this.opcode("invokeHelper",d.length,e.original,o["default"].helpers.simpleId(e))}},PathExpression:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0],c=o["default"].helpers.scopedId(a),d=!a.depth&&!c&&this.blockParamIndex(b);d?this.opcode("lookupBlockParam",d,a.parts):b?a.data?(this.options.data=!0,this.opcode("lookupData",a.depth,a.parts,a.strict)):this.opcode("lookupOnContext",a.parts,a.falsy,a.strict,c):this.opcode("pushContext")},StringLiteral:function(a){this.opcode("pushString",a.value)},NumberLiteral:function(a){this.opcode("pushLiteral",a.value)},BooleanLiteral:function(a){this.opcode("pushLiteral",a.value)},UndefinedLiteral:function(){this.opcode("pushLiteral","undefined")},NullLiteral:function(){this.opcode("pushLiteral","null")},Hash:function(a){var b=a.pairs,c=0,d=b.length;for(this.opcode("pushHash");c<d;c++)this.pushParam(b[c].value);for(;c--;)this.opcode("assignToHash",b[c].key);this.opcode("popHash")},opcode:function(a){this.opcodes.push({opcode:a,args:p.call(arguments,1),loc:this.sourceNode[0].loc})},addDepth:function(a){a&&(this.useDepths=!0)},classifySexpr:function(a){var b=o["default"].helpers.simpleId(a.path),c=b&&!!this.blockParamIndex(a.path.parts[0]),d=!c&&o["default"].helpers.helperExpression(a),e=!c&&(d||b);if(e&&!d){var f=a.path.parts[0],g=this.options;g.knownHelpers[f]?d=!0:g.knownHelpersOnly&&(e=!1)}return d?"helper":e?"ambiguous":"simple"},pushParams:function(a){for(var b=0,c=a.length;b<c;b++)this.pushParam(a[b])},pushParam:function(a){var b=null!=a.value?a.value:a.original||"";if(this.stringParams)b.replace&&(b=b.replace(/^(\.?\.\/)*/g,"").replace(/\//g,".")),a.depth&&this.addDepth(a.depth),this.opcode("getContext",a.depth||0),this.opcode("pushStringParam",b,a.type),"SubExpression"===a.type&&this.accept(a);else{if(this.trackIds){var c=void 0;if(!a.parts||o["default"].helpers.scopedId(a)||a.depth||(c=this.blockParamIndex(a.parts[0])),c){var d=a.parts.slice(1).join(".");this.opcode("pushId","BlockParam",c,d)}else b=a.original||b,b.replace&&(b=b.replace(/^this(?:\.|$)/,"").replace(/^\.\//,"").replace(/^\.$/,"")),this.opcode("pushId",a.type,b)}this.accept(a)}},setupFullMustacheParams:function(a,b,c,d){var e=a.params;return this.pushParams(e),this.opcode("pushProgram",b),this.opcode("pushProgram",c),a.hash?this.accept(a.hash):this.opcode("emptyHash",d),e},blockParamIndex:function(a){for(var b=0,c=this.options.blockParams.length;b<c;b++){var d=this.options.blockParams[b],e=d&&m.indexOf(d,a);if(d&&e>=0)return[b,e]}}}},function(a,b,c){"use strict";function d(a){this.value=a}function e(){}function f(a,b,c,d){var e=b.popStack(),f=0,g=c.length;for(a&&g--;f<g;f++)e=b.nameLookup(e,c[f],d);return a?[b.aliasable("container.strict"),"(",e,", ",b.quotedString(c[f]),", ",JSON.stringify(b.source.currentLocation)," )"]:e}var g=c(13)["default"],h=c(1)["default"];b.__esModule=!0;var i=c(4),j=c(6),k=h(j),l=c(5),m=c(53),n=h(m);e.prototype={nameLookup:function(a,b){return this.internalNameLookup(a,b)},depthedLookup:function(a){return[this.aliasable("container.lookup"),"(depths, ",JSON.stringify(a),")"]},compilerInfo:function(){var a=i.COMPILER_REVISION,b=i.REVISION_CHANGES[a];return[a,b]},appendToBuffer:function(a,b,c){return l.isArray(a)||(a=[a]),a=this.source.wrap(a,b),this.environment.isSimple?["return ",a,";"]:c?["buffer += ",a,";"]:(a.appendToBuffer=!0,a)},initializeBuffer:function(){return this.quotedString("")},internalNameLookup:function(a,b){return this.lookupPropertyFunctionIsUsed=!0,["lookupProperty(",a,",",JSON.stringify(b),")"]},lookupPropertyFunctionIsUsed:!1,compile:function(a,b,c,d){this.environment=a,this.options=b,this.stringParams=this.options.stringParams,this.trackIds=this.options.trackIds,this.precompile=!d,this.name=this.environment.name,this.isChild=!!c,this.context=c||{decorators:[],programs:[],environments:[]},this.preamble(),this.stackSlot=0,this.stackVars=[],this.aliases={},this.registers={list:[]},this.hashes=[],this.compileStack=[],this.inlineStack=[],this.blockParams=[],this.compileChildren(a,b),this.useDepths=this.useDepths||a.useDepths||a.useDecorators||this.options.compat,this.useBlockParams=this.useBlockParams||a.useBlockParams;var e=a.opcodes,f=void 0,g=void 0,h=void 0,i=void 0;for(h=0,i=e.length;h<i;h++)f=e[h],this.source.currentLocation=f.loc,g=g||f.loc,this[f.opcode].apply(this,f.args);if(this.source.currentLocation=g,this.pushSource(""),this.stackSlot||this.inlineStack.length||this.compileStack.length)throw new k["default"]("Compile completed with content left on stack");this.decorators.isEmpty()?this.decorators=void 0:(this.useDecorators=!0,this.decorators.prepend(["var decorators = container.decorators, ",this.lookupPropertyFunctionVarDeclaration(),";\n"]),
-this.decorators.push("return fn;"),d?this.decorators=Function.apply(this,["fn","props","container","depth0","data","blockParams","depths",this.decorators.merge()]):(this.decorators.prepend("function(fn, props, container, depth0, data, blockParams, depths) {\n"),this.decorators.push("}\n"),this.decorators=this.decorators.merge()));var j=this.createFunctionContext(d);if(this.isChild)return j;var l={compiler:this.compilerInfo(),main:j};this.decorators&&(l.main_d=this.decorators,l.useDecorators=!0);var m=this.context,n=m.programs,o=m.decorators;for(h=0,i=n.length;h<i;h++)n[h]&&(l[h]=n[h],o[h]&&(l[h+"_d"]=o[h],l.useDecorators=!0));return this.environment.usePartial&&(l.usePartial=!0),this.options.data&&(l.useData=!0),this.useDepths&&(l.useDepths=!0),this.useBlockParams&&(l.useBlockParams=!0),this.options.compat&&(l.compat=!0),d?l.compilerOptions=this.options:(l.compiler=JSON.stringify(l.compiler),this.source.currentLocation={start:{line:1,column:0}},l=this.objectLiteral(l),b.srcName?(l=l.toStringWithSourceMap({file:b.destName}),l.map=l.map&&l.map.toString()):l=l.toString()),l},preamble:function(){this.lastContext=0,this.source=new n["default"](this.options.srcName),this.decorators=new n["default"](this.options.srcName)},createFunctionContext:function(a){var b=this,c="",d=this.stackVars.concat(this.registers.list);d.length>0&&(c+=", "+d.join(", "));var e=0;g(this.aliases).forEach(function(a){var d=b.aliases[a];d.children&&d.referenceCount>1&&(c+=", alias"+ ++e+"="+a,d.children[0]="alias"+e)}),this.lookupPropertyFunctionIsUsed&&(c+=", "+this.lookupPropertyFunctionVarDeclaration());var f=["container","depth0","helpers","partials","data"];(this.useBlockParams||this.useDepths)&&f.push("blockParams"),this.useDepths&&f.push("depths");var h=this.mergeSource(c);return a?(f.push(h),Function.apply(this,f)):this.source.wrap(["function(",f.join(","),") {\n ",h,"}"])},mergeSource:function(a){var b=this.environment.isSimple,c=!this.forceBuffer,d=void 0,e=void 0,f=void 0,g=void 0;return this.source.each(function(a){a.appendToBuffer?(f?a.prepend(" + "):f=a,g=a):(f&&(e?f.prepend("buffer += "):d=!0,g.add(";"),f=g=void 0),e=!0,b||(c=!1))}),c?f?(f.prepend("return "),g.add(";")):e||this.source.push('return "";'):(a+=", buffer = "+(d?"":this.initializeBuffer()),f?(f.prepend("return buffer + "),g.add(";")):this.source.push("return buffer;")),a&&this.source.prepend("var "+a.substring(2)+(d?"":";\n")),this.source.merge()},lookupPropertyFunctionVarDeclaration:function(){return"\n lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n }\n ".trim()},blockValue:function(a){var b=this.aliasable("container.hooks.blockHelperMissing"),c=[this.contextName(0)];this.setupHelperArgs(a,0,c);var d=this.popStack();c.splice(1,0,d),this.push(this.source.functionCall(b,"call",c))},ambiguousBlockValue:function(){var a=this.aliasable("container.hooks.blockHelperMissing"),b=[this.contextName(0)];this.setupHelperArgs("",0,b,!0),this.flushInline();var c=this.topStack();b.splice(1,0,c),this.pushSource(["if (!",this.lastHelper,") { ",c," = ",this.source.functionCall(a,"call",b),"}"])},appendContent:function(a){this.pendingContent?a=this.pendingContent+a:this.pendingLocation=this.source.currentLocation,this.pendingContent=a},append:function(){if(this.isInline())this.replaceStack(function(a){return[" != null ? ",a,' : ""']}),this.pushSource(this.appendToBuffer(this.popStack()));else{var a=this.popStack();this.pushSource(["if (",a," != null) { ",this.appendToBuffer(a,void 0,!0)," }"]),this.environment.isSimple&&this.pushSource(["else { ",this.appendToBuffer("''",void 0,!0)," }"])}},appendEscaped:function(){this.pushSource(this.appendToBuffer([this.aliasable("container.escapeExpression"),"(",this.popStack(),")"]))},getContext:function(a){this.lastContext=a},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(a,b,c,d){var e=0;d||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(a[e++])),this.resolvePath("context",a,e,b,c)},lookupBlockParam:function(a,b){this.useBlockParams=!0,this.push(["blockParams[",a[0],"][",a[1],"]"]),this.resolvePath("context",b,1)},lookupData:function(a,b,c){a?this.pushStackLiteral("container.data(data, "+a+")"):this.pushStackLiteral("data"),this.resolvePath("data",b,0,!0,c)},resolvePath:function(a,b,c,d,e){var g=this;if(this.options.strict||this.options.assumeObjects)return void this.push(f(this.options.strict&&e,this,b,a));for(var h=b.length;c<h;c++)this.replaceStack(function(e){var f=g.nameLookup(e,b[c],a);return d?[" && ",f]:[" != null ? ",f," : ",e]})},resolvePossibleLambda:function(){this.push([this.aliasable("container.lambda"),"(",this.popStack(),", ",this.contextName(0),")"])},pushStringParam:function(a,b){this.pushContext(),this.pushString(b),"SubExpression"!==b&&("string"==typeof a?this.pushString(a):this.pushStackLiteral(a))},emptyHash:function(a){this.trackIds&&this.push("{}"),this.stringParams&&(this.push("{}"),this.push("{}")),this.pushStackLiteral(a?"undefined":"{}")},pushHash:function(){this.hash&&this.hashes.push(this.hash),this.hash={values:{},types:[],contexts:[],ids:[]}},popHash:function(){var a=this.hash;this.hash=this.hashes.pop(),this.trackIds&&this.push(this.objectLiteral(a.ids)),this.stringParams&&(this.push(this.objectLiteral(a.contexts)),this.push(this.objectLiteral(a.types))),this.push(this.objectLiteral(a.values))},pushString:function(a){this.pushStackLiteral(this.quotedString(a))},pushLiteral:function(a){this.pushStackLiteral(a)},pushProgram:function(a){null!=a?this.pushStackLiteral(this.programExpression(a)):this.pushStackLiteral(null)},registerDecorator:function(a,b){var c=this.nameLookup("decorators",b,"decorator"),d=this.setupHelperArgs(b,a);this.decorators.push(["fn = ",this.decorators.functionCall(c,"",["fn","props","container",d])," || fn;"])},invokeHelper:function(a,b,c){var d=this.popStack(),e=this.setupHelper(a,b),f=[];c&&f.push(e.name),f.push(d),this.options.strict||f.push(this.aliasable("container.hooks.helperMissing"));var g=["(",this.itemsSeparatedBy(f,"||"),")"],h=this.source.functionCall(g,"call",e.callParams);this.push(h)},itemsSeparatedBy:function(a,b){var c=[];c.push(a[0]);for(var d=1;d<a.length;d++)c.push(b,a[d]);return c},invokeKnownHelper:function(a,b){var c=this.setupHelper(a,b);this.push(this.source.functionCall(c.name,"call",c.callParams))},invokeAmbiguous:function(a,b){this.useRegister("helper");var c=this.popStack();this.emptyHash();var d=this.setupHelper(0,a,b),e=this.lastHelper=this.nameLookup("helpers",a,"helper"),f=["(","(helper = ",e," || ",c,")"];this.options.strict||(f[0]="(helper = ",f.push(" != null ? helper : ",this.aliasable("container.hooks.helperMissing"))),this.push(["(",f,d.paramsInit?["),(",d.paramsInit]:[],"),","(typeof helper === ",this.aliasable('"function"')," ? ",this.source.functionCall("helper","call",d.callParams)," : helper))"])},invokePartial:function(a,b,c){var d=[],e=this.setupParams(b,1,d);a&&(b=this.popStack(),delete e.name),c&&(e.indent=JSON.stringify(c)),e.helpers="helpers",e.partials="partials",e.decorators="container.decorators",a?d.unshift(b):d.unshift(this.nameLookup("partials",b,"partial")),this.options.compat&&(e.depths="depths"),e=this.objectLiteral(e),d.push(e),this.push(this.source.functionCall("container.invokePartial","",d))},assignToHash:function(a){var b=this.popStack(),c=void 0,d=void 0,e=void 0;this.trackIds&&(e=this.popStack()),this.stringParams&&(d=this.popStack(),c=this.popStack());var f=this.hash;c&&(f.contexts[a]=c),d&&(f.types[a]=d),e&&(f.ids[a]=e),f.values[a]=b},pushId:function(a,b,c){"BlockParam"===a?this.pushStackLiteral("blockParams["+b[0]+"].path["+b[1]+"]"+(c?" + "+JSON.stringify("."+c):"")):"PathExpression"===a?this.pushString(b):"SubExpression"===a?this.pushStackLiteral("true"):this.pushStackLiteral("null")},compiler:e,compileChildren:function(a,b){for(var c=a.children,d=void 0,e=void 0,f=0,g=c.length;f<g;f++){d=c[f],e=new this.compiler;var h=this.matchExistingProgram(d);if(null==h){this.context.programs.push("");var i=this.context.programs.length;d.index=i,d.name="program"+i,this.context.programs[i]=e.compile(d,b,this.context,!this.precompile),this.context.decorators[i]=e.decorators,this.context.environments[i]=d,this.useDepths=this.useDepths||e.useDepths,this.useBlockParams=this.useBlockParams||e.useBlockParams,d.useDepths=this.useDepths,d.useBlockParams=this.useBlockParams}else d.index=h.index,d.name="program"+h.index,this.useDepths=this.useDepths||h.useDepths,this.useBlockParams=this.useBlockParams||h.useBlockParams}},matchExistingProgram:function(a){for(var b=0,c=this.context.environments.length;b<c;b++){var d=this.context.environments[b];if(d&&d.equals(a))return d}},programExpression:function(a){var b=this.environment.children[a],c=[b.index,"data",b.blockParams];return(this.useBlockParams||this.useDepths)&&c.push("blockParams"),this.useDepths&&c.push("depths"),"container.program("+c.join(", ")+")"},useRegister:function(a){this.registers[a]||(this.registers[a]=!0,this.registers.list.push(a))},push:function(a){return a instanceof d||(a=this.source.wrap(a)),this.inlineStack.push(a),a},pushStackLiteral:function(a){this.push(new d(a))},pushSource:function(a){this.pendingContent&&(this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent),this.pendingLocation)),this.pendingContent=void 0),a&&this.source.push(a)},replaceStack:function(a){var b=["("],c=void 0,e=void 0,f=void 0;if(!this.isInline())throw new k["default"]("replaceStack on non-inline");var g=this.popStack(!0);if(g instanceof d)c=[g.value],b=["(",c],f=!0;else{e=!0;var h=this.incrStack();b=["((",this.push(h)," = ",g,")"],c=this.topStack()}var i=a.call(this,c);f||this.popStack(),e&&this.stackSlot--,this.push(b.concat(i,")"))},incrStack:function(){return this.stackSlot++,this.stackSlot>this.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;this.inlineStack=[];for(var b=0,c=a.length;b<c;b++){var e=a[b];if(e instanceof d)this.compileStack.push(e);else{var f=this.incrStack();this.pushSource([f," = ",e,";"]),this.compileStack.push(f)}}},isInline:function(){return this.inlineStack.length},popStack:function(a){var b=this.isInline(),c=(b?this.inlineStack:this.compileStack).pop();if(!a&&c instanceof d)return c.value;if(!b){if(!this.stackSlot)throw new k["default"]("Invalid stack pop");this.stackSlot--}return c},topStack:function(){var a=this.isInline()?this.inlineStack:this.compileStack,b=a[a.length-1];return b instanceof d?b.value:b},contextName:function(a){return this.useDepths&&a?"depths["+a+"]":"depth"+a},quotedString:function(a){return this.source.quotedString(a)},objectLiteral:function(a){return this.source.objectLiteral(a)},aliasable:function(a){var b=this.aliases[a];return b?(b.referenceCount++,b):(b=this.aliases[a]=this.source.wrap(a),b.aliasable=!0,b.referenceCount=1,b)},setupHelper:function(a,b,c){var d=[],e=this.setupHelperArgs(b,a,d,c),f=this.nameLookup("helpers",b,"helper"),g=this.aliasable(this.contextName(0)+" != null ? "+this.contextName(0)+" : (container.nullContext || {})");return{params:d,paramsInit:e,name:f,callParams:[g].concat(d)}},setupParams:function(a,b,c){var d={},e=[],f=[],g=[],h=!c,i=void 0;h&&(c=[]),d.name=this.quotedString(a),d.hash=this.popStack(),this.trackIds&&(d.hashIds=this.popStack()),this.stringParams&&(d.hashTypes=this.popStack(),d.hashContexts=this.popStack());var j=this.popStack(),k=this.popStack();(k||j)&&(d.fn=k||"container.noop",d.inverse=j||"container.noop");for(var l=b;l--;)i=this.popStack(),c[l]=i,this.trackIds&&(g[l]=this.popStack()),this.stringParams&&(f[l]=this.popStack(),e[l]=this.popStack());return h&&(d.args=this.source.generateArray(c)),this.trackIds&&(d.ids=this.source.generateArray(g)),this.stringParams&&(d.types=this.source.generateArray(f),d.contexts=this.source.generateArray(e)),this.options.data&&(d.data="data"),this.useBlockParams&&(d.blockParams="blockParams"),d},setupHelperArgs:function(a,b,c,d){var e=this.setupParams(a,b,c);return e.loc=JSON.stringify(this.source.currentLocation),e=this.objectLiteral(e),d?(this.useRegister("options"),c.push("options"),["options=",e]):c?(c.push(e),""):e}},function(){for(var a="break else new var case finally return void catch for switch while continue function this with default if throw delete in try do instanceof typeof abstract enum int short boolean export interface static byte extends long super char final native synchronized class float package throws const goto private transient debugger implements protected volatile double import public let yield await null true false".split(" "),b=e.RESERVED_WORDS={},c=0,d=a.length;c<d;c++)b[a[c]]=!0}(),e.isValidJavaScriptVariableName=function(a){return!e.RESERVED_WORDS[a]&&/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(a)},b["default"]=e,a.exports=b["default"]},function(a,b,c){"use strict";function d(a,b,c){if(g.isArray(a)){for(var d=[],e=0,f=a.length;e<f;e++)d.push(b.wrap(a[e],c));return d}return"boolean"==typeof a||"number"==typeof a?a+"":a}function e(a){this.srcFile=a,this.source=[]}var f=c(13)["default"];b.__esModule=!0;var g=c(5),h=void 0;try{}catch(i){}h||(h=function(a,b,c,d){this.src="",d&&this.add(d)},h.prototype={add:function(a){g.isArray(a)&&(a=a.join("")),this.src+=a},prepend:function(a){g.isArray(a)&&(a=a.join("")),this.src=a+this.src},toStringWithSourceMap:function(){return{code:this.toString()}},toString:function(){return this.src}}),e.prototype={isEmpty:function(){return!this.source.length},prepend:function(a,b){this.source.unshift(this.wrap(a,b))},push:function(a,b){this.source.push(this.wrap(a,b))},merge:function(){var a=this.empty();return this.each(function(b){a.add([" ",b,"\n"])}),a},each:function(a){for(var b=0,c=this.source.length;b<c;b++)a(this.source[b])},empty:function(){var a=this.currentLocation||{start:{}};return new h(a.start.line,a.start.column,this.srcFile)},wrap:function(a){var b=arguments.length<=1||void 0===arguments[1]?this.currentLocation||{start:{}}:arguments[1];return a instanceof h?a:(a=d(a,this,b),new h(b.start.line,b.start.column,this.srcFile,a))},functionCall:function(a,b,c){return c=this.generateList(c),this.wrap([a,b?"."+b+"(":"(",c,")"])},quotedString:function(a){return'"'+(a+"").replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")+'"'},objectLiteral:function(a){var b=this,c=[];f(a).forEach(function(e){var f=d(a[e],b);"undefined"!==f&&c.push([b.quotedString(e),":",f])});var e=this.generateList(c);return e.prepend("{"),e.add("}"),e},generateList:function(a){for(var b=this.empty(),c=0,e=a.length;c<e;c++)c&&b.add(","),b.add(d(a[c],this));return b},generateArray:function(a){var b=this.generateList(a);return b.prepend("["),b.add("]"),b}},b["default"]=e,a.exports=b["default"]}])}); \ No newline at end of file
diff --git a/apidoc/vendor/jquery.min.js b/apidoc/vendor/jquery.min.js
deleted file mode 100644
index 6a190698..00000000
--- a/apidoc/vendor/jquery.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */
-!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)})},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2})},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2})},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")}),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={})[a.uniqueID]||(o[a.uniqueID]={})[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={})[a.uniqueID]||(o[a.uniqueID]={})[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={})[a.uniqueID]||(o[a.uniqueID]={})[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={})[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""}).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(D).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType})},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0});for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var j,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)}),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0})),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function Se(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function ke(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Ae(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}}):void 0===Y.get(e,i)&&S.event.add(e,i,Ce)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click",Ce),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Ae(this,e,Se),!1},trigger:function(){return Ae(this,e),!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return ke(this,e,t,n,r)},one:function(e,t,n,r){return ke(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){S.event.remove(this,e,n,t)})}});var Ne=/<script|<style|<link/i,De=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function Pe(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&De.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,He),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(je,""),u,l))}return n}function Re(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Me=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Ie=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},We=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Fe=new RegExp(ne.join("|"),"i");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||Ie(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Me.test(a)&&Fe.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function $e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px",t.style.height="1px",n.style.height="9px",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}})}();var _e=["Webkit","Moz","ms"],ze=E.createElement("div").style,Ue={};function Xe(e){var t=S.cssProps[e]||Ue[e];return t||(e in ze?e:Ue[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=_e.length;while(n--)if((e=_e[n]+t)in ze)return e}(e)||e)}var Ve=/^(none|table(?!-c[ea]).+)/,Ge=/^--/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):We(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Ie(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=$e(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},function(){return e.getBoundingClientRect().left})+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue}),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})}),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]}),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])}),u=ct(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",y.checkOn=""!==rt.value,y.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",y.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(P)||[]).join(" ")}function yt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,yt(this)))});if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,yt(this)))});if(!arguments.length)return this.attr("class","");if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,yt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=mt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=yt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+vt(yt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""}),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))}):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:vt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||S.error("Invalid XML: "+e),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function Dt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):Dt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)Dt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)Dt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var jt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Bt(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function $t(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={})[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,S.ajaxSettings),t):$t(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Bt(Rt,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Ot.test(v.type),f=v.url.replace(qt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(jt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Et.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+It+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Bt(Mt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();y.cors=!!zt&&"withCredentials"in zt,y.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(y.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=vt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
diff --git a/apidoc/vendor/list.min.js b/apidoc/vendor/list.min.js
deleted file mode 100644
index 06c4721a..00000000
--- a/apidoc/vendor/list.min.js
+++ /dev/null
@@ -1,2 +0,0 @@
-// List.js v1.3.0 (http://www.listjs.com) by Jonny Strömberg (http://javve.com)
-!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){!function(c,d){"use strict";var e=c.document,f=a("./src/utils/get-by-class"),g=a("./src/utils/extend"),h=a("./src/utils/index-of"),i=a("./src/utils/events"),j=a("./src/utils/to-string"),k=a("./src/utils/natural-sort"),l=a("./src/utils/classes"),m=a("./src/utils/get-attribute"),n=a("./src/utils/to-array"),o=function(b,c,p){var q,r=this,s=a("./src/item")(r),t=a("./src/add-async")(r);q={start:function(){r.listClass="list",r.searchClass="search",r.sortClass="sort",r.page=1e4,r.i=1,r.items=[],r.visibleItems=[],r.matchingItems=[],r.searched=!1,r.filtered=!1,r.searchColumns=d,r.handlers={updated:[]},r.plugins={},r.valueNames=[],r.utils={getByClass:f,extend:g,indexOf:h,events:i,toString:j,naturalSort:k,classes:l,getAttribute:m,toArray:n},r.utils.extend(r,c),r.listContainer="string"==typeof b?e.getElementById(b):b,r.listContainer&&(r.list=f(r.listContainer,r.listClass,!0),r.parse=a("./src/parse")(r),r.templater=a("./src/templater")(r),r.search=a("./src/search")(r),r.filter=a("./src/filter")(r),r.sort=a("./src/sort")(r),this.handlers(),this.items(),r.update(),this.plugins())},handlers:function(){for(var a in r.handlers)r[a]&&r.on(a,r[a])},items:function(){r.parse(r.list),p!==d&&r.add(p)},plugins:function(){for(var a=0;a<r.plugins.length;a++){var b=r.plugins[a];r[b.name]=b,b.init(r,o)}}},this.reIndex=function(){r.items=[],r.visibleItems=[],r.matchingItems=[],r.searched=!1,r.filtered=!1,r.parse(r.list)},this.toJSON=function(){for(var a=[],b=0,c=r.items.length;b<c;b++)a.push(r.items[b].values());return a},this.add=function(a,b){if(0!==a.length){if(b)return void t(a,b);var c=[],e=!1;a[0]===d&&(a=[a]);for(var f=0,g=a.length;f<g;f++){var h=null;e=r.items.length>r.page,h=new s(a[f],d,e),r.items.push(h),c.push(h)}return r.update(),c}},this.show=function(a,b){return this.i=a,this.page=b,r.update(),r},this.remove=function(a,b,c){for(var d=0,e=0,f=r.items.length;e<f;e++)r.items[e].values()[a]==b&&(r.templater.remove(r.items[e],c),r.items.splice(e,1),f--,e--,d++);return r.update(),d},this.get=function(a,b){for(var c=[],d=0,e=r.items.length;d<e;d++){var f=r.items[d];f.values()[a]==b&&c.push(f)}return c},this.size=function(){return r.items.length},this.clear=function(){return r.templater.clear(),r.items=[],r},this.on=function(a,b){return r.handlers[a].push(b),r},this.off=function(a,b){var c=r.handlers[a],d=h(c,b);return d>-1&&c.splice(d,1),r},this.trigger=function(a){for(var b=r.handlers[a].length;b--;)r.handlers[a][b](r);return r},this.reset={filter:function(){for(var a=r.items,b=a.length;b--;)a[b].filtered=!1;return r},search:function(){for(var a=r.items,b=a.length;b--;)a[b].found=!1;return r}},this.update=function(){var a=r.items,b=a.length;r.visibleItems=[],r.matchingItems=[],r.templater.clear();for(var c=0;c<b;c++)a[c].matching()&&r.matchingItems.length+1>=r.i&&r.visibleItems.length<r.page?(a[c].show(),r.visibleItems.push(a[c]),r.matchingItems.push(a[c])):a[c].matching()?(r.matchingItems.push(a[c]),a[c].hide()):a[c].hide();return r.trigger("updated"),r},q.start()};"function"==typeof define&&define.amd&&define(function(){return o}),b.exports=o,c.List=o}(window)},{"./src/add-async":2,"./src/filter":3,"./src/item":4,"./src/parse":5,"./src/search":6,"./src/sort":7,"./src/templater":8,"./src/utils/classes":9,"./src/utils/events":10,"./src/utils/extend":11,"./src/utils/get-attribute":12,"./src/utils/get-by-class":13,"./src/utils/index-of":14,"./src/utils/natural-sort":15,"./src/utils/to-array":16,"./src/utils/to-string":17}],2:[function(a,b,c){b.exports=function(a){var b=function(c,d,e){var f=c.splice(0,50);e=e||[],e=e.concat(a.add(f)),c.length>0?setTimeout(function(){b(c,d,e)},1):(a.update(),d(e))};return b}},{}],3:[function(a,b,c){b.exports=function(a){return a.handlers.filterStart=a.handlers.filterStart||[],a.handlers.filterComplete=a.handlers.filterComplete||[],function(b){if(a.trigger("filterStart"),a.i=1,a.reset.filter(),void 0===b)a.filtered=!1;else{a.filtered=!0;for(var c=a.items,d=0,e=c.length;d<e;d++){var f=c[d];b(f)?f.filtered=!0:f.filtered=!1}}return a.update(),a.trigger("filterComplete"),a.visibleItems}}},{}],4:[function(a,b,c){b.exports=function(a){return function(b,c,d){var e=this;this._values={},this.found=!1,this.filtered=!1;var f=function(b,c,d){if(void 0===c)d?e.values(b,d):e.values(b);else{e.elm=c;var f=a.templater.get(e,b);e.values(f)}};this.values=function(b,c){if(void 0===b)return e._values;for(var d in b)e._values[d]=b[d];c!==!0&&a.templater.set(e,e.values())},this.show=function(){a.templater.show(e)},this.hide=function(){a.templater.hide(e)},this.matching=function(){return a.filtered&&a.searched&&e.found&&e.filtered||a.filtered&&!a.searched&&e.filtered||!a.filtered&&a.searched&&e.found||!a.filtered&&!a.searched},this.visible=function(){return!(!e.elm||e.elm.parentNode!=a.list)},f(b,c,d)}}},{}],5:[function(a,b,c){b.exports=function(b){var c=a("./item")(b),d=function(a){for(var b=a.childNodes,c=[],d=0,e=b.length;d<e;d++)void 0===b[d].data&&c.push(b[d]);return c},e=function(a,d){for(var e=0,f=a.length;e<f;e++)b.items.push(new c(d,a[e]))},f=function(a,c){var d=a.splice(0,50);e(d,c),a.length>0?setTimeout(function(){f(a,c)},1):(b.update(),b.trigger("parseComplete"))};return b.handlers.parseComplete=b.handlers.parseComplete||[],function(){var a=d(b.list),c=b.valueNames;b.indexAsync?f(a,c):e(a,c)}}},{"./item":4}],6:[function(a,b,c){b.exports=function(a){var b,c,d,e,f={resetList:function(){a.i=1,a.templater.clear(),e=void 0},setOptions:function(a){2==a.length&&a[1]instanceof Array?c=a[1]:2==a.length&&"function"==typeof a[1]?(c=void 0,e=a[1]):3==a.length?(c=a[1],e=a[2]):c=void 0},setColumns:function(){0!==a.items.length&&void 0===c&&(c=void 0===a.searchColumns?f.toArray(a.items[0].values()):a.searchColumns)},setSearchString:function(b){b=a.utils.toString(b).toLowerCase(),b=b.replace(/[-[\]{}()*+?.,\\^$|#]/g,"\\$&"),d=b},toArray:function(a){var b=[];for(var c in a)b.push(c);return b}},g={list:function(){for(var b=0,c=a.items.length;b<c;b++)g.item(a.items[b])},item:function(a){a.found=!1;for(var b=0,d=c.length;b<d;b++)if(g.values(a.values(),c[b]))return void(a.found=!0)},values:function(c,e){return!!(c.hasOwnProperty(e)&&(b=a.utils.toString(c[e]).toLowerCase(),""!==d&&b.search(d)>-1))},reset:function(){a.reset.search(),a.searched=!1}},h=function(b){return a.trigger("searchStart"),f.resetList(),f.setSearchString(b),f.setOptions(arguments),f.setColumns(),""===d?g.reset():(a.searched=!0,e?e(d,c):g.list()),a.update(),a.trigger("searchComplete"),a.visibleItems};return a.handlers.searchStart=a.handlers.searchStart||[],a.handlers.searchComplete=a.handlers.searchComplete||[],a.utils.events.bind(a.utils.getByClass(a.listContainer,a.searchClass),"keyup",function(b){var c=b.target||b.srcElement,d=""===c.value&&!a.searched;d||h(c.value)}),a.utils.events.bind(a.utils.getByClass(a.listContainer,a.searchClass),"input",function(a){var b=a.target||a.srcElement;""===b.value&&h("")}),h}},{}],7:[function(a,b,c){b.exports=function(a){a.sortFunction=a.sortFunction||function(b,c,d){return d.desc="desc"==d.order,a.utils.naturalSort(b.values()[d.valueName],c.values()[d.valueName],d)};var b={els:void 0,clear:function(){for(var c=0,d=b.els.length;c<d;c++)a.utils.classes(b.els[c]).remove("asc"),a.utils.classes(b.els[c]).remove("desc")},getOrder:function(b){var c=a.utils.getAttribute(b,"data-order");return"asc"==c||"desc"==c?c:a.utils.classes(b).has("desc")?"asc":a.utils.classes(b).has("asc")?"desc":"asc"},getInSensitive:function(b,c){var d=a.utils.getAttribute(b,"data-insensitive");"false"===d?c.insensitive=!1:c.insensitive=!0},setOrder:function(c){for(var d=0,e=b.els.length;d<e;d++){var f=b.els[d];if(a.utils.getAttribute(f,"data-sort")===c.valueName){var g=a.utils.getAttribute(f,"data-order");"asc"==g||"desc"==g?g==c.order&&a.utils.classes(f).add(c.order):a.utils.classes(f).add(c.order)}}}},c=function(){a.trigger("sortStart");var c={},d=arguments[0].currentTarget||arguments[0].srcElement||void 0;d?(c.valueName=a.utils.getAttribute(d,"data-sort"),b.getInSensitive(d,c),c.order=b.getOrder(d)):(c=arguments[1]||c,c.valueName=arguments[0],c.order=c.order||"asc",c.insensitive="undefined"==typeof c.insensitive||c.insensitive),b.clear(),b.setOrder(c),c.sortFunction=c.sortFunction||a.sortFunction,a.items.sort(function(a,b){var d="desc"===c.order?-1:1;return c.sortFunction(a,b,c)*d}),a.update(),a.trigger("sortComplete")};return a.handlers.sortStart=a.handlers.sortStart||[],a.handlers.sortComplete=a.handlers.sortComplete||[],b.els=a.utils.getByClass(a.listContainer,a.sortClass),a.utils.events.bind(b.els,"click",c),a.on("searchStart",b.clear),a.on("filterStart",b.clear),c}},{}],8:[function(a,b,c){var d=function(a){var b,c=this,d=function(){b=c.getItemSource(a.item),b&&(b=c.clearSourceItem(b,a.valueNames))};this.clearSourceItem=function(b,c){for(var d=0,e=c.length;d<e;d++){var f;if(c[d].data)for(var g=0,h=c[d].data.length;g<h;g++)b.setAttribute("data-"+c[d].data[g],"");else c[d].attr&&c[d].name?(f=a.utils.getByClass(b,c[d].name,!0),f&&f.setAttribute(c[d].attr,"")):(f=a.utils.getByClass(b,c[d],!0),f&&(f.innerHTML=""));f=void 0}return b},this.getItemSource=function(b){if(void 0===b){for(var c=a.list.childNodes,d=0,e=c.length;d<e;d++)if(void 0===c[d].data)return c[d].cloneNode(!0)}else{if(/<tr[\s>]/g.exec(b)){var f=document.createElement("tbody");return f.innerHTML=b,f.firstChild}if(b.indexOf("<")!==-1){var g=document.createElement("div");return g.innerHTML=b,g.firstChild}var h=document.getElementById(a.item);if(h)return h}},this.get=function(b,d){c.create(b);for(var e={},f=0,g=d.length;f<g;f++){var h;if(d[f].data)for(var i=0,j=d[f].data.length;i<j;i++)e[d[f].data[i]]=a.utils.getAttribute(b.elm,"data-"+d[f].data[i]);else d[f].attr&&d[f].name?(h=a.utils.getByClass(b.elm,d[f].name,!0),e[d[f].name]=h?a.utils.getAttribute(h,d[f].attr):""):(h=a.utils.getByClass(b.elm,d[f],!0),e[d[f]]=h?h.innerHTML:"");h=void 0}return e},this.set=function(b,d){var e=function(b){for(var c=0,d=a.valueNames.length;c<d;c++)if(a.valueNames[c].data){for(var e=a.valueNames[c].data,f=0,g=e.length;f<g;f++)if(e[f]===b)return{data:b}}else{if(a.valueNames[c].attr&&a.valueNames[c].name&&a.valueNames[c].name==b)return a.valueNames[c];if(a.valueNames[c]===b)return b}},f=function(c,d){var f,g=e(c);g&&(g.data?b.elm.setAttribute("data-"+g.data,d):g.attr&&g.name?(f=a.utils.getByClass(b.elm,g.name,!0),f&&f.setAttribute(g.attr,d)):(f=a.utils.getByClass(b.elm,g,!0),f&&(f.innerHTML=d)),f=void 0)};if(!c.create(b))for(var g in d)d.hasOwnProperty(g)&&f(g,d[g])},this.create=function(a){if(void 0!==a.elm)return!1;if(void 0===b)throw new Error("The list need to have at list one item on init otherwise you'll have to add a template.");var d=b.cloneNode(!0);return d.removeAttribute("id"),a.elm=d,c.set(a,a.values()),!0},this.remove=function(b){b.elm.parentNode===a.list&&a.list.removeChild(b.elm)},this.show=function(b){c.create(b),a.list.appendChild(b.elm)},this.hide=function(b){void 0!==b.elm&&b.elm.parentNode===a.list&&a.list.removeChild(b.elm)},this.clear=function(){if(a.list.hasChildNodes())for(;a.list.childNodes.length>=1;)a.list.removeChild(a.list.firstChild)},d()};b.exports=function(a){return new d(a)}},{}],9:[function(a,b,c){function d(a){if(!a||!a.nodeType)throw new Error("A DOM element reference is required");this.el=a,this.list=a.classList}var e=a("./index-of"),f=/\s+/,g=Object.prototype.toString;b.exports=function(a){return new d(a)},d.prototype.add=function(a){if(this.list)return this.list.add(a),this;var b=this.array(),c=e(b,a);return~c||b.push(a),this.el.className=b.join(" "),this},d.prototype.remove=function(a){if("[object RegExp]"==g.call(a))return this.removeMatching(a);if(this.list)return this.list.remove(a),this;var b=this.array(),c=e(b,a);return~c&&b.splice(c,1),this.el.className=b.join(" "),this},d.prototype.removeMatching=function(a){for(var b=this.array(),c=0;c<b.length;c++)a.test(b[c])&&this.remove(b[c]);return this},d.prototype.toggle=function(a,b){return this.list?("undefined"!=typeof b?b!==this.list.toggle(a,b)&&this.list.toggle(a):this.list.toggle(a),this):("undefined"!=typeof b?b?this.add(a):this.remove(a):this.has(a)?this.remove(a):this.add(a),this)},d.prototype.array=function(){var a=this.el.getAttribute("class")||"",b=a.replace(/^\s+|\s+$/g,""),c=b.split(f);return""===c[0]&&c.shift(),c},d.prototype.has=d.prototype.contains=function(a){return this.list?this.list.contains(a):!!~e(this.array(),a)}},{"./index-of":14}],10:[function(a,b,c){var d=window.addEventListener?"addEventListener":"attachEvent",e=window.removeEventListener?"removeEventListener":"detachEvent",f="addEventListener"!==d?"on":"",g=a("./to-array");c.bind=function(a,b,c,e){a=g(a);for(var h=0;h<a.length;h++)a[h][d](f+b,c,e||!1)},c.unbind=function(a,b,c,d){a=g(a);for(var h=0;h<a.length;h++)a[h][e](f+b,c,d||!1)}},{"./to-array":16}],11:[function(a,b,c){b.exports=function(a){for(var b,c=Array.prototype.slice.call(arguments,1),d=0;b=c[d];d++)if(b)for(var e in b)a[e]=b[e];return a}},{}],12:[function(a,b,c){b.exports=function(a,b){var c=a.getAttribute&&a.getAttribute(b)||null;if(!c)for(var d=a.attributes,e=d.length,f=0;f<e;f++)void 0!==b[f]&&b[f].nodeName===b&&(c=b[f].nodeValue);return c}},{}],13:[function(a,b,c){b.exports=function(){return document.getElementsByClassName?function(a,b,c){return c?a.getElementsByClassName(b)[0]:a.getElementsByClassName(b)}:document.querySelector?function(a,b,c){return b="."+b,c?a.querySelector(b):a.querySelectorAll(b)}:function(a,b,c){var d=[],e="*";null===a&&(a=document);for(var f=a.getElementsByTagName(e),g=f.length,h=new RegExp("(^|\\s)"+b+"(\\s|$)"),i=0,j=0;i<g;i++)if(h.test(f[i].className)){if(c)return f[i];d[j]=f[i],j++}return d}}()},{}],14:[function(a,b,c){var d=[].indexOf;b.exports=function(a,b){if(d)return a.indexOf(b);for(var c=0;c<a.length;++c)if(a[c]===b)return c;return-1}},{}],15:[function(a,b,c){b.exports=function(a,b,c){var d,e,f=/(^([+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|^0x[\da-fA-F]+$|\d+)/g,g=/^\s+|\s+$/g,h=/\s+/g,i=/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,j=/^0x[0-9a-f]+$/i,k=/^0/,l=c||{},m=function(a){return(l.insensitive&&(""+a).toLowerCase()||""+a).replace(g,"")},n=m(a),o=m(b),p=n.replace(f,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0"),q=o.replace(f,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0"),r=parseInt(n.match(j),16)||1!==p.length&&Date.parse(n),s=parseInt(o.match(j),16)||r&&o.match(i)&&Date.parse(o)||null,t=function(a,b){return(!a.match(k)||1==b)&&parseFloat(a)||a.replace(h," ").replace(g,"")||0};if(s){if(r<s)return-1;if(r>s)return 1}for(var u=0,v=p.length,w=q.length,x=Math.max(v,w);u<x;u++){if(d=t(p[u]||"",v),e=t(q[u]||"",w),isNaN(d)!==isNaN(e))return isNaN(d)?1:-1;if(/[^\x00-\x80]/.test(d+e)&&d.localeCompare){var y=d.localeCompare(e);return y/Math.abs(y)}if(d<e)return-1;if(d>e)return 1}return 0}},{}],16:[function(a,b,c){function d(a){return"[object Array]"===Object.prototype.toString.call(a)}b.exports=function(a){if("undefined"==typeof a)return[];if(null===a)return[null];if(a===window)return[window];if("string"==typeof a)return[a];if(d(a))return a;if("number"!=typeof a.length)return[a];if("function"==typeof a&&a instanceof Function)return[a];for(var b=[],c=0;c<a.length;c++)(Object.prototype.hasOwnProperty.call(a,c)||c in a)&&b.push(a[c]);return b.length?b:[]}},{}],17:[function(a,b,c){b.exports=function(a){return a=void 0===a?"":a,a=null===a?"":a,a=a.toString()}},{}]},{},[1]); \ No newline at end of file
diff --git a/apidoc/vendor/lodash.custom.min.js b/apidoc/vendor/lodash.custom.min.js
deleted file mode 100644
index 24f0dac6..00000000
--- a/apidoc/vendor/lodash.custom.min.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @license
- * Lodash (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
- * Build: `lodash -p -o template/vendor/lodash.custom.min.js include="get,set,groupBy,each,extend,some,isNaN" exports="amd"`
- */
-;(function(){function t(t,e,r){switch(r.length){case 0:return t.call(e);case 1:return t.call(e,r[0]);case 2:return t.call(e,r[0],r[1]);case 3:return t.call(e,r[0],r[1],r[2])}return t.apply(e,r)}function e(t,e,r,n){for(var o=-1,c=null==t?0:t.length;++o<c;){var u=t[o];e(n,u,r(u),t)}return n}function r(t,e){for(var r=-1,n=null==t?0:t.length;++r<n&&false!==e(t[r],r,t););return t}function n(t,e){for(var r=-1,n=null==t?0:t.length,o=0,c=[];++r<n;){var u=t[r];e(u,r,t)&&(c[o++]=u)}return c}function o(t,e){for(var r=-1,n=e.length,o=t.length;++r<n;)t[o+r]=e[r];
-return t}function c(t,e){for(var r=-1,n=null==t?0:t.length;++r<n;)if(e(t[r],r,t))return true;return false}function u(t){return function(e){return null==e?Ut:e[t]}}function i(t){return function(e){return t(e)}}function a(t){var e=-1,r=Array(t.size);return t.forEach(function(t,n){r[++e]=[n,t]}),r}function f(t){var e=Object;return function(r){return t(e(r))}}function s(t){var e=-1,r=Array(t.size);return t.forEach(function(t){r[++e]=t}),r}function l(){}function b(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){
-var n=t[e];this.set(n[0],n[1])}}function h(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function p(t){var e=-1,r=null==t?0:t.length;for(this.clear();++e<r;){var n=t[e];this.set(n[0],n[1])}}function y(t){var e=-1,r=null==t?0:t.length;for(this.__data__=new p;++e<r;)this.add(t[e])}function j(t){this.size=(this.__data__=new h(t)).size}function _(t,e){var r=Ke(t),n=!r&&Je(t),o=!r&&!n&&Qe(t),c=!r&&!n&&!o&&Ze(t);if(r=r||n||o||c){for(var n=t.length,u=String,i=-1,a=Array(n);++i<n;)a[i]=u(i);
-n=a}else n=[];var f,u=n.length;for(f in t)!e&&!ce.call(t,f)||r&&("length"==f||o&&("offset"==f||"parent"==f)||c&&("buffer"==f||"byteLength"==f||"byteOffset"==f)||ot(f,u))||n.push(f);return n}function v(t,e,r){var n=t[e];ce.call(t,e)&&pt(n,r)&&(r!==Ut||e in t)||m(t,e,r)}function g(t,e){for(var r=t.length;r--;)if(pt(t[r][0],e))return r;return-1}function d(t,e,r,n){return Pe(t,function(t,o,c){e(n,t,r(t),c)}),n}function A(t,e){return t&&G(e,St(e),t)}function w(t,e){return t&&G(e,zt(e),t)}function m(t,e,r){
-"__proto__"==e&&ve?ve(t,e,{configurable:true,enumerable:true,value:r,writable:true}):t[e]=r}function O(t,e,n,o,c,u){var i,a=1&e,f=2&e,s=4&e;if(n&&(i=c?n(t,o,c,u):n(t)),i!==Ut)return i;if(!vt(t))return t;if(o=Ke(t)){if(i=rt(t),!a)return W(t,i)}else{var l=We(t),b="[object Function]"==l||"[object GeneratorFunction]"==l;if(Qe(t))return R(t,a);if("[object Object]"==l||"[object Arguments]"==l||b&&!c){if(i=f||b?{}:typeof t.constructor!="function"||it(t)?{}:Ne(he(t)),!a)return f?H(t,w(i,t)):q(t,A(i,t))}else{if(!Tt[l])return c?t:{};
-i=nt(t,l,a)}}if(u||(u=new j),c=u.get(t))return c;if(u.set(t,i),Ye(t))return t.forEach(function(r){i.add(O(r,e,n,r,t,u))}),i;if(Xe(t))return t.forEach(function(r,o){i.set(o,O(r,e,n,o,t,u))}),i;var f=s?f?X:Q:f?zt:St,h=o?Ut:f(t);return r(h||t,function(r,o){h&&(o=r,r=t[o]),v(i,o,O(r,e,n,o,t,u))}),i}function S(t,e){e=C(e,t);for(var r=0,n=e.length;null!=t&&r<n;)t=t[st(e[r++])];return r&&r==n?t:Ut}function z(t,e,r){return e=e(t),Ke(t)?e:o(e,r(t))}function k(t){if(null==t)t=t===Ut?"[object Undefined]":"[object Null]";else if(_e&&_e in Object(t)){
-var e=ce.call(t,_e),r=t[_e];try{t[_e]=Ut;var n=true}catch(t){}var o=ie.call(t);n&&(e?t[_e]=r:delete t[_e]),t=o}else t=ie.call(t);return t}function x(t){return gt(t)&&"[object Arguments]"==k(t)}function E(t,e,r,n,o){if(t===e)e=true;else if(null==t||null==e||!gt(t)&&!gt(e))e=t!==t&&e!==e;else t:{var c=Ke(t),u=Ke(e),i=c?"[object Array]":We(t),a=u?"[object Array]":We(e),i="[object Arguments]"==i?"[object Object]":i,a="[object Arguments]"==a?"[object Object]":a,f="[object Object]"==i,u="[object Object]"==a;
-if((a=i==a)&&Qe(t)){if(!Qe(e)){e=false;break t}c=true,f=false}if(a&&!f)o||(o=new j),e=c||Ze(t)?J(t,e,r,n,E,o):K(t,e,i,r,n,E,o);else{if(!(1&r)&&(c=f&&ce.call(t,"__wrapped__"),i=u&&ce.call(e,"__wrapped__"),c||i)){t=c?t.value():t,e=i?e.value():e,o||(o=new j),e=E(t,e,r,n,o);break t}if(a)e:if(o||(o=new j),c=1&r,i=Q(t),u=i.length,a=Q(e).length,u==a||c){for(f=u;f--;){var s=i[f];if(!(c?s in e:ce.call(e,s))){e=false;break e}}if((a=o.get(t))&&o.get(e))e=a==e;else{a=true,o.set(t,e),o.set(e,t);for(var l=c;++f<u;){var s=i[f],b=t[s],h=e[s];
-if(n)var p=c?n(h,b,s,e,t,o):n(b,h,s,t,e,o);if(p===Ut?b!==h&&!E(b,h,r,n,o):!p){a=false;break}l||(l="constructor"==s)}a&&!l&&(r=t.constructor,n=e.constructor,r!=n&&"constructor"in t&&"constructor"in e&&!(typeof r=="function"&&r instanceof r&&typeof n=="function"&&n instanceof n)&&(a=false)),o.delete(t),o.delete(e),e=a}}else e=false;else e=false}}return e}function F(t){return gt(t)&&"[object Map]"==We(t)}function I(t,e){var r=e.length,n=r;if(null==t)return!n;for(t=Object(t);r--;){var o=e[r];if(o[2]?o[1]!==t[o[0]]:!(o[0]in t))return false;
-}for(;++r<n;){var o=e[r],c=o[0],u=t[c],i=o[1];if(o[2]){if(u===Ut&&!(c in t))return false}else if(o=new j,void 0===Ut?!E(i,u,3,void 0,o):1)return false}return true}function M(t){return gt(t)&&"[object Set]"==We(t)}function U(t){return gt(t)&&_t(t.length)&&!!Rt[k(t)]}function B(t){return typeof t=="function"?t:null==t?xt:typeof t=="object"?Ke(t)?$(t[0],t[1]):D(t):Ft(t)}function D(t){var e=tt(t);return 1==e.length&&e[0][2]?at(e[0][0],e[0][1]):function(r){return r===t||I(r,e)}}function $(t,e){return ut(t)&&e===e&&!vt(e)?at(st(t),e):function(r){
-var n=mt(r,t);return n===Ut&&n===e?Ot(r,t):E(e,n,3)}}function L(t){return function(e){return S(e,t)}}function N(t){return Ge(ft(t,xt),t+"")}function P(t,e){var r;return Pe(t,function(t,n,o){return r=e(t,n,o),!r}),!!r}function V(t){if(typeof t=="string")return t;if(Ke(t)){for(var e=V,r=-1,n=null==t?0:t.length,o=Array(n);++r<n;)o[r]=e(t[r],r,t);return o+""}return At(t)?Le?Le.call(t):"":(e=t+"","0"==e&&1/t==-Bt?"-0":e)}function C(t,e){return Ke(t)?t:ut(t,e)?[t]:qe(wt(t))}function R(t,e){if(e)return t.slice();
-var r=t.length,r=be?be(r):new t.constructor(r);return t.copy(r),r}function T(t){var e=new t.constructor(t.byteLength);return new le(e).set(new le(t)),e}function W(t,e){var r=-1,n=t.length;for(e||(e=Array(n));++r<n;)e[r]=t[r];return e}function G(t,e,r){var n=!r;r||(r={});for(var o=-1,c=e.length;++o<c;){var u=e[o],i=Ut;i===Ut&&(i=t[u]),n?m(r,u,i):v(r,u,i)}return r}function q(t,e){return G(t,Re(t),e)}function H(t,e){return G(t,Te(t),e)}function J(t,e,r,n,o,u){var i=1&r,a=t.length,f=e.length;if(a!=f&&!(i&&f>a))return false;
-if((f=u.get(t))&&u.get(e))return f==e;var f=-1,s=true,l=2&r?new y:Ut;for(u.set(t,e),u.set(e,t);++f<a;){var b=t[f],h=e[f];if(n)var p=i?n(h,b,f,e,t,u):n(b,h,f,t,e,u);if(p!==Ut){if(p)continue;s=false;break}if(l){if(!c(e,function(t,e){if(!l.has(e)&&(b===t||o(b,t,r,n,u)))return l.push(e)}){s=false;break}}else if(b!==h&&!o(b,h,r,n,u)){s=false;break}}return u.delete(t),u.delete(e),s}function K(t,e,r,n,o,c,u){switch(r){case"[object DataView]":if(t.byteLength!=e.byteLength||t.byteOffset!=e.byteOffset)break;t=t.buffer,
-e=e.buffer;case"[object ArrayBuffer]":if(t.byteLength!=e.byteLength||!c(new le(t),new le(e)))break;return true;case"[object Boolean]":case"[object Date]":case"[object Number]":return pt(+t,+e);case"[object Error]":return t.name==e.name&&t.message==e.message;case"[object RegExp]":case"[object String]":return t==e+"";case"[object Map]":var i=a;case"[object Set]":if(i||(i=s),t.size!=e.size&&!(1&n))break;return(r=u.get(t))?r==e:(n|=2,u.set(t,e),e=J(i(t),i(e),n,o,c,u),u.delete(t),e);case"[object Symbol]":
-if($e)return $e.call(t)==$e.call(e)}return false}function Q(t){return z(t,St,Re)}function X(t){return z(t,zt,Te)}function Y(){var t=l.iteratee||Et,t=t===Et?B:t;return arguments.length?t(arguments[0],arguments[1]):t}function Z(t,e){var r=t.__data__,n=typeof e;return("string"==n||"number"==n||"symbol"==n||"boolean"==n?"__proto__"!==e:null===e)?r[typeof e=="string"?"string":"hash"]:r.map}function tt(t){for(var e=St(t),r=e.length;r--;){var n=e[r],o=t[n];e[r]=[n,o,o===o&&!vt(o)]}return e}function et(t,e){
-var r=null==t?Ut:t[e];return(!vt(r)||ue&&ue in r?0:(jt(r)?ae:Vt).test(lt(r)))?r:Ut}function rt(t){var e=t.length,r=new t.constructor(e);return e&&"string"==typeof t[0]&&ce.call(t,"index")&&(r.index=t.index,r.input=t.input),r}function nt(t,e,r){var n=t.constructor;switch(e){case"[object ArrayBuffer]":return T(t);case"[object Boolean]":case"[object Date]":return new n(+t);case"[object DataView]":return e=r?T(t.buffer):t.buffer,new t.constructor(e,t.byteOffset,t.byteLength);case"[object Float32Array]":
-case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return e=r?T(t.buffer):t.buffer,new t.constructor(e,t.byteOffset,t.length);case"[object Map]":return new n;case"[object Number]":case"[object String]":return new n(t);case"[object RegExp]":return e=new t.constructor(t.source,Pt.exec(t)),e.lastIndex=t.lastIndex,e;case"[object Set]":return new n;
-case"[object Symbol]":return $e?Object($e.call(t)):{}}}function ot(t,e){var r=typeof t;return e=null==e?9007199254740991:e,!!e&&("number"==r||"symbol"!=r&&Ct.test(t))&&-1<t&&0==t%1&&t<e}function ct(t,e,r){if(!vt(r))return false;var n=typeof e;return!!("number"==n?yt(r)&&ot(e,r.length):"string"==n&&e in r)&&pt(r[e],t)}function ut(t,e){if(Ke(t))return false;var r=typeof t;return!("number"!=r&&"symbol"!=r&&"boolean"!=r&&null!=t&&!At(t))||($t.test(t)||!Dt.test(t)||null!=e&&t in Object(e))}function it(t){var e=t&&t.constructor;
-return t===(typeof e=="function"&&e.prototype||re)}function at(t,e){return function(r){return null!=r&&(r[t]===e&&(e!==Ut||t in Object(r)))}}function ft(e,r){var n=void 0,n=we(n===Ut?e.length-1:n,0);return function(){for(var o=arguments,c=-1,u=we(o.length-n,0),i=Array(u);++c<u;)i[c]=o[n+c];for(c=-1,u=Array(n+1);++c<n;)u[c]=o[c];return u[n]=r(i),t(e,this,u)}}function st(t){if(typeof t=="string"||At(t))return t;var e=t+"";return"0"==e&&1/t==-Bt?"-0":e}function lt(t){if(null!=t){try{return oe.call(t);
-}catch(t){}return t+""}return""}function bt(t,e){return(Ke(t)?r:Pe)(t,Y(e,3))}function ht(t,e){function r(){var n=arguments,o=e?e.apply(this,n):n[0],c=r.cache;return c.has(o)?c.get(o):(n=t.apply(this,n),r.cache=c.set(o,n)||c,n)}if(typeof t!="function"||null!=e&&typeof e!="function")throw new TypeError("Expected a function");return r.cache=new(ht.Cache||p),r}function pt(t,e){return t===e||t!==t&&e!==e}function yt(t){return null!=t&&_t(t.length)&&!jt(t)}function jt(t){return!!vt(t)&&(t=k(t),"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t);
-}function _t(t){return typeof t=="number"&&-1<t&&0==t%1&&9007199254740991>=t}function vt(t){var e=typeof t;return null!=t&&("object"==e||"function"==e)}function gt(t){return null!=t&&typeof t=="object"}function dt(t){return typeof t=="number"||gt(t)&&"[object Number]"==k(t)}function At(t){return typeof t=="symbol"||gt(t)&&"[object Symbol]"==k(t)}function wt(t){return null==t?"":V(t)}function mt(t,e,r){return t=null==t?Ut:S(t,e),t===Ut?r:t}function Ot(t,e){var r;if(r=null!=t){r=t;var n;n=C(e,r);for(var o=-1,c=n.length,u=false;++o<c;){
-var i=st(n[o]);if(!(u=null!=r&&null!=r&&i in Object(r)))break;r=r[i]}u||++o!=c?r=u:(c=null==r?0:r.length,r=!!c&&_t(c)&&ot(i,c)&&(Ke(r)||Je(r)))}return r}function St(t){if(yt(t))t=_(t);else if(it(t)){var e,r=[];for(e in Object(t))ce.call(t,e)&&"constructor"!=e&&r.push(e);t=r}else t=Ae(t);return t}function zt(t){if(yt(t))t=_(t,true);else if(vt(t)){var e,r=it(t),n=[];for(e in t)("constructor"!=e||!r&&ce.call(t,e))&&n.push(e);t=n}else{if(e=[],null!=t)for(r in Object(t))e.push(r);t=e}return t}function kt(t){
-return function(){return t}}function xt(t){return t}function Et(t){return B(typeof t=="function"?t:O(t,1))}function Ft(t){return ut(t)?u(st(t)):L(t)}function It(){return[]}function Mt(){return false}var Ut,Bt=1/0,Dt=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,$t=/^\w*$/,Lt=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,Nt=/\\(\\)?/g,Pt=/\w*$/,Vt=/^\[object .+?Constructor\]$/,Ct=/^(?:0|[1-9]\d*)$/,Rt={};Rt["[object Float32Array]"]=Rt["[object Float64Array]"]=Rt["[object Int8Array]"]=Rt["[object Int16Array]"]=Rt["[object Int32Array]"]=Rt["[object Uint8Array]"]=Rt["[object Uint8ClampedArray]"]=Rt["[object Uint16Array]"]=Rt["[object Uint32Array]"]=true,
-Rt["[object Arguments]"]=Rt["[object Array]"]=Rt["[object ArrayBuffer]"]=Rt["[object Boolean]"]=Rt["[object DataView]"]=Rt["[object Date]"]=Rt["[object Error]"]=Rt["[object Function]"]=Rt["[object Map]"]=Rt["[object Number]"]=Rt["[object Object]"]=Rt["[object RegExp]"]=Rt["[object Set]"]=Rt["[object String]"]=Rt["[object WeakMap]"]=false;var Tt={};Tt["[object Arguments]"]=Tt["[object Array]"]=Tt["[object ArrayBuffer]"]=Tt["[object DataView]"]=Tt["[object Boolean]"]=Tt["[object Date]"]=Tt["[object Float32Array]"]=Tt["[object Float64Array]"]=Tt["[object Int8Array]"]=Tt["[object Int16Array]"]=Tt["[object Int32Array]"]=Tt["[object Map]"]=Tt["[object Number]"]=Tt["[object Object]"]=Tt["[object RegExp]"]=Tt["[object Set]"]=Tt["[object String]"]=Tt["[object Symbol]"]=Tt["[object Uint8Array]"]=Tt["[object Uint8ClampedArray]"]=Tt["[object Uint16Array]"]=Tt["[object Uint32Array]"]=true,
-Tt["[object Error]"]=Tt["[object Function]"]=Tt["[object WeakMap]"]=false;var Wt,Gt=typeof global=="object"&&global&&global.Object===Object&&global,qt=typeof self=="object"&&self&&self.Object===Object&&self,Ht=Gt||qt||Function("return this")(),Jt=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Kt=Jt&&typeof module=="object"&&module&&!module.nodeType&&module,Qt=Kt&&Kt.exports===Jt,Xt=Qt&&Gt.process;t:{try{Wt=Xt&&Xt.binding&&Xt.binding("util");break t}catch(t){}Wt=void 0}var Yt=Wt&&Wt.isMap,Zt=Wt&&Wt.isSet,te=Wt&&Wt.isTypedArray,ee=Array.prototype,re=Object.prototype,ne=Ht["__core-js_shared__"],oe=Function.prototype.toString,ce=re.hasOwnProperty,ue=function(){
-var t=/[^.]+$/.exec(ne&&ne.keys&&ne.keys.IE_PROTO||"");return t?"Symbol(src)_1."+t:""}(),ie=re.toString,ae=RegExp("^"+oe.call(ce).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),fe=Qt?Ht.Buffer:Ut,se=Ht.Symbol,le=Ht.Uint8Array,be=fe?fe.a:Ut,he=f(Object.getPrototypeOf),pe=Object.create,ye=re.propertyIsEnumerable,je=ee.splice,_e=se?se.toStringTag:Ut,ve=function(){try{var t=et(Object,"defineProperty");return t({},"",{}),t}catch(t){}
-}(),ge=Object.getOwnPropertySymbols,de=fe?fe.isBuffer:Ut,Ae=f(Object.keys),we=Math.max,me=Date.now,Oe=et(Ht,"DataView"),Se=et(Ht,"Map"),ze=et(Ht,"Promise"),ke=et(Ht,"Set"),xe=et(Ht,"WeakMap"),Ee=et(Object,"create"),Fe=lt(Oe),Ie=lt(Se),Me=lt(ze),Ue=lt(ke),Be=lt(xe),De=se?se.prototype:Ut,$e=De?De.valueOf:Ut,Le=De?De.toString:Ut,Ne=function(){function t(){}return function(e){return vt(e)?pe?pe(e):(t.prototype=e,e=new t,t.prototype=Ut,e):{}}}();b.prototype.clear=function(){this.__data__=Ee?Ee(null):{},
-this.size=0},b.prototype.delete=function(t){return t=this.has(t)&&delete this.__data__[t],this.size-=t?1:0,t},b.prototype.get=function(t){var e=this.__data__;return Ee?(t=e[t],"__lodash_hash_undefined__"===t?Ut:t):ce.call(e,t)?e[t]:Ut},b.prototype.has=function(t){var e=this.__data__;return Ee?e[t]!==Ut:ce.call(e,t)},b.prototype.set=function(t,e){var r=this.__data__;return this.size+=this.has(t)?0:1,r[t]=Ee&&e===Ut?"__lodash_hash_undefined__":e,this},h.prototype.clear=function(){this.__data__=[],this.size=0;
-},h.prototype.delete=function(t){var e=this.__data__;return t=g(e,t),!(0>t)&&(t==e.length-1?e.pop():je.call(e,t,1),--this.size,true)},h.prototype.get=function(t){var e=this.__data__;return t=g(e,t),0>t?Ut:e[t][1]},h.prototype.has=function(t){return-1<g(this.__data__,t)},h.prototype.set=function(t,e){var r=this.__data__,n=g(r,t);return 0>n?(++this.size,r.push([t,e])):r[n][1]=e,this},p.prototype.clear=function(){this.size=0,this.__data__={hash:new b,map:new(Se||h),string:new b}},p.prototype.delete=function(t){
-return t=Z(this,t).delete(t),this.size-=t?1:0,t},p.prototype.get=function(t){return Z(this,t).get(t)},p.prototype.has=function(t){return Z(this,t).has(t)},p.prototype.set=function(t,e){var r=Z(this,t),n=r.size;return r.set(t,e),this.size+=r.size==n?0:1,this},y.prototype.add=y.prototype.push=function(t){return this.__data__.set(t,"__lodash_hash_undefined__"),this},y.prototype.has=function(t){return this.__data__.has(t)},j.prototype.clear=function(){this.__data__=new h,this.size=0},j.prototype.delete=function(t){
-var e=this.__data__;return t=e.delete(t),this.size=e.size,t},j.prototype.get=function(t){return this.__data__.get(t)},j.prototype.has=function(t){return this.__data__.has(t)},j.prototype.set=function(t,e){var r=this.__data__;if(r instanceof h){var n=r.__data__;if(!Se||199>n.length)return n.push([t,e]),this.size=++r.size,this;r=this.__data__=new p(n)}return r.set(t,e),this.size=r.size,this};var Pe=function(t,e){return function(r,n){if(null==r)return r;if(!yt(r))return t(r,n);for(var o=r.length,c=e?o:-1,u=Object(r);(e?c--:++c<o)&&false!==n(u[c],c,u););
-return r}}(function(t,e){return t&&Ve(t,e,St)}),Ve=function(t){return function(e,r,n){var o=-1,c=Object(e);n=n(e);for(var u=n.length;u--;){var i=n[t?u:++o];if(false===r(c[i],i,c))break}return e}}(),Ce=ve?function(t,e){return ve(t,"toString",{configurable:true,enumerable:false,value:kt(e),writable:true})}:xt,Re=ge?function(t){return null==t?[]:(t=Object(t),n(ge(t),function(e){return ye.call(t,e)})}:It,Te=ge?function(t){for(var e=[];t;)o(e,Re(t)),t=he(t);return e}:It,We=k;(Oe&&"[object DataView]"!=We(new Oe(new ArrayBuffer(1)))||Se&&"[object Map]"!=We(new Se)||ze&&"[object Promise]"!=We(ze.resolve())||ke&&"[object Set]"!=We(new ke)||xe&&"[object WeakMap]"!=We(new xe))&&(We=function(t){
-var e=k(t);if(t=(t="[object Object]"==e?t.constructor:Ut)?lt(t):"")switch(t){case Fe:return"[object DataView]";case Ie:return"[object Map]";case Me:return"[object Promise]";case Ue:return"[object Set]";case Be:return"[object WeakMap]"}return e});var Ge=function(t){var e=0,r=0;return function(){var n=me(),o=16-(n-r);if(r=n,0<o){if(800<=++e)return arguments[0]}else e=0;return t.apply(Ut,arguments)}}(Ce),qe=function(t){t=ht(t,function(t){return 500===e.size&&e.clear(),t});var e=t.cache;return t}(function(t){
-var e=[];return 46===t.charCodeAt(0)&&e.push(""),t.replace(Lt,function(t,r,n,o){e.push(n?o.replace(Nt,"$1"):r||t)}),e}),He=function(t,r){return function(n,o){var c=Ke(n)?e:d,u=r?r():{};return c(n,t,Y(o,2),u)}}(function(t,e,r){ce.call(t,r)?t[r].push(e):m(t,r,[e])});ht.Cache=p;var Je=x(function(){return arguments}())?x:function(t){return gt(t)&&ce.call(t,"callee")&&!ye.call(t,"callee")},Ke=Array.isArray,Qe=de||Mt,Xe=Yt?i(Yt):F,Ye=Zt?i(Zt):M,Ze=te?i(te):U,tr=function(t){return N(function(e,r){var n=-1,o=r.length,c=1<o?r[o-1]:Ut,u=2<o?r[2]:Ut,c=3<t.length&&typeof c=="function"?(o--,
-c):Ut;for(u&&ct(r[0],r[1],u)&&(c=3>o?Ut:c,o=1),e=Object(e);++n<o;)(u=r[n])&&t(e,u,n,c);return e})}(function(t,e){G(e,zt(e),t)});l.assignIn=tr,l.constant=kt,l.groupBy=He,l.iteratee=Et,l.keys=St,l.keysIn=zt,l.memoize=ht,l.property=Ft,l.set=function(t,e,r){if(null!=t&&vt(t)){e=C(e,t);for(var n=-1,o=e.length,c=o-1,u=t;null!=u&&++n<o;){var i=st(e[n]),a=r;if(n!=c){var f=u[i],a=Ut;a===Ut&&(a=vt(f)?f:ot(e[n+1])?[]:{})}v(u,i,a),u=u[i]}}return t},l.extend=tr,l.eq=pt,l.forEach=bt,l.get=mt,l.hasIn=Ot,l.identity=xt,
-l.isArguments=Je,l.isArray=Ke,l.isArrayLike=yt,l.isBuffer=Qe,l.isFunction=jt,l.isLength=_t,l.isMap=Xe,l.isNaN=function(t){return dt(t)&&t!=+t},l.isNumber=dt,l.isObject=vt,l.isObjectLike=gt,l.isSet=Ye,l.isSymbol=At,l.isTypedArray=Ze,l.stubArray=It,l.stubFalse=Mt,l.some=function(t,e,r){var n=Ke(t)?c:P;return r&&ct(t,e,r)&&(e=Ut),n(t,Y(e,3))},l.toString=wt,l.each=bt,l.VERSION="4.17.5",typeof define=="function"&&typeof define.amd=="object"&&define.amd&& define(function(){return l})}).call(this); \ No newline at end of file
diff --git a/apidoc/vendor/path-to-regexp/LICENSE b/apidoc/vendor/path-to-regexp/LICENSE
deleted file mode 100644
index 983fbe8a..00000000
--- a/apidoc/vendor/path-to-regexp/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2014 Blake Embrey ([email protected])
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/apidoc/vendor/path-to-regexp/index.js b/apidoc/vendor/path-to-regexp/index.js
deleted file mode 100644
index 5cb8ed8b..00000000
--- a/apidoc/vendor/path-to-regexp/index.js
+++ /dev/null
@@ -1,204 +0,0 @@
-var isArray = Array.isArray || function (arr) {
- return Object.prototype.toString.call(arr) == '[object Array]';
-};
-
-/**
- * Expose `pathToRegexp`.
- */
-// module.exports = pathToRegexp
-
-/**
- * The main path matching regexp utility.
- *
- * @type {RegExp}
- */
-var PATH_REGEXP = new RegExp([
- // Match escaped characters that would otherwise appear in future matches.
- // This allows the user to escape special characters that won't transform.
- '(\\\\.)',
- // Match Express-style parameters and un-named parameters with a prefix
- // and optional suffixes. Matches appear as:
- //
- // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?"]
- // "/route(\\d+)" => [undefined, undefined, undefined, "\d+", undefined]
- '([\\/.])?(?:\\:(\\w+)(?:\\(((?:\\\\.|[^)])*)\\))?|\\(((?:\\\\.|[^)])*)\\))([+*?])?',
- // Match regexp special characters that are always escaped.
- '([.+*?=^!:${}()[\\]|\\/])'
-].join('|'), 'g');
-
-/**
- * Escape the capturing group by escaping special characters and meaning.
- *
- * @param {String} group
- * @return {String}
- */
-function escapeGroup (group) {
- return group.replace(/([=!:$\/()])/g, '\\$1');
-}
-
-/**
- * Attach the keys as a property of the regexp.
- *
- * @param {RegExp} re
- * @param {Array} keys
- * @return {RegExp}
- */
-function attachKeys (re, keys) {
- re.keys = keys;
- return re;
-}
-
-/**
- * Get the flags for a regexp from the options.
- *
- * @param {Object} options
- * @return {String}
- */
-function flags (options) {
- return options.sensitive ? '' : 'i';
-}
-
-/**
- * Pull out keys from a regexp.
- *
- * @param {RegExp} path
- * @param {Array} keys
- * @return {RegExp}
- */
-function regexpToRegexp (path, keys) {
- // Use a negative lookahead to match only capturing groups.
- var groups = path.source.match(/\((?!\?)/g);
-
- if (groups) {
- for (var i = 0; i < groups.length; i++) {
- keys.push({
- name: i,
- delimiter: null,
- optional: false,
- repeat: false
- });
- }
- }
-
- return attachKeys(path, keys);
-}
-
-/**
- * Transform an array into a regexp.
- *
- * @param {Array} path
- * @param {Array} keys
- * @param {Object} options
- * @return {RegExp}
- */
-function arrayToRegexp (path, keys, options) {
- var parts = [];
-
- for (var i = 0; i < path.length; i++) {
- parts.push(pathToRegexp(path[i], keys, options).source);
- }
-
- var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options));
- return attachKeys(regexp, keys);
-}
-
-/**
- * Replace the specific tags with regexp strings.
- *
- * @param {String} path
- * @param {Array} keys
- * @return {String}
- */
-function replacePath (path, keys) {
- var index = 0;
-
- function replace (_, escaped, prefix, key, capture, group, suffix, escape) {
- if (escaped) {
- return escaped;
- }
-
- if (escape) {
- return '\\' + escape;
- }
-
- var repeat = suffix === '+' || suffix === '*';
- var optional = suffix === '?' || suffix === '*';
-
- keys.push({
- name: key || index++,
- delimiter: prefix || '/',
- optional: optional,
- repeat: repeat
- });
-
- prefix = prefix ? ('\\' + prefix) : '';
- capture = escapeGroup(capture || group || '[^' + (prefix || '\\/') + ']+?');
-
- if (repeat) {
- capture = capture + '(?:' + prefix + capture + ')*';
- }
-
- if (optional) {
- return '(?:' + prefix + '(' + capture + '))?';
- }
-
- // Basic parameter support.
- return prefix + '(' + capture + ')';
- }
-
- return path.replace(PATH_REGEXP, replace);
-}
-
-/**
- * Normalize the given path string, returning a regular expression.
- *
- * An empty array can be passed in for the keys, which will hold the
- * placeholder key descriptions. For example, using `/user/:id`, `keys` will
- * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
- *
- * @param {(String|RegExp|Array)} path
- * @param {Array} [keys]
- * @param {Object} [options]
- * @return {RegExp}
- */
-function pathToRegexp (path, keys, options) {
- keys = keys || [];
-
- if (!isArray(keys)) {
- options = keys;
- keys = [];
- } else if (!options) {
- options = {};
- }
-
- if (path instanceof RegExp) {
- return regexpToRegexp(path, keys, options);
- }
-
- if (isArray(path)) {
- return arrayToRegexp(path, keys, options);
- }
-
- var strict = options.strict;
- var end = options.end !== false;
- var route = replacePath(path, keys);
- var endsWithSlash = path.charAt(path.length - 1) === '/';
-
- // In non-strict mode we allow a slash at the end of match. If the path to
- // match already ends with a slash, we remove it for consistency. The slash
- // is valid at the end of a path match, not in the middle. This is important
- // in non-ending mode, where "/test/" shouldn't match "/test//route".
- if (!strict) {
- route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?';
- }
-
- if (end) {
- route += '$';
- } else {
- // In non-ending mode, we need the capturing groups to match as much as
- // possible by using a positive lookahead to the end or next path segment.
- route += strict && endsWithSlash ? '' : '(?=\\/|$)';
- }
-
- return attachKeys(new RegExp('^' + route, flags(options)), keys);
-}
diff --git a/apidoc/vendor/polyfill.js b/apidoc/vendor/polyfill.js
deleted file mode 100644
index 1d8c61cd..00000000
--- a/apidoc/vendor/polyfill.js
+++ /dev/null
@@ -1,96 +0,0 @@
-// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
-if (!Object.keys) {
- Object.keys = (function () {
- 'use strict';
- var hasOwnProperty = Object.prototype.hasOwnProperty,
- hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
- dontEnums = [
- 'toString',
- 'toLocaleString',
- 'valueOf',
- 'hasOwnProperty',
- 'isPrototypeOf',
- 'propertyIsEnumerable',
- 'constructor'
- ],
- dontEnumsLength = dontEnums.length;
-
- return function (obj) {
- if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
- throw new TypeError('Object.keys called on non-object');
- }
-
- var result = [], prop, i;
-
- for (prop in obj) {
- if (hasOwnProperty.call(obj, prop)) {
- result.push(prop);
- }
- }
-
- if (hasDontEnumBug) {
- for (i = 0; i < dontEnumsLength; i++) {
- if (hasOwnProperty.call(obj, dontEnums[i])) {
- result.push(dontEnums[i]);
- }
- }
- }
- return result;
- };
- }());
-}
-
-//Production steps of ECMA-262, Edition 5, 15.4.4.18
-//Reference: http://es5.github.com/#x15.4.4.18
-if (!Array.prototype.forEach) {
- Array.prototype.forEach = function (callback, thisArg) {
- var T, k;
-
- if (this == null) {
- throw new TypeError(' this is null or not defined');
- }
-
- // 1. Let O be the result of calling ToObject passing the |this| value as the argument.
- var O = Object(this);
-
- // 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".
- // 3. Let len be ToUint32(lenValue).
- var len = O.length >>> 0;
-
- // 4. If IsCallable(callback) is false, throw a TypeError exception.
- // See: http://es5.github.com/#x9.11
- if (typeof callback !== "function") {
- throw new TypeError(callback + " is not a function");
- }
-
- // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
- if (arguments.length > 1) {
- T = thisArg;
- }
-
- // 6. Let k be 0
- k = 0;
-
- // 7. Repeat, while k < len
- while (k < len) {
- var kValue;
-
- // a. Let Pk be ToString(k).
- // This is implicit for LHS operands of the in operator
- // b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.
- // This step can be combined with c
- // c. If kPresent is true, then
- if (k in O) {
- // i. Let kValue be the result of calling the Get internal method of O with argument Pk.
- kValue = O[k];
-
- // ii. Call the Call internal method of callback with T as the this value and
- // argument list containing kValue, k, and O.
- callback.call(T, kValue, k, O);
- }
- // d. Increase k by 1.
- k++;
- }
- // 8. return undefined
- };
-}
diff --git a/apidoc/vendor/prism.css b/apidoc/vendor/prism.css
deleted file mode 100644
index 4fac8142..00000000
--- a/apidoc/vendor/prism.css
+++ /dev/null
@@ -1,125 +0,0 @@
-/* PrismJS 1.21.0
-https://prismjs.com/download.html#themes=prism-tomorrow&languages=clike+javascript+bash+c+csharp+cpp+clojure+elixir+erlang+go+http+json+json5+jsonp+lua+perl+python+rust */
-/**
- * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
- * Based on https://github.com/chriskempson/tomorrow-theme
- * @author Rose Pritchard
- */
-
-code[class*="language-"],
-pre[class*="language-"] {
- color: #ccc;
- background: none;
- font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
- font-size: 1em;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- word-wrap: normal;
- line-height: 1.5;
-
- -moz-tab-size: 4;
- -o-tab-size: 4;
- tab-size: 4;
-
- -webkit-hyphens: none;
- -moz-hyphens: none;
- -ms-hyphens: none;
- hyphens: none;
-
-}
-
-/* Code blocks */
-pre[class*="language-"] {
- padding: 1em;
- margin: .5em 0;
- overflow: auto;
-}
-
-:not(pre) > code[class*="language-"],
-pre[class*="language-"] {
- background: #2d2d2d;
-}
-
-/* Inline code */
-:not(pre) > code[class*="language-"] {
- padding: .1em;
- border-radius: .3em;
- white-space: normal;
-}
-
-.token.comment,
-.token.block-comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
- color: #999;
-}
-
-.token.punctuation {
- color: #ccc;
-}
-
-.token.tag,
-.token.attr-name,
-.token.namespace,
-.token.deleted {
- color: #e2777a;
-}
-
-.token.function-name {
- color: #6196cc;
-}
-
-.token.boolean,
-.token.number,
-.token.function {
- color: #f08d49;
-}
-
-.token.property,
-.token.class-name,
-.token.constant,
-.token.symbol {
- color: #f8c555;
-}
-
-.token.selector,
-.token.important,
-.token.atrule,
-.token.keyword,
-.token.builtin {
- color: #cc99cd;
-}
-
-.token.string,
-.token.char,
-.token.attr-value,
-.token.regex,
-.token.variable {
- color: #7ec699;
-}
-
-.token.operator,
-.token.entity,
-.token.url {
- color: #67cdcc;
-}
-
-.token.important,
-.token.bold {
- font-weight: bold;
-}
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
-
-.token.inserted {
- color: green;
-}
-
diff --git a/apidoc/vendor/prism.js b/apidoc/vendor/prism.js
deleted file mode 100644
index 137746f1..00000000
--- a/apidoc/vendor/prism.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/* PrismJS 1.21.0
-https://prismjs.com/download.html#themes=prism-tomorrow&languages=clike+javascript+bash+c+csharp+cpp+clojure+elixir+erlang+go+http+json+json5+jsonp+lua+perl+python+rust */
-var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function t(e,r){var a,n;switch(r=r||{},M.util.type(e)){case"Object":if(n=M.util.objId(e),r[n])return r[n];for(var i in a={},r[n]=a,e)e.hasOwnProperty(i)&&(a[i]=t(e[i],r));return a;case"Array":return n=M.util.objId(e),r[n]?r[n]:(a=[],r[n]=a,e.forEach(function(e,n){a[n]=t(e,r)}),a);default:return e}},getLanguage:function(e){for(;e&&!c.test(e.className);)e=e.parentElement;return e?(e.className.match(c)||[,"none"])[1].toLowerCase():"none"},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(e){var n=(/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(e.stack)||[])[1];if(n){var t=document.getElementsByTagName("script");for(var r in t)if(t[r].src==n)return t[r]}return null}},isActive:function(e,n,t){for(var r="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{extend:function(e,n){var t=M.util.clone(M.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(t,e,n,r){var a=(r=r||M.languages)[t],i={};for(var l in a)if(a.hasOwnProperty(l)){if(l==e)for(var o in n)n.hasOwnProperty(o)&&(i[o]=n[o]);n.hasOwnProperty(l)||(i[l]=a[l])}var s=r[t];return r[t]=i,M.languages.DFS(M.languages,function(e,n){n===s&&e!=t&&(this[e]=i)}),i},DFS:function e(n,t,r,a){a=a||{};var i=M.util.objId;for(var l in n)if(n.hasOwnProperty(l)){t.call(n,l,n[l],r||l);var o=n[l],s=M.util.type(o);"Object"!==s||a[i(o)]?"Array"!==s||a[i(o)]||(a[i(o)]=!0,e(o,t,l,a)):(a[i(o)]=!0,e(o,t,null,a))}}},plugins:{},highlightAll:function(e,n){M.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};M.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),M.hooks.run("before-all-elements-highlight",r);for(var a,i=0;a=r.elements[i++];)M.highlightElement(a,!0===n,r.callback)},highlightElement:function(e,n,t){var r=M.util.getLanguage(e),a=M.languages[r];e.className=e.className.replace(c,"").replace(/\s+/g," ")+" language-"+r;var i=e.parentElement;i&&"pre"===i.nodeName.toLowerCase()&&(i.className=i.className.replace(c,"").replace(/\s+/g," ")+" language-"+r);var l={element:e,language:r,grammar:a,code:e.textContent};function o(e){l.highlightedCode=e,M.hooks.run("before-insert",l),l.element.innerHTML=l.highlightedCode,M.hooks.run("after-highlight",l),M.hooks.run("complete",l),t&&t.call(l.element)}if(M.hooks.run("before-sanity-check",l),!l.code)return M.hooks.run("complete",l),void(t&&t.call(l.element));if(M.hooks.run("before-highlight",l),l.grammar)if(n&&u.Worker){var s=new Worker(M.filename);s.onmessage=function(e){o(e.data)},s.postMessage(JSON.stringify({language:l.language,code:l.code,immediateClose:!0})}else o(M.highlight(l.code,l.grammar,l.language));else o(M.util.encode(l.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};return M.hooks.run("before-tokenize",r),r.tokens=M.tokenize(r.code,r.grammar),M.hooks.run("after-tokenize",r),W.stringify(M.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new i;return I(a,a.head,e),function e(n,t,r,a,i,l){for(var o in r)if(r.hasOwnProperty(o)&&r[o]){var s=r[o];s=Array.isArray(s)?s:[s];for(var u=0;u<s.length;++u){if(l&&l.cause==o+","+u)return;var c=s[u],g=c.inside,f=!!c.lookbehind,h=!!c.greedy,d=0,v=c.alias;if(h&&!c.pattern.global){var p=c.pattern.toString().match(/[imsuy]*$/)[0];c.pattern=RegExp(c.pattern.source,p+"g")}for(var m=c.pattern||c,y=a.next,k=i;y!==t.tail&&!(l&&k>=l.reach);k+=y.value.length,y=y.next){var b=y.value;if(t.length>n.length)return;if(!(b instanceof W)){var x=1;if(h&&y!=t.tail.prev){m.lastIndex=k;var w=m.exec(n);if(!w)break;var A=w.index+(f&&w[1]?w[1].length:0),P=w.index+w[0].length,S=k;for(S+=y.value.length;S<=A;)y=y.next,S+=y.value.length;if(S-=y.value.length,k=S,y.value instanceof W)continue;for(var E=y;E!==t.tail&&(S<P||"string"==typeof E.value);E=E.next)x++,S+=E.value.length;x--,b=n.slice(k,S),w.index-=k}else{m.lastIndex=0;var w=m.exec(b)}if(w){f&&(d=w[1]?w[1].length:0);var A=w.index+d,O=w[0].slice(d),P=A+O.length,L=b.slice(0,A),N=b.slice(P),j=k+b.length;l&&j>l.reach&&(l.reach=j);var C=y.prev;L&&(C=I(t,C,L),k+=L.length),z(t,C,x);var _=new W(o,g?M.tokenize(O,g):O,v,O);y=I(t,C,_),N&&I(t,y,N),1<x&&e(n,t,r,y.prev,k,{cause:o+","+u,reach:j})}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function z(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;(n.next=r).prev=n,e.length-=a}if(u.Prism=M,W.stringify=function n(e,t){if("string"==typeof e)return e;if(Array.isArray(e)){var r="";return e.forEach(function(e){r+=n(e,t)}),r}var a={type:e.type,content:n(e.content,t),tag:"span",classes:["token",e.type],attributes:{},language:t},i=e.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),M.hooks.run("wrap",a);var l="";for(var o in a.attributes)l+=" "+o+'="'+(a.attributes[o]||"").replace(/"/g,"&quot;")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+l+">"+a.content+"</"+a.tag+">"},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var e=M.util.currentScript();function t(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var r=document.readyState;"loading"===r||"interactive"===r&&e&&e.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
-Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
-Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])[_$A-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,function:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0},"function-variable":{pattern:/#?[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*)?\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/[_$a-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:[_$A-Za-z\xA0-\uFFFF][$\w\xA0-\uFFFF]*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()]|\([^()]*\))+?(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript;
-!function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--?|-=|\+\+?|\+=|!=?|~|\*\*?|\*=|\/=?|%=?|<<=?|>>=?|<=?|>=?|==?|&&?|&=|\^=?|\|\|?|\|=|\?|:/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)\w+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b\w+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+?)\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:n},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s*(?:\r?\n|\r)[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\](?:\\\\)*)(["'])(?:\\[\s\S]|\$\([^)]+\)|`[^`]+`|(?!\2)[^\\])*\2/,lookbehind:!0,greedy:!0,inside:n}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:n.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|==?|!=?|=~|<<[<-]?|[&\d]?>>|\d?[<>]&?|&[>&]?|\|[&|]?|<=?|>=?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}};for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],r=n.variable[1].inside,s=0;s<a.length;s++)r[a[s]]=e.languages.bash[a[s]];e.languages.shell=e.languages.bash}(Prism);
-Prism.languages.c=Prism.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+/,lookbehind:!0},keyword:/\b(?:__attribute__|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,function:/[a-z_]\w*(?=\s*\()/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/,number:/(?:\b0x(?:[\da-f]+\.?[\da-f]*|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?)[ful]*/i}),Prism.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z]+(?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},Prism.languages.c.string],comment:Prism.languages.c.comment,directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:Prism.languages.c}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete Prism.languages.c.boolean;
-!function(s){function a(e,s){return e.replace(/<<(\d+)>>/g,function(e,n){return"(?:"+s[+n]+")"})}function t(e,n,s){return RegExp(a(e,n),s||"")}function e(e,n){for(var s=0;s<n;s++)e=e.replace(/<<self>>/g,function(){return"(?:"+e+")"});return e.replace(/<<self>>/g,"[^\\s\\S]")}var n="bool byte char decimal double dynamic float int long object sbyte short string uint ulong ushort var void",r="class enum interface struct",i="add alias and ascending async await by descending from get global group into join let nameof not notnull on or orderby partial remove select set unmanaged value when where where",o="abstract as base break case catch checked const continue default delegate do else event explicit extern finally fixed for foreach goto if implicit in internal is lock namespace new null operator out override params private protected public readonly ref return sealed sizeof stackalloc static switch this throw try typeof unchecked unsafe using virtual volatile while yield";function l(e){return"\\b(?:"+e.trim().replace(/ /g,"|")+")\\b"}var d=l(r),p=RegExp(l(n+" "+r+" "+i+" "+o)),c=l(r+" "+i+" "+o),u=l(n+" "+r+" "+o),g=e("<(?:[^<>;=+\\-*/%&|^]|<<self>>)*>",2),b=e("\\((?:[^()]|<<self>>)*\\)",2),h="@?\\b[A-Za-z_]\\w*\\b",f=a("<<0>>(?:\\s*<<1>>)?",[h,g]),m=a("(?!<<0>>)<<1>>(?:\\s*\\.\\s*<<1>>)*",[c,f]),k="\\[\\s*(?:,\\s*)*\\]",y=a("<<0>>(?:\\s*(?:\\?\\s*)?<<1>>)*(?:\\s*\\?)?",[m,k]),w=a("(?:<<0>>|<<1>>)(?:\\s*(?:\\?\\s*)?<<2>>)*(?:\\s*\\?)?",[a("\\(<<0>>+(?:,<<0>>+)+\\)",[a("[^,()<>[\\];=+\\-*/%&|^]|<<0>>|<<1>>|<<2>>",[g,b,k])]),m,k]),v={keyword:p,punctuation:/[<>()?,.:[\]]/},x="'(?:[^\r\n'\\\\]|\\\\.|\\\\[Uux][\\da-fA-F]{1,8})'",$='"(?:\\\\.|[^\\\\"\r\n])*"';s.languages.csharp=s.languages.extend("clike",{string:[{pattern:t("(^|[^$\\\\])<<0>>",['@"(?:""|\\\\[^]|[^\\\\"])*"(?!")']),lookbehind:!0,greedy:!0},{pattern:t("(^|[^@$\\\\])<<0>>",[$]),lookbehind:!0,greedy:!0},{pattern:RegExp(x),greedy:!0,alias:"character"}],"class-name":[{pattern:t("(\\busing\\s+static\\s+)<<0>>(?=\\s*;)",[m]),lookbehind:!0,inside:v},{pattern:t("(\\busing\\s+<<0>>\\s*=\\s*)<<1>>(?=\\s*;)",[h,w]),lookbehind:!0,inside:v},{pattern:t("(\\busing\\s+)<<0>>(?=\\s*=)",[h]),lookbehind:!0},{pattern:t("(\\b<<0>>\\s+)<<1>>",[d,f]),lookbehind:!0,inside:v},{pattern:t("(\\bcatch\\s*\\(\\s*)<<0>>",[m]),lookbehind:!0,inside:v},{pattern:t("(\\bwhere\\s+)<<0>>",[h]),lookbehind:!0},{pattern:t("(\\b(?:is(?:\\s+not)?|as)\\s+)<<0>>",[y]),lookbehind:!0,inside:v},{pattern:t("\\b<<0>>(?=\\s+(?!<<1>>)<<2>>(?:\\s*[=,;:{)\\]]|\\s+(?:in|when)\\b))",[w,u,h]),inside:v}],keyword:p,number:/(?:\b0(?:x[\da-f_]*[\da-f]|b[01_]*[01])|(?:\B\.\d+(?:_+\d+)*|\b\d+(?:_+\d+)*(?:\.\d+(?:_+\d+)*)?)(?:e[-+]?\d+(?:_+\d+)*)?)(?:ul|lu|[dflmu])?\b/i,operator:/>>=?|<<=?|[-=]>|([-+&|])\1|~|\?\?=?|[-+*/%&|^!=<>]=?/,punctuation:/\?\.?|::|[{}[\];(),.:]/}),s.languages.insertBefore("csharp","number",{range:{pattern:/\.\./,alias:"operator"}}),s.languages.insertBefore("csharp","punctuation",{"named-parameter":{pattern:t("([(,]\\s*)<<0>>(?=\\s*:)",[h]),lookbehind:!0,alias:"punctuation"}}),s.languages.insertBefore("csharp","class-name",{namespace:{pattern:t("(\\b(?:namespace|using)\\s+)<<0>>(?:\\s*\\.\\s*<<0>>)*(?=\\s*[;{])",[h]),lookbehind:!0,inside:{punctuation:/\./}},"type-expression":{pattern:t("(\\b(?:default|typeof|sizeof)\\s*\\(\\s*)(?:[^()\\s]|\\s(?!\\s*\\))|<<0>>)*(?=\\s*\\))",[b]),lookbehind:!0,alias:"class-name",inside:v},"return-type":{pattern:t("<<0>>(?=\\s+(?:<<1>>\\s*(?:=>|[({]|\\.\\s*this\\s*\\[)|this\\s*\\[))",[w,m]),inside:v,alias:"class-name"},"constructor-invocation":{pattern:t("(\\bnew\\s+)<<0>>(?=\\s*[[({])",[w]),lookbehind:!0,inside:v,alias:"class-name"},"generic-method":{pattern:t("<<0>>\\s*<<1>>(?=\\s*\\()",[h,g]),inside:{function:t("^<<0>>",[h]),generic:{pattern:RegExp(g),alias:"class-name",inside:v}}},"type-list":{pattern:t("\\b((?:<<0>>\\s+<<1>>|where\\s+<<2>>)\\s*:\\s*)(?:<<3>>|<<4>>)(?:\\s*,\\s*(?:<<3>>|<<4>>))*(?=\\s*(?:where|[{;]|=>|$))",[d,f,h,w,p.source]),lookbehind:!0,inside:{keyword:p,"class-name":{pattern:RegExp(w),greedy:!0,inside:v},punctuation:/,/}},preprocessor:{pattern:/(^\s*)#.*/m,lookbehind:!0,alias:"property",inside:{directive:{pattern:/(\s*#)\b(?:define|elif|else|endif|endregion|error|if|line|pragma|region|undef|warning)\b/,lookbehind:!0,alias:"keyword"}}}});var _=$+"|"+x,B=a("/(?![*/])|//[^\r\n]*[\r\n]|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>",[_]),E=e(a("[^\"'/()]|<<0>>|\\(<<self>>*\\)",[B]),2),R="\\b(?:assembly|event|field|method|module|param|property|return|type)\\b",P=a("<<0>>(?:\\s*\\(<<1>>*\\))?",[m,E]);s.languages.insertBefore("csharp","class-name",{attribute:{pattern:t("((?:^|[^\\s\\w>)?])\\s*\\[\\s*)(?:<<0>>\\s*:\\s*)?<<1>>(?:\\s*,\\s*<<1>>)*(?=\\s*\\])",[R,P]),lookbehind:!0,greedy:!0,inside:{target:{pattern:t("^<<0>>(?=\\s*:)",[R]),alias:"keyword"},"attribute-arguments":{pattern:t("\\(<<0>>*\\)",[E]),inside:s.languages.csharp},"class-name":{pattern:RegExp(m),inside:{punctuation:/\./}},punctuation:/[:,]/}}});var z=":[^}\r\n]+",S=e(a("[^\"'/()]|<<0>>|\\(<<self>>*\\)",[B]),2),j=a("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[S,z]),A=e(a("[^\"'/()]|/(?!\\*)|/\\*(?:[^*]|\\*(?!/))*\\*/|<<0>>|\\(<<self>>*\\)",[_]),2),F=a("\\{(?!\\{)(?:(?![}:])<<0>>)*<<1>>?\\}",[A,z]);function U(e,n){return{interpolation:{pattern:t("((?:^|[^{])(?:\\{\\{)*)<<0>>",[e]),lookbehind:!0,inside:{"format-string":{pattern:t("(^\\{(?:(?![}:])<<0>>)*)<<1>>(?=\\}$)",[n,z]),lookbehind:!0,inside:{punctuation:/^:/}},punctuation:/^\{|\}$/,expression:{pattern:/[\s\S]+/,alias:"language-csharp",inside:s.languages.csharp}}},string:/[\s\S]+/}}s.languages.insertBefore("csharp","string",{"interpolation-string":[{pattern:t('(^|[^\\\\])(?:\\$@|@\\$)"(?:""|\\\\[^]|\\{\\{|<<0>>|[^\\\\{"])*"',[j]),lookbehind:!0,greedy:!0,inside:U(j,S)},{pattern:t('(^|[^@\\\\])\\$"(?:\\\\.|\\{\\{|<<0>>|[^\\\\"{])*"',[F]),lookbehind:!0,greedy:!0,inside:U(F,A)}]})}(Prism),Prism.languages.dotnet=Prism.languages.cs=Prism.languages.csharp;
-!function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/;e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp("(\\b(?:class|concept|enum|struct|typename)\\s+)(?!<keyword>)\\w+".replace(/<keyword>/g,function(){return t.source}),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+\.?[\da-f']*|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+\.?[\d']*|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]*/i,greedy:!0},operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:true|false)\b/}),e.languages.insertBefore("cpp","string",{"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)(?:[^;{}"'])+?(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","operator",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(Prism);
-Prism.languages.clojure={comment:/;.*/,string:{pattern:/"(?:[^"\\]|\\.)*"/,greedy:!0},operator:/(?:::|[:|'])\b[a-z][\w*+!?-]*\b/i,keyword:{pattern:/([^\w+*'?-])(?:def|if|do|let|\.\.|quote|var|->>|->|fn|loop|recur|throw|try|monitor-enter|\.|new|set!|def\-|defn|defn\-|defmacro|defmulti|defmethod|defstruct|defonce|declare|definline|definterface|defprotocol|==|defrecord|>=|deftype|<=|defproject|ns|\*|\+|\-|\/|<|=|>|accessor|agent|agent-errors|aget|alength|all-ns|alter|and|append-child|apply|array-map|aset|aset-boolean|aset-byte|aset-char|aset-double|aset-float|aset-int|aset-long|aset-short|assert|assoc|await|await-for|bean|binding|bit-and|bit-not|bit-or|bit-shift-left|bit-shift-right|bit-xor|boolean|branch\?|butlast|byte|cast|char|children|class|clear-agent-errors|comment|commute|comp|comparator|complement|concat|conj|cons|constantly|cond|if-not|construct-proxy|contains\?|count|create-ns|create-struct|cycle|dec|deref|difference|disj|dissoc|distinct|doall|doc|dorun|doseq|dosync|dotimes|doto|double|down|drop|drop-while|edit|end\?|ensure|eval|every\?|false\?|ffirst|file-seq|filter|find|find-doc|find-ns|find-var|first|float|flush|for|fnseq|frest|gensym|get-proxy-class|get|hash-map|hash-set|identical\?|identity|if-let|import|in-ns|inc|index|insert-child|insert-left|insert-right|inspect-table|inspect-tree|instance\?|int|interleave|intersection|into|into-array|iterate|join|key|keys|keyword|keyword\?|last|lazy-cat|lazy-cons|left|lefts|line-seq|list\*|list|load|load-file|locking|long|loop|macroexpand|macroexpand-1|make-array|make-node|map|map-invert|map\?|mapcat|max|max-key|memfn|merge|merge-with|meta|min|min-key|name|namespace|neg\?|new|newline|next|nil\?|node|not|not-any\?|not-every\?|not=|ns-imports|ns-interns|ns-map|ns-name|ns-publics|ns-refers|ns-resolve|ns-unmap|nth|nthrest|or|parse|partial|path|peek|pop|pos\?|pr|pr-str|print|print-str|println|println-str|prn|prn-str|project|proxy|proxy-mappings|quot|rand|rand-int|range|re-find|re-groups|re-matcher|re-matches|re-pattern|re-seq|read|read-line|reduce|ref|ref-set|refer|rem|remove|remove-method|remove-ns|rename|rename-keys|repeat|replace|replicate|resolve|rest|resultset-seq|reverse|rfirst|right|rights|root|rrest|rseq|second|select|select-keys|send|send-off|seq|seq-zip|seq\?|set|short|slurp|some|sort|sort-by|sorted-map|sorted-map-by|sorted-set|special-symbol\?|split-at|split-with|str|string\?|struct|struct-map|subs|subvec|symbol|symbol\?|sync|take|take-nth|take-while|test|time|to-array|to-array-2d|tree-seq|true\?|union|up|update-proxy|val|vals|var-get|var-set|var\?|vector|vector-zip|vector\?|when|when-first|when-let|when-not|with-local-vars|with-meta|with-open|with-out-str|xml-seq|xml-zip|zero\?|zipmap|zipper)(?=[^\w+*'?-])/,lookbehind:!0},boolean:/\b(?:true|false|nil)\b/,number:/\b[\da-f]+\b/i,punctuation:/[{}\[\](),]/};
-Prism.languages.elixir={comment:/#.*/m,regex:{pattern:/~[rR](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|[^\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[uismxfr]*/,greedy:!0},string:[{pattern:/~[cCsSwW](?:("""|''')(?:\\[\s\S]|(?!\1)[^\\])+\1|([\/|"'])(?:\\.|(?!\2)[^\\\r\n])+\2|\((?:\\.|[^\\)\r\n])+\)|\[(?:\\.|[^\\\]\r\n])+\]|\{(?:\\.|#\{[^}]+\}|#(?!\{)|[^#\\}\r\n])+\}|<(?:\\.|[^\\>\r\n])+>)[csa]?/,greedy:!0,inside:{}},{pattern:/("""|''')[\s\S]*?\1/,greedy:!0,inside:{}},{pattern:/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{}}],atom:{pattern:/(^|[^:]):\w+/,lookbehind:!0,alias:"symbol"},"attr-name":/\w+\??:(?!:)/,capture:{pattern:/(^|[^&])&(?:[^&\s\d()][^\s()]*|(?=\())/,lookbehind:!0,alias:"function"},argument:{pattern:/(^|[^&])&\d+/,lookbehind:!0,alias:"variable"},attribute:{pattern:/@\w+/,alias:"variable"},number:/\b(?:0[box][a-f\d_]+|\d[\d_]*)(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?\b/i,keyword:/\b(?:after|alias|and|case|catch|cond|def(?:callback|exception|impl|module|p|protocol|struct)?|do|else|end|fn|for|if|import|not|or|require|rescue|try|unless|use|when)\b/,boolean:/\b(?:true|false|nil)\b/,operator:[/\bin\b|&&?|\|[|>]?|\\\\|::|\.\.\.?|\+\+?|-[->]?|<[-=>]|>=|!==?|\B!|=(?:==?|[>~])?|[*\/^]/,{pattern:/([^<])<(?!<)/,lookbehind:!0},{pattern:/([^>])>(?!>)/,lookbehind:!0}],punctuation:/<<|>>|[.,%\[\]{}()]/},Prism.languages.elixir.string.forEach(function(e){e.inside={interpolation:{pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"},rest:Prism.languages.elixir}}}});
-Prism.languages.erlang={comment:/%.+/,string:{pattern:/"(?:\\.|[^\\"\r\n])*"/,greedy:!0},"quoted-function":{pattern:/'(?:\\.|[^\\'\r\n])+'(?=\()/,alias:"function"},"quoted-atom":{pattern:/'(?:\\.|[^\\'\r\n])+'/,alias:"atom"},boolean:/\b(?:true|false)\b/,keyword:/\b(?:fun|when|case|of|end|if|receive|after|try|catch)\b/,number:[/\$\\?./,/\d+#[a-z0-9]+/i,/(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i],function:/\b[a-z][\w@]*(?=\()/,variable:{pattern:/(^|[^@])(?:\b|\?)[A-Z_][\w@]*/,lookbehind:!0},operator:[/[=\/<>:]=|=[:\/]=|\+\+?|--?|[=*\/!]|\b(?:bnot|div|rem|band|bor|bxor|bsl|bsr|not|and|or|xor|orelse|andalso)\b/,{pattern:/(^|[^<])<(?!<)/,lookbehind:!0},{pattern:/(^|[^>])>(?!>)/,lookbehind:!0}],atom:/\b[a-z][\w@]*/,punctuation:/[()[\]{}:;,.#|]|<<|>>/};
-Prism.languages.go=Prism.languages.extend("clike",{keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/,boolean:/\b(?:_|iota|nil|true|false)\b/,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,number:/(?:\b0x[a-f\d]+|(?:\b\d+\.?\d*|\B\.\d+)(?:e[-+]?\d+)?)i?/i,string:{pattern:/(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,greedy:!0}}),delete Prism.languages.go["class-name"];
-!function(t){t.languages.http={"request-line":{pattern:/^(?:POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\s(?:https?:\/\/|\/)\S+\sHTTP\/[0-9.]+/m,inside:{property:/^(?:POST|GET|PUT|DELETE|OPTIONS|PATCH|TRACE|CONNECT)\b/,"attr-name":/:\w+/}},"response-status":{pattern:/^HTTP\/1.[01] \d+.*/m,inside:{property:{pattern:/(^HTTP\/1.[01] )\d+.*/i,lookbehind:!0}}},"header-name":{pattern:/^[\w-]+:(?=.)/m,alias:"keyword"}};var a,e,n,i=t.languages,p={"application/javascript":i.javascript,"application/json":i.json||i.javascript,"application/xml":i.xml,"text/xml":i.xml,"text/html":i.html,"text/css":i.css},s={"application/json":!0,"application/xml":!0};for(var r in p)if(p[r]){a=a||{};var T=s[r]?(void 0,n=(e=r).replace(/^[a-z]+\//,""),"(?:"+e+"|\\w+/(?:[\\w.-]+\\+)+"+n+"(?![+\\w.-]))"):r;a[r.replace(/\//g,"-")]={pattern:RegExp("(content-type:\\s*"+T+"[\\s\\S]*?)(?:\\r?\\n|\\r){2}[\\s\\S]*","i"),lookbehind:!0,inside:p[r]}}a&&t.languages.insertBefore("http","header-name",a)}(Prism);
-Prism.languages.json={property:{pattern:/"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,greedy:!0},string:{pattern:/"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json;
-!function(n){var e=/("|')(?:\\(?:\r\n?|\n|.)|(?!\1)[^\\\r\n])*\1/;n.languages.json5=n.languages.extend("json",{property:[{pattern:RegExp(e.source+"(?=\\s*:)"),greedy:!0},{pattern:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*:)/,alias:"unquoted"}],string:{pattern:e,greedy:!0},number:/[+-]?\b(?:NaN|Infinity|0x[a-fA-F\d]+)\b|[+-]?(?:\b\d+\.?\d*|\B\.\d+)(?:[eE][+-]?\d+\b)?/})}(Prism);
-Prism.languages.jsonp=Prism.languages.extend("json",{punctuation:/[{}[\]();,.]/}),Prism.languages.insertBefore("jsonp","punctuation",{function:/[_$a-zA-Z\xA0-\uFFFF][$\w\xA0-\uFFFF]*(?=\s*\()/});
-Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[\s\S]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+\.?[a-f\d]*(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|\.?\d*(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/};
-Prism.languages.perl={comment:[{pattern:/(^\s*)=\w+[\s\S]*?=cut.*/m,lookbehind:!0},{pattern:/(^|[^\\$])#.*/,lookbehind:!0}],string:[{pattern:/\b(?:q|qq|qx|qw)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/\b(?:q|qq|qx|qw)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/\b(?:q|qq|qx|qw)\s*\((?:[^()\\]|\\[\s\S])*\)/,greedy:!0},{pattern:/\b(?:q|qq|qx|qw)\s*\{(?:[^{}\\]|\\[\s\S])*\}/,greedy:!0},{pattern:/\b(?:q|qq|qx|qw)\s*\[(?:[^[\]\\]|\\[\s\S])*\]/,greedy:!0},{pattern:/\b(?:q|qq|qx|qw)\s*<(?:[^<>\\]|\\[\s\S])*>/,greedy:!0},{pattern:/("|`)(?:(?!\1)[^\\]|\\[\s\S])*\1/,greedy:!0},{pattern:/'(?:[^'\\\r\n]|\\.)*'/,greedy:!0}],regex:[{pattern:/\b(?:m|qr)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,greedy:!0},{pattern:/\b(?:m|qr)\s+([a-zA-Z0-9])(?:(?!\1)[^\\]|\\[\s\S])*\1[msixpodualngc]*/,greedy:!0},{pattern:/\b(?:m|qr)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngc]*/,greedy:!0},{pattern:/\b(?:m|qr)\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngc]*/,greedy:!0},{pattern:/\b(?:m|qr)\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngc]*/,greedy:!0},{pattern:/\b(?:m|qr)\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngc]*/,greedy:!0},{pattern:/(^|[^-]\b)(?:s|tr|y)\s*([^a-zA-Z0-9\s{(\[<])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,lookbehind:!0,greedy:!0},{pattern:/(^|[^-]\b)(?:s|tr|y)\s+([a-zA-Z0-9])(?:(?!\2)[^\\]|\\[\s\S])*\2(?:(?!\2)[^\\]|\\[\s\S])*\2[msixpodualngcer]*/,lookbehind:!0,greedy:!0},{pattern:/(^|[^-]\b)(?:s|tr|y)\s*\((?:[^()\\]|\\[\s\S])*\)\s*\((?:[^()\\]|\\[\s\S])*\)[msixpodualngcer]*/,lookbehind:!0,greedy:!0},{pattern:/(^|[^-]\b)(?:s|tr|y)\s*\{(?:[^{}\\]|\\[\s\S])*\}\s*\{(?:[^{}\\]|\\[\s\S])*\}[msixpodualngcer]*/,lookbehind:!0,greedy:!0},{pattern:/(^|[^-]\b)(?:s|tr|y)\s*\[(?:[^[\]\\]|\\[\s\S])*\]\s*\[(?:[^[\]\\]|\\[\s\S])*\][msixpodualngcer]*/,lookbehind:!0,greedy:!0},{pattern:/(^|[^-]\b)(?:s|tr|y)\s*<(?:[^<>\\]|\\[\s\S])*>\s*<(?:[^<>\\]|\\[\s\S])*>[msixpodualngcer]*/,lookbehind:!0,greedy:!0},{pattern:/\/(?:[^\/\\\r\n]|\\.)*\/[msixpodualngc]*(?=\s*(?:$|[\r\n,.;})&|\-+*~<>!?^]|(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor|x)\b))/,greedy:!0}],variable:[/[&*$@%]\{\^[A-Z]+\}/,/[&*$@%]\^[A-Z_]/,/[&*$@%]#?(?=\{)/,/[&*$@%]#?(?:(?:::)*'?(?!\d)[\w$]+)+(?:::)*/i,/[&*$@%]\d+/,/(?!%=)[$@%][!"#$%&'()*+,\-.\/:;<=>?@[\\\]^_`{|}~]/],filehandle:{pattern:/<(?![<=])\S*>|\b_\b/,alias:"symbol"},vstring:{pattern:/v\d+(?:\.\d+)*|\d+(?:\.\d+){2,}/,alias:"string"},function:{pattern:/sub [a-z0-9_]+/i,inside:{keyword:/sub/}},keyword:/\b(?:any|break|continue|default|delete|die|do|else|elsif|eval|for|foreach|given|goto|if|last|local|my|next|our|package|print|redo|require|return|say|state|sub|switch|undef|unless|until|use|when|while)\b/,number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)\b/,operator:/-[rwxoRWXOezsfdlpSbctugkTBMAC]\b|\+[+=]?|-[-=>]?|\*\*?=?|\/\/?=?|=[=~>]?|~[~=]?|\|\|?=?|&&?=?|<(?:=>?|<=?)?|>>?=?|![~=]?|[%^]=?|\.(?:=|\.\.?)?|[\\?]|\bx(?:=|\b)|\b(?:lt|gt|le|ge|eq|ne|cmp|not|and|or|xor)\b/,punctuation:/[{}[\];(),:]/};
-Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"string-interpolation":{pattern:/(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^\s*)@\w+(?:\.\w+)*/im,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*\.?\d*|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python;
-!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|<self>)*\\*/",t=0;t<2;t++)a=a.replace(/<self>/g,function(){return a});a=a.replace(/<self>/g,function(){return"[^\\s\\S]"}),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u{(?:[\da-fA-F]_*){1,6}|.)|[^\\\r\n\t'])'/,greedy:!0,alias:"string"},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|Self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:[ui](?:8|16|32|64|128|size)|f(?:32|64)|bool|char|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:\d(?:_?\d)*)?\.?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:[iu](?:8|16|32|64|size)?|f32|f64))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism);
diff --git a/apidoc/vendor/require.min.js b/apidoc/vendor/require.min.js
deleted file mode 100644
index de7c7d2f..00000000
--- a/apidoc/vendor/require.min.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- RequireJS 2.1.22 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
- Available via the MIT or new BSD license.
- see: http://github.com/jrburke/requirejs for details
-*/
-var requirejs,require,define;
-(function(ha){function L(b){return"[object Function]"===R.call(b)}function M(b){return"[object Array]"===R.call(b)}function x(b,c){if(b){var d;for(d=0;d<b.length&&(!b[d]||!c(b[d],d,b));d+=1);}}function Y(b,c){if(b){var d;for(d=b.length-1;-1<d&&(!b[d]||!c(b[d],d,b));--d);}}function w(b,c){return la.call(b,c)}function g(b,c){return w(b,c)&&b[c]}function E(b,c){for(var d in b)if(w(b,d)&&c(b[d],d))break}function Z(b,c,d,k){c&&E(c,function(c,g){if(d||!w(b,g))!k||"object"!==typeof c||!c||M(c)||L(c)||c instanceof
-RegExp?b[g]=c:(b[g]||(b[g]={}),Z(b[g],c,d,k))});return b}function y(b,c){return function(){return c.apply(b,arguments)}}function ia(b){throw b;}function ja(b){if(!b)return b;var c=ha;x(b.split("."),function(b){c=c[b]});return c}function G(b,c,d,g){c=Error(c+"\nhttp://requirejs.org/docs/errors.html#"+b);c.requireType=b;c.requireModules=g;d&&(c.originalError=d);return c}function ma(b){function c(a,n,b){var f,l,c,d,h,k,e,A;n=n&&n.split("/");var q=m.map,p=q&&q["*"];if(a){a=a.split("/");l=a.length-1;m.nodeIdCompat&&
-V.test(a[l])&&(a[l]=a[l].replace(V,""));"."===a[0].charAt(0)&&n&&(l=n.slice(0,n.length-1),a=l.concat(a));l=a;for(c=0;c<l.length;c++)d=l[c],"."===d?(l.splice(c,1),--c):".."===d&&0!==c&&(1!==c||".."!==l[2])&&".."!==l[c-1]&&0<c&&(l.splice(c-1,2),c-=2);a=a.join("/")}if(b&&q&&(n||p)){l=a.split("/");c=l.length;a:for(;0<c;--c){h=l.slice(0,c).join("/");if(n)for(d=n.length;0<d;--d)if(b=g(q,n.slice(0,d).join("/")))if(b=g(b,h)){f=b;k=c;break a}!e&&p&&g(p,h)&&(e=g(p,h),A=c)}!f&&e&&(f=e,k=A);f&&(l.splice(0,k,
-f),a=l.join("/"))}return(f=g(m.pkgs,a))?f:a}function d(a){F&&x(document.getElementsByTagName("script"),function(n){if(n.getAttribute("data-requiremodule")===a&&n.getAttribute("data-requirecontext")===h.contextName)return n.parentNode.removeChild(n),!0})}function p(a){var n=g(m.paths,a);if(n&&M(n)&&1<n.length)return n.shift(),h.require.undef(a),h.makeRequire(null,{skipMap:!0})([a]),!0}function e(a){var n,b=a?a.indexOf("!"):-1;-1<b&&(n=a.substring(0,b),a=a.substring(b+1,a.length));return[n,a]}function q(a,
-n,b,f){var l,d,z=null,k=n?n.name:null,m=a,q=!0,A="";a||(q=!1,a="_@r"+(R+=1));a=e(a);z=a[0];a=a[1];z&&(z=c(z,k,f),d=g(r,z));a&&(z?A=d&&d.normalize?d.normalize(a,function(a){return c(a,k,f)}):-1===a.indexOf("!")?c(a,k,f):a:(A=c(a,k,f),a=e(A),z=a[0],A=a[1],b=!0,l=h.nameToUrl(A)));b=!z||d||b?"":"_unnormalized"+(U+=1);return{prefix:z,name:A,parentMap:n,unnormalized:!!b,url:l,originalName:m,isDefine:q,id:(z?z+"!"+A:A)+b}}function u(a){var b=a.id,c=g(t,b);c||(c=t[b]=new h.Module(a));return c}function v(a,
-b,c){var f=a.id,l=g(t,f);if(!w(r,f)||l&&!l.defineEmitComplete)if(l=u(a),l.error&&"error"===b)c(l.error);else l.on(b,c);else"defined"===b&&c(r[f])}function B(a,b){var c=a.requireModules,f=!1;if(b)b(a);else if(x(c,function(b){if(b=g(t,b))b.error=a,b.events.error&&(f=!0,b.emit("error",a))}),!f)k.onError(a)}function C(){W.length&&(x(W,function(a){var b=a[0];"string"===typeof b&&(h.defQueueMap[b]=!0);H.push(a)}),W=[])}function D(a){delete t[a];delete aa[a]}function K(a,b,c){var f=a.map.id;a.error?a.emit("error",
-a.error):(b[f]=!0,x(a.depMaps,function(f,d){var h=f.id,k=g(t,h);!k||a.depMatched[d]||c[h]||(g(b,h)?(a.defineDep(d,r[h]),a.check()):K(k,b,c))}),c[f]=!0)}function I(){var a,b,c=(a=1E3*m.waitSeconds)&&h.startTime+a<(new Date).getTime(),f=[],l=[],k=!1,g=!0;if(!ba){ba=!0;E(aa,function(a){var h=a.map,e=h.id;if(a.enabled&&(h.isDefine||l.push(a),!a.error))if(!a.inited&&c)p(e)?k=b=!0:(f.push(e),d(e));else if(!a.inited&&a.fetched&&h.isDefine&&(k=!0,!h.prefix))return g=!1});if(c&&f.length)return a=G("timeout",
-"Load timeout for modules: "+f,null,f),a.contextName=h.contextName,B(a);g&&x(l,function(a){K(a,{},{})});c&&!b||!k||!F&&!ka||ca||(ca=setTimeout(function(){ca=0;I()},50));ba=!1}}function J(a){w(r,a[0])||u(q(a[0],null,!0)).init(a[1],a[2])}function P(a){a=a.currentTarget||a.srcElement;var b=h.onScriptLoad;a.detachEvent&&!da?a.detachEvent("onreadystatechange",b):a.removeEventListener("load",b,!1);b=h.onScriptError;a.detachEvent&&!da||a.removeEventListener("error",b,!1);return{node:a,id:a&&a.getAttribute("data-requiremodule")}}
-function Q(){var a;for(C();H.length;){a=H.shift();if(null===a[0])return B(G("mismatch","Mismatched anonymous define() module: "+a[a.length-1]));J(a)}h.defQueueMap={}}var ba,ea,h,S,ca,m={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},t={},aa={},fa={},H=[],r={},X={},ga={},R=1,U=1;S={require:function(a){return a.require?a.require:a.require=h.makeRequire(a.map)},exports:function(a){a.usingExports=!0;if(a.map.isDefine)return a.exports?r[a.map.id]=a.exports:a.exports=r[a.map.id]=
-{}},module:function(a){return a.module?a.module:a.module={id:a.map.id,uri:a.map.url,config:function(){return g(m.config,a.map.id)||{}},exports:a.exports||(a.exports={})}}};ea=function(a){this.events=g(fa,a.id)||{};this.map=a;this.shim=g(m.shim,a.id);this.depExports=[];this.depMaps=[];this.depMatched=[];this.pluginMaps={};this.depCount=0};ea.prototype={init:function(a,b,c,f){f=f||{};if(!this.inited){this.factory=b;if(c)this.on("error",c);else this.events.error&&(c=y(this,function(a){this.emit("error",
-a)});this.depMaps=a&&a.slice(0);this.errback=c;this.inited=!0;this.ignore=f.ignore;f.enabled||this.enabled?this.enable():this.check()}},defineDep:function(a,b){this.depMatched[a]||(this.depMatched[a]=!0,--this.depCount,this.depExports[a]=b)},fetch:function(){if(!this.fetched){this.fetched=!0;h.startTime=(new Date).getTime();var a=this.map;if(this.shim)h.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],y(this,function(){return a.prefix?this.callPlugin():this.load()});else return a.prefix?
-this.callPlugin():this.load()}},load:function(){var a=this.map.url;X[a]||(X[a]=!0,h.load(this.map.id,a))},check:function(){if(this.enabled&&!this.enabling){var a,b,c=this.map.id;b=this.depExports;var f=this.exports,l=this.factory;if(!this.inited)w(h.defQueueMap,c)||this.fetch();else if(this.error)this.emit("error",this.error);else if(!this.defining){this.defining=!0;if(1>this.depCount&&!this.defined){if(L(l)){try{f=h.execCb(c,l,b,f)}catch(d){a=d}this.map.isDefine&&void 0===f&&((b=this.module)?f=b.exports:
-this.usingExports&&(f=this.exports));if(a){if(this.events.error&&this.map.isDefine||k.onError!==ia)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",B(this.error=a);if("undefined"!==typeof console&&console.error)console.error(a);else k.onError(a)}}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(r[c]=f,k.onResourceLoad)){var e=[];x(this.depMaps,function(a){e.push(a.normalizedMap||a)});k.onResourceLoad(h,
-this.map,e)}D(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}},callPlugin:function(){var a=this.map,b=a.id,d=q(a.prefix);this.depMaps.push(d);v(d,"defined",y(this,function(f){var l,d,e=g(ga,this.map.id),N=this.map.name,p=this.map.parentMap?this.map.parentMap.name:null,r=h.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(N=f.normalize(N,function(a){return c(a,
-p,!0)})||""),d=q(a.prefix+"!"+N,this.map.parentMap),v(d,"defined",y(this,function(a){this.map.normalizedMap=d;this.init([],function(){return a},null,{enabled:!0,ignore:!0})}),f=g(t,d.id)){this.depMaps.push(d);if(this.events.error)f.on("error",y(this,function(a){this.emit("error",a)});f.enable()}}else e?(this.map.url=h.nameToUrl(e),this.load()):(l=y(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=y(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];
-E(t,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&D(a.map.id)});B(a)}),l.fromText=y(this,function(f,c){var d=a.name,e=q(d),N=T;c&&(f=c);N&&(T=!1);u(e);w(m.config,b)&&(m.config[d]=m.config[b]);try{k.exec(f)}catch(g){return B(G("fromtexteval","fromText eval for "+b+" failed: "+g,g,[b]))}N&&(T=!0);this.depMaps.push(e);h.completeLoad(d);r([d],l)}),f.load(a.name,r,l,m))});h.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){aa[this.map.id]=this;this.enabling=this.enabled=!0;x(this.depMaps,
-y(this,function(a,b){var c,f;if("string"===typeof a){a=q(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c=g(S,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;v(a,"defined",y(this,function(a){this.undefed||(this.defineDep(b,a),this.check())});this.errback?v(a,"error",y(this,this.errback)):this.events.error&&v(a,"error",y(this,function(a){this.emit("error",a)})}c=a.id;f=t[c];w(S,c)||!f||f.enabled||h.enable(a,this)});E(this.pluginMaps,y(this,function(a){var b=
-g(t,a.id);b&&!b.enabled&&h.enable(a,this)});this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]=[]);c.push(b)},emit:function(a,b){x(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};h={config:m,contextName:b,registry:t,defined:r,urlFetched:X,defQueue:H,defQueueMap:{},Module:ea,makeModuleMap:q,nextTick:k.nextTick,onError:B,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=m.shim,c={paths:!0,
-bundles:!0,config:!0,map:!0};E(a,function(a,b){c[b]?(m[b]||(m[b]={}),Z(m[b],a,!0,!0)):m[b]=a});a.bundles&&E(a.bundles,function(a,b){x(a,function(a){a!==b&&(ga[a]=b)})});a.shim&&(E(a.shim,function(a,c){M(a)&&(a={deps:a});!a.exports&&!a.init||a.exportsFn||(a.exportsFn=h.makeShimExports(a));b[c]=a}),m.shim=b);a.packages&&x(a.packages,function(a){var b;a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(m.paths[b]=a.location);m.pkgs[b]=a.name+"/"+(a.main||"main").replace(na,"").replace(V,"")});E(t,
-function(a,b){a.inited||a.map.unnormalized||(a.map=q(b,null,!0))});(a.deps||a.callback)&&h.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b;a.init&&(b=a.init.apply(ha,arguments));return b||a.exports&&ja(a.exports)}},makeRequire:function(a,n){function e(c,d,g){var m,p;n.enableBuildCallback&&d&&L(d)&&(d.__requireJsBuild=!0);if("string"===typeof c){if(L(d))return B(G("requireargs","Invalid require call"),g);if(a&&w(S,c))return S[c](t[a.id]);if(k.get)return k.get(h,
-c,a,e);m=q(c,a,!1,!0);m=m.id;return w(r,m)?r[m]:B(G("notloaded",'Module name "'+m+'" has not been loaded yet for context: '+b+(a?"":". Use require([])")))}Q();h.nextTick(function(){Q();p=u(q(null,a));p.skipMap=n.skipMap;p.init(c,d,g,{enabled:!0});I()});return e}n=n||{};Z(e,{isBrowser:F,toUrl:function(b){var d,e=b.lastIndexOf("."),n=b.split("/")[0];-1!==e&&("."!==n&&".."!==n||1<e)&&(d=b.substring(e,b.length),b=b.substring(0,e));return h.nameToUrl(c(b,a&&a.id,!0),d,!0)},defined:function(b){return w(r,
-q(b,a,!1,!0).id)},specified:function(b){b=q(b,a,!1,!0).id;return w(r,b)||w(t,b)}});a||(e.undef=function(b){C();var c=q(b,a,!0),e=g(t,b);e.undefed=!0;d(b);delete r[b];delete X[c.url];delete fa[b];Y(H,function(a,c){a[0]===b&&H.splice(c,1)});delete h.defQueueMap[b];e&&(e.events.defined&&(fa[b]=e.events),D(b))});return e},enable:function(a){g(t,a.id)&&u(a).enable()},completeLoad:function(a){var b,c,d=g(m.shim,a)||{},e=d.exports;for(C();H.length;){c=H.shift();if(null===c[0]){c[0]=a;if(b)break;b=!0}else c[0]===
-a&&(b=!0);J(c)}h.defQueueMap={};c=g(t,a);if(!b&&!w(r,a)&&c&&!c.inited)if(!m.enforceDefine||e&&ja(e))J([a,d.deps||[],d.exportsFn]);else return p(a)?void 0:B(G("nodefine","No define call for "+a,null,[a]));I()},nameToUrl:function(a,b,c){var d,e,p;(d=g(m.pkgs,a))&&(a=d);if(d=g(ga,a))return h.nameToUrl(d,b,c);if(k.jsExtRegExp.test(a))d=a+(b||"");else{d=m.paths;a=a.split("/");for(e=a.length;0<e;--e)if(p=a.slice(0,e).join("/"),p=g(d,p)){M(p)&&(p=p[0]);a.splice(0,e,p);break}d=a.join("/");d+=b||(/^data\:|\?/.test(d)||
-c?"":".js");d=("/"===d.charAt(0)||d.match(/^[\w\+\.\-]+:/)?"":m.baseUrl)+d}return m.urlArgs?d+((-1===d.indexOf("?")?"?":"&")+m.urlArgs):d},load:function(a,b){k.load(h,a,b)},execCb:function(a,b,c,d){return b.apply(d,c)},onScriptLoad:function(a){if("load"===a.type||oa.test((a.currentTarget||a.srcElement).readyState))O=null,a=P(a),h.completeLoad(a.id)},onScriptError:function(a){var b=P(a);if(!p(b.id)){var c=[];E(t,function(a,d){0!==d.indexOf("_@r")&&x(a.depMaps,function(a){a.id===b.id&&c.push(d);return!0})});
-return B(G("scripterror",'Script error for "'+b.id+(c.length?'", needed by: '+c.join(", "):'"'),a,[b.id]))}}};h.require=h.makeRequire();return h}function pa(){if(O&&"interactive"===O.readyState)return O;Y(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return O=b});return O}var k,C,D,I,P,J,O,Q,u,U,qa=/(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,ra=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,V=/\.js$/,na=/^\.\//;C=Object.prototype;var R=C.toString,la=C.hasOwnProperty,
-F=!("undefined"===typeof window||"undefined"===typeof navigator||!window.document),ka=!F&&"undefined"!==typeof importScripts,oa=F&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,da="undefined"!==typeof opera&&"[object Opera]"===opera.toString(),K={},v={},W=[],T=!1;if("undefined"===typeof define){if("undefined"!==typeof requirejs){if(L(requirejs))return;v=requirejs;requirejs=void 0}"undefined"===typeof require||L(require)||(v=require,require=void 0);k=requirejs=function(b,
-c,d,p){var e,q="_";M(b)||"string"===typeof b||(e=b,M(c)?(b=c,c=d,d=p):b=[]);e&&e.context&&(q=e.context);(p=g(K,q))||(p=K[q]=k.s.newContext(q));e&&p.configure(e);return p.require(b,c,d)};k.config=function(b){return k(b)};k.nextTick="undefined"!==typeof setTimeout?function(b){setTimeout(b,4)}:function(b){b()};require||(require=k);k.version="2.1.22";k.jsExtRegExp=/^\/|:|\?|\.js$/;k.isBrowser=F;C=k.s={contexts:K,newContext:ma};k({});x(["toUrl","undef","defined","specified"],function(b){k[b]=function(){var c=
-K._;return c.require[b].apply(c,arguments)}});F&&(D=C.head=document.getElementsByTagName("head")[0],I=document.getElementsByTagName("base")[0])&&(D=C.head=I.parentNode);k.onError=ia;k.createNode=function(b,c,d){c=b.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");c.type=b.scriptType||"text/javascript";c.charset="utf-8";c.async=!0;return c};k.load=function(b,c,d){var g=b&&b.config||{},e;if(F){e=k.createNode(g,c,d);if(g.onNodeCreated)g.onNodeCreated(e,
-g,c,d);e.setAttribute("data-requirecontext",b.contextName);e.setAttribute("data-requiremodule",c);!e.attachEvent||e.attachEvent.toString&&0>e.attachEvent.toString().indexOf("[native code")||da?(e.addEventListener("load",b.onScriptLoad,!1),e.addEventListener("error",b.onScriptError,!1)):(T=!0,e.attachEvent("onreadystatechange",b.onScriptLoad));e.src=d;Q=e;I?D.insertBefore(e,I):D.appendChild(e);Q=null;return e}if(ka)try{importScripts(d),b.completeLoad(c)}catch(q){b.onError(G("importscripts","importScripts failed for "+
-c+" at "+d,q,[c]))}};F&&!v.skipDataMain&&Y(document.getElementsByTagName("script"),function(b){D||(D=b.parentNode);if(P=b.getAttribute("data-main"))return u=P,v.baseUrl||(J=u.split("/"),u=J.pop(),U=J.length?J.join("/")+"/":"./",v.baseUrl=U),u=u.replace(V,""),k.jsExtRegExp.test(u)&&(u=P),v.deps=v.deps?v.deps.concat(u):[u],!0});define=function(b,c,d){var g,e;"string"!==typeof b&&(d=c,c=b,b=null);M(c)||(d=c,c=null);!c&&L(d)&&(c=[],d.length&&(d.toString().replace(qa,"").replace(ra,function(b,d){c.push(d)}),
-c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));T&&(g=Q||pa())&&(b||(b=g.getAttribute("data-requiremodule")),e=K[g.getAttribute("data-requirecontext")]);e?(e.defQueue.push([b,c,d]),e.defQueueMap[b]=!0):W.push([b,c,d])};define.amd={jQuery:!0};k.exec=function(b){return eval(b)};k(v)}})(this);
diff --git a/apidoc/vendor/semver.min.js b/apidoc/vendor/semver.min.js
deleted file mode 100644
index c2b3ff48..00000000
--- a/apidoc/vendor/semver.min.js
+++ /dev/null
@@ -1 +0,0 @@
-(function(e){if(typeof module==="object"&&module.exports===e)e=module.exports=K;e.SEMVER_SPEC_VERSION="2.0.0";var r=256;var t=Number.MAX_SAFE_INTEGER||9007199254740991;var n=e.re=[];var i=e.src=[];var s=0;var o=s++;i[o]="0|[1-9]\\d*";var a=s++;i[a]="[0-9]+";var f=s++;i[f]="\\d*[a-zA-Z-][a-zA-Z0-9-]*";var u=s++;i[u]="("+i[o]+")\\."+"("+i[o]+")\\."+"("+i[o]+")";var l=s++;i[l]="("+i[a]+")\\."+"("+i[a]+")\\."+"("+i[a]+")";var p=s++;i[p]="(?:"+i[o]+"|"+i[f]+")";var h=s++;i[h]="(?:"+i[a]+"|"+i[f]+")";var c=s++;i[c]="(?:-("+i[p]+"(?:\\."+i[p]+")*))";var v=s++;i[v]="(?:-?("+i[h]+"(?:\\."+i[h]+")*))";var m=s++;i[m]="[0-9A-Za-z-]+";var g=s++;i[g]="(?:\\+("+i[m]+"(?:\\."+i[m]+")*))";var w=s++;var y="v?"+i[u]+i[c]+"?"+i[g]+"?";i[w]="^"+y+"$";var d="[v=\\s]*"+i[l]+i[v]+"?"+i[g]+"?";var j=s++;i[j]="^"+d+"$";var b=s++;i[b]="((?:<|>)?=?)";var E=s++;i[E]=i[a]+"|x|X|\\*";var $=s++;i[$]=i[o]+"|x|X|\\*";var k=s++;i[k]="[v=\\s]*("+i[$]+")"+"(?:\\.("+i[$]+")"+"(?:\\.("+i[$]+")"+"(?:"+i[c]+")?"+i[g]+"?"+")?)?";var R=s++;i[R]="[v=\\s]*("+i[E]+")"+"(?:\\.("+i[E]+")"+"(?:\\.("+i[E]+")"+"(?:"+i[v]+")?"+i[g]+"?"+")?)?";var S=s++;i[S]="^"+i[b]+"\\s*"+i[k]+"$";var x=s++;i[x]="^"+i[b]+"\\s*"+i[R]+"$";var I=s++;i[I]="(?:~>?)";var T=s++;i[T]="(\\s*)"+i[I]+"\\s+";n[T]=new RegExp(i[T],"g");var V="$1~";var A=s++;i[A]="^"+i[I]+i[k]+"$";var C=s++;i[C]="^"+i[I]+i[R]+"$";var M=s++;i[M]="(?:\\^)";var N=s++;i[N]="(\\s*)"+i[M]+"\\s+";n[N]=new RegExp(i[N],"g");var _="$1^";var z=s++;i[z]="^"+i[M]+i[k]+"$";var P=s++;i[P]="^"+i[M]+i[R]+"$";var X=s++;i[X]="^"+i[b]+"\\s*("+d+")$|^$";var Z=s++;i[Z]="^"+i[b]+"\\s*("+y+")$|^$";var q=s++;i[q]="(\\s*)"+i[b]+"\\s*("+d+"|"+i[k]+")";n[q]=new RegExp(i[q],"g");var L="$1$2$3";var F=s++;i[F]="^\\s*("+i[k]+")"+"\\s+-\\s+"+"("+i[k]+")"+"\\s*$";var G=s++;i[G]="^\\s*("+i[R]+")"+"\\s+-\\s+"+"("+i[R]+")"+"\\s*$";var O=s++;i[O]="(<|>)?=?\\s*\\*";for(var B=0;B<s;B++){if(!n[B])n[B]=new RegExp(i[B])}e.parse=D;function D(e,t){if(e instanceof K)return e;if(typeof e!=="string")return null;if(e.length>r)return null;var i=t?n[j]:n[w];if(!i.test(e))return null;try{return new K(e,t)}catch(s){return null}}e.valid=H;function H(e,r){var t=D(e,r);return t?t.version:null}e.clean=J;function J(e,r){var t=D(e.trim().replace(/^[=v]+/,""),r);return t?t.version:null}e.SemVer=K;function K(e,i){if(e instanceof K){if(e.loose===i)return e;else e=e.version}else if(typeof e!=="string"){throw new TypeError("Invalid Version: "+e)}if(e.length>r)throw new TypeError("version is longer than "+r+" characters");if(!(this instanceof K))return new K(e,i);this.loose=i;var s=e.trim().match(i?n[j]:n[w]);if(!s)throw new TypeError("Invalid Version: "+e);this.raw=e;this.major=+s[1];this.minor=+s[2];this.patch=+s[3];if(this.major>t||this.major<0)throw new TypeError("Invalid major version");if(this.minor>t||this.minor<0)throw new TypeError("Invalid minor version");if(this.patch>t||this.patch<0)throw new TypeError("Invalid patch version");if(!s[4])this.prerelease=[];else this.prerelease=s[4].split(".").map(function(e){if(/^[0-9]+$/.test(e)){var r=+e;if(r>=0&&r<t)return r}return e});this.build=s[5]?s[5].split("."):[];this.format()}K.prototype.format=function(){this.version=this.major+"."+this.minor+"."+this.patch;if(this.prerelease.length)this.version+="-"+this.prerelease.join(".");return this.version};K.prototype.inspect=function(){return'<SemVer "'+this+'">'};K.prototype.toString=function(){return this.version};K.prototype.compare=function(e){if(!(e instanceof K))e=new K(e,this.loose);return this.compareMain(e)||this.comparePre(e)};K.prototype.compareMain=function(e){if(!(e instanceof K))e=new K(e,this.loose);return Y(this.major,e.major)||Y(this.minor,e.minor)||Y(this.patch,e.patch)};K.prototype.comparePre=function(e){if(!(e instanceof K))e=new K(e,this.loose);if(this.prerelease.length&&!e.prerelease.length)return-1;else if(!this.prerelease.length&&e.prerelease.length)return 1;else if(!this.prerelease.length&&!e.prerelease.length)return 0;var r=0;do{var t=this.prerelease[r];var n=e.prerelease[r];if(t===undefined&&n===undefined)return 0;else if(n===undefined)return 1;else if(t===undefined)return-1;else if(t===n)continue;else return Y(t,n)}while(++r)};K.prototype.inc=function(e,r){switch(e){case"premajor":this.prerelease.length=0;this.patch=0;this.minor=0;this.major++;this.inc("pre",r);break;case"preminor":this.prerelease.length=0;this.patch=0;this.minor++;this.inc("pre",r);break;case"prepatch":this.prerelease.length=0;this.inc("patch",r);this.inc("pre",r);break;case"prerelease":if(this.prerelease.length===0)this.inc("patch",r);this.inc("pre",r);break;case"major":if(this.minor!==0||this.patch!==0||this.prerelease.length===0)this.major++;this.minor=0;this.patch=0;this.prerelease=[];break;case"minor":if(this.patch!==0||this.prerelease.length===0)this.minor++;this.patch=0;this.prerelease=[];break;case"patch":if(this.prerelease.length===0)this.patch++;this.prerelease=[];break;case"pre":if(this.prerelease.length===0)this.prerelease=[0];else{var t=this.prerelease.length;while(--t>=0){if(typeof this.prerelease[t]==="number"){this.prerelease[t]++;t=-2}}if(t===-1)this.prerelease.push(0)}if(r){if(this.prerelease[0]===r){if(isNaN(this.prerelease[1]))this.prerelease=[r,0]}else this.prerelease=[r,0]}break;default:throw new Error("invalid increment argument: "+e)}this.format();return this};e.inc=Q;function Q(e,r,t,n){if(typeof t==="string"){n=t;t=undefined}try{return new K(e,t).inc(r,n).version}catch(i){return null}}e.diff=U;function U(e,r){if(pr(e,r)){return null}else{var t=D(e);var n=D(r);if(t.prerelease.length||n.prerelease.length){for(var i in t){if(i==="major"||i==="minor"||i==="patch"){if(t[i]!==n[i]){return"pre"+i}}}return"prerelease"}for(var i in t){if(i==="major"||i==="minor"||i==="patch"){if(t[i]!==n[i]){return i}}}}}e.compareIdentifiers=Y;var W=/^[0-9]+$/;function Y(e,r){var t=W.test(e);var n=W.test(r);if(t&&n){e=+e;r=+r}return t&&!n?-1:n&&!t?1:e<r?-1:e>r?1:0}e.rcompareIdentifiers=er;function er(e,r){return Y(r,e)}e.major=rr;function rr(e,r){return new K(e,r).major}e.minor=tr;function tr(e,r){return new K(e,r).minor}e.patch=nr;function nr(e,r){return new K(e,r).patch}e.compare=ir;function ir(e,r,t){return new K(e,t).compare(r)}e.compareLoose=sr;function sr(e,r){return ir(e,r,true)}e.rcompare=or;function or(e,r,t){return ir(r,e,t)}e.sort=ar;function ar(r,t){return r.sort(function(r,n){return e.compare(r,n,t)})}e.rsort=fr;function fr(r,t){return r.sort(function(r,n){return e.rcompare(r,n,t)})}e.gt=ur;function ur(e,r,t){return ir(e,r,t)>0}e.lt=lr;function lr(e,r,t){return ir(e,r,t)<0}e.eq=pr;function pr(e,r,t){return ir(e,r,t)===0}e.neq=hr;function hr(e,r,t){return ir(e,r,t)!==0}e.gte=cr;function cr(e,r,t){return ir(e,r,t)>=0}e.lte=vr;function vr(e,r,t){return ir(e,r,t)<=0}e.cmp=mr;function mr(e,r,t,n){var i;switch(r){case"===":if(typeof e==="object")e=e.version;if(typeof t==="object")t=t.version;i=e===t;break;case"!==":if(typeof e==="object")e=e.version;if(typeof t==="object")t=t.version;i=e!==t;break;case"":case"=":case"==":i=pr(e,t,n);break;case"!=":i=hr(e,t,n);break;case">":i=ur(e,t,n);break;case">=":i=cr(e,t,n);break;case"<":i=lr(e,t,n);break;case"<=":i=vr(e,t,n);break;default:throw new TypeError("Invalid operator: "+r)}return i}e.Comparator=gr;function gr(e,r){if(e instanceof gr){if(e.loose===r)return e;else e=e.value}if(!(this instanceof gr))return new gr(e,r);this.loose=r;this.parse(e);if(this.semver===wr)this.value="";else this.value=this.operator+this.semver.version}var wr={};gr.prototype.parse=function(e){var r=this.loose?n[X]:n[Z];var t=e.match(r);if(!t)throw new TypeError("Invalid comparator: "+e);this.operator=t[1];if(this.operator==="=")this.operator="";if(!t[2])this.semver=wr;else this.semver=new K(t[2],this.loose)};gr.prototype.inspect=function(){return'<SemVer Comparator "'+this+'">'};gr.prototype.toString=function(){return this.value};gr.prototype.test=function(e){if(this.semver===wr)return true;if(typeof e==="string")e=new K(e,this.loose);return mr(e,this.operator,this.semver,this.loose)};e.Range=yr;function yr(e,r){if(e instanceof yr&&e.loose===r)return e;if(!(this instanceof yr))return new yr(e,r);this.loose=r;this.raw=e;this.set=e.split(/\s*\|\|\s*/).map(function(e){return this.parseRange(e.trim())},this).filter(function(e){return e.length});if(!this.set.length){throw new TypeError("Invalid SemVer Range: "+e)}this.format()}yr.prototype.inspect=function(){return'<SemVer Range "'+this.range+'">'};yr.prototype.format=function(){this.range=this.set.map(function(e){return e.join(" ").trim()}).join("||").trim();return this.range};yr.prototype.toString=function(){return this.range};yr.prototype.parseRange=function(e){var r=this.loose;e=e.trim();var t=r?n[G]:n[F];e=e.replace(t,Tr);e=e.replace(n[q],L);e=e.replace(n[T],V);e=e.replace(n[N],_);e=e.split(/\s+/).join(" ");var i=r?n[X]:n[Z];var s=e.split(" ").map(function(e){return jr(e,r)}).join(" ").split(/\s+/);if(this.loose){s=s.filter(function(e){return!!e.match(i)})}s=s.map(function(e){return new gr(e,r)});return s};e.toComparators=dr;function dr(e,r){return new yr(e,r).set.map(function(e){return e.map(function(e){return e.value}).join(" ").trim().split(" ")})}function jr(e,r){e=kr(e,r);e=Er(e,r);e=Sr(e,r);e=Ir(e,r);return e}function br(e){return!e||e.toLowerCase()==="x"||e==="*"}function Er(e,r){return e.trim().split(/\s+/).map(function(e){return $r(e,r)}).join(" ")}function $r(e,r){var t=r?n[C]:n[A];return e.replace(t,function(e,r,t,n,i){var s;if(br(r))s="";else if(br(t))s=">="+r+".0.0 <"+(+r+1)+".0.0";else if(br(n))s=">="+r+"."+t+".0 <"+r+"."+(+t+1)+".0";else if(i){if(i.charAt(0)!=="-")i="-"+i;s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0"}else s=">="+r+"."+t+"."+n+" <"+r+"."+(+t+1)+".0";return s})}function kr(e,r){return e.trim().split(/\s+/).map(function(e){return Rr(e,r)}).join(" ")}function Rr(e,r){var t=r?n[P]:n[z];return e.replace(t,function(e,r,t,n,i){var s;if(br(r))s="";else if(br(t))s=">="+r+".0.0 <"+(+r+1)+".0.0";else if(br(n)){if(r==="0")s=">="+r+"."+t+".0 <"+r+"."+(+t+1)+".0";else s=">="+r+"."+t+".0 <"+(+r+1)+".0.0"}else if(i){if(i.charAt(0)!=="-")i="-"+i;if(r==="0"){if(t==="0")s=">="+r+"."+t+"."+n+i+" <"+r+"."+t+"."+(+n+1);else s=">="+r+"."+t+"."+n+i+" <"+r+"."+(+t+1)+".0"}else s=">="+r+"."+t+"."+n+i+" <"+(+r+1)+".0.0"}else{if(r==="0"){if(t==="0")s=">="+r+"."+t+"."+n+" <"+r+"."+t+"."+(+n+1);else s=">="+r+"."+t+"."+n+" <"+r+"."+(+t+1)+".0"}else s=">="+r+"."+t+"."+n+" <"+(+r+1)+".0.0"}return s})}function Sr(e,r){return e.split(/\s+/).map(function(e){return xr(e,r)}).join(" ")}function xr(e,r){e=e.trim();var t=r?n[x]:n[S];return e.replace(t,function(e,r,t,n,i,s){var o=br(t);var a=o||br(n);var f=a||br(i);var u=f;if(r==="="&&u)r="";if(o){if(r===">"||r==="<"){e="<0.0.0"}else{e="*"}}else if(r&&u){if(a)n=0;if(f)i=0;if(r===">"){r=">=";if(a){t=+t+1;n=0;i=0}else if(f){n=+n+1;i=0}}else if(r==="<="){r="<";if(a)t=+t+1;else n=+n+1}e=r+t+"."+n+"."+i}else if(a){e=">="+t+".0.0 <"+(+t+1)+".0.0"}else if(f){e=">="+t+"."+n+".0 <"+t+"."+(+n+1)+".0"}return e})}function Ir(e,r){return e.trim().replace(n[O],"")}function Tr(e,r,t,n,i,s,o,a,f,u,l,p,h){if(br(t))r="";else if(br(n))r=">="+t+".0.0";else if(br(i))r=">="+t+"."+n+".0";else r=">="+r;if(br(f))a="";else if(br(u))a="<"+(+f+1)+".0.0";else if(br(l))a="<"+f+"."+(+u+1)+".0";else if(p)a="<="+f+"."+u+"."+l+"-"+p;else a="<="+a;return(r+" "+a).trim()}yr.prototype.test=function(e){if(!e)return false;if(typeof e==="string")e=new K(e,this.loose);for(var r=0;r<this.set.length;r++){if(Vr(this.set[r],e))return true}return false};function Vr(e,r){for(var t=0;t<e.length;t++){if(!e[t].test(r))return false}if(r.prerelease.length){for(var t=0;t<e.length;t++){if(e[t].semver===wr)return true;if(e[t].semver.prerelease.length>0){var n=e[t].semver;if(n.major===r.major&&n.minor===r.minor&&n.patch===r.patch)return true}}return false}return true}e.satisfies=Ar;function Ar(e,r,t){try{r=new yr(r,t)}catch(n){return false}return r.test(e)}e.maxSatisfying=Cr;function Cr(e,r,t){return e.filter(function(e){return Ar(e,r,t)}).sort(function(e,r){return or(e,r,t)})[0]||null}e.validRange=Mr;function Mr(e,r){try{return new yr(e,r).range||"*"}catch(t){return null}}e.ltr=Nr;function Nr(e,r,t){return zr(e,r,"<",t)}e.gtr=_r;function _r(e,r,t){return zr(e,r,">",t)}e.outside=zr;function zr(e,r,t,n){e=new K(e,n);r=new yr(r,n);var i,s,o,a,f;switch(t){case">":i=ur;s=vr;o=lr;a=">";f=">=";break;case"<":i=lr;s=cr;o=ur;a="<";f="<=";break;default:throw new TypeError('Must provide a hilo val of "<" or ">"')}if(Ar(e,r,n)){return false}for(var u=0;u<r.set.length;++u){var l=r.set[u];var p=null;var h=null;l.forEach(function(e){p=p||e;h=h||e;if(i(e.semver,p.semver,n)){p=e}else if(o(e.semver,h.semver,n)){h=e}});if(p.operator===a||p.operator===f){return false}if((!h.operator||h.operator===a)&&s(e,h.semver)){return false}else if(h.operator===f&&o(e,h.semver)){return false}}return true}if(typeof define==="function"&&define.amd)define(e)})(typeof exports==="object"?exports:typeof define==="function"&&define.amd?{}:semver={}); \ No newline at end of file
diff --git a/apidoc/vendor/webfontloader.js b/apidoc/vendor/webfontloader.js
deleted file mode 100644
index b5365501..00000000
--- a/apidoc/vendor/webfontloader.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Web Font Loader v1.6.24 - (c) Adobe Systems, Google. License: Apache 2.0 */
-(function(){function aa(a,b,d){return a.call.apply(a.bind,arguments)}function ba(a,b,d){if(!a)throw Error();if(2<arguments.length){var c=Array.prototype.slice.call(arguments,2);return function(){var d=Array.prototype.slice.call(arguments);Array.prototype.unshift.apply(d,c);return a.apply(b,d)}}return function(){return a.apply(b,arguments)}}function p(a,b,d){p=Function.prototype.bind&&-1!=Function.prototype.bind.toString().indexOf("native code")?aa:ba;return p.apply(null,arguments)}var q=Date.now||function(){return+new Date};function ca(a,b){this.a=a;this.m=b||a;this.c=this.m.document}var da=!!window.FontFace;function t(a,b,d,c){b=a.c.createElement(b);if(d)for(var e in d)d.hasOwnProperty(e)&&("style"==e?b.style.cssText=d[e]:b.setAttribute(e,d[e]));c&&b.appendChild(a.c.createTextNode(c));return b}function u(a,b,d){a=a.c.getElementsByTagName(b)[0];a||(a=document.documentElement);a.insertBefore(d,a.lastChild)}function v(a){a.parentNode&&a.parentNode.removeChild(a)}
-function w(a,b,d){b=b||[];d=d||[];for(var c=a.className.split(/\s+/),e=0;e<b.length;e+=1){for(var f=!1,g=0;g<c.length;g+=1)if(b[e]===c[g]){f=!0;break}f||c.push(b[e])}b=[];for(e=0;e<c.length;e+=1){f=!1;for(g=0;g<d.length;g+=1)if(c[e]===d[g]){f=!0;break}f||b.push(c[e])}a.className=b.join(" ").replace(/\s+/g," ").replace(/^\s+|\s+$/,"")}function y(a,b){for(var d=a.className.split(/\s+/),c=0,e=d.length;c<e;c++)if(d[c]==b)return!0;return!1}
-function z(a){if("string"===typeof a.f)return a.f;var b=a.m.location.protocol;"about:"==b&&(b=a.a.location.protocol);return"https:"==b?"https:":"http:"}function ea(a){return a.m.location.hostname||a.a.location.hostname}
-function A(a,b,d){function c(){k&&e&&f&&(k(g),k=null)}b=t(a,"link",{rel:"stylesheet",href:b,media:"all"});var e=!1,f=!0,g=null,k=d||null;da?(b.onload=function(){e=!0;c()},b.onerror=function(){e=!0;g=Error("Stylesheet failed to load");c()}):setTimeout(function(){e=!0;c()},0);u(a,"head",b)}
-function B(a,b,d,c){var e=a.c.getElementsByTagName("head")[0];if(e){var f=t(a,"script",{src:b}),g=!1;f.onload=f.onreadystatechange=function(){g||this.readyState&&"loaded"!=this.readyState&&"complete"!=this.readyState||(g=!0,d&&d(null),f.onload=f.onreadystatechange=null,"HEAD"==f.parentNode.tagName&&e.removeChild(f))};e.appendChild(f);setTimeout(function(){g||(g=!0,d&&d(Error("Script load timeout")))},c||5E3);return f}return null};function C(){this.a=0;this.c=null}function D(a){a.a++;return function(){a.a--;E(a)}}function F(a,b){a.c=b;E(a)}function E(a){0==a.a&&a.c&&(a.c(),a.c=null)};function G(a){this.a=a||"-"}G.prototype.c=function(a){for(var b=[],d=0;d<arguments.length;d++)b.push(arguments[d].replace(/[\W_]+/g,"").toLowerCase());return b.join(this.a)};function H(a,b){this.c=a;this.f=4;this.a="n";var d=(b||"n4").match(/^([nio])([1-9])$/i);d&&(this.a=d[1],this.f=parseInt(d[2],10))}function fa(a){return I(a)+" "+(a.f+"00")+" 300px "+J(a.c)}function J(a){var b=[];a=a.split(/,\s*/);for(var d=0;d<a.length;d++){var c=a[d].replace(/['"]/g,"");-1!=c.indexOf(" ")||/^\d/.test(c)?b.push("'"+c+"'"):b.push(c)}return b.join(",")}function K(a){return a.a+a.f}function I(a){var b="normal";"o"===a.a?b="oblique":"i"===a.a&&(b="italic");return b}
-function ga(a){var b=4,d="n",c=null;a&&((c=a.match(/(normal|oblique|italic)/i))&&c[1]&&(d=c[1].substr(0,1).toLowerCase()),(c=a.match(/([1-9]00|normal|bold)/i))&&c[1]&&(/bold/i.test(c[1])?b=7:/[1-9]00/.test(c[1])&&(b=parseInt(c[1].substr(0,1),10))));return d+b};function ha(a,b){this.c=a;this.f=a.m.document.documentElement;this.h=b;this.a=new G("-");this.j=!1!==b.events;this.g=!1!==b.classes}function ia(a){a.g&&w(a.f,[a.a.c("wf","loading")]);L(a,"loading")}function M(a){if(a.g){var b=y(a.f,a.a.c("wf","active")),d=[],c=[a.a.c("wf","loading")];b||d.push(a.a.c("wf","inactive"));w(a.f,d,c)}L(a,"inactive")}function L(a,b,d){if(a.j&&a.h[b])if(d)a.h[b](d.c,K(d));else a.h[b]()};function ja(){this.c={}}function ka(a,b,d){var c=[],e;for(e in b)if(b.hasOwnProperty(e)){var f=a.c[e];f&&c.push(f(b[e],d))}return c};function N(a,b){this.c=a;this.f=b;this.a=t(this.c,"span",{"aria-hidden":"true"},this.f)}function O(a){u(a.c,"body",a.a)}function P(a){return"display:block;position:absolute;top:-9999px;left:-9999px;font-size:300px;width:auto;height:auto;line-height:normal;margin:0;padding:0;font-variant:normal;white-space:nowrap;font-family:"+J(a.c)+";"+("font-style:"+I(a)+";font-weight:"+(a.f+"00")+";")};function Q(a,b,d,c,e,f){this.g=a;this.j=b;this.a=c;this.c=d;this.f=e||3E3;this.h=f||void 0}Q.prototype.start=function(){var a=this.c.m.document,b=this,d=q(),c=new Promise(function(c,e){function k(){q()-d>=b.f?e():a.fonts.load(fa(b.a),b.h).then(function(a){1<=a.length?c():setTimeout(k,25)},function(){e()})}k()}),e=new Promise(function(a,c){setTimeout(c,b.f)});Promise.race([e,c]).then(function(){b.g(b.a)},function(){b.j(b.a)})};function R(a,b,d,c,e,f,g){this.v=a;this.B=b;this.c=d;this.a=c;this.s=g||"BESbswy";this.f={};this.w=e||3E3;this.u=f||null;this.o=this.j=this.h=this.g=null;this.g=new N(this.c,this.s);this.h=new N(this.c,this.s);this.j=new N(this.c,this.s);this.o=new N(this.c,this.s);a=new H(this.a.c+",serif",K(this.a));a=P(a);this.g.a.style.cssText=a;a=new H(this.a.c+",sans-serif",K(this.a));a=P(a);this.h.a.style.cssText=a;a=new H("serif",K(this.a));a=P(a);this.j.a.style.cssText=a;a=new H("sans-serif",K(this.a));a=
-P(a);this.o.a.style.cssText=a;O(this.g);O(this.h);O(this.j);O(this.o)}var S={D:"serif",C:"sans-serif"},T=null;function U(){if(null===T){var a=/AppleWebKit\/([0-9]+)(?:\.([0-9]+))/.exec(window.navigator.userAgent);T=!!a&&(536>parseInt(a[1],10)||536===parseInt(a[1],10)&&11>=parseInt(a[2],10))}return T}R.prototype.start=function(){this.f.serif=this.j.a.offsetWidth;this.f["sans-serif"]=this.o.a.offsetWidth;this.A=q();la(this)};
-function ma(a,b,d){for(var c in S)if(S.hasOwnProperty(c)&&b===a.f[S[c]]&&d===a.f[S[c]])return!0;return!1}function la(a){var b=a.g.a.offsetWidth,d=a.h.a.offsetWidth,c;(c=b===a.f.serif&&d===a.f["sans-serif"])||(c=U()&&ma(a,b,d));c?q()-a.A>=a.w?U()&&ma(a,b,d)&&(null===a.u||a.u.hasOwnProperty(a.a.c))?V(a,a.v):V(a,a.B):na(a):V(a,a.v)}function na(a){setTimeout(p(function(){la(this)},a),50)}function V(a,b){setTimeout(p(function(){v(this.g.a);v(this.h.a);v(this.j.a);v(this.o.a);b(this.a)},a),0)};function W(a,b,d){this.c=a;this.a=b;this.f=0;this.o=this.j=!1;this.s=d}var X=null;W.prototype.g=function(a){var b=this.a;b.g&&w(b.f,[b.a.c("wf",a.c,K(a).toString(),"active")],[b.a.c("wf",a.c,K(a).toString(),"loading"),b.a.c("wf",a.c,K(a).toString(),"inactive")]);L(b,"fontactive",a);this.o=!0;oa(this)};
-W.prototype.h=function(a){var b=this.a;if(b.g){var d=y(b.f,b.a.c("wf",a.c,K(a).toString(),"active")),c=[],e=[b.a.c("wf",a.c,K(a).toString(),"loading")];d||c.push(b.a.c("wf",a.c,K(a).toString(),"inactive"));w(b.f,c,e)}L(b,"fontinactive",a);oa(this)};function oa(a){0==--a.f&&a.j&&(a.o?(a=a.a,a.g&&w(a.f,[a.a.c("wf","active")],[a.a.c("wf","loading"),a.a.c("wf","inactive")]),L(a,"active")):M(a.a))};function pa(a){this.j=a;this.a=new ja;this.h=0;this.f=this.g=!0}pa.prototype.load=function(a){this.c=new ca(this.j,a.context||this.j);this.g=!1!==a.events;this.f=!1!==a.classes;qa(this,new ha(this.c,a),a)};
-function ra(a,b,d,c,e){var f=0==--a.h;(a.f||a.g)&&setTimeout(function(){var a=e||null,k=c||null||{};if(0===d.length&&f)M(b.a);else{b.f+=d.length;f&&(b.j=f);var h,m=[];for(h=0;h<d.length;h++){var l=d[h],n=k[l.c],r=b.a,x=l;r.g&&w(r.f,[r.a.c("wf",x.c,K(x).toString(),"loading")]);L(r,"fontloading",x);r=null;null===X&&(X=window.FontFace?(x=/Gecko.*Firefox\/(\d+)/.exec(window.navigator.userAgent))?42<parseInt(x[1],10):!0:!1);X?r=new Q(p(b.g,b),p(b.h,b),b.c,l,b.s,n):r=new R(p(b.g,b),p(b.h,b),b.c,l,b.s,a,
-n);m.push(r)}for(h=0;h<m.length;h++)m[h].start()}},0)}function qa(a,b,d){var c=[],e=d.timeout;ia(b);var c=ka(a.a,d,a.c),f=new W(a.c,b,e);a.h=c.length;b=0;for(d=c.length;b<d;b++)c[b].load(function(b,c,d){ra(a,f,b,c,d)})};function sa(a,b){this.c=a;this.a=b}function ta(a,b,d){var c=z(a.c);a=(a.a.api||"fast.fonts.net/jsapi").replace(/^.*http(s?):(\/\/)?/,"");return c+"//"+a+"/"+b+".js"+(d?"?v="+d:"")}
-sa.prototype.load=function(a){function b(){if(e["__mti_fntLst"+d]){var c=e["__mti_fntLst"+d](),g=[],k;if(c)for(var h=0;h<c.length;h++){var m=c[h].fontfamily;void 0!=c[h].fontStyle&&void 0!=c[h].fontWeight?(k=c[h].fontStyle+c[h].fontWeight,g.push(new H(m,k))):g.push(new H(m))}a(g)}else setTimeout(function(){b()},50)}var d=this.a.projectId,c=this.a.version;if(d){var e=this.c.m;B(this.c,ta(this,d,c),function(c){c?a([]):b()}).id="__MonotypeAPIScript__"+d}else a([])};function ua(a,b){this.c=a;this.a=b}ua.prototype.load=function(a){var b,d,c=this.a.urls||[],e=this.a.families||[],f=this.a.testStrings||{},g=new C;b=0;for(d=c.length;b<d;b++)A(this.c,c[b],D(g));var k=[];b=0;for(d=e.length;b<d;b++)if(c=e[b].split(":"),c[1])for(var h=c[1].split(","),m=0;m<h.length;m+=1)k.push(new H(c[0],h[m]));else k.push(new H(c[0]));F(g,function(){a(k,f)})};function va(a,b,d){a?this.c=a:this.c=b+wa;this.a=[];this.f=[];this.g=d||""}var wa="//fonts.googleapis.com/css";function xa(a,b){for(var d=b.length,c=0;c<d;c++){var e=b[c].split(":");3==e.length&&a.f.push(e.pop());var f="";2==e.length&&""!=e[1]&&(f=":");a.a.push(e.join(f))}}
-function ya(a){if(0==a.a.length)throw Error("No fonts to load!");if(-1!=a.c.indexOf("kit="))return a.c;for(var b=a.a.length,d=[],c=0;c<b;c++)d.push(a.a[c].replace(/ /g,"+"));b=a.c+"?family="+d.join("%7C");0<a.f.length&&(b+="&subset="+a.f.join(","));0<a.g.length&&(b+="&text="+encodeURIComponent(a.g));return b};function za(a){this.f=a;this.a=[];this.c={}}
-var Aa={latin:"BESbswy",cyrillic:"\u0439\u044f\u0416",greek:"\u03b1\u03b2\u03a3",khmer:"\u1780\u1781\u1782",Hanuman:"\u1780\u1781\u1782"},Ba={thin:"1",extralight:"2","extra-light":"2",ultralight:"2","ultra-light":"2",light:"3",regular:"4",book:"4",medium:"5","semi-bold":"6",semibold:"6","demi-bold":"6",demibold:"6",bold:"7","extra-bold":"8",extrabold:"8","ultra-bold":"8",ultrabold:"8",black:"9",heavy:"9",l:"3",r:"4",b:"7"},Ca={i:"i",italic:"i",n:"n",normal:"n"},Da=/^(thin|(?:(?:extra|ultra)-?)?light|regular|book|medium|(?:(?:semi|demi|extra|ultra)-?)?bold|black|heavy|l|r|b|[1-9]00)?(n|i|normal|italic)?$/;
-function Ea(a){for(var b=a.f.length,d=0;d<b;d++){var c=a.f[d].split(":"),e=c[0].replace(/\+/g," "),f=["n4"];if(2<=c.length){var g;var k=c[1];g=[];if(k)for(var k=k.split(","),h=k.length,m=0;m<h;m++){var l;l=k[m];if(l.match(/^[\w-]+$/)){var n=Da.exec(l.toLowerCase());if(null==n)l="";else{l=n[2];l=null==l||""==l?"n":Ca[l];n=n[1];if(null==n||""==n)n="4";else var r=Ba[n],n=r?r:isNaN(n)?"4":n.substr(0,1);l=[l,n].join("")}}else l="";l&&g.push(l)}0<g.length&&(f=g);3==c.length&&(c=c[2],g=[],c=c?c.split(","):
-g,0<c.length&&(c=Aa[c[0]])&&(a.c[e]=c))}a.c[e]||(c=Aa[e])&&(a.c[e]=c);for(c=0;c<f.length;c+=1)a.a.push(new H(e,f[c]))}};function Fa(a,b){this.c=a;this.a=b}var Ga={Arimo:!0,Cousine:!0,Tinos:!0};Fa.prototype.load=function(a){var b=new C,d=this.c,c=new va(this.a.api,z(d),this.a.text),e=this.a.families;xa(c,e);var f=new za(e);Ea(f);A(d,ya(c),D(b));F(b,function(){a(f.a,f.c,Ga)})};function Ha(a,b){this.c=a;this.a=b}Ha.prototype.load=function(a){var b=this.a.id,d=this.c.m;b?B(this.c,(this.a.api||"https://use.typekit.net")+"/"+b+".js",function(b){if(b)a([]);else if(d.Typekit&&d.Typekit.config&&d.Typekit.config.fn){b=d.Typekit.config.fn;for(var e=[],f=0;f<b.length;f+=2)for(var g=b[f],k=b[f+1],h=0;h<k.length;h++)e.push(new H(g,k[h]));try{d.Typekit.load({events:!1,classes:!1,async:!0})}catch(m){}a(e)}},2E3):a([])};function Ia(a,b){this.c=a;this.f=b;this.a=[]}Ia.prototype.load=function(a){var b=this.f.id,d=this.c.m,c=this;b?(d.__webfontfontdeckmodule__||(d.__webfontfontdeckmodule__={}),d.__webfontfontdeckmodule__[b]=function(b,d){for(var g=0,k=d.fonts.length;g<k;++g){var h=d.fonts[g];c.a.push(new H(h.name,ga("font-weight:"+h.weight+";font-style:"+h.style)))}a(c.a)},B(this.c,z(this.c)+(this.f.api||"//f.fontdeck.com/s/css/js/")+ea(this.c)+"/"+b+".js",function(b){b&&a([])}):a([])};var Y=new pa(window);Y.a.c.custom=function(a,b){return new ua(b,a)};Y.a.c.fontdeck=function(a,b){return new Ia(b,a)};Y.a.c.monotype=function(a,b){return new sa(b,a)};Y.a.c.typekit=function(a,b){return new Ha(b,a)};Y.a.c.google=function(a,b){return new Fa(b,a)};var Z={load:p(Y.load,Y)};"function"===typeof define&&define.amd?define(function(){return Z}):"undefined"!==typeof module&&module.exports?module.exports=Z:(window.WebFont=Z,window.WebFontConfig&&Y.load(window.WebFontConfig));}());
diff --git a/app.js b/app.js
deleted file mode 100644
index 89ba136b..00000000
--- a/app.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import fastify from "fastify";
-import pino from "pino";
-
-export default fastify({ logger: pino(), disableRequestLogging: true, maxParamLength: 500 });
diff --git a/db/db.js b/db/db.js
deleted file mode 100644
index 9e7cc25b..00000000
--- a/db/db.js
+++ /dev/null
@@ -1,5 +0,0 @@
-import Sequelize from "@sequelize/core";
-import config from "$config";
-
-let { database, user, password, options } = config.db;
-export default new Sequelize(database, user, password, options);
diff --git a/db/index.js b/db/index.js
deleted file mode 100644
index 0437ece6..00000000
--- a/db/index.js
+++ /dev/null
@@ -1,158 +0,0 @@
-import Sequelize from "@sequelize/core";
-
-import db from "$db/db";
-
-db.authenticate().catch(err => {
- console.debug("Error connecting to database: " + err.message);
-});
-
-import "./models/accounts";
-import "./models/codes";
-import "./models/deposits";
-import "./models/invoices";
-import "./models/keys";
-import "./models/payments";
-import "./models/orders";
-import "./models/requests";
-import "./models/users";
-import "./models/withdrawals";
-
-import "./models/referrals";
-import "./models/waiting_list";
-
-const { User, Account, Payment, Invoice, Key, Order, Referral, Request } = db;
-
-User.hasMany(Account, {
- as: "accounts",
- foreignKey: "user_id"
-});
-
-User.hasMany(Invoice, {
- as: "invoices",
- foreignKey: "user_id"
-});
-
-User.hasMany(Key, {
- as: "keys",
- foreignKey: "user_id"
-});
-
-User.hasMany(Order, {
- as: "orders",
- foreignKey: "user_id"
-});
-
-User.hasMany(Payment, {
- as: "payments",
- foreignKey: "user_id"
-});
-
-User.belongsTo(Account, {
- as: "account",
- foreignKey: "account_id"
-});
-
-Invoice.belongsTo(Account, {
- as: "account",
- foreignKey: "account_id"
-});
-
-Account.belongsTo(User, {
- as: "user",
- foreignKey: "user_id"
-});
-
-Invoice.belongsTo(User, {
- as: "user",
- foreignKey: "user_id"
-});
-
-Key.belongsTo(User, {
- as: "user",
- foreignKey: "user_id"
-});
-
-Payment.belongsTo(Account, {
- as: "account",
- foreignKey: "account_id"
-});
-
-Payment.belongsTo(User, {
- as: "user",
- foreignKey: "user_id"
-});
-
-Payment.belongsTo(Invoice, {
- as: "invoice",
- foreignKey: "invoice_id"
-});
-
-Order.belongsTo(User, {
- as: "user",
- foreignKey: "user_id"
-});
-
-Order.belongsTo(Account, {
- as: "acc1",
- foreignKey: "a1_id"
-});
-
-Order.belongsTo(Account, {
- as: "acc2",
- foreignKey: "a2_id"
-});
-
-User.hasMany(Referral, {
- as: "referral_codes",
- foreignKey: "sponsor_id"
-});
-
-User.hasMany(Referral, {
- as: "sponsors",
- foreignKey: "user_id"
-});
-
-Referral.belongsTo(User, {
- as: "sponsor",
- foreignKey: "sponsor_id"
-});
-
-Referral.belongsTo(User, {
- as: "user",
- foreignKey: "user_id"
-});
-
-Payment.belongsTo(Payment, {
- as: "fee_payment",
- foreignKey: "fee_payment_id"
-});
-
-Payment.belongsTo(User, {
- as: "with",
- foreignKey: "with_id"
-});
-
-Request.belongsTo(User, {
- as: "requester",
- foreignKey: "requester_id"
-});
-
-Request.belongsTo(User, {
- as: "recipient",
- foreignKey: "recipient_id"
-});
-
-Request.belongsTo(Invoice, {
- as: "invoice",
- foreignKey: "invoice_id"
-});
-
-Invoice.hasOne(Request, {
- as: "request",
- foreignKey: "invoice_id"
-});
-
-
-db.Order = Order;
-
-export default db;
diff --git a/db/init/prodschema.sql b/db/init/prodschema.sql
deleted file mode 100644
index 38e25324..00000000
--- a/db/init/prodschema.sql
+++ /dev/null
@@ -1,312 +0,0 @@
--- MySQL dump 10.14 Distrib 5.5.68-MariaDB, for Linux (x86_64)
---
--- Host: localhost Database: coinos
--- ------------------------------------------------------
--- Server version 5.5.68-MariaDB
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8 */;
-/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
-/*!40103 SET TIME_ZONE='+00:00' */;
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
-/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
-/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-
---
--- Table structure for table `SequelizeMeta`
---
-
-DROP TABLE IF EXISTS `SequelizeMeta`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `SequelizeMeta` (
- `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
- PRIMARY KEY (`name`),
- UNIQUE KEY `name` (`name`),
- UNIQUE KEY `SequelizeMeta_name_unique` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `accounts`
---
-
-DROP TABLE IF EXISTS `accounts`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `accounts` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `asset` varchar(255) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `balance` double DEFAULT NULL,
- `pending` double DEFAULT NULL,
- `name` varchar(255) DEFAULT NULL,
- `ticker` varchar(255) DEFAULT NULL,
- `precision` int(11) DEFAULT NULL,
- `domain` varchar(255) DEFAULT NULL,
- `contract` text,
- `index` int(11) NOT NULL DEFAULT '0',
- `pubkey` varchar(255) DEFAULT NULL,
- `hide` tinyint(1) DEFAULT NULL,
- `seed` varchar(255) DEFAULT NULL,
- `path` varchar(255) DEFAULT NULL,
- `network` varchar(255) DEFAULT NULL,
- `privkey` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `asset` (`asset`)
-) ENGINE=InnoDB AUTO_INCREMENT=20553 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `cheaters`
---
-
-DROP TABLE IF EXISTS `cheaters`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `cheaters` (
- `id` int(11) NOT NULL DEFAULT '0',
- `username` varchar(255) DEFAULT NULL,
- `sum` double DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `codes`
---
-
-DROP TABLE IF EXISTS `codes`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `codes` (
- `code` varchar(255) NOT NULL DEFAULT '',
- `text` text,
- PRIMARY KEY (`code`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `deposits`
---
-
-DROP TABLE IF EXISTS `deposits`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `deposits` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `amount` double DEFAULT NULL,
- `credited` tinyint(1) DEFAULT NULL,
- `code` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=4554 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `invoices`
---
-
-DROP TABLE IF EXISTS `invoices`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `invoices` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `text` text,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `rate` double DEFAULT NULL,
- `currency` varchar(255) NOT NULL,
- `address` varchar(255) DEFAULT NULL,
- `received` double DEFAULT NULL,
- `amount` double DEFAULT NULL,
- `tip` double DEFAULT NULL,
- `network` varchar(255) DEFAULT NULL,
- `unconfidential` varchar(255) DEFAULT NULL,
- `uuid` varchar(255) DEFAULT NULL,
- `memo` text,
- `account_id` int(11) DEFAULT NULL,
- `path` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `part_of_unconfidential` (`unconfidential`(10)),
- KEY `text_index` (`text`(100)),
- KEY `unconfidential_index` (`unconfidential`(100)),
- KEY `address_index` (`address`(100))
-) ENGINE=InnoDB AUTO_INCREMENT=36355 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `linkingkeys`
---
-
-DROP TABLE IF EXISTS `linkingkeys`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `linkingkeys` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `hex` varchar(255) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=11822 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `naughty`
---
-
-DROP TABLE IF EXISTS `naughty`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `naughty` (
- `id` int(11) NOT NULL DEFAULT '0',
- `username` varchar(255) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `orders`
---
-
-DROP TABLE IF EXISTS `orders`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `orders` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `a1` varchar(255) DEFAULT NULL,
- `a2` varchar(255) DEFAULT NULL,
- `v1` double DEFAULT NULL,
- `v2` double DEFAULT NULL,
- `user_id` int(11) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `accepted` tinyint(1) NOT NULL DEFAULT '0',
- `a1_id` int(11) DEFAULT NULL,
- `a2_id` int(11) DEFAULT NULL,
- `rate` double AS (v2/v1) VIRTUAL,
- `completedAt` datetime DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=389 DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `payments`
---
-
-DROP TABLE IF EXISTS `payments`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `payments` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `hash` text,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `rate` double DEFAULT NULL,
- `currency` varchar(255) DEFAULT NULL,
- `address` varchar(255) DEFAULT NULL,
- `received` tinyint(1) DEFAULT NULL,
- `amount` double DEFAULT NULL,
- `tip` double NOT NULL DEFAULT '0',
- `confirmed` tinyint(1) NOT NULL,
- `fee` double NOT NULL DEFAULT '0',
- `network` varchar(255) DEFAULT NULL,
- `account_id` int(11) DEFAULT NULL,
- `preimage` varchar(255) DEFAULT NULL,
- `memo` text,
- `redeemed` tinyint(1) NOT NULL DEFAULT '0',
- `redeemcode` varchar(255) DEFAULT NULL,
- `path` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `idx_redeemcode` (`redeemcode`)
-) ENGINE=InnoDB AUTO_INCREMENT=25828 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `reset`
---
-
-DROP TABLE IF EXISTS `reset`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `reset` (
- `password` varchar(255) DEFAULT NULL,
- `seed` varchar(255) DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `users`
---
-
-DROP TABLE IF EXISTS `users`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `users` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `username` varchar(255) DEFAULT NULL,
- `password` varchar(255) DEFAULT NULL,
- `unit` varchar(255) DEFAULT 'SAT',
- `symbol` varchar(255) DEFAULT NULL,
- `currency` varchar(255) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `twofa` tinyint(1) DEFAULT NULL,
- `pin` varchar(255) DEFAULT NULL,
- `currencies` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
- `otpsecret` varchar(255) DEFAULT NULL,
- `account_id` int(11) DEFAULT NULL,
- `ip` int(10) unsigned DEFAULT NULL,
- `subscriptions` text,
- `seed` varchar(255) DEFAULT NULL,
- `fiat` tinyint(1) NOT NULL DEFAULT '0',
- `index` int(11) NOT NULL DEFAULT '0',
- `verified` varchar(255) DEFAULT NULL,
- `locked` tinyint(1) DEFAULT '0',
- PRIMARY KEY (`id`),
- KEY `ip` (`ip`),
- KEY `username` (`username`)
-) ENGINE=InnoDB AUTO_INCREMENT=14579 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `withdrawals`
---
-
-DROP TABLE IF EXISTS `withdrawals`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `withdrawals` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) NOT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `amount` double DEFAULT NULL,
- `completed` tinyint(1) DEFAULT NULL,
- `transit` varchar(255) DEFAULT NULL,
- `account` varchar(255) DEFAULT NULL,
- `institution` varchar(255) DEFAULT NULL,
- `notes` text,
- `email` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=4118 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
-
-/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
-/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-
--- Dump completed on 2021-07-15 1:26:35
diff --git a/db/migrations/20210612181508_init_referrals.js b/db/migrations/20210612181508_init_referrals.js
deleted file mode 100644
index 63b20ce4..00000000
--- a/db/migrations/20210612181508_init_referrals.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export const up = function(knex) {
- return Promise.all([
- knex.schema.dropTableIfExists('referrals'),
-
- knex.schema.createTable('referrals', function(t) {
- t.increments('id').unsigned().primary();
- t.integer('user_id').nullable();
- t.foreign('user_id').references('users.id');
-
- t.integer('sponsor_id').notNull();
- t.foreign('sponsor_id').references('users.id');
-
- t.string('token').notNull();
- t.string('expiry').nullable();
- t.enum('status', ['available', 'used', 'expired', 'cancelled']).notNull().defaultTo('available');
-
- t.timestamps(true, true);
- })
- ])
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('referrals');
-};
diff --git a/db/migrations/20210612192804_init_waiting_list.js.js b/db/migrations/20210612192804_init_waiting_list.js.js
deleted file mode 100644
index 0cef7356..00000000
--- a/db/migrations/20210612192804_init_waiting_list.js.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export const up = function(knex) {
-
- return Promise.all([
- knex.schema.dropTableIfExists('waiting_list'),
-
- knex.schema.createTable('waiting_list', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('email').notNull();
- t.string('phone').notNull();
- t.enu('status', ['pending', 'activated', 'expired', 'cancelled']).notNull();
-
- t.integer('user_id').nullable();
- t.foreign('user_id').references('users.id');
- t.text('notes').nullable();
-
- t.timestamps(true, true);
- })
- ])
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('waiting_list');
-};
diff --git a/db/migrations/20210612203333_schema_diff_merges.js b/db/migrations/20210612203333_schema_diff_merges.js
deleted file mode 100644
index 418105d2..00000000
--- a/db/migrations/20210612203333_schema_diff_merges.js
+++ /dev/null
@@ -1,39 +0,0 @@
-export const up = function(knex) {
- return Promise.all([
- knex.schema.dropTableIfExists('reset'),
- knex.schema.dropTableIfExists('naughty'),
- knex.schema.dropTableIfExists('cheaters'),
-
- knex.raw("UPDATE accounts set createdAt = '2020-01-01' where createdAt < '2020-01-01'"),
- knex.raw("UPDATE accounts set updatedAt = '2020-01-01' where updatedAt < '2020-01-01'"),
- knex.raw("ALTER TABLE accounts modify `contract` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL"),
-
- knex.schema.alterTable('orders', function(t) {
- t.dropColumn('a1');
- t.dropColumn('a2');
- }),
-
- knex.schema.alterTable("users", function(t) {
- t.string('authyId').nullable();
- t.dropColumn('symbol');
- }),
-
- knex.raw("ALTER TABLE users MODIFY `subscriptions` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL"),
-
- ])
-};
-
-export const down = async function(knex) {
- return Promise.all([
- knex.schema.table("orders", function(t) {
- t.integer("a1");
- t.integer("a2")
- }),
-
- knex.schema.table("users", function(t) {
- t.string("symbol");
- t.dropColumn("unit");
- t.dropColumn("authyId");
- }),
- ])
-}; \ No newline at end of file
diff --git a/db/migrations/20210625232223_add_invoice_id_to_payments.js b/db/migrations/20210625232223_add_invoice_id_to_payments.js
deleted file mode 100644
index adf99d24..00000000
--- a/db/migrations/20210625232223_add_invoice_id_to_payments.js
+++ /dev/null
@@ -1,13 +0,0 @@
-export const up = async function (knex) {
- return knex.schema.table("payments", function(table) {
- table.integer("invoice_id");
- table.foreign("invoice_id").references("invoices.id");
- })
-};
-
-export const down = async function (knex) {
- return knex.schema.table("payments", function(table) {
- table.dropForeign("invoice_id");
- table.dropColumn("invoice_id");
- })
-};
diff --git a/db/migrations/20210628221727_add_webhook_to_invoices.js b/db/migrations/20210628221727_add_webhook_to_invoices.js
deleted file mode 100644
index 434819e5..00000000
--- a/db/migrations/20210628221727_add_webhook_to_invoices.js
+++ /dev/null
@@ -1,11 +0,0 @@
-export const up = async function(knex) {
- return knex.schema.table("invoices", function(table) {
- table.text("webhook");
- });
-};
-
-export const down = async function(knex) {
- return knex.schema.table("invoices", function(table) {
- table.dropColumn("webhook");
- });
-};
diff --git a/db/migrations/20210713174217_add_admin_to_users.js b/db/migrations/20210713174217_add_admin_to_users.js
deleted file mode 100644
index 879c8cb7..00000000
--- a/db/migrations/20210713174217_add_admin_to_users.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export const up = async function(knex) {
- return knex.schema.table("users", function(t) {
- t.boolean("admin");
- t.string('email');
- t.string('phone');
-
- });
-};
-
-export const down = async function(knex) {
- return knex.schema.table("users", function(t) {
- t.dropColumn("admin");
- t.dropColumn('email')
- t.dropColumn('phone')
- });
-};
diff --git a/db/migrations/20210714123455_data_fixes_merge.js b/db/migrations/20210714123455_data_fixes_merge.js
deleted file mode 100644
index dfe96509..00000000
--- a/db/migrations/20210714123455_data_fixes_merge.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export const up = function(knex) {
- return Promise.all([
- knex.raw("delete from invoices where invoices.account_id not in (select id from accounts)"),
- knex.raw("delete from orders where orders.a1_id not in (select id from accounts) or orders.a2_id not in (select id from accounts)"),
- knex.raw("update users set account_id = 10427 where id = 6262 and account_id = 10428"),
- knex.raw("delete from payments where account_id not in (select id from accounts)"),
- knex.raw("alter table orders drop rate"),
- knex.raw("alter table orders add rate double"),
- knex.raw("update orders set rate = v1/v2"),
-
- knex.raw('update accounts left join users on accounts.user_id = users.id set user_id = null where length(username) > 32'),
- knex.raw('update accounts left join users on accounts.user_id = users.id set user_id = null where users.id is null'),
- knex.raw('delete from accounts where user_id is null'),
- knex.raw('delete from users where length(username) > 32')
- ])
-};
-
-export const down = function(knex) {
- return Promise.all([
-
- ])
-};
diff --git a/db/migrations/20210714123456_add_fks_merge.js b/db/migrations/20210714123456_add_fks_merge.js
deleted file mode 100644
index 3d5f3e94..00000000
--- a/db/migrations/20210714123456_add_fks_merge.js
+++ /dev/null
@@ -1,45 +0,0 @@
-export const up = function(knex) {
- return Promise.all([
-
- // alter table invoices add foreign key (user_id) references users (id);
- // alter table invoices add foreign key (account_id) references accounts (id);
- knex.schema.alterTable("invoices", function(t) {
- t.foreign('user_id').references('users.id')
- t.foreign('account_id').references('accounts.id')
- t.index('updatedAt')
- }),
-
- // alter table payments add foreign key (user_id) references users (id);
- // alter table payments add foreign key (account_id) references accounts (id);
- knex.schema.alterTable("payments", function(t) {
- t.foreign('user_id').references('users.id')
- t.foreign('account_id').references('accounts.id')
- t.index('updatedAt')
- }),
-
- // alter table orders add foreign key (user_id) references users (id);
- // alter table orders add foreign key (a1_id) references accounts (id);
- // alter table orders add foreign key (a2_id) references accounts (id);
- knex.schema.alterTable("orders", function(t) {
- t.foreign('user_id').references('users.id')
- t.foreign('a1_id').references('accounts.id')
- t.foreign('a2_id').references('accounts.id')
- t.index('updatedAt')
- }),
-
- // alter table deposits add foreign key (user_id) references users (id)
- knex.schema.alterTable("deposits", function(t) {
- t.foreign('user_id').references('users.id')
- t.index('updatedAt')
- }),
-
- // alter table withdrawals add foreign key (user_id) references users (id)
- knex.schema.alterTable("withdrawals", function(t) {
- t.foreign('user_id').references('users.id')
- t.index('updatedAt')
- }),
- ])
-};
-
-export const down = function(knex) {
-};
diff --git a/db/migrations/s2/user_adjustments.js b/db/migrations/s2/user_adjustments.js
deleted file mode 100644
index cbe17977..00000000
--- a/db/migrations/s2/user_adjustments.js
+++ /dev/null
@@ -1,67 +0,0 @@
-
-export const up = function(knex) {
- return Promise.all([
-
- // move security fields to separate t (potentially different access permissions)
-
- knex.schema.createTable('user_security', function (t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.user_id');
-
- t.boolean('twofa').notNull().defaultTo(false);
- t.string('pin').notNull();
- t.string('otp_secret').nullable();
- t.string('seed').nullable();
- }),
-
- knex.raw("INSERT INTO user_security (user_id, twofa, pin, otp_secret, seed) SELECT users.id, twofa, pin, otpsecret, seed FROM users"),
-
- // move user-customizeable fields to separate t (potentially different access permissions)
-
- knex.schema.createTable('user_preferences', function (t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.user_id');
-
- t.enum('default_unit', ['SAT', 'BTC', 'CAD']).notNull().defaultTo('SAT');
- t.enum('default_currency', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.enum('default_fiat', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.set('show_currencies', ['CAD', 'USD']).notNull().defaultTo('CAD');
- }),
-
- knex.raw("INSERT INTO user_preferences (user_id, default_unit, default_currency, default_fiat, show_currencies) SELECT users.id, unit, currency, fiat, currencies FROM users"),
-
- // remove deprecated fields
-
- knex.schema.table('users', function (t) {
- t.string('uuid');
- t.enum('access', ['Anonymous', 'Member', 'Admin']).defaultTo('Anonymous');
-
- t.dropColumn('account_id');
- t.dropColumn('unit');
- t.dropColumn('fiat');
- t.dropColumn('currency');
- t.dropColumn('currencies');
- })
- ])
-
-};
-
-export const down = function(knex) {
- return Promise.all([
- knex.schema.table('users', function (t) {
- t.dropColumn('uuid');
- t.dropColumn('access');
-
- t.int('account_id');
- t.string('unit');
- t.string('fiat');
- t.string('currency');
- t.string('currencies');
- }),
-
- knex.schema.dropTable('user_preferences'),
- knex.schema.dropTable('user_security'),
- ]);
-};
diff --git a/db/models/accounts.js b/db/models/accounts.js
deleted file mode 100644
index 9485bc99..00000000
--- a/db/models/accounts.js
+++ /dev/null
@@ -1,217 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- seed: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "seed"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- name: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "name"
- },
- contract: {
- type: DataTypes.TEXT,
- get: function() {
- return JSON.parse(this.getDataValue("contract"));
- },
- set: function(value) {
- return this.setDataValue("contract", JSON.stringify(value));
- },
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "contract"
- },
- domain: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "domain"
- },
- ticker: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "ticker"
- },
- asset: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "asset"
- },
- balance: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "balance"
- },
- btc_credits: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: 0.0,
- primaryKey: false,
- autoIncrement: false,
- comment: "Credits that can be used towards paying Bitcoin withdrawal fees",
- field: "btc_credits"
- },
- liquid_credits: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: 0.0,
- primaryKey: false,
- autoIncrement: false,
- comment: "Credits that can be used towards paying Liquid withdrawal fees",
- field: "liquid_credits"
- },
- lightning_credits: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: 0.0,
- primaryKey: false,
- autoIncrement: false,
- comment: "Credits that can be used towards paying Lightning withdrawal fees",
- field: "lightning_credits"
- },
- pending: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "pending"
- },
- hide: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hide"
- },
- index: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "index"
- },
- privkey: {
- type: DataTypes.STRING,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "privkey"
- },
- pubkey: {
- type: DataTypes.STRING,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "pubkey"
- },
- precision: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "precision"
- },
-};
-
-const options = {
- tableName: "accounts",
- comment: "",
- indexes: []
-};
-
-db["Account"] = db.define("accounts_model", attributes, options);
diff --git a/db/models/codes.js b/db/models/codes.js
deleted file mode 100644
index 0981ac5e..00000000
--- a/db/models/codes.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- code: {
- type: DataTypes.STRING(255),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: false,
- comment: null,
- field: "code"
- },
- text: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "text"
- },
-};
-
-const options = {
- tableName: "codes",
- comment: "",
- indexes: [],
- timestamps: false
-};
-
-db["Code"] = db.define("codes_model", attributes, options);
diff --git a/db/models/deposits.js b/db/models/deposits.js
deleted file mode 100644
index c486f468..00000000
--- a/db/models/deposits.js
+++ /dev/null
@@ -1,76 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- credited: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "credited"
- },
- code: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "code"
- },
-};
-
-const options = {
- tableName: "deposits",
- comment: "",
- indexes: []
-};
-
-db["Deposit"] = db.define("deposits_model", attributes, options);
diff --git a/db/models/invoices.js b/db/models/invoices.js
deleted file mode 100644
index 82e64427..00000000
--- a/db/models/invoices.js
+++ /dev/null
@@ -1,202 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- text: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "text"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- uuid: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: DataTypes.UUIDV4,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "uuid"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- unconfidential: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "unconfidential"
- },
- address: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- received: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "received"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- pending: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "pending"
- },
- webhook: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "webhook"
- },
- status: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: "unpaid",
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "status"
- },
- tip: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "tip"
- },
- prompt: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "prompt"
- },
-};
-
-const options = {
- tableName: "invoices",
- comment: "",
- indexes: []
-};
-
-db["Invoice"] = db.define("invoices_model", attributes, options);
diff --git a/db/models/keys.js b/db/models/keys.js
deleted file mode 100644
index 5a5fda0c..00000000
--- a/db/models/keys.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- hex: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hex"
- },
-};
-
-const options = {
- tableName: "linkingkeys",
- comment: "",
- indexes: []
-};
-
-db["Key"] = db.define("keys_model", attributes, options);
diff --git a/db/models/orders.js b/db/models/orders.js
deleted file mode 100644
index 50a74c40..00000000
--- a/db/models/orders.js
+++ /dev/null
@@ -1,112 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- a1_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "a1_id"
- },
- a2_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "a2_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- completedAt: {
- type: DataTypes.DATE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "completedAt"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- v1: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "v1"
- },
- v2: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "v2"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- accepted: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "accepted"
- },
-};
-
-const options = {
- tableName: "orders",
- comment: "",
- indexes: []
-};
-
-db.Order = db.define("orders_model", attributes, options);
diff --git a/db/models/payments.js b/db/models/payments.js
deleted file mode 100644
index fac8ff56..00000000
--- a/db/models/payments.js
+++ /dev/null
@@ -1,220 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- with_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "with_id"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- invoice_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "invoice_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- hash: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hash"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- preimage: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "preimage"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- address: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- received: {
- type: DataTypes.INTEGER(1),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "received"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- fee: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fee"
- },
- tip: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "tip"
- },
- redeemed: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemed"
- },
- redeemcode: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemcode"
- },
- confirmed: {
- type: DataTypes.INTEGER(1),
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "confirmed"
- },
- fee_payment_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fee_payment_id"
- }
-};
-
-const options = {
- tableName: "payments",
- comment: "",
- indexes: []
-};
-
-db["Payment"] = db.define("payments_model", attributes, options);
diff --git a/db/models/referrals.js b/db/models/referrals.js
deleted file mode 100644
index 8aebde2e..00000000
--- a/db/models/referrals.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- sponsor_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "sponsor_id"
- },
-
- token: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "token"
- },
- expiry: {
- type: DataTypes.DATE(),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "token"
- },
- status: {
- type: DataTypes.ENUM,
- values: ['available', 'used', 'expired', 'cancelled'],
- allowNull: true,
- defaultValue: 'available',
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "token"
- }
-};
-
-const options = {
- tableName: "referrals",
- comment: "",
- indexes: []
-};
-
-db["Referral"] = db.define("referrals_model", attributes, options);
-
-// exports.up = function(knex) {
-// return knex.schema.createTable('referrals', function(t) {
-// t.increments('id').unsigned().primary();
-// t.int('user_id').nullable();
-// t.foreign('user_id').references('users.id');
-
-// t.int('sponsor_id').notNull();
-// t.foreign('sponsor_id').references('users.id');
-
-// t.string('token').notNull();
-// t.string('expiry').nullable();
-// t.enum('status', ['available', 'used', 'expired', 'cancelled']).notNull().defaultTo('available');
-
-// t.timestamps();
-// })
-// };
-
-// exports.down = function(knex) {
-// return knex.schema.dropTable('referrals');
-// };
diff --git a/db/models/requests.js b/db/models/requests.js
deleted file mode 100644
index 76703a72..00000000
--- a/db/models/requests.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- requester_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "requester_id"
- },
- recipient_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "recipient_id"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
-};
-
-const options = {
- tableName: "requests",
- comment: "",
- indexes: []
-};
-
-db["Request"] = db.define("requests_model", attributes, options);
diff --git a/db/models/users.js b/db/models/users.js
deleted file mode 100644
index faf41576..00000000
--- a/db/models/users.js
+++ /dev/null
@@ -1,250 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- uuid: {
- type: DataTypes.STRING,
- allowNull: false,
- defaultValue: DataTypes.UUIDV4,
- primaryKey: true,
- autoIncrement: false,
- comment: null,
- field: "uuid"
- },
- address: {
- type: DataTypes.STRING,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- theme: {
- type: DataTypes.STRING,
- allowNull: true,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "theme"
- },
- profile: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "profile"
- },
- banner: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "banner"
- },
- admin: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "admin"
- },
- locked: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "locked"
- },
- verified: {
- type: DataTypes.STRING,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "verified"
- },
- fiat: {
- type: DataTypes.BOOLEAN,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fiat"
- },
- index: {
- type: DataTypes.INTEGER,
- allowNull: true,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "index"
- },
- ip: {
- type: DataTypes.INTEGER.UNSIGNED,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "ip"
- },
- seed: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "seed"
- },
- username: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "username"
- },
- password: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "password"
- },
- unit: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: 'SAT',
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "unit"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- otpsecret: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: "CAD",
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "otpsecret"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: "CAD",
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- currencies: {
- type: DataTypes.JSON,
- allowNull: false,
- defaultValue: ["USD"],
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currencies"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- subscriptions: {
- type: DataTypes.TEXT,
- get: function() {
- return JSON.parse(this.getDataValue("subscriptions"));
- },
- set: function(value) {
- return this.setDataValue("subscriptions", JSON.stringify(value));
- },
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "subscriptions"
- },
- twofa: {
- type: DataTypes.INTEGER(1),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "twofa"
- },
- pin: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "pin"
- },
- email: {
- type: DataTypes.STRING(255)
- },
- phone: {
- type: DataTypes.STRING(255)
- }
-};
-
-const options = {
- tableName: "users",
- comment: "",
- indexes: []
-};
-
-db["User"] = db.define("users_model", attributes, options);
diff --git a/db/models/waiting_list.js b/db/models/waiting_list.js
deleted file mode 100644
index 37f2889b..00000000
--- a/db/models/waiting_list.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- primaryKey: true,
- autoIncrement: true,
- allowNull: false
- },
- email: {
- type: DataTypes.STRING(255),
- validate: {
- isEmail: true
- }
- },
- phone: {
- type: DataTypes.STRING(255),
- validate: {
- is: /^[0-9]+$/ // replace spaces, brackets, dashes dynamically prior to create
- }
- },
- status: {
- type: DataTypes.ENUM,
- values: ['pending', 'activated', 'expired', 'cancelled'],
- defaultValue: 'pending',
- allowNull: false
- }
-}
-
-const options = {
- tableName: "waiting_list",
- comment: "Users on waiting list",
- timestamps: true,
- createdAt: 'created_at',
- updatedAt: 'updated_at',
- indexes: [
- {
- unique: true,
- fields: ['email', 'phone']
- }
- ]
-};
-
-db["WaitingList"] = db.define("waiting_list_model", attributes, options);
diff --git a/db/models/withdrawals.js b/db/models/withdrawals.js
deleted file mode 100644
index fa2afb22..00000000
--- a/db/models/withdrawals.js
+++ /dev/null
@@ -1,103 +0,0 @@
-import db from "$db/db";
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- transit: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "transit"
- },
- institution: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "institution"
- },
- account: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account"
- },
- email: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "email"
- },
- notes: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "notes"
- },
-};
-
-const options = {
- tableName: "withdrawals",
- comment: "",
- indexes: []
-};
-
-db["Withdrawal"] = db.define("withdrawals_model", attributes, options);
diff --git a/db/normalized/README.md b/db/normalized/README.md
deleted file mode 100644
index fd3cb0d3..00000000
--- a/db/normalized/README.md
+++ /dev/null
@@ -1,48 +0,0 @@
-# General guidelines for Database schema:
-
-- String fields whose values are NOT open-ended (ie can contain random strings) should be changed to either:
- - an FK to a separate lookup table (when the domain of options is large or can grow)
- - an enum (when there are a short list of essentailly static options)
-
-- Field names should follow SQL standards:
- - lower case
- - underscore_separated_words
-
-- options for designated models should be standardized with:
- {
- tableName: "table_name",
- comment: "description of table if not self-evident",
- timestamps: true,
- createdAt: 'created_at',
- updatedAt: 'updated_at',
- indexes: [
- { <as required> }
- ]
- };
-
- ## Note regarding field attributes specified in model:
-
- - createdAt, updatedAt are renamed to abide by SQL standard.
-
- - by default allowNull is false, so this attribute need only be specified when fields are NOT NULL.
-
- - comment attribute should added to any field that is not self-evident
-
- - may need to add indexes to more fields for rapid access
-
- ## Notes regarding changes / updates
-
- - Some 1-1 tables are split up simply to separate scope or to control access permission (ie only user_preferences table may be edited by users themselves)
-
- ## Sequelize Operational Questions:
- - Are indexes automatically generated by Sequelize migration for primary keys and/or foreign keys ?
- - Does Sequelize add non-unique indexes for data mining if specified: eg { fields: ['username'] }
- - Do timestamp fields require default value spec (eg Sequelize.NOW) ... or how can we define this in model ?
-
- ## Ongoing Questions:
- - payments table needs to be investigated and refactored
- - is invoices table required or is this just summary information ?
- - orders table needs to be investigated and refactored
- - need to add subscriptions table if applicable ( what is this comprised of ?)
- - user_keys table should be commented to clarify application of each of these values.
-
diff --git a/db/normalized/accounts.js b/db/normalized/accounts.js
deleted file mode 100644
index 8e5aad33..00000000
--- a/db/normalized/accounts.js
+++ /dev/null
@@ -1,231 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('accounts', function(t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.id');
-
- t.int('uuid').notNull();
-
- t.double('balance');
- t.double('pending');
-
- t.enu('network', ['Bitcoin', 'Liquid', 'Lightning', 'CoinOS']).notNull();
-
- t.longtext('contract').collate('utf8mb4').nullable(); // custodial ?
-
- // knex.raw("ALTER TABLE accounts MODIFY `contract` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL")
-
- // t.string('hide');
- // t.string('index');
-
- t.int('liquid_asset_id').notNull();
- t.foreign('liquid_asset_id').references('liquid_assets.id');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('accounts');
-};
-
-// Change
-//
-// move assets fields (asset, ticker, name, precision...) to separate liquid_assets reference
-
-// separate network specific fields to bitcoin_accounts / liquid_accounts / coinos_accounts tables ? or just non_custodial ?
-// eg liquid -> liquid_asset info
-// non-custodial ? -> privkey, pubkey, path, seed ?
-// contract, hide, index ?
-//
-
-
-// const { DataTypes } = require('@sequelize/core');
-
-// const attributes = {
-// id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: true,
-// autoIncrement: true,
-// comment: null,
-// field: "id"
-// },
-// user_id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "user_id"
-// },
-// createdAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "createdAt"
-// },
-// updatedAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "updatedAt"
-// },
-// path: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "path"
-// },
-// seed: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "seed"
-// },
-// network: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "network"
-// },
-// name: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "name"
-// },
-// contract: {
-// type: DataTypes.TEXT,
-// get: function() {
-// return JSON.parse(this.getDataValue("contract"));
-// },
-// set: function(value) {
-// return this.setDataValue("contract", JSON.stringify(value));
-// },
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "contract"
-// },
-// domain: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "domain"
-// },
-// ticker: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "ticker"
-// },
-// asset: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "asset"
-// },
-// balance: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "balance"
-// },
-// pending: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "pending"
-// },
-// hide: {
-// type: DataTypes.BOOLEAN,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "hide"
-// },
-// index: {
-// type: DataTypes.INTEGER(11),
-// allowNull: false,
-// defaultValue: 0,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "index"
-// },
-// privkey: {
-// type: DataTypes.STRING,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "privkey"
-// },
-// pubkey: {
-// type: DataTypes.STRING,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "pubkey"
-// },
-// precision: {
-// type: DataTypes.INTEGER(11),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "precision"
-// },
-// };
-
-// const options = {
-// tableName: "accounts",
-// comment: "",
-// indexes: []
-// };
-
-// db["Account"] = db.define("accounts_model", attributes, options);
diff --git a/db/normalized/bank_accounts.js b/db/normalized/bank_accounts.js
deleted file mode 100644
index 5d8ea0dc..00000000
--- a/db/normalized/bank_accounts.js
+++ /dev/null
@@ -1,24 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('bank_accounts', function(t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.id');
-
- t.int('transit_number');
- t.int('institution_number');
- t.int('account_number');
-
- t.string('swift');
- t.string('iban');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('user_security');
-};
-
-// Changes:
-//
-// bank info -> bank_account records
diff --git a/db/normalized/credits.js b/db/normalized/credits.js
deleted file mode 100644
index 5511b616..00000000
--- a/db/normalized/credits.js
+++ /dev/null
@@ -1,236 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('credits', function(t) {
- t.increments('id').unsigned().primary();
-
- t.enu('type', ['deposit', 'order', 'transfer', 'invoice', 'exchange'])
- t.string('description')
-
- t.int('account_id').notNull();
- t.foreign('account_id').references('accounts.id');
-
- t.double('amount');
-
- t.enu('status', ['pending', 'completed', 'reversed', 'cancelled'])
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
-return knex.schema.dropTable('credits');
-};
-
-// Changes:
-//
-// Should these be tracked as transactions ?
-// SAT -> SAT
-// tracking various exchange variations (outside of external networks ?)
-//
-// Is user / account / amount info redundant ?
-// + transaction_type: deposit / withdrawal / transfer / exchange ?
-//
-// add transfers table ? (for internal transfers only ?)
-// add redemptions table ? (for bitcoin transfers only ?)
-// add exchanges table ? (for conversion from one currency to another)
-//
-// network -> scope: internal / bitcoin / liquid / lightning ?
-// add bitcoin_transaction ? (with redemption attributes)
-// add liquid_transaction ? ()
-// add lightning_transaction ? (with LN_invoice_hash)
-// add internal_transaction ? ()
-//
-// context for path, memo, rate, preimage, address, received, fee, tip, confirmed, redeemcode ?
-
-
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- hash: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hash"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- preimage: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "preimage"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- address: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- received: {
- type: DataTypes.INTEGER(1),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "received"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- fee: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fee"
- },
- tip: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "tip"
- },
- redeemed: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemed"
- },
- redeemcode: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemcode"
- },
- confirmed: {
- type: DataTypes.INTEGER(1),
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "confirmed"
- }
-};
-
-const options = {
- tableName: "payments",
- comment: "",
- indexes: []
-};
-
-db["Payment"] = db.define("payments_model", attributes, options);
diff --git a/db/normalized/debits.js b/db/normalized/debits.js
deleted file mode 100644
index 6fcee974..00000000
--- a/db/normalized/debits.js
+++ /dev/null
@@ -1,236 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('debits', function(t) {
- t.increments('id').unsigned().primary();
-
- t.enu('type', ['withdrawal', 'order', 'transfer', 'invoice', 'exchange'])
-
- t.int('account_id').notNull();
- t.foreign('account_id').references('accounts.id');
-
- t.double('amount');
-
- t.enu('type', ['withdrawal', 'transfer', 'order', 'invoice'])
- t.enu('status', ['pending', 'completed', 'reversed', 'cancelled'])
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
-return knex.schema.dropTable('debits');
-};
-
-// Changes:
-//
-// Should these be tracked as transactions ?
-// SAT -> SAT
-// tracking various exchange variations (outside of external networks ?)
-//
-// Is user / account / amount info redundant ?
-// + transaction_type: deposit / withdrawal / transfer / exchange ?
-//
-// add transfers table ? (for internal transfers only ?)
-// add redemptions table ? (for bitcoin transfers only ?)
-// add exchanges table ? (for conversion from one currency to another)
-//
-// network -> scope: internal / bitcoin / liquid / lightning ?
-// add bitcoin_transaction ? (with redemption attributes)
-// add liquid_transaction ? ()
-// add lightning_transaction ? (with LN_invoice_hash)
-// add internal_transaction ? ()
-//
-// context for path, memo, rate, preimage, address, received, fee, tip, confirmed, redeemcode ?
-
-
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- hash: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hash"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- preimage: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "preimage"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- address: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- received: {
- type: DataTypes.INTEGER(1),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "received"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- fee: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fee"
- },
- tip: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "tip"
- },
- redeemed: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemed"
- },
- redeemcode: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemcode"
- },
- confirmed: {
- type: DataTypes.INTEGER(1),
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "confirmed"
- }
-};
-
-const options = {
- tableName: "payments",
- comment: "",
- indexes: []
-};
-
-db["Payment"] = db.define("payments_model", attributes, options);
diff --git a/db/normalized/deposits.js b/db/normalized/deposits.js
deleted file mode 100644
index 17a7c500..00000000
--- a/db/normalized/deposits.js
+++ /dev/null
@@ -1,100 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('deposits', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('credit_id').notNull();
- t.foreign('credit_id').references('credits.id');
-
- t.string('confirmation_code');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('deposits');
-};
-
-// Changes:
-//
-// reference transaction
-// reference account rather than user
-// credited - redundant with confirmation_code ?
-// code -> confirmation_code
-
-
-// const { DataTypes } = require('@sequelize/core');
-
-// const attributes = {
-// id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: true,
-// autoIncrement: true,
-// comment: null,
-// field: "id"
-// },
-// amount: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "amount"
-// },
-// user_id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "user_id"
-// },
-// createdAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "createdAt"
-// },
-// updatedAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "updatedAt"
-// },
-// credited: {
-// type: DataTypes.BOOLEAN,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "credited"
-// },
-// code: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "code"
-// },
-// };
-
-// const options = {
-// tableName: "deposits",
-// comment: "",
-// indexes: []
-// };
-
-// db["Deposit"] = db.define("deposits_model", attributes, options);
diff --git a/db/normalized/exchanges.js b/db/normalized/exchanges.js
deleted file mode 100644
index 2be91990..00000000
--- a/db/normalized/exchanges.js
+++ /dev/null
@@ -1,232 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('exchanges', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('transfer_id').notNull();
- t.foreign('transfer_id').references('transfers.id');
-
- t.double('exchange_rate').notNull()
- t.double('exchange_fee').notNull().defaultTo(0)
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
-return knex.schema.dropTable('exchanges');
-};
-
-// Changes:
-//
-// Should these be tracked as transactions ?
-// SAT -> SAT
-// tracking various exchange variations (outside of external networks ?)
-//
-// Is user / account / amount info redundant ?
-// + transaction_type: deposit / withdrawal / transfer / exchange ?
-//
-// add transfers table ? (for internal transfers only ?)
-// add redemptions table ? (for bitcoin transfers only ?)
-// add exchanges table ? (for conversion from one currency to another)
-//
-// network -> scope: internal / bitcoin / liquid / lightning ?
-// add bitcoin_transaction ? (with redemption attributes)
-// add liquid_transaction ? ()
-// add lightning_transaction ? (with LN_invoice_hash)
-// add internal_transaction ? ()
-//
-// context for path, memo, rate, preimage, address, received, fee, tip, confirmed, redeemcode ?
-
-
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- hash: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hash"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- preimage: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "preimage"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- address: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- received: {
- type: DataTypes.INTEGER(1),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "received"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- fee: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fee"
- },
- tip: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "tip"
- },
- redeemed: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemed"
- },
- redeemcode: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemcode"
- },
- confirmed: {
- type: DataTypes.INTEGER(1),
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "confirmed"
- }
-};
-
-const options = {
- tableName: "payments",
- comment: "",
- indexes: []
-};
-
-db["Payment"] = db.define("payments_model", attributes, options);
diff --git a/db/normalized/invoices.js b/db/normalized/invoices.js
deleted file mode 100644
index 823ad11d..00000000
--- a/db/normalized/invoices.js
+++ /dev/null
@@ -1,206 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('invoices', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('transfer_id').notNull();
- t.foreign('transfer_id').references('transfers.id');
-
- t.enu('network', ['Bitcoin', 'Liquid', 'Lightning', 'CoinOS']).notNull();
-
- t.string('bolt11'); // was 'text'
-
- // Clarify ??? - break out ? - context ? include everything encoded in hash...
- t.double('amount');
-
- // Exchanges
- // ( are there a couple of types of invoices ? - eg checkout / voucher / receive ... with different attributes ?)
- t.double('rate')
- t.string('currency')
- t.double('tip')
-
- t.string('path')
- t.string('uuid')
- t.string('memo')
- t.string('unconfidential')
- t.string('address')
- t.string('received')
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('invoices');
-};
-
-
-// Variations: ?
-// wallet -> receive - fields ?
-// checkout - fields ?
-// voucher - fields ?
-
-// const { DataTypes } = require('@sequelize/core');
-
-// const attributes = {
-// id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: true,
-// autoIncrement: true,
-// comment: null,
-// field: "id"
-// },
-// account_id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "account_id"
-// },
-// user_id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "user_id"
-// },
-// text: {
-// type: DataTypes.TEXT,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "text"
-// },
-// createdAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "createdAt"
-// },
-// updatedAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "updatedAt"
-// },
-// path: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "path"
-// },
-// rate: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "rate"
-// },
-// uuid: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "uuid"
-// },
-// memo: {
-// type: DataTypes.TEXT,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "memo"
-// },
-// network: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "network"
-// },
-// currency: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "currency"
-// },
-// unconfidential: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "unconfidential"
-// },
-// address: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "address"
-// },
-// received: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "received"
-// },
-// amount: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "amount"
-// },
-// tip: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "tip"
-// },
-// };
-
-// const options = {
-// tableName: "invoices",
-// comment: "",
-// indexes: []
-// };
-
-// db["Invoice"] = db.define("invoices_model", attributes, options);
diff --git a/db/normalized/liquid_assets.js b/db/normalized/liquid_assets.js
deleted file mode 100644
index fab96dc5..00000000
--- a/db/normalized/liquid_assets.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('liquid_assets', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('asset_id').notNull();
- t.string('name').notNull();
-
- t.string('domain')
- t.string('ticker').notNull();
- t.int('precision').defaultTo(8);
- t.string('issuer_pubkey')
-
- t.boolean('registered').defaultTo(false);
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('liquid_assets');
-}; \ No newline at end of file
diff --git a/db/normalized/ln_keys.js b/db/normalized/ln_keys.js
deleted file mode 100644
index 7922e40e..00000000
--- a/db/normalized/ln_keys.js
+++ /dev/null
@@ -1,16 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('ln_keys', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.id');
-
- t.string('hex').notNull();
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('ln_keys');
-}; \ No newline at end of file
diff --git a/db/normalized/lnurl_codes.js b/db/normalized/lnurl_codes.js
deleted file mode 100644
index 5ed81135..00000000
--- a/db/normalized/lnurl_codes.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('lnurl_codes', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('code').notNull();
- t.text('text');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('lnurl_codes');
-};
diff --git a/db/normalized/non_custodial_accounts.js b/db/normalized/non_custodial_accounts.js
deleted file mode 100644
index e8190ce6..00000000
--- a/db/normalized/non_custodial_accounts.js
+++ /dev/null
@@ -1,91 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('non_custodial_accounts', function(t) {
- t.increments('id').unsigned().primary();
- t.int('account_id').notNull();
- t.foreign('account_id').references('accounts.id');
-
- // what is the scope / context of these attributes ?
- t.string('path');
- t.string('seed');
- // t.string('hide');
- // t.string('index');
- t.string('pub_key');
- t.string('priv_key');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('non_custodial_accounts');
-};
-
-// const { DataTypes } = require('@sequelize/core');
-
-// const attributes = {
-// id: {
-// type: DataTypes.INTEGER(11),
-// primaryKey: true,
-// autoIncrement: true,
-// allowNull: false
-// },
-// account_id: {
-// type: DataTypes.INTEGER(11),
-// references: { model: Account, key: 'id' },
-// allowNull: false,
-// comment: "Reference to account"
-// },
-// path: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// },
-// seed: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// },
-// network: {
-// type: DataTypes.INTEGER(11),
-// references: { model: Network, key: 'id' },
-// allowNull: false,
-// comment: "Reference to network"
-// },
-// domain: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ? ... is it unique or an enum ?"
-// },
-// ticker: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// },
-// hide: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// },
-// index: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// },
-// pub_key: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// },
-// priv_key: {
-// type: DataTypes.STRING(255),
-// comment: "What is this ?"
-// }
-// }
-// const options = {
-// tableName: "non_custodial_accounts",
-// comment: "",
-// timestamps: true,
-// createdAt: 'created_at',
-// updatedAt: 'updated_at',
-// indexes: [
-// {
-// unique: true,
-// fields: ['account_id']
-// }
-// ]
-// };
-
-// db["NonCustodialAccount"] = db.define("non_custodial_accounts_model", attributes, options);
diff --git a/db/normalized/orders.js b/db/normalized/orders.js
deleted file mode 100644
index 06e83db1..00000000
--- a/db/normalized/orders.js
+++ /dev/null
@@ -1,29 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('orders', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('sell_transfer_id').notNull();
- t.foreign('sell_transfer_id').references('transfers.id');
-
- t.int('buy_transfer_id').notNull();
- t.foreign('buy_transfer_id').references('transfers.id');
-
- // t.int('exchange_id').notNull();
- // t.foreign('exchange_id').references('exchanges.id');
-
- t.double('exchange_rate').notNull();
- // t.double('amount').notNull();
-
- t.enu('status', ['Submitted', 'Accepted', 'Cancelled']).notNull();
- t.date('completion_date')
-
- t.timestamps();
- })
-};
-
-// Bid / Accepted ... separate into Bid (credit + debit), Accepted (credit + debit)
-
-export const down = function(knex) {
- return knex.schema.dropTable('orders');
-};
-
diff --git a/db/normalized/referrals.js b/db/normalized/referrals.js
deleted file mode 100644
index 7380f2cf..00000000
--- a/db/normalized/referrals.js
+++ /dev/null
@@ -1,20 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('referrals', function(t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').nullable();
- t.foreign('user_id').references('users.id');
-
- t.int('sponsor_id').notNull();
- t.foreign('sponsor_id').references('users.id');
-
- t.string('token').notNull();
- t.string('expiry').nullable();
- t.enum('status', ['available', 'used', 'expired', 'cancelled']).notNull().defaultTo('available');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('referrals');
-};
diff --git a/db/normalized/transactions.js b/db/normalized/transactions.js
deleted file mode 100644
index 230faca4..00000000
--- a/db/normalized/transactions.js
+++ /dev/null
@@ -1,41 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('transactions', function(t) {
- t.increments('id').unsigned().primary();
-
- t.enu('type', ['deposit', 'withdrawal', 'transfer', 'exchange', 'invoice', 'voucher', 'new asset'])
-
- // t.text('notes');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
-return knex.schema.dropTable('transactions');
-};
-
-// Changes:
-//
-// Deposit = deposit + credit
-// Withdrawal = withdrawal + debit
-// Transfer = credit + debit
-// Exchange = credit + debit + debit + credit
-// Invoice = invoice + debit ?
-// Voucher = invoice + debit ?
-// New Asset = liquid_asset + credit
-
-//
-// context for path, memo, rate, preimage, address, received, fee, tip, confirmed, redeemcode ?
-export const up = function(knex) {
- return knex.schema.createTable('transactions', function(t) {
- t.increments('id').unsigned().primary();
-
- t.enu('type', ['deposit', 'withdrawal', 'order', 'transfer', 'invoice', 'voucher'])
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
-return knex.schema.dropTable('transactions');
-}; \ No newline at end of file
diff --git a/db/normalized/transfers.js b/db/normalized/transfers.js
deleted file mode 100644
index 64f5c392..00000000
--- a/db/normalized/transfers.js
+++ /dev/null
@@ -1,243 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('transfers', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('transaction_id').notNull();
- t.foreign('transaction_id').references('accounts.id');
-
- t.int('debit_id').notNull();
- t.foreign('debit_id').references('debits.id');
-
- t.int('credit_id').notNull();
- t.foreign('credit_id').references('credits.id');
-
- // t.int('liquid_asset_id').notNull();
- // t.foreign('liquid_asset_id').references('liquid_assets.id');
-
- // t.double('amount');
- t.double('transfer_fee').notNull().defaultTo(0)
-
- t.enu('status', ['pending', 'completed', 'reversed', 'cancelled'])
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
-return knex.schema.dropTable('transfers');
-};
-
-// Changes:
-//
-// Should these be tracked as transactions ?
-// SAT -> SAT
-// tracking various exchange variations (outside of external networks ?)
-//
-// Is user / account / amount info redundant ?
-// + transaction_type: deposit / withdrawal / transfer / exchange ?
-//
-// add transfers table ? (for internal transfers only ?)
-// add redemptions table ? (for bitcoin transfers only ?)
-// add exchanges table ? (for conversion from one currency to another)
-//
-// network -> scope: internal / bitcoin / liquid / lightning ?
-// add bitcoin_transaction ? (with redemption attributes)
-// add liquid_transaction ? ()
-// add lightning_transaction ? (with LN_invoice_hash)
-// add internal_transaction ? ()
-//
-// context for path, memo, rate, preimage, address, received, fee, tip, confirmed, redeemcode ?
-
-
-import { DataTypes } from '@sequelize/core';
-
-const attributes = {
- id: {
- type: DataTypes.INTEGER(11),
- allowNull: false,
- defaultValue: null,
- primaryKey: true,
- autoIncrement: true,
- comment: null,
- field: "id"
- },
- account_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "account_id"
- },
- user_id: {
- type: DataTypes.INTEGER(11),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "user_id"
- },
- path: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "path"
- },
- memo: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "memo"
- },
- hash: {
- type: DataTypes.TEXT,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "hash"
- },
- createdAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "createdAt"
- },
- updatedAt: {
- type: DataTypes.DATE,
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "updatedAt"
- },
- rate: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "rate"
- },
- preimage: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "preimage"
- },
- network: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "network"
- },
- currency: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "currency"
- },
- address: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "address"
- },
- received: {
- type: DataTypes.INTEGER(1),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "received"
- },
- amount: {
- type: DataTypes.DOUBLE,
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "amount"
- },
- fee: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "fee"
- },
- tip: {
- type: DataTypes.DOUBLE,
- allowNull: false,
- defaultValue: 0,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "tip"
- },
- redeemed: {
- type: DataTypes.BOOLEAN,
- allowNull: false,
- defaultValue: false,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemed"
- },
- redeemcode: {
- type: DataTypes.STRING(255),
- allowNull: true,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "redeemcode"
- },
- confirmed: {
- type: DataTypes.INTEGER(1),
- allowNull: false,
- defaultValue: null,
- primaryKey: false,
- autoIncrement: false,
- comment: null,
- field: "confirmed"
- }
-};
-
-const options = {
- tableName: "payments",
- comment: "",
- indexes: []
-};
-
-db["Payment"] = db.define("payments_model", attributes, options);
diff --git a/db/normalized/user_preferences.js b/db/normalized/user_preferences.js
deleted file mode 100644
index 6af69f3f..00000000
--- a/db/normalized/user_preferences.js
+++ /dev/null
@@ -1,20 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('user_preferences', function(t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.id');
-
- t.enum('default_unit', ['SAT', 'BTC', 'CAD']).notNull().defaultTo('SAT');
- t.enum('default_currency', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.enum('default_fiat', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.set('show_currencies', ['CAD', 'USD']).notNull().defaultTo('CAD');
- t.longtext(`subscriptions`).collate('utf8mb4').nullable(); // CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL")
- t.timestamps();
-
- // knex.raw("ALTER TABLE users MODIFY `subscriptions` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL")
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('user_preferences');
-};
diff --git a/db/normalized/user_security.js b/db/normalized/user_security.js
deleted file mode 100644
index 919b2902..00000000
--- a/db/normalized/user_security.js
+++ /dev/null
@@ -1,22 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('user_security', function(t) {
- t.increments('id').unsigned().primary();
- t.int('user_id').notNull();
- t.foreign('user_id').references('users.id');
-
- t.boolean('twofa').notNull().defaultTo(false);
- t.string('pin').notNull();
- t.string('otp_secret').nullable();
- t.string('seed').nullable();
-
- t.boolean('email_verified').notNull().default(false)
- t.boolean('phone_verified').notNull().default(false)
- t.boolean('kyc_verified').notNull().default(false)
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('user_security');
-}; \ No newline at end of file
diff --git a/db/normalized/users.js b/db/normalized/users.js
deleted file mode 100644
index dd239f24..00000000
--- a/db/normalized/users.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('users', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('uuid').notNull().index();
- t.string('username').notNull().index();
- t.string('password').notNull();
- t.string('email').nullable().index();
- t.string('phone').nullable();
- t.enum('access', ['Anonymous', 'Registered', 'Admin']).notNull().defaultTo('Anonymous');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('users');
-}; \ No newline at end of file
diff --git a/db/normalized/vouchers.js b/db/normalized/vouchers.js
deleted file mode 100644
index 35d54de2..00000000
--- a/db/normalized/vouchers.js
+++ /dev/null
@@ -1,18 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('vouchers', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('invoice_id').notNull();
- t.foreign('invoice_id').references('invoices.id');
-
- t.string('redemption_code').notNull();
-
- t.enu('status', ['pending', 'redeemed', 'cancelled']).notNull();
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('vouchers');
-}; \ No newline at end of file
diff --git a/db/normalized/waiting_list.js b/db/normalized/waiting_list.js
deleted file mode 100644
index 5a37dc52..00000000
--- a/db/normalized/waiting_list.js
+++ /dev/null
@@ -1,60 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('waiting_list', function(t) {
- t.increments('id').unsigned().primary();
-
- t.string('email').notNull();
- t.string('phone').notNull();
- t.enu('status', ['pending', 'activated', 'expired', 'cancelled']).notNull();
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('waiting_list');
-};
-
-// const { DataTypes } = require('@sequelize/core');
-
-// const attributes = {
-// id: {
-// type: DataTypes.INTEGER(11),
-// primaryKey: true,
-// autoIncrement: true,
-// allowNull: false
-// },
-// email: {
-// type: DataTypes.STRING(255),
-// validate: {
-// isEmail: true
-// }
-// },
-// sms: {
-// type: DataTypes.STRING(255),
-// validate: {
-// is: /^[0-9]+$/ // replace spaces, brackets, dashes dynamically prior to create
-// }
-// },
-// status: {
-// type: DataTypes.ENUM,
-// values: ['pending', 'activated', 'expired', 'cancelled'],
-// defaultValue: 'pending',
-// allowNull: false
-// }
-// }
-
-// const options = {
-// tableName: "waiting_list",
-// comment: "Users on waiting list",
-// timestamps: true,
-// createdAt: 'created_at',
-// updatedAt: 'updated_at',
-// indexes: [
-// {
-// unique: true,
-// fields: ['email', 'sms']
-// }
-// ]
-// };
-
-// db["WaitingList"] = db.define("waiting_list_model", attributes, options);
diff --git a/db/normalized/withdrawals.js b/db/normalized/withdrawals.js
deleted file mode 100644
index 742f3dbf..00000000
--- a/db/normalized/withdrawals.js
+++ /dev/null
@@ -1,128 +0,0 @@
-export const up = function(knex) {
- return knex.schema.createTable('withdrawals', function(t) {
- t.increments('id').unsigned().primary();
-
- t.int('debit_id').notNull();
- t.foreign('debit_id').references('debits.id');
-
- t.int('bank_account_id').notNull();
- t.foreign('bank_account_id').references('bank_accounts.id');
-
- t.double('withdrawal_fee').notNull().defaultTo(0)
-
- t.text('notes');
-
- t.timestamps();
- })
-};
-
-export const down = function(knex) {
- return knex.schema.dropTable('withdrawals');
-};
-
-// Changes:
-//
-// bank info -> bank_account records
-
-// const { DataTypes } = require('@sequelize/core');
-
-// const attributes = {
-// id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: true,
-// autoIncrement: true,
-// comment: null,
-// field: "id"
-// },
-// amount: {
-// type: DataTypes.DOUBLE,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "amount"
-// },
-// user_id: {
-// type: DataTypes.INTEGER(11),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "user_id"
-// },
-// createdAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "createdAt"
-// },
-// updatedAt: {
-// type: DataTypes.DATE,
-// allowNull: false,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "updatedAt"
-// },
-// transit: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "transit"
-// },
-// institution: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "institution"
-// },
-// account: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "account"
-// },
-// email: {
-// type: DataTypes.STRING(255),
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "email"
-// },
-// notes: {
-// type: DataTypes.TEXT,
-// allowNull: true,
-// defaultValue: null,
-// primaryKey: false,
-// autoIncrement: false,
-// comment: null,
-// field: "notes"
-// },
-// };
-
-// const options = {
-// tableName: "withdrawals",
-// comment: "",
-// indexes: []
-// };
-
-// db["Withdrawal"] = db.define("withdrawals_model", attributes, options);
diff --git a/db/schema.sql b/db/schema.sql
deleted file mode 100644
index e6e2e03f..00000000
--- a/db/schema.sql
+++ /dev/null
@@ -1,479 +0,0 @@
--- MariaDB dump 10.19 Distrib 10.6.1-MariaDB, for debian-linux-gnu (x86_64)
---
--- Host: localhost Database: coinos
--- ------------------------------------------------------
--- Server version 10.6.1-MariaDB-1:10.6.1+maria~focal
-
-/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
-/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
-/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
-/*!40101 SET NAMES utf8mb4 */;
-/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
-/*!40103 SET TIME_ZONE='+00:00' */;
-/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
-/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
-/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-
---
--- Current Database: `coinos`
---
-
-CREATE DATABASE /*!32312 IF NOT EXISTS*/ `coinos` /*!40100 DEFAULT CHARACTER SET latin1 */;
-
-USE `coinos`;
-
---
--- Table structure for table `SequelizeMeta`
---
-
-DROP TABLE IF EXISTS `SequelizeMeta`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `SequelizeMeta` (
- `name` varchar(255) COLLATE utf8mb3_unicode_ci NOT NULL,
- PRIMARY KEY (`name`),
- UNIQUE KEY `name` (`name`),
- UNIQUE KEY `SequelizeMeta_name_unique` (`name`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `accounts`
---
-
-DROP TABLE IF EXISTS `accounts`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `accounts` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `asset` varchar(255) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `balance` double DEFAULT NULL,
- `pending` double DEFAULT NULL,
- `name` varchar(255) DEFAULT NULL,
- `ticker` varchar(255) DEFAULT NULL,
- `precision` int(11) DEFAULT NULL,
- `domain` varchar(255) DEFAULT NULL,
- `contract` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
- `index` int(11) NOT NULL DEFAULT 0,
- `pubkey` varchar(255) DEFAULT NULL,
- `hide` tinyint(1) DEFAULT NULL,
- `seed` varchar(255) DEFAULT NULL,
- `path` varchar(255) DEFAULT NULL,
- `network` varchar(255) DEFAULT NULL,
- `privkey` varchar(255) DEFAULT NULL,
- `btc_credits` double NOT NULL DEFAULT 0,
- `liquid_credits` double NOT NULL DEFAULT 0,
- `lightning_credits` double NOT NULL DEFAULT 0,
- PRIMARY KEY (`id`),
- KEY `asset` (`asset`)
-) ENGINE=InnoDB AUTO_INCREMENT=21826 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `codes`
---
-
-DROP TABLE IF EXISTS `codes`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `codes` (
- `code` varchar(255) NOT NULL DEFAULT '',
- `text` text DEFAULT NULL,
- PRIMARY KEY (`code`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `deposits`
---
-
-DROP TABLE IF EXISTS `deposits`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `deposits` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `amount` double DEFAULT NULL,
- `credited` tinyint(1) DEFAULT NULL,
- `code` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `deposits_user_id_foreign` (`user_id`),
- CONSTRAINT `deposits_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=4568 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `invoices`
---
-
-DROP TABLE IF EXISTS `invoices`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `invoices` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `text` text DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `rate` double DEFAULT NULL,
- `currency` varchar(255) NOT NULL,
- `address` varchar(255) DEFAULT NULL,
- `received` bigint(20) NOT NULL DEFAULT 0,
- `amount` bigint(20) DEFAULT NULL,
- `tip` double DEFAULT NULL,
- `network` varchar(255) DEFAULT NULL,
- `unconfidential` varchar(255) DEFAULT NULL,
- `uuid` varchar(255) DEFAULT uuid(),
- `memo` text DEFAULT NULL,
- `account_id` int(11) DEFAULT NULL,
- `path` varchar(255) DEFAULT NULL,
- `webhook` text DEFAULT NULL,
- `status` varchar(255) DEFAULT 'unpaid',
- `prompt` tinyint(1) NOT NULL DEFAULT 0,
- `pending` bigint(20) DEFAULT 0,
- PRIMARY KEY (`id`),
- KEY `part_of_unconfidential` (`unconfidential`(10)),
- KEY `text_index` (`text`(100)),
- KEY `unconfidential_index` (`unconfidential`(100)),
- KEY `address_index` (`address`(100)),
- KEY `invoices_user_id_foreign` (`user_id`),
- KEY `invoices_account_id_foreign` (`account_id`),
- KEY `uuid` (`uuid`(10)),
- CONSTRAINT `invoices_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`),
- CONSTRAINT `invoices_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=49340 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `linkingkeys`
---
-
-DROP TABLE IF EXISTS `linkingkeys`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `linkingkeys` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `hex` varchar(255) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=12640 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `lnurl_migrations`
---
-
-DROP TABLE IF EXISTS `lnurl_migrations`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `lnurl_migrations` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(255) DEFAULT NULL,
- `batch` int(11) DEFAULT NULL,
- `migration_time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `lnurl_migrations_lock`
---
-
-DROP TABLE IF EXISTS `lnurl_migrations_lock`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `lnurl_migrations_lock` (
- `index` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `is_locked` int(11) DEFAULT NULL,
- PRIMARY KEY (`index`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `migrations`
---
-
-DROP TABLE IF EXISTS `migrations`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `migrations` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `name` varchar(255) DEFAULT NULL,
- `batch` int(11) DEFAULT NULL,
- `migration_time` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `migrations_lock`
---
-
-DROP TABLE IF EXISTS `migrations_lock`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `migrations_lock` (
- `index` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `is_locked` int(11) DEFAULT NULL,
- PRIMARY KEY (`index`)
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `orders`
---
-
-DROP TABLE IF EXISTS `orders`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `orders` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `v1` double DEFAULT NULL,
- `v2` double DEFAULT NULL,
- `user_id` int(11) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `accepted` tinyint(1) NOT NULL DEFAULT 0,
- `a1_id` int(11) DEFAULT NULL,
- `a2_id` int(11) DEFAULT NULL,
- `completedAt` datetime DEFAULT NULL,
- `rate` double DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `orders_user_id_foreign` (`user_id`),
- KEY `orders_a1_id_foreign` (`a1_id`),
- KEY `orders_a2_id_foreign` (`a2_id`),
- CONSTRAINT `orders_a1_id_foreign` FOREIGN KEY (`a1_id`) REFERENCES `accounts` (`id`),
- CONSTRAINT `orders_a2_id_foreign` FOREIGN KEY (`a2_id`) REFERENCES `accounts` (`id`),
- CONSTRAINT `orders_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=337 DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `payments`
---
-
-DROP TABLE IF EXISTS `payments`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `payments` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `hash` text DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `rate` double DEFAULT NULL,
- `currency` varchar(255) DEFAULT NULL,
- `address` varchar(255) DEFAULT NULL,
- `received` tinyint(1) DEFAULT NULL,
- `amount` double DEFAULT NULL,
- `tip` double NOT NULL DEFAULT 0,
- `confirmed` tinyint(1) NOT NULL,
- `fee` double NOT NULL DEFAULT 0,
- `network` varchar(255) DEFAULT NULL,
- `account_id` int(11) DEFAULT NULL,
- `preimage` varchar(255) DEFAULT NULL,
- `memo` text DEFAULT NULL,
- `redeemed` tinyint(1) NOT NULL DEFAULT 0,
- `redeemcode` varchar(255) DEFAULT NULL,
- `path` varchar(255) DEFAULT NULL,
- `invoice_id` int(11) DEFAULT NULL,
- `fee_payment_id` int(11) DEFAULT NULL,
- `with_id` int(11) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `idx_redeemcode` (`redeemcode`),
- KEY `payments_invoice_id_foreign` (`invoice_id`),
- KEY `payments_user_id_foreign` (`user_id`),
- KEY `payments_account_id_foreign` (`account_id`),
- KEY `fk_payments` (`fee_payment_id`),
- KEY `fk_with` (`with_id`),
- CONSTRAINT `fk_payments` FOREIGN KEY (`fee_payment_id`) REFERENCES `payments` (`id`),
- CONSTRAINT `fk_with` FOREIGN KEY (`with_id`) REFERENCES `users` (`id`) ON DELETE SET NULL,
- CONSTRAINT `payments_account_id_foreign` FOREIGN KEY (`account_id`) REFERENCES `accounts` (`id`),
- CONSTRAINT `payments_invoice_id_foreign` FOREIGN KEY (`invoice_id`) REFERENCES `invoices` (`id`),
- CONSTRAINT `payments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=30378 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `prs`
---
-
-DROP TABLE IF EXISTS `prs`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `prs` (
- `text` text DEFAULT NULL,
- `preimage` text DEFAULT NULL
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `referrals`
---
-
-DROP TABLE IF EXISTS `referrals`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `referrals` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `user_id` int(11) DEFAULT NULL,
- `sponsor_id` int(11) NOT NULL,
- `token` varchar(255) NOT NULL,
- `expiry` varchar(255) DEFAULT NULL,
- `status` enum('available','used','expired','cancelled') NOT NULL DEFAULT 'available',
- `created_at` datetime DEFAULT NULL,
- `updated_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `referrals_user_id_foreign` (`user_id`),
- KEY `referrals_sponsor_id_foreign` (`sponsor_id`),
- CONSTRAINT `referrals_sponsor_id_foreign` FOREIGN KEY (`sponsor_id`) REFERENCES `users` (`id`),
- CONSTRAINT `referrals_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `requests`
---
-
-DROP TABLE IF EXISTS `requests`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `requests` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `requester_id` int(11) DEFAULT NULL,
- `recipient_id` int(11) DEFAULT NULL,
- `memo` text DEFAULT NULL,
- `createdAt` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
- `updatedAt` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
- `invoice_id` int(11) DEFAULT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `urls`
---
-
-DROP TABLE IF EXISTS `urls`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `urls` (
- `hash` varchar(255) DEFAULT NULL,
- `apiKeyId` varchar(255) DEFAULT NULL,
- `tag` varchar(255) DEFAULT NULL,
- `params` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`params`)),
- `initialUses` int(10) unsigned DEFAULT 1,
- `remainingUses` int(10) unsigned DEFAULT 0,
- `createdAt` timestamp NOT NULL DEFAULT current_timestamp(),
- `updatedAt` timestamp NOT NULL DEFAULT current_timestamp(),
- UNIQUE KEY `urls_hash_unique` (`hash`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `users`
---
-
-DROP TABLE IF EXISTS `users`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `users` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `username` varchar(255) DEFAULT NULL,
- `password` varchar(255) DEFAULT NULL,
- `unit` varchar(255) DEFAULT 'SAT',
- `currency` varchar(255) DEFAULT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `twofa` tinyint(1) DEFAULT NULL,
- `pin` varchar(255) DEFAULT NULL,
- `currencies` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
- `otpsecret` varchar(255) DEFAULT NULL,
- `account_id` int(11) DEFAULT NULL,
- `ip` int(10) unsigned DEFAULT NULL,
- `subscriptions` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
- `seed` varchar(255) DEFAULT NULL,
- `fiat` tinyint(1) NOT NULL DEFAULT 0,
- `index` int(11) NOT NULL DEFAULT 0,
- `verified` varchar(255) DEFAULT NULL,
- `locked` tinyint(1) DEFAULT 0,
- `authyId` varchar(255) DEFAULT NULL,
- `admin` tinyint(1) DEFAULT NULL,
- `email` varchar(255) DEFAULT NULL,
- `phone` varchar(255) DEFAULT NULL,
- `address` text DEFAULT NULL,
- `profile` tinyint(1) DEFAULT 0,
- `banner` tinyint(1) DEFAULT 0,
- `theme` varchar(255) DEFAULT NULL,
- `uuid` varchar(255) NOT NULL DEFAULT uuid(),
- PRIMARY KEY (`id`),
- KEY `ip` (`ip`),
- KEY `username` (`username`)
-) ENGINE=InnoDB AUTO_INCREMENT=15518 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `waiting_list`
---
-
-DROP TABLE IF EXISTS `waiting_list`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `waiting_list` (
- `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
- `email` varchar(255) NOT NULL,
- `phone` varchar(255) NOT NULL,
- `status` enum('pending','activated','expired','cancelled') NOT NULL,
- `user_id` int(11) DEFAULT NULL,
- `notes` text DEFAULT NULL,
- `created_at` datetime DEFAULT NULL,
- `updated_at` datetime DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `waiting_list_user_id_foreign` (`user_id`),
- CONSTRAINT `waiting_list_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Table structure for table `withdrawals`
---
-
-DROP TABLE IF EXISTS `withdrawals`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `withdrawals` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `user_id` int(11) NOT NULL,
- `createdAt` datetime NOT NULL,
- `updatedAt` datetime NOT NULL,
- `amount` double DEFAULT NULL,
- `completed` tinyint(1) DEFAULT NULL,
- `transit` varchar(255) DEFAULT NULL,
- `account` varchar(255) DEFAULT NULL,
- `institution` varchar(255) DEFAULT NULL,
- `notes` text DEFAULT NULL,
- `email` varchar(255) DEFAULT NULL,
- PRIMARY KEY (`id`),
- KEY `withdrawals_user_id_foreign` (`user_id`),
- CONSTRAINT `withdrawals_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
-) ENGINE=InnoDB AUTO_INCREMENT=4119 DEFAULT CHARSET=latin1;
-/*!40101 SET character_set_client = @saved_cs_client */;
-/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
-
-/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
-/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
-/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
-/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
-/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
-/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-
--- Dump completed on 2022-11-24 19:44:06
diff --git a/doc/PAYMENTS.md b/doc/PAYMENTS.md
deleted file mode 100644
index 2934aae8..00000000
--- a/doc/PAYMENTS.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# This document describes the types of transactions and accounts that can occur in CoinOS
-
-## Receive bitcoin
-
-There are four ways a user can receive bitcoin
-
-- Bitcoin
-- Liquid
-- Lightning
-- Internal
-
-In every case, a payment record is added to the `payments` table
-The payment `type` will be one of BTC, LBTC, LNBTC, or COINOS
-The `amount` will be a positive integer representing the number of satoshis received
-
-In the case of Bitcoin and Liquid payments, the `confirmed` column will be set to `false` initially until the transaction
-is mined into a block on the blockchain.
-
-Also, the payment amount will be reflected in users' active account record in the `accounts` table under the `pending` column. The `balance` column will be updated when confirmations are received and the `pending` amount will be debited.
-
-## Send bitcoin
-
-Users can also send bitcoin over any of the four networks by pasting in or scanning a QR code of a bitcoin or liquid address, lightning invoice, or username.
-
-In the case of lightning, it's also possible to paste an [LNURL](https://github.com/fiatjaf/lnurl-rfc) which is a way of getting a lightning invoice from a remote server or other wallet over HTTP.
-
-If scanning or pasting an address or invoice that happens to belong to another coinos user, coinos will detect that and automatically change the payment type to an internal COINOS transfer as if you had typed in the recipient's username.
-
-## Creating Liquid Assets
-
-Users can issue new assets on the Liquid network at https://coinos.io/asset
-
-This will create an on-chain transaction that will issue a specified amount of new tokens. A new account record will be created in the `accounts` table for the user to track their balance of the new asset. As with receiving bitcoin over the Liquid network, the balance will be `pending` until one block confirmation has been received and then it will be updated.
-
-A separate payment record will be created to cover the fee for the issuance transaction, which is paid in L-BTC.
-
-
-## Receiving Liquid Assets
-
-If the user has not received a particular asset before, a new account will be generated for them at the time the payment is detected.
-
-## Sending Liquid Assets
-
-Users can choose from a drop down menu to pick which account they want to be the active one. In the case of Liquid assets, they will only be able to an internal transfer to another coinos user, or send to a Liquid address. Users will receive an error if they paste in an LN invoice or on-chain BTC address while they have a Liquid asset accounted selected as their active account.
-
-## Depositing Fiat
-
-After having their account verified, users can fill out the deposit form at https://coinos.io/funding to indicate that they intend to send an interac or wire transfer. If the user is added to the list of accounts enabled for auto-deposit (under the `imap` config in config/index.js) then coinos will parse the Interac email it receives and automatically generate a new payment record and update the users Bitcoin account balance to credit them with an amount of bitcoin calculated equivalent to the fiat amount received, based on the current exchange rate less 2%.
-
-## Withdrawing Fiat
-
-Fiat withdrawals are currently processed manually. When a user requests to withdraw, we manually calculate how much bitcoin to remove from their account and do that with a database query before sending them an interac or wire transfer.
diff --git a/doc/fund-server-bitcoin-cli.md b/doc/fund-server-bitcoin-cli.md
deleted file mode 100644
index e0a2c5e3..00000000
--- a/doc/fund-server-bitcoin-cli.md
+++ /dev/null
@@ -1,44 +0,0 @@
-## Fund Coinos server (via bitcoin-cli)
-
-Bitcoin Regtest Mode allows us to create our own Bitcoin sandbox blockchain for use in testing & development.
-
-
-From the coinos-server dir on your localfilesystem (ie- after following the 'Getting Started' section of our [root README])
-
-```bash
-
-docker exec -it bitcoin bash
-
-# get an address
-bitcoin-cli -regtest -rpcuser=admin1 -rpcpassword=123 getnewaddress
-> bcrt1qzneawwyxe0fts5p8a6tsp4gu2mfnqzs92235hm # (example)
-
-# mine a block to the new address
-bitcoin-cli -regtest -datadir=/home/bitcoin/.bitcoin generatetoaddress 101 theaddressgeneratedabove
-
-# verify you got the reward by doing:
-bitcoin-cli -regtest -rpcuser=admin1 -rpcpassword=123 getbalance
-> 50.00000000
-
-# send 10 bitcoin to a coinos wallet account you created
-# (get the address to send to from ./receive, select 'Bitcoin')
-bitcoin-cli -regtest -rpcuser=admin1 -rpcpassword=123 sendtoaddress [account-address] 10
-
-# confirm the transaction
-# (do the mining command again)
-bitcoin-cli -regtest -rpcuser=admin1 -rpcpassword=123 generatetoaddress 101 theoriginaladdressgeneratedabove
-```
-
-![](./img/50-bitcoin-server-balance.gif)
-
-
-
-#### further reading
-
-On why to generate 101 blocks and some general info on Regtest Mode:
-
-https://developer.bitcoin.org/examples/testing.html
-
-
-[root README]:https://github.com/coinos/coinos-server
-
diff --git a/doc/img/50-bitcoin-server-balance.gif b/doc/img/50-bitcoin-server-balance.gif
deleted file mode 100644
index 2fba5088..00000000
--- a/doc/img/50-bitcoin-server-balance.gif
+++ /dev/null
Binary files differ
diff --git a/docker-compose.yml b/docker-compose.yml
index 3fec7487..9958458f 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,176 +1,75 @@
version: '3.6'
services:
app:
- depends_on:
- - maria
- - bitcoin
- - liquid
- - lnd
- container_name: app
image: cs
build: .
+ container_name: app
+ depends_on:
+ - db
+ - bc
+ - cl
command: "pnpm dev"
- ports:
- - '3119:3119'
environment:
- NODE_OPTIONS: "--es-module-specifier-resolution=node --experimental-modules --loader ./loader.js --openssl-legacy-provider"
+ NODE_OPTIONS: "--es-module-specifier-resolution=node --experimental-modules --loader ./loader.js"
NODE_ENV: development
+ URL: http://localhost:3119
+ ports:
+ - '3119:3119'
volumes:
- ./:/app
- ./logs:/logs
- extra_hosts:
- - host.docker.internal:host-gateway
- networks:
- default:
- ipv4_address: 172.18.0.22
- bitcoin:
- image: ghcr.io/vulpemventures/bitcoin
- container_name: bitcoin
- volumes:
- - ./config/bitcoin:/home/bitcoin/.bitcoin
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.23
- liquid:
- image: ghcr.io/vulpemventures/elements
- container_name: liquid
- volumes:
- - ./config/liquid:/home/elements/.elements
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.24
- lnd:
- image: lightninglabs/lnd:v0.15.1-beta
- container_name: lnd
+ restart: always
+ bc:
+ image: asoltys/bitcoin
+ container_name: bc
volumes:
- - ./config/lnd:/root/.lnd
- - ./config/bitcoin:/root/.bitcoin
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.25
- clightning:
- image: elementsproject/lightningd:v0.12.0
+ - ./data/bitcoin:/home/bitcoin/.bitcoin
+ restart: always
+ cl:
+ image: elementsproject/lightningd:latest
container_name: cl
environment:
LIGHTNINGD_NETWORK: regtest
volumes:
- - ./config/lightning:/root/.lightning
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.31
- maria:
- container_name: maria
- image: mariadb:10.6.1
+ - ./data/lightning:/root/.lightning
restart: always
+ clb:
+ image: elementsproject/lightningd:latest
+ container_name: clb
environment:
- MARIADB_ROOT_PASSWORD: ${ROOT_PASSWORD}
- volumes:
- - ./mysql:/var/lib/mysql
- ports:
- - 3307:3306
- networks:
- default:
- ipv4_address: 172.18.0.26
- electrsb:
- depends_on:
- - bitcoin
- image: ghcr.io/vulpemventures/electrs
- container_name: electrsb
- entrypoint:
- - /build/electrs
- command:
- - -vvvv
- - --network
- - regtest
- - --daemon-dir
- - /config
- - --daemon-rpc-addr
- - bitcoin:18443
- - --cookie
- - admin1:123
- - --http-addr
- - 0.0.0.0:3095
- - --electrum-rpc-addr
- - 0.0.0.0:60400
- - --cors
- - "*"
- volumes:
- - ./config/bitcoin/:/config
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.28
- electrs-liquid:
- image: ghcr.io/vulpemventures/electrs-liquid
- container_name: electrs
- depends_on:
- - liquid
- entrypoint:
- - /build/electrs
- command:
- - --jsonrpc-import
- - -vvvv
- - --parent-network
- - regtest
- - --network
- - liquidregtest
- - --daemon-dir
- - /config
- - --daemon-rpc-addr
- - liquid:7040
- - --cookie
- - admin1:123
- - --http-addr
- - 0.0.0.0:3002
- - --electrum-rpc-addr
- - 0.0.0.0:60401
- - --cors
- - "*"
+ LIGHTNINGD_NETWORK: regtest
volumes:
- - ./config/liquid/:/config
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.29
- esplora-liquid:
- image: vulpemventures/esplora:latest
- container_name: esplora-liquid
- depends_on:
- - electrs-liquid
+ - ./data/lightningb:/root/.lightning
+ restart: always
+ clc:
+ image: elementsproject/lightningd:latest
+ container_name: clc
environment:
- API_URL: ${LIQUID_ELECTRS_URL}
- NATIVE_ASSET_ID: 5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225
- IS_ELEMENTS: 1
- ports:
- - ${LIQUID_ESPLORA_PORT}:5000
- restart: unless-stopped
- networks:
- default:
- ipv4_address: 172.18.0.30
- spark:
- image: shesek/spark-wallet:standalone
- container_name: spark
+ LIGHTNINGD_NETWORK: regtest
volumes:
- - ./config/spark:/data
- - ./config/lightning/regtest:/etc/lightning
- ports:
- - '9737:9737'
+ - ./data/lightningc:/root/.lightning
+ restart: always
+ cld:
+ image: elementsproject/lightningd:latest
+ container_name: cld
environment:
- LOGIN: "${LOGIN}"
- NO_TLS: "${NO_TLS}"
- networks:
- default:
- ipv4_address: 172.18.0.32
- redis:
- container_name: redis
- image: redis
+ LIGHTNINGD_NETWORK: regtest
+ volumes:
+ - ./data/lightningd:/root/.lightning
+ restart: always
+ db:
+ image: eqalpha/keydb
+ container_name: db
volumes:
- - ./config/redis:/data
-networks:
- default:
- name: net
- external: true
+ - ./data/db:/data
+ restart: always
+ nostr:
+ container_name: nostr
+ image: asoltys/nostr-rs-relay
+ restart: always
+ user: 100:100
+ volumes:
+ - "./data/nostr/data:/usr/src/app/db"
+ - "./data/nostr/config.toml:/usr/src/app/config.toml"
+ ports:
+ - '8082:8080'
diff --git a/fx.sample b/fx.sample
deleted file mode 100644
index bdfbf9ea..00000000
--- a/fx.sample
+++ /dev/null
@@ -1 +0,0 @@
-{"fx":{"AED":3.6732,"AFN":76.916238,"ALL":102.317329,"AMD":481.616267,"ANG":1.794577,"AOA":655.221553,"ARS":81.969207,"AUD":1.343089,"AWG":1.8,"AZN":1.7025,"BAM":1.614261,"BBD":2,"BDT":84.775754,"BGN":1.617356,"BHD":0.377015,"BIF":1940.93179,"BMD":1,"BND":1.335611,"BOB":6.883324,"BRL":5.1698,"BSD":1,"BTC":0.000054,"BTN":73.603314,"BWP":10.890769,"BYN":2.553493,"BZD":2.015195,"CAD":1.28192,"CDF":1968.605194,"CHF":0.889253,"CLF":0.026934,"CLP":743.201103,"CNH":6.52695,"CNY":6.5432,"COP":3498.827763,"CRC":601.611868,"CUC":0.999757,"CUP":25.750002,"CVE":91.517508,"CZK":21.767701,"DJF":177.984204,"DKK":6.160477,"DOP":58.1879,"DZD":131.135347,"EGP":15.688401,"ERN":14.999681,"ETB":38.380578,"EUR":0.827603,"FJD":2.0594,"FKP":0.747215,"GBP":0.747215,"GEL":3.295,"GGP":0.747215,"GHS":5.865177,"GIP":0.747215,"GMD":51.775005,"GNF":9900.000797,"GTQ":7.803103,"GYD":209.079747,"HKD":7.75215,"HNL":24.277427,"HRK":6.247201,"HTG":67.978168,"HUF":295.195892,"IDR":14112.940636,"ILS":3.24973,"IMP":0.747215,"INR":73.753254,"IQD":1192.518145,"IRR":42105.00339,"ISK":127.030011,"JEP":0.747215,"JMD":143.995324,"JOD":0.709,"JPY":104.271008,"KES":111.400009,"KGS":84.795464,"KHR":4054.500326,"KMF":408.250238,"KPW":900.000073,"KRW":1085.489331,"KWD":0.304948,"KYD":0.833116,"KZT":420.239329,"LAK":9290.000748,"LBP":1519.000122,"LKR":185.75786,"LRD":160.450008,"LSL":14.960001,"LYD":1.35,"MAD":8.998358,"MDL":17.334117,"MGA":3867.375108,"MKD":51.003691,"MMK":1331.69855,"MNT":2855.764265,"MOP":7.98247,"MRO":357.000029,"MRU":37.121155,"MUR":39.903163,"MVR":15.455002,"MWK":765.388159,"MXN":19.864809,"MYR":4.0675,"MZN":74.150003,"NAD":14.960001,"NGN":381.321569,"NIO":34.83301,"NOK":8.836006,"NPR":117.76525,"NZD":1.423995,"OMR":0.385003,"PAB":1,"PEN":3.598707,"PGK":3.518051,"PHP":48.147447,"PKR":160.450013,"PLN":3.665672,"PYG":7034.254563,"QAR":3.64075,"RON":4.0275,"RSD":97.340008,"RUB":73.672606,"RWF":985.000079,"SAR":3.751408,"SBD":8.018641,"SCR":21.205532,"SDG":55.325005,"SEK":8.489209,"SGD":1.336996,"SHP":0.747215,"SLL":10194.893602,"SOS":584.000047,"SRD":14.154001,"SSP":130.26001,"STD":20900.545921,"STN":20.500001,"SVC":8.747973,"SYP":512.818375,"SZL":14.960001,"THB":30.045003,"TJS":11.324825,"TMT":3.51,"TND":2.7105,"TOP":2.288166,"TRY":7.823654,"TTD":6.793277,"TWD":28.256202,"TZS":2318.448187,"UAH":28.0933,"UGX":3680.09987,"USD":1,"UYU":42.677098,"UZS":10440.165624,"VEF":248487.662247,"VES":930536.054919,"VND":23187.74545,"VUV":111.531348,"WST":2.5692,"XAF":542.871898,"XAG":0.041832,"XAU":0.000545,"XCD":2.70255,"XDR":0.696164,"XOF":542.871898,"XPD":0.000439,"XPF":98.759293,"XPT":0.000995,"YER":250.350086,"ZAR":14.964601,"ZMW":21.038963,"ZWL":322.000026}} \ No newline at end of file
diff --git a/git_hooks/pre-commit b/git_hooks/pre-commit
deleted file mode 100644
index 78876285..00000000
--- a/git_hooks/pre-commit
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
-[ -z "$FILES" ] && exit 0
-
-# Prettify all selected files
-echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write
-
-# Add back the modified/prettified files to staging
-echo "$FILES" | xargs git add
-
-exit 0
diff --git a/index.js b/index.js
index 759893dc..da7e6319 100644
--- a/index.js
+++ b/index.js
@@ -1,45 +1,90 @@
-import app from "./app";
-import persist from "./lib/persist";
-import config from "./config/index";
-import store from "./lib/store";
-import { l, err } from "./lib/logging";
-import { optionalAuth } from "$lib/passport";
+import app from "$lib/app";
+import { auth, optional } from "$lib/auth";
-import "./db";
-import "./lib/redis";
-import "./lib/sockets";
-import "./lib/webhooks";
-import "./lib/passport";
-import "./lib/upload";
-import "./lib/sync";
-import "./lib/rates";
-import "./lib/notifications";
-import "./lib/mail";
+import { fillPool } from "$lib/nostr";
+import { listenForLightning } from "$lib/lightning";
+import { getLocations } from "$lib/locations";
+import { getRates, sendRates } from "$lib/rates";
+import { sendHeartbeat } from "$lib/sockets";
-import "./routes/assets";
-import "./routes/locations";
-import "./routes/info";
-import "./routes/users";
-import "./routes/invoices";
-import "./routes/payments";
-import "./routes/requests";
-import "./routes/lnurl";
-import "./routes/tickets";
+import email from "$routes/email";
+import info from "$routes/info";
+import locations from "$routes/locations";
+import lnurl from "$routes/lnurl";
+import nostr from "$routes/nostr";
+import rates from "$routes/rates";
+import invoices from "$routes/invoices";
+import users from "$routes/users";
+import payments from "$routes/payments";
+import requests from "$routes/requests";
-if (config.bitcoin) store.networks.push("bitcoin");
-if (config.liquid) store.networks.push("liquid");
-if (config.lna) store.networks.push("lightning");
+fillPool();
+listenForLightning();
+
+getLocations();
+getRates();
+
+setInterval(sendRates, 1000);
+setInterval(sendHeartbeat, 2000);
+
+app.get("/balances", info.balances);
+app.post("/email", email.send);
+
+app.get("/rate", rates.last);
+app.get("/rates", rates.index);
+
+app.get("/nostr.json", nostr.identities);
+app.get("/:pubkey/followers", nostr.followers);
+app.get("/:pubkey/follows", nostr.follows);
+app.get("/:pubkey/notes", nostr.notes);
+app.get("/event/:id", nostr.event);
+app.post("/event", nostr.broadcast);
+
+app.get("/locations", locations.list);
+
+app.get("/invoice/:hash", invoices.get);
+app.post("/invoice", optional, invoices.create);
+app.get("/invoice/classic/:username", invoices.classic);
+
+app.post("/payments", auth, payments.create);
+app.get("/payments", auth, payments.list);
+app.get("/payments/:hash", auth, payments.get);
+app.post("/parse", payments.parse);
+app.get("/pot/:name", payments.pot);
+app.post("/take", auth, payments.take);
+
+app.get("/encode", lnurl.encode);
+app.get("/decode", lnurl.decode);
+app.get("/lnurlp/:username", lnurl.lnurlp);
+app.get("/lnurl/:id", lnurl.lnurl);
+
+app.post("/bitcoin", payments.bitcoin);
+app.post("/bitcoin/fee", auth, payments.fee);
+app.post("/bitcoin/send", auth, payments.send);
+
+app.get("/me", auth, users.me);
+app.get("/users/:key", users.get);
+app.post("/register", users.create);
+app.post("/disable2fa", auth, users.disable2fa);
+app.post("/2fa", auth, users.enable2fa);
+app.post("/user", auth, users.update);
+app.post("/upload/:type", auth, users.upload);
+app.get('/users/delete/:username', users.del);
+
+app.post("/login", users.login);
+app.post("/logout", optional, users.logout);
+
+app.post("/subscribe", auth, users.subscribe);
+app.post("/password", auth, users.password);
+app.post("/otpsecret", auth, users.otpsecret);
+app.get("/contacts", auth, users.contacts);
+
+app.get("/request/:id", auth, requests.get);
+app.get("/requests", auth, requests.list);
+app.post("/requests", auth, requests.create);
+app.post("/requests/delete", auth, requests.destroy);
let host = process.env.HOST || "0.0.0.0";
let port = process.env.PORT || 3119;
-app.post('/echo', optionalAuth, async (req, res) => {
- console.log(req.user.username)
- console.log(req.body)
- res.send(req.body);
-});
-
-app.listen({ host, port }, (e, address) => {
- e && err(e) && process.exit(1);
- l(`CoinOS Server listening on ${address}`);
-});
+app.listen({ host, port });
diff --git a/k8s/app-claim0-persistentvolumeclaim.yaml b/k8s/app-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index f4d8470e..00000000
--- a/k8s/app-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: app-claim0
- name: app-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/app-deployment.yaml b/k8s/app-deployment.yaml
deleted file mode 100644
index 8dc491fa..00000000
--- a/k8s/app-deployment.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: app
- name: app
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: app
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: app
- spec:
- containers:
- - env:
- - name: NODE_ENV
- value: development
- image: asoltys/coinos-server
- name: app
- ports:
- - containerPort: 3119
- resources: {}
- volumeMounts:
- - mountPath: /app
- name: app-claim0
- restartPolicy: Always
- volumes:
- - name: app-claim0
- persistentVolumeClaim:
- claimName: app-claim0
-status: {}
diff --git a/k8s/app-service.yaml b/k8s/app-service.yaml
deleted file mode 100644
index 38a3b515..00000000
--- a/k8s/app-service.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: app
- name: app
-spec:
- ports:
- - name: "3119"
- port: 3119
- targetPort: 3119
- selector:
- io.kompose.service: app
-status:
- loadBalancer: {}
diff --git a/k8s/bitcoin-claim0-persistentvolumeclaim.yaml b/k8s/bitcoin-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index 8ea5e7d0..00000000
--- a/k8s/bitcoin-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: bitcoin-claim0
- name: bitcoin-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/bitcoin-deployment.yaml b/k8s/bitcoin-deployment.yaml
deleted file mode 100644
index 2192ece4..00000000
--- a/k8s/bitcoin-deployment.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: bitcoin
- name: bitcoin
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: bitcoin
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: bitcoin
- spec:
- containers:
- - image: asoltys/bitcoin:latest
- name: bitcoin
- ports:
- - containerPort: 18442
- - containerPort: 18443
- resources: {}
- volumeMounts:
- - mountPath: /config
- name: bitcoin-claim0
- restartPolicy: Always
- volumes:
- - name: bitcoin-claim0
- persistentVolumeClaim:
- claimName: bitcoin-claim0
-status: {}
diff --git a/k8s/bitcoin-service.yaml b/k8s/bitcoin-service.yaml
deleted file mode 100644
index 1d6a6c12..00000000
--- a/k8s/bitcoin-service.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: bitcoin
- name: bitcoin
-spec:
- ports:
- - name: "18442"
- port: 18442
- targetPort: 18442
- - name: "18443"
- port: 18443
- targetPort: 18443
- selector:
- io.kompose.service: bitcoin
-status:
- loadBalancer: {}
diff --git a/k8s/docker-compose-resolved.yaml b/k8s/docker-compose-resolved.yaml
deleted file mode 100644
index 8ec00d5e..00000000
--- a/k8s/docker-compose-resolved.yaml
+++ /dev/null
@@ -1,118 +0,0 @@
-services:
- app:
- container_name: app
- environment:
- NODE_ENV: development
- image: asoltys/coinos-server
- ports:
- - published: 3119
- target: 3119
- volumes:
- - /home/adam/coinos-server:/app:rw
- bitcoin:
- container_name: bitcoin
- image: asoltys/bitcoin:latest
- ports:
- - published: 18442
- target: 18442
- - published: 18443
- target: 18443
- restart: unless-stopped
- volumes:
- - /home/adam/coinos-server/config/bitcoin:/config:rw
- electrs-liquid:
- command:
- - -vvvv
- - --parent-network
- - regtest
- - --network
- - liquidregtest
- - --daemon-dir
- - /config
- - --daemon-rpc-addr
- - liquid:7040
- - --cookie
- - admin1:123
- - --http-addr
- - 0.0.0.0:3002
- - --electrum-rpc-addr
- - 0.0.0.0:60401
- - --cors
- - '*'
- container_name: electrs-liquid
- entrypoint:
- - /build/electrs
- image: vulpemventures/electrs-liquid:latest
- ports:
- - published: 3013
- target: 3002
- - published: 60402
- target: 60401
- restart: unless-stopped
- volumes:
- - /home/adam/coinos-server/liquid:/config:rw
- esplora-liquid:
- container_name: esplora-liquid
- environment:
- API_URL: http://localhost:3012
- IS_ELEMENTS: 1
- NATIVE_ASSET_ID: 5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225
- image: vulpemventures/esplora:latest
- ports:
- - published: 5006
- target: 5000
- restart: unless-stopped
- la:
- container_name: la
- environment:
- LIGHTNINGD_NETWORK: regtest
- image: elementsproject/lightningd:latest
- restart: unless-stopped
- volumes:
- - /home/adam/coinos-server/config/lightning:/root/.lightning:rw
- lb:
- container_name: lb
- environment:
- LIGHTNINGD_NETWORK: regtest
- image: elementsproject/lightningd:latest
- restart: unless-stopped
- volumes:
- - /home/adam/coinos-server/config/lightningb:/root/.lightning:rw
- liquid:
- container_name: liquid
- image: asoltys/liquid:latest
- ports:
- - published: 7040
- target: 7040
- - published: 18444
- target: 18444
- - published: 18602
- target: 18602
- - published: 18603
- target: 18603
- restart: unless-stopped
- volumes:
- - /home/adam/coinos-server/config/liquid:/config:rw
- maria:
- container_name: mariadb
- environment:
- MARIADB_ROOT_PASSWORD: password
- image: mariadb:10.6.1
- ports:
- - published: 3307
- target: 3306
- restart: always
- volumes:
- - /home/adam/coinos-server/mysql:/var/lib/mysql:rw
- ui:
- container_name: ui
- environment:
- NODE_ENV: development
- image: asoltys/coinos-ui
- ports:
- - published: 8085
- target: 8085
- volumes:
- - /home/adam/coinos-ui:/coinos:rw
-version: '3.6'
-
diff --git a/k8s/electrs-liquid-claim0-persistentvolumeclaim.yaml b/k8s/electrs-liquid-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index 43109416..00000000
--- a/k8s/electrs-liquid-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: electrs-liquid-claim0
- name: electrs-liquid-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/electrs-liquid-deployment.yaml b/k8s/electrs-liquid-deployment.yaml
deleted file mode 100644
index e33098f2..00000000
--- a/k8s/electrs-liquid-deployment.yaml
+++ /dev/null
@@ -1,62 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: electrs-liquid
- name: electrs-liquid
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: electrs-liquid
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: electrs-liquid
- spec:
- containers:
- - args:
- - -vvvv
- - --parent-network
- - regtest
- - --network
- - liquidregtest
- - --daemon-dir
- - /config
- - --daemon-rpc-addr
- - liquid:7040
- - --cookie
- - admin1:123
- - --http-addr
- - 0.0.0.0:3002
- - --electrum-rpc-addr
- - 0.0.0.0:60401
- - --cors
- - '*'
- command:
- - /build/electrs
- image: vulpemventures/electrs-liquid:latest
- name: electrs-liquid
- ports:
- - containerPort: 3002
- - containerPort: 60401
- resources: {}
- volumeMounts:
- - mountPath: /config
- name: electrs-liquid-claim0
- restartPolicy: Always
- volumes:
- - name: electrs-liquid-claim0
- persistentVolumeClaim:
- claimName: electrs-liquid-claim0
-status: {}
diff --git a/k8s/electrs-liquid-service.yaml b/k8s/electrs-liquid-service.yaml
deleted file mode 100644
index 83e57bd1..00000000
--- a/k8s/electrs-liquid-service.yaml
+++ /dev/null
@@ -1,22 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: electrs-liquid
- name: electrs-liquid
-spec:
- ports:
- - name: "3013"
- port: 3013
- targetPort: 3002
- - name: "60402"
- port: 60402
- targetPort: 60401
- selector:
- io.kompose.service: electrs-liquid
-status:
- loadBalancer: {}
diff --git a/k8s/esplora-liquid-deployment.yaml b/k8s/esplora-liquid-deployment.yaml
deleted file mode 100644
index 4606a416..00000000
--- a/k8s/esplora-liquid-deployment.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: esplora-liquid
- name: esplora-liquid
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: esplora-liquid
- strategy: {}
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: esplora-liquid
- spec:
- containers:
- - env:
- - name: API_URL
- value: http://localhost:3012
- - name: IS_ELEMENTS
- value: "1"
- - name: NATIVE_ASSET_ID
- value: 5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225
- image: vulpemventures/esplora:latest
- name: esplora-liquid
- ports:
- - containerPort: 5000
- resources: {}
- restartPolicy: Always
-status: {}
diff --git a/k8s/esplora-liquid-service.yaml b/k8s/esplora-liquid-service.yaml
deleted file mode 100644
index 17875690..00000000
--- a/k8s/esplora-liquid-service.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: esplora-liquid
- name: esplora-liquid
-spec:
- ports:
- - name: "5006"
- port: 5006
- targetPort: 5000
- selector:
- io.kompose.service: esplora-liquid
-status:
- loadBalancer: {}
diff --git a/k8s/la-claim0-persistentvolumeclaim.yaml b/k8s/la-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index d8c062a8..00000000
--- a/k8s/la-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: la-claim0
- name: la-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/la-deployment.yaml b/k8s/la-deployment.yaml
deleted file mode 100644
index a42eee8c..00000000
--- a/k8s/la-deployment.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: la
- name: la
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: la
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: la
- spec:
- containers:
- - env:
- - name: LIGHTNINGD_NETWORK
- value: regtest
- image: elementsproject/lightningd:latest
- name: la
- resources: {}
- volumeMounts:
- - mountPath: /root/.lightning
- name: la-claim0
- restartPolicy: Always
- volumes:
- - name: la-claim0
- persistentVolumeClaim:
- claimName: la-claim0
-status: {}
diff --git a/k8s/lb-claim0-persistentvolumeclaim.yaml b/k8s/lb-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index 2e77148f..00000000
--- a/k8s/lb-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: lb-claim0
- name: lb-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/lb-deployment.yaml b/k8s/lb-deployment.yaml
deleted file mode 100644
index 064df112..00000000
--- a/k8s/lb-deployment.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: lb
- name: lb
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: lb
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: lb
- spec:
- containers:
- - env:
- - name: LIGHTNINGD_NETWORK
- value: regtest
- image: elementsproject/lightningd:latest
- name: lb
- resources: {}
- volumeMounts:
- - mountPath: /root/.lightning
- name: lb-claim0
- restartPolicy: Always
- volumes:
- - name: lb-claim0
- persistentVolumeClaim:
- claimName: lb-claim0
-status: {}
diff --git a/k8s/liquid-claim0-persistentvolumeclaim.yaml b/k8s/liquid-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index 2d9030df..00000000
--- a/k8s/liquid-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: liquid-claim0
- name: liquid-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/liquid-deployment.yaml b/k8s/liquid-deployment.yaml
deleted file mode 100644
index 006a06e6..00000000
--- a/k8s/liquid-deployment.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: liquid
- name: liquid
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: liquid
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: liquid
- spec:
- containers:
- - image: asoltys/liquid:latest
- name: liquid
- ports:
- - containerPort: 7040
- - containerPort: 18444
- - containerPort: 18602
- - containerPort: 18603
- resources: {}
- volumeMounts:
- - mountPath: /config
- name: liquid-claim0
- restartPolicy: Always
- volumes:
- - name: liquid-claim0
- persistentVolumeClaim:
- claimName: liquid-claim0
-status: {}
diff --git a/k8s/liquid-service.yaml b/k8s/liquid-service.yaml
deleted file mode 100644
index d3b56800..00000000
--- a/k8s/liquid-service.yaml
+++ /dev/null
@@ -1,28 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: liquid
- name: liquid
-spec:
- ports:
- - name: "7040"
- port: 7040
- targetPort: 7040
- - name: "18444"
- port: 18444
- targetPort: 18444
- - name: "18602"
- port: 18602
- targetPort: 18602
- - name: "18603"
- port: 18603
- targetPort: 18603
- selector:
- io.kompose.service: liquid
-status:
- loadBalancer: {}
diff --git a/k8s/maria-claim0-persistentvolumeclaim.yaml b/k8s/maria-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index 55503cdb..00000000
--- a/k8s/maria-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: maria-claim0
- name: maria-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/maria-deployment.yaml b/k8s/maria-deployment.yaml
deleted file mode 100644
index 75d6153f..00000000
--- a/k8s/maria-deployment.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: maria
- name: maria
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: maria
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: maria
- spec:
- containers:
- - env:
- - name: MARIADB_ROOT_PASSWORD
- value: password
- image: mariadb:10.6.1
- name: mariadb
- ports:
- - containerPort: 3306
- resources: {}
- volumeMounts:
- - mountPath: /var/lib/mysql
- name: maria-claim0
- restartPolicy: Always
- volumes:
- - name: maria-claim0
- persistentVolumeClaim:
- claimName: maria-claim0
-status: {}
diff --git a/k8s/maria-service.yaml b/k8s/maria-service.yaml
deleted file mode 100644
index 31789fe1..00000000
--- a/k8s/maria-service.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: maria
- name: maria
-spec:
- ports:
- - name: "3307"
- port: 3307
- targetPort: 3306
- selector:
- io.kompose.service: maria
-status:
- loadBalancer: {}
diff --git a/k8s/ui-claim0-persistentvolumeclaim.yaml b/k8s/ui-claim0-persistentvolumeclaim.yaml
deleted file mode 100644
index aafbd9b4..00000000
--- a/k8s/ui-claim0-persistentvolumeclaim.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-apiVersion: v1
-kind: PersistentVolumeClaim
-metadata:
- creationTimestamp: null
- labels:
- io.kompose.service: ui-claim0
- name: ui-claim0
-spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 100Mi
-status: {}
diff --git a/k8s/ui-deployment.yaml b/k8s/ui-deployment.yaml
deleted file mode 100644
index 86912390..00000000
--- a/k8s/ui-deployment.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-apiVersion: apps/v1
-kind: Deployment
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: ui
- name: ui
-spec:
- replicas: 1
- selector:
- matchLabels:
- io.kompose.service: ui
- strategy:
- type: Recreate
- template:
- metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: ui
- spec:
- containers:
- - env:
- - name: NODE_ENV
- value: development
- image: asoltys/coinos-ui
- name: ui
- ports:
- - containerPort: 8085
- resources: {}
- volumeMounts:
- - mountPath: /coinos
- name: ui-claim0
- restartPolicy: Always
- volumes:
- - name: ui-claim0
- persistentVolumeClaim:
- claimName: ui-claim0
-status: {}
diff --git a/k8s/ui-service.yaml b/k8s/ui-service.yaml
deleted file mode 100644
index 21019ff6..00000000
--- a/k8s/ui-service.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-apiVersion: v1
-kind: Service
-metadata:
- annotations:
- kompose.cmd: kompose convert -f docker-compose-resolved.yaml
- kompose.version: 1.22.0 (955b78124)
- creationTimestamp: null
- labels:
- io.kompose.service: ui
- name: ui
-spec:
- ports:
- - name: "8085"
- port: 8085
- targetPort: 8085
- selector:
- io.kompose.service: ui
-status:
- loadBalancer: {}
diff --git a/lib/account.js b/lib/account.js
deleted file mode 100644
index 1576546a..00000000
--- a/lib/account.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import axios from "axios";
-import db from "$db";
-import store from "$lib/store";
-
-export default async (asset, user, transaction) => {
- const account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (account) return account;
-
- let params = {
- user_id: user.id,
- asset
- };
- let name = asset.substr(0, 6);
- let domain = "";
- let ticker = asset.substr(0, 3).toUpperCase();
- let precision = 8;
-
- if (store.assets[asset]) {
- ({ domain, ticker, precision, name } = store.assets[asset]);
- } else {
- const existing = await db.Account.findOne({
- where: {
- asset
- },
- order: [["id", "ASC"]],
- limit: 1,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (existing) {
- ({ domain, ticker, precision, name } = existing);
- }
- }
-
- params = { ...params, ...{ domain, ticker, precision, name } };
- params.balance = 0;
- params.pending = 0;
- return db.Account.create(params, { transaction });
-};
diff --git a/lib/app.js b/lib/app.js
new file mode 100644
index 00000000..4691786a
--- /dev/null
+++ b/lib/app.js
@@ -0,0 +1,40 @@
+import config from "$config";
+import fastify from "fastify";
+import fastifyWs from "@fastify/websocket";
+import fastifyMultipart from "@fastify/multipart";
+import fastifyStatic from "@fastify/static";
+import fastifyPassport from "@fastify/passport";
+import fastifySecureSession from "@fastify/secure-session";
+
+import path from "path";
+import pino from "pino";
+
+import { jwtStrategy } from "$lib/auth";
+import { socketServer } from "$lib/sockets";
+
+const app = fastify({
+ logger: pino(),
+ disableRequestLogging: true,
+ maxParamLength: 500
+});
+
+app.register(fastifySecureSession, {
+ key: Buffer.from(config.jwt, "hex")
+});
+
+app.register(fastifyPassport.initialize());
+app.register(fastifyPassport.secureSession());
+
+fastifyPassport.use("jwt", jwtStrategy);
+
+app.register(fastifyMultipart);
+
+app.register(fastifyStatic, {
+ root: path.join("/app/data/uploads"),
+ prefix: "/public/"
+});
+
+app.register(fastifyWs);
+app.register(socketServer);
+
+export default app;
diff --git a/lib/auth.js b/lib/auth.js
new file mode 100644
index 00000000..9720cd83
--- /dev/null
+++ b/lib/auth.js
@@ -0,0 +1,37 @@
+import fastifyPassport from "@fastify/passport";
+import { g } from "$lib/db";
+import config from "$config";
+import jwt from "passport-jwt";
+
+export const optional = {
+ preValidation: fastifyPassport.authenticate(
+ "jwt",
+ { session: false },
+ function(req, res, err, user, info) {
+ req.user = user;
+ }
+ )
+};
+
+export const auth = {
+ preValidation: fastifyPassport.authenticate("jwt", {
+ authInfo: false,
+ session: false
+ })
+};
+
+export const requirePin = async ({ body, user }) => {
+ if (!user || (user.pin && user.pin !== body.pin))
+ throw new Error("Invalid pin");
+};
+
+export const jwtStrategy = new jwt.Strategy(
+ {
+ jwtFromRequest: jwt.ExtractJwt.fromExtractors([
+ jwt.ExtractJwt.fromAuthHeaderAsBearerToken(),
+ req => (req.cookies ? req.cookies.token : null)
+ ]),
+ secretOrKey: config.jwt
+ },
+ async (payload, next) => next(null, await g(`user:${payload.id}`))
+);
diff --git a/lib/binance.js b/lib/binance.js
deleted file mode 100644
index 9f7f149f..00000000
--- a/lib/binance.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import app from "$app";
-import WebSocket from "ws";
-import { err } from "./logging";
-import store from "./store";
-
-export default () => {
- const binance = new WebSocket(
- "wss://stream.binance.com:9443/ws/btcusdt@ticker"
- );
-
- binance.onmessage = async function(event) {
- try {
- let msg = JSON.parse(event.data);
-
- if (!store.fx) return;
-
- Object.keys(store.fx).map(symbol => {
- store.rates[symbol] = msg.c * store.fx[symbol];
- });
-
- // app.set("ask", msg.a);
- // app.set("bid", msg.b);
- store.last = msg.c;
- // console.log("last", msg.c, store.fx["CAD"], msg.c * store.fx["CAD"]);
- } catch (e) {
- err("binance message error", e.message);
- }
- };
-
- binance.onerror = async function(error) {
- console.log(error);
- err("binance socket error", error.message);
- };
-
- return binance;
-};
diff --git a/lib/bitcoin.js b/lib/bitcoin.js
index eda8b4b0..a811dc14 100644
--- a/lib/bitcoin.js
+++ b/lib/bitcoin.js
@@ -1,3 +1,3 @@
import config from "$config";
-import rpc from "./rpc";
+import rpc from "$lib/rpc";
export default rpc(config.bitcoin);
diff --git a/lib/buildliquidtx.js b/lib/buildliquidtx.js
deleted file mode 100644
index 4aad18f4..00000000
--- a/lib/buildliquidtx.js
+++ /dev/null
@@ -1,160 +0,0 @@
-import config from "$config";
-import db from "$db";
-import store from "./store";
-import { prod } from "./utils";
-import axios from "axios";
-import liquid from "liquidjs-lib";
-import coinselect from "coinselect";
-import split from "coinselect/split";
-const api = prod
- ? "https://blockstream.info/liquid/api"
- : "http://localhost:3002";
-const SATS = 100000000;
-const network = prod ? liquid.networks["liquid"] : liquid.networks["regtest"];
-import { Op } from "@sequelize/core";
-
-export default async ({
- address,
- asset,
- amount,
- feeRate,
- replaceable,
- user
-}) => {
- const { btcasset: btc } = config.liquid;
-
- if (!feeRate) {
- let { feerate } = await lq.estimateSmartFee(6);
- if (!feerate) feerate = 0.00002;
- feeRate = feerate * SATS;
- }
- feeRate = Math.round(feeRate / 100);
- if (asset !== btc) feeRate = 0;
-
- let payments;
- if (asset === btc) {
- payments = await db.Payment.findAll({
- where: {
- received: true,
- account_id: user.account_id,
- network: "liquid"
- }
- });
- } else {
- payments = await db.Payment.findAll({
- where: {
- "$account.pubkey": { [Op.ne]: null },
- received: true,
- user_id: user.id,
- network: "liquid"
- },
- include: {
- model: db.Account,
- as: "account"
- }
- });
- }
-
- let utxos = [];
- for (let i = 0; i < payments.length; i++) {
- let url = `${api}/address/${payments[i].address}/utxo`;
- try {
- utxos.push(...(await axios.get(url)).data);
- } catch (e) {
- err("problem fetching utxos", e.message, url);
- }
- }
-
- let feeInput = utxos.find(utxo => utxo.asset === btc && utxo.value > 1000);
- if (!feeInput)
- throw new Error(
- "Insufficient balance, couldn't find an input to cover the fee"
- );
-
- utxos = utxos.filter(utxo => utxo.asset === asset);
-
- let feeChange = feeInput.value - 1000;
-
- let targets = [
- {
- address,
- value: amount
- }
- ];
-
- let { inputs, outputs, fee } = coinselect(utxos, targets, feeRate);
- if (!inputs || !outputs) {
- l(
- "utxos",
- amount,
- feeRate,
- utxos.map(u => u.value),
- inputs,
- outputs,
- fee
- );
-
- throw new Error(
- "Couldn't find inputs for transaction, check your balance/fee"
- );
- }
-
- let psbt = new liquid.Psbt({ network });
- let total = 0;
-
- let { address: changeAddress } = payments[payments.length - 1];
-
- outputs.map(({ address, value }) => {
- total += value;
- if (!address) {
- address = changeAddress;
- store.change.push(address);
- }
-
- psbt = psbt.addOutput({
- address,
- asset,
- value
- });
- });
-
- for (let i = 0; i < inputs.length; i++) {
- let { txid, vout } = inputs[i];
- psbt = psbt.addInput({
- hash: txid,
- index: vout,
- nonWitnessUtxo: Buffer.from((await lq.getTransaction(txid)).hex, "hex")
- });
- }
-
- if (asset !== btc) {
- psbt.addInput({
- hash: feeInput.txid,
- index: feeInput.vout,
- nonWitnessUtxo: Buffer.from(
- await lq.getTransaction(feeInput.txid).hex,
- "hex"
- )
- });
-
- psbt.addOutput({
- changeAddress,
- asset: btc,
- value: feeChange
- });
- }
-
- psbt.addOutput({
- asset: btc,
- script: Buffer.alloc(0),
- value: fee,
- nonce: Buffer.alloc(1, 0)
- });
-
- if (replaceable) psbt.setInputSequence(0, 0xffffffff - 2);
-
- feeRate = Math.round(feeRate * 1000);
- psbt = psbt.toBase64();
-
- return { tx: psbt, feeRate };
-};
diff --git a/lib/buildtx.js b/lib/buildtx.js
deleted file mode 100644
index daed2e73..00000000
--- a/lib/buildtx.js
+++ /dev/null
@@ -1,90 +0,0 @@
-import store from "./store";
-import { prod } from "./utils";
-import axios from "axios";
-import bitcoin from "bitcoinjs-lib";
-import coinselect from "coinselect";
-import split from "coinselect/split";
-const api = prod ? "https://blockstream.info/api" : "http://electrsb:3095";
-const SATS = 100000000;
-const network = prod
- ? bitcoin.networks["bitcoin"]
- : bitcoin.networks["regtest"];
-
-export default async ({ address, amount, feeRate, replaceable, user }) => {
- if (!feeRate) feeRate = (await bc.estimateSmartFee(6)).feerate * SATS;
- feeRate = Math.round(feeRate / 1000);
-
- const payments = await db.Payment.findAll({
- where: {
- received: true,
- account_id: user.account_id,
- network: "bitcoin"
- }
- });
-
- const addresses = [...new Set(payments.map(p => p.address))];
- const utxos = [];
- for (let i = 0; i < addresses.length; i++) {
- try {
- utxos.push(
- ...(await axios.get(`${api}/address/${addresses[i]}/utxo`)).data
- );
- } catch (e) {
- err("problem fetching utxos", e.message);
- }
- }
-
- let targets = [
- {
- address,
- value: amount
- }
- ];
-
- let { inputs, outputs, fee } = coinselect(utxos, targets, feeRate);
-
- if (!inputs || !outputs) {
- l(
- "utxos",
- amount,
- feeRate,
- utxos.map(u => u.value)
- );
- throw new Error(
- "Couldn't find inputs for transaction, check your balance/fee"
- );
- }
-
- let psbt = new bitcoin.Psbt({ network });
- let total = 0;
-
- outputs.map(({ address, value }) => {
- total += value;
- if (!address) {
- address = payments[payments.length - 1].address;
- store.change.push(address);
- }
-
- psbt = psbt.addOutput({
- address,
- value
- });
- });
-
- for (let i = 0; i < inputs.length; i++) {
- let { txid, vout } = inputs[i];
- let nonWitnessUtxo = Buffer.from(await bc.getRawTransaction(txid), "hex");
- psbt = psbt.addInput({
- hash: txid,
- index: vout,
- nonWitnessUtxo
- });
- }
-
- if (replaceable) psbt.setInputSequence(0, 0xffffffff - 2);
-
- feeRate = Math.round(feeRate * 1000);
- psbt = psbt.toBase64();
-
- return { tx: psbt, feeRate };
-};
diff --git a/lib/db.js b/lib/db.js
new file mode 100644
index 00000000..86f8082e
--- /dev/null
+++ b/lib/db.js
@@ -0,0 +1,33 @@
+import config from "$config";
+import { sleep } from "$lib/utils";
+import { createClient } from "redis";
+
+export const db = createClient({ url: config.db });
+await db.connect();
+export default db;
+
+export let g = async k => JSON.parse(await db.get(k));
+export let s = (k, v) => db.set(k, JSON.stringify(v));
+
+let retries = {};
+export let t = async (k, f) => {
+ try {
+ await db.watch(k);
+ await f(await db.get(k), db);
+ } catch (err) {
+ if (!err.message.includes("watch")) throw err;
+
+ let r = retries[k] || 0;
+ retries[k] = r + 1;
+
+ if (r < 10) {
+ await sleep(100);
+ await t(k, f);
+ } else {
+ delete retries[k];
+ throw new Error("unable to obtain lock");
+ }
+ }
+
+ delete retries[k];
+};
diff --git a/lib/invoices.js b/lib/invoices.js
new file mode 100644
index 00000000..4a09f44b
--- /dev/null
+++ b/lib/invoices.js
@@ -0,0 +1,75 @@
+import store from "$lib/store";
+import { l } from "$lib/logging";
+import { emit } from "$lib/sockets";
+import { db, g, s } from "$lib/db";
+import { bip21, fail } from "$lib/utils";
+import { types } from "$lib/payments";
+import { v4 } from "uuid";
+
+import bc from "$lib/bitcoin";
+import ln from "$lib/ln";
+
+export let generate = async ({ invoice, user, sender }) => {
+ let { currency, tip, amount, rate, request_id, type } = invoice;
+
+ amount = parseInt(amount || 0);
+ tip = parseInt(tip || 0);
+
+ if (amount < 0) fail("amount out of range");
+ if (tip > 5 * amount || tip < 0) fail("tip amount out of range");
+
+ if (!user) user = sender;
+ let uid = await g(`user:${user.username}`);
+ user = await g(`user:${uid}`);
+
+ if (!user) fail("user not provided");
+
+ if (!currency) currency = user.currency;
+ if (!rate) rate = store.rates[currency];
+ if (amount < 0) fail("invalid amount");
+
+ let hash, text;
+ if (type === types.lightning) {
+ let amt = amount ? `${amount + tip}sat` : "any";
+ let r = await ln.invoice(amt, new Date(), "", 3600);
+
+ hash = r.payment_hash;
+ text = r.bolt11;
+ } else if (type === types.bitcoin) {
+ hash = await bc.getNewAddress();
+ text = bip21(hash, invoice);
+ } else if (type === types.internal) {
+ hash = v4();
+ } else {
+ fail("unrecognized type");
+ }
+
+ invoice = {
+ ...invoice,
+ amount,
+ hash,
+ text,
+ currency,
+ rate,
+ tip,
+ uid,
+ received: 0,
+ created: Date.now()
+ };
+
+ l("creating invoice", user.username, amount, tip, currency, invoice.hash);
+
+ await s(`invoice:${hash}`, invoice);
+ await db.lPush(`${uid}:invoices`, hash);
+
+ if (request_id) {
+ let request = await g(`request:${request_id}`);
+ let { invoice_id: prev } = request;
+ request.invoice_id = invoice.id;
+ await s(`request:${request_id}`, request);
+
+ if (!prev) emit(request.requester.username, "invoice", invoice);
+ }
+
+ return invoice;
+};
diff --git a/lib/lightning.js b/lib/lightning.js
new file mode 100644
index 00000000..2915b7c7
--- /dev/null
+++ b/lib/lightning.js
@@ -0,0 +1,39 @@
+import { emit } from "$lib/sockets";
+import config from "$config";
+import { notify } from "$lib/notifications";
+import { callWebhook } from "$lib/webhooks";
+import ln from "$lib/ln";
+import { l, err, warn } from "$lib/logging";
+import { g, s, t, db } from "$lib/db";
+import { credit, types } from "$lib/payments";
+
+export async function listenForLightning() {
+ let event = await ln.waitanyinvoice(await g("pay_index"));
+ let {
+ payment_hash: hash,
+ bolt11,
+ pay_index,
+ status,
+ msatoshi_received,
+ payment_preimage: preimage
+ } = event;
+
+ await s("pay_index", pay_index);
+ setTimeout(listenForLightning);
+
+ let received = Math.round(msatoshi_received / 1000);
+
+ try {
+ l("incoming lightning payment", received);
+
+ if (!preimage) return;
+
+ let invoice = await g(`invoice:${hash}`);
+ if (!invoice) return warn("received lightning with no invoice", bolt11);
+
+ await credit(hash, received, invoice.memo, preimage, types.lightning);
+ } catch (e) {
+ console.log(e);
+ err("problem receiving lightning payment", e.message);
+ }
+}
diff --git a/lib/liquid.js b/lib/liquid.js
deleted file mode 100644
index ccf6aafb..00000000
--- a/lib/liquid.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import config from "$config";
-import rpc from "./rpc";
-export default rpc(config.liquid);
diff --git a/lib/ln.js b/lib/ln.js
index 13bbd004..c4445b26 100644
--- a/lib/ln.js
+++ b/lib/ln.js
@@ -2,6 +2,6 @@ import config from "$config";
let ln;
let { LightningClient } = (await import("clightning-client")).default;
-ln = new LightningClient(config.lna.dir);
+ln = new LightningClient(config.lightning);
export default ln;
diff --git a/lib/lnd.js b/lib/lnd.js
deleted file mode 100644
index ff8b4c56..00000000
--- a/lib/lnd.js
+++ /dev/null
@@ -1 +0,0 @@
-export default {};
diff --git a/lib/locations.js b/lib/locations.js
new file mode 100644
index 00000000..39883555
--- /dev/null
+++ b/lib/locations.js
@@ -0,0 +1,18 @@
+import got from "got";
+import { s } from "$lib/db";
+
+export let getLocations = async () => {
+ try {
+ let locations = await got(
+ "https://api.btcmap.org/v2/elements?updated_since=2022-09-19"
+ ).json();
+
+ locations = locations.filter(
+ l => l["osm_json"].tags && l["osm_json"].tags["payment:coinos"] === "yes"
+ );
+
+ await s("locations", locations);
+ } catch (e) {}
+
+ setTimeout(getLocations, 60000);
+};
diff --git a/lib/logo.js b/lib/logo.js
deleted file mode 100644
index 922716ac..00000000
--- a/lib/logo.js
+++ /dev/null
@@ -1 +0,0 @@
-export default "iVBORw0KGgoAAAANSUhEUgAABbYAAAW2CAYAAABXn/ThAAAgAElEQVR4Xuza2W7d5bnA4c/OyLQRUxg2IEoACaG2opV6F0jcTg/KCRfAQS+qJ5VQq1Y9aCuKxFyGTUMgk5Ot729WmrJ35WQ18Vo/+4nkOkm9sl4/7xs7/pmdMcaN4QcBAgQIECBAgAABAgQIECBAgAABAgQIEIgI7AjbkU0ZkwABAgQIECBAgAABAgQIECBAgAABAgQWAWHbIRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIEDNS+v0AACAASURBVCBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIECBAgAABAgQIECBAgACBlICwnVqXYQkQIECAAAECBAgQIECAAAECBAgQIEBA2HYDBAgQIECAAAECBAgQIECAAAECBAgQIJASELZT6zIsAQIECBAgQIAAAQIECBAgQIAAAQIECAjbboAAAQIECBAgQIAAAQIECBAgQIAAAQIEUgLCdmpdhiVAgAABAgQIECBAgAABAgQIECBAgAABYdsNECBAgAABAgQIECBAgAABAgQIECBAgEBKQNhOrcuwBAgQIECAAAECBAgQIECAAAECBAgQICBsuwECBAgQIECAAAECBAgQIECAAAECBAgQSAkI26l1GZYAAQIECBAgQIAAAQIECBAgQIAAAQIEhG03QIAAAQIECBAgQIAAAQIECBAgQIAAAQIpAWE7tS7DEiBAgAABAgQIECBAgAABAgQIECBAgICw7QYIECBAgAABAgQIECBAgAABAgQIECBAICUgbKfWZVgCBAgQIECAAAECBAgQIECAAAECBAgQELbdAAECBAgQIECAAAECBAgQIECAAAECBAikBITt1LoMS4AAAQIECBAgQIAAAQIECBAgQIAAAQLCthsgQIAAAQIECBAgQIAAAQIECBAgQIAAgZSAsJ1al2EJECBAgAABAgQIECBAgAABAgQIECBAQNh2AwQIECBAgAABAgQIECBAgAABAgQIECCQEhC2U+syLAECBAgQIECAAAECBAgQIECAAAECBAgI226AAAECBAgQIECAAAECBAgQIECAAAECBFICwnZqXYYlQIAAAQIECBAgQIAAAQIECBAgQIAAAWHbDRAgQIAAAQIECBAgQIAAAQIECBAgQIBASkDYTq3LsAQIECBAgAABAgQIECBAgAABAgQIECAgbLsBAgQIECBAgAABAgQIECBAgAABAgQIEEgJCNupdRmWAAECBAgQIECAAAECBAgQIECAAAECBIRtN0CAAAECBAgQIECAAAECBAgQIECAAAECKQFhO7UuwxIgQIAAAQIECBAgQIAAAQIECBAgQICAsO0GCBAgQIAAAQIECBAgQIAAAQIECBAgQCAlIGyn1mVYAgQIECBAgAABAgQIECBAgAABzP6fVgAAIABJREFUAgQIEBC23QABAgQIECBAgAABAgQIECBAgAABAgQIpASE7dS6DEuAAAECBAgQIECAAAECBAgQIECAAAECwrYbIECAAAECBAgQIECAAAECBAgQIECAAIGUgLCdWpdhCRAgQIAAAQIECBAgQIAAAQIECBAgQEDYdgMECBAgQIAAAQIECBAgQIAAAQIECBAgkBIQtlPrMiwBAgQIECBAgAABAgQIECBAgAABAgQICNtugAABAgQIECBAgAABAgQIECBAgAABAgRSAsJ2al2GJUCAAAECBAgQIECAAAECBAgQIECAAAFh2w0QIECAAAECBAgQIECAAAECBAgQIECAQEpA2E6ty7AECBAgQIAAAQIECBAgQIAAAQIECBAgIGy7AQIECBAgQIAAAQIECBAgQIAAAQIECBBICQjbqXUZlgABAgQIECBAgAABAgQIECBAgAABAgSEbTdAgAABAgQIECBAgAABAgQIECBAgAABAikBYTu1LsMSIECAAAECBAgQIECAAAECBAgQIECAgLDtBggQIECAAAECBAgQIECAAAECBAgQIEAgJSBsp9ZlWAIECBAgQIAAAQIECBAgQIAAAQIECBAQtt0AAQIECBAgQIAAAQIECBAgQIAAAQIECKQEhO3UugxLgAABAgQIECBAgAABAgQIECBAgAABAsK2GyBAgAABAgQIbJHAm2++Od56663x+uuvH+pUv/rVr8Y777wzLl68eKjP68kIECBAgAABAgQIECCwjoCwvY6axxAgQIAAAQIE7pGAsH2PYP2xBAgQIECAAAECBAgcKQFh+0it0ztDgAABAgQI1AWE7foGzU+AAAECBAgQIECAwGEICNuHoew5CBAgQIAAAQK3KSBs3yaUNyNAgAABAgQIECBA4FgLCNvHev3eeQIECBAgQGDbBITtbduIeQgQIECAAAECBAgQ2EYBYXsbt2ImAgQIECBA4NgKCNvHdvXecQIECBAgQIAAAQIE7kBA2L4DLG9KgAABAgQIELjXAsL2vRb25xMgQIAAAQIECBAgcBQEhO2jsEXvAwECBAgQIHBkBITtI7NK7wgBAgQIECBAgAABAvdQQNi+h7j+aAIECBAgQIDAnQoI23cq5u0JECBAgAABAgQIEDiOAsL2cdy695kAAQIECBDYWgFhe2tXYzACBAgQIECAAAECBLZIQNjeomUYhQABAgQIECAgbLsBAgQIECBAgAABAgQIHCwgbB9s5C0IECBAgAABAocmIGwfGrUnIkCAAAECBAgQIEAgLCBsh5dndAIECBAgQODoCQjbR2+n3iMCBAgQIECAAAECBO6+gLB99039iQQIECBAgACBtQWE7bXpPJAAAQIECBAgQIAAgWMkIGwfo2V7VwkQIECAAIHtFxC2t39HJiRAgAABAgQIECBAYPMCwvbmd2ACAgQIECBAgMBNAWHbMRAgQIAAAQIECBAgQOBgAWH7YCNvQYAAAQIECBA4NAFh+9CoPREBAgQIECBAgAABAmEBYTu8PKMTIECAAAECR09A2D56O/UeESBAgAABAgQIECBw9wWE7btv6k8kQIAAAQIECKwtIGyvTeeBBAgQIECAAAECBAgcIwFh+xgt27tKgAABAgQIbL+AsL39OzIhAQIECBAgQIAAAQKbFxC2N78DExAgQIAAAQIEbgoI246BAAECBAgQIECAAAECBwsI2wcbeQsCBAgQIECAwKEJCNuHRu2JCBAgQIAAAQIECBAICwjb4eUZnQABAgQIEDh6AsL20dup94gAAQIECBAgQIAAgbsvIGzffVN/IgECBAgQIEBgbQFhe206DyRAgAABAgQIECBA4BgJCNvHaNneVQIECBAgQGD7BYTt7d+RCQkQIECAAAECBAgQ2LyAsL35HZiAAAECBAgQIHBTQNh2DAQIECBAgAABAgQIEDhYQNg+2MhbECBAgAABAgQOTUDYPjRqT0SAAAECBAgQIECAQFhA2A4vz+gECBAgQIDA0RMQto/eTr1HBAgQIECAAAECBAjcfQFh++6b+hMJECBAgAABAmsLCNtr03kgAQIECBAgQIAAAQLHSEDYPkbL9q4SIECAAAEC2y8gbG//jkxIgAABAgQIECBAgMDmBYTtze/ABAQIECBAgACBmwLCtmMgQIAAAQIECBAgQIDAwQLC9sFG3oIAAQIECBAgcGgCwvahUXsiAgQIECBAgAABAgTCAsJ2eHlGJ0CAAAECBI6egLB99HbqPSJAgAABAgQIECBA4O4LCNt339SfSIAAAQIECBBYW0DYXpvOAwkQIECAAAECBAgQOEYCwvYxWrZ3lQABAgQIENh+AWF7+3dkQgIECBAgQIAAAQIENi8gbG9+ByYgQIAAAQIECNwUELYdAwECBAgQIECAAAECBA4WELYPNvIWBAgQIECAAIFDE3jjjTfGL3/5y/HTn/700J5zPtHbb789fv3rX4+LFy8e6vN6MgIECBAgQIAAAQIECKwjIGyvo+YxBAgQIECAAIF7JHD+/Pnxi1/8Ypw7d+4ePcP//8f+5je/Ge++++64evXqoT6vJyNAgAABAgQIECBAgMA6AsL2OmoeQ4AAAQIECBAgQIAAAQIECBAgQIAAAQIbExC2N0bviQkQIECAAAECBAgQIECAAAECBAgQIEBgHQFhex01jyFAgAABAgQIECBAgAABAgQIECBAgACBjQkI2xuj98QECBAgQIAAAQIECBAgQIAAAQIECBAgsI6AsL2OmscQIECAAAECBAgQIECAAAECBAgQIECAwMYEhO2N0XtiAgQIECBAgAABAgQIECBAgAABAgQIEFhHQNheR81jCBAgQIAAAQIECBAgQIAAAQIECBAgQGBjAsL2xug9MQECBAgQIECAAAECBAgQIECAAAECBAisIyBsr6PmMQQIECBAgAABAgQIECBAgAABAgQIECCwMQFhe2P0npgAAQIECBAgQIAAAQIECBAgQIAAAQIE1hEQttdR8xgCBAgQIECAAAECBAgQIECAAAECBAgQ2JiAsL0xek9MgAABAgQIECBAgAABAgQIECBAgAABAusICNvrqHkMAQIECBAgQIAAAQIECBAgQIAAAQIECGxMQNjeGL0nJkCAAAECBAgQIECAAAECBAgQIECAAIF1BITtddQ8hgABAgQIECBAgAABAgQIECBAgAABAgQ2JiBsb4zeExMgQIAAAQIECBAgQIAAAQIECBAgQIDAOgLC9jpqHkOAAAECBAgQIECAAAECBAgQIECAAAECGxMQtjdG74kJECBAgAABAgQIECBAgAABAgQIECBAYB0BYXsdNY8hQIAAAQIECBAgQIAAAQIECBAgQIAAgY0JCNsbo/fEBAgQIECAAAECBAgQIECAAAECBAgQILCOgLC9jprHECBAgAABAgQIECBAgAABAgQIECBAgMDGBITtjdF7YgIECBAgQIAAAQIECBAgQIAAAQIECBBYR0DYXkfNYwgQIECAAAECBAgQIECAAAECBAgQIEBgYwLC9sboPTEBAgQIECBAgAABAgQIECBAgAABAgQIrCMgbK+j5jEECBAgQIAAAQIECBAgQIAAAQIECBAgsDEBYXtj9J6YAAECBAgQIECAAAECBAgQIECAAAECBNYRELbXUfMYAgS2QmBnZ2fMl9WPW39948aNMV/mj9XrH/58K94JQxw7gdu929W93nq/xw7LO0yAQEbg331s++Hn4ls/P2feOYMSOEBg/nN0/5+k+/8uXX79/WPmv0a//yfp/Nny83/+Gi2BpsDqS7DV3d/89XLl+/+z/5XY/i9uvXn339y5qQlsq4Cwva2bMReBYyqwu7s75suJEyeWaL369Xy9+qJ5vj5z5sx46KGHxv3337+8zfy9++67b5w+fXqR++6778bly5fH3t7euHTp0rh27dryevV78wvr69evL9H71tfz7eev54sfBO5E4NbbXd3kD+933vUDDzyw3O6pU6f+z91euXJludN5f/Nmv/nmm+Vl/vyHt7q6Uzd7J1vytgQIrCNw6+fj+XFsvtz6cW7+en4Onh/b5ufnkydPjrNnzy4f5+bHqvlxbX58my8XLlwY33777fL5efVx7NbX8/fni2/qrbMpj7nbAru7Y5zYnf8enS/j+5edsTvD9e78DyzGOHVqZzz0wInxwP3z78bOOLE7xtmzu8vvzx+XLl8fly/vh70rV66PCxf3xrff7Y29a2NcXyL3/LfoGNev31h+vbzeG2Pv+r/GwLv9vvnzCNwqMG95/9bnne+Mnfl6+YbN/u/dfD3GOH16d5w9s7Pc+33Lre+O06d3xtkz8+u4Ma5duzEuXbo+ru3tP8Pl+Xfgyvy6a//vw3yZN7//TZ5/frNn9evl78P8/eX1/t8JMdy9EiDw7wSEbbdBgMBGBFbxen7xu/oieUbpp556avzoRz8azz333HjyySeXX8/X586dG48++uh4+OGHl5f5hfOt/7X2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AZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAWsFCLat9aQ1BBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAZsFCLZtBqZ5BBBAAAEEEEAAAQQQQAABBBBAAIH/b8cOCQAAABiE9W/9EtytAGISAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBBSidlBAAAgAElEQVQgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaARW1geMAAAewSURBVGO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUwtltPNQIECBAgQIAAAQIECBAgQIAAAQIECBA4CxjbZ2B5AgQIECBAgAABAgQIECBAgAABAgQIEGgFjO3WU40AAQIECBAgQIAAAQIECBAgQIAAAQIEzgLG9hlYngABAgQIECBAgAABAgQIECBAgAABAgRaAWO79VQjQIAAAQIECBAgQIAAAQIECBAgQIAAgbOAsX0GlidAgAABAgQIECBAgAABAgQIECBAgACBVsDYbj3VCBAgQIAAAQIECBAgQIAAAQIECBAgQOAsYGyfgeUJECBAgAABAgQIECBAgAABAgQIECBAoBUYUqkaGlqg5VYAAAAASUVORK5CYII=";
diff --git a/lib/mail.js b/lib/mail.js
deleted file mode 100644
index a146d128..00000000
--- a/lib/mail.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import app from "$app";
-import config from "$config";
-import persist from "./persist";
-const emails = persist("data/emails.json");
-
-app.post("/email", async (req, res) => {
- try {
- let file = persist("data/emails.json");
- file.emails = [...file.emails, req.body];
-
- try {
- var postmark = await import("postmark");
-
- var client = new postmark.ServerClient(config.postmark);
-
- await client.sendEmail({
- Subject: req.body.subject || "Email Signup",
- HtmlBody: JSON.stringify(req.body),
- TextBody: JSON.stringify(req.body),
- MessageStream: "outbound"
- });
-
- res.send({ ok: true });
- } catch (e) {
- console.log("problem sending email", e);
- res.code(500).send(e.message);
- }
- } catch (e) {
- console.log(e);
- res.code(500).send(e.message);
- }
-});
diff --git a/lib/nostr.js b/lib/nostr.js
new file mode 100644
index 00000000..065fafb0
--- /dev/null
+++ b/lib/nostr.js
@@ -0,0 +1,164 @@
+import config from "$config";
+import { Relay, RelayPool } from "nostr";
+import { broadcast } from "$lib/sockets";
+import store from "$lib/store";
+import { g, s, db } from "$lib/db";
+import { nada, wait } from "$lib/utils";
+
+export let pool;
+
+export let fillPool = () => {
+ pool = RelayPool(config.relays);
+ pool.on("open", relay => {
+ if (relay.url.includes(config.relay)) coinos = relay;
+ relay.subscribe("live", { limit: 1 });
+ });
+
+ pool.on("event", async (relay, sub, ev) => {
+ if (!coinos) return;
+ if (timeouts[sub]) timeouts[sub].extend(ev);
+ try {
+ let content;
+ try {
+ content = JSON.parse(ev.content);
+ } catch (e) {
+ content = ev.content;
+ }
+
+ if (sub === "live") {
+ let { pubkey } = ev;
+
+ if (Math.abs(Math.floor(Date.now() / 1000) - ev.created_at) > 7200)
+ return;
+
+ if (seen.includes(ev.id)) return;
+ seen.push(ev.id);
+ seen.length > 1000 && seen.shift();
+
+ if (coinos && ev.kind < 5) {
+ // coinos.send(["EVENT", ev]);
+ ev.user = await getUser(pubkey);
+ // broadcast("event", ev);
+ }
+ } else if (sub.includes("profile")) {
+ let { pubkey } = ev;
+ let user = await getUser(pubkey);
+
+ if (user.updated > ev.created_at) return;
+
+ if (content.name && user.username === pubkey.substr(0, 6))
+ user.username = content.name;
+
+ delete content.name;
+
+ user = {
+ ...user,
+ ...content,
+ updated: ev.created_at
+ };
+
+ await s(`user:${pubkey}`, JSON.stringify(user));
+ coinos.send(ev);
+ } else if (sub.includes("follows")) {
+ let pubkey = sub.split(":")[0];
+ await s(`${pubkey}:follows`, JSON.stringify(ev.tags));
+ for (let f of ev.tags) {
+ let [_, followPubkey] = f;
+ await db.sAdd(`${followPubkey}:followers`, pubkey);
+ }
+ coinos.send(ev);
+ } else if (sub.includes("followers")) {
+ let followed = sub.split(":")[0];
+ let { pubkey } = ev;
+ await db.sAdd(`${followed}:followers`, pubkey);
+ coinos.send(ev);
+ } else if (sub.includes("notes")) {
+ let pubkey = sub.split(":")[0];
+ await db.sAdd(pubkey, ev.id);
+ await s(`ev:${ev.id}`, JSON.stringify(ev));
+ }
+ } catch (e) {
+ console.log(e);
+ }
+ });
+};
+
+export let coinos;
+let now = () => Math.round(Date.now() / 1000);
+
+let timeouts = {};
+export let q = async (
+ sub,
+ query,
+ { timeout = 20000, since = 3600, eager = 200 }
+) =>
+ new Promise(async (r, j) => {
+ let start = Date.now();
+ let seen = [];
+ let rejected;
+ query.since = await g(`since:${sub}`);
+ if (now() - query.since < since) return r();
+
+ let done = { [sub]: [] };
+
+ let check = s => {
+ let elapsed = Date.now() - start;
+ if (rejected) return true;
+ if (
+ done[s] &&
+ (done[s].length === pool.relays.length ||
+ (done[s].length && elapsed > eager))
+ ) {
+ r();
+ if (timeouts[s]) timeouts[s].clear();
+ return true;
+ }
+ };
+
+ timeouts[sub] = {
+ async clear() {
+ clearTimeout(this.timer);
+ delete timeouts[sub];
+ pool.unsubscribe(sub);
+ await s(`since:${sub}`, now());
+ },
+ extend(ev) {
+ if (ev) {
+ if (seen.includes(ev.id)) return;
+ seen.push(ev.id);
+ seen.length > 1000 && seen.shift();
+ }
+
+ clearTimeout(this.timer);
+ this.timer = setTimeout(() => {
+ j(new Error(`query timed out: ${sub} ${Date.now()}`));
+ pool.unsubscribe(sub);
+ rejected = true;
+ }, timeout);
+ },
+ timer: undefined
+ };
+
+ timeouts[sub].extend();
+ pool.subscribe(sub, query);
+
+ pool.on("eose", (relay, s) => {
+ if (done[s]) done[s].push(relay.url);
+ check(s);
+ });
+
+ try {
+ await wait(() => check(sub), 100, 200);
+ } catch (e) {
+ console.log(e);
+ }
+ });
+
+let seen = [];
+
+let getUser = async pubkey =>
+ JSON.parse(await g(`user:${pubkey}`)) || {
+ username: pubkey.substr(0, 6),
+ pubkey,
+ anon: true
+ };
diff --git a/lib/passport.js b/lib/passport.js
deleted file mode 100644
index ac2949a5..00000000
--- a/lib/passport.js
+++ /dev/null
@@ -1,84 +0,0 @@
-import app from "$app";
-import db from "$db";
-import jwt from "passport-jwt";
-import { Op } from "@sequelize/core";
-import fastifyPassport from "@fastify/passport";
-import fastifySecureSession from "@fastify/secure-session";
-import config from "$config";
-import fs from "fs";
-import path from "path";
-import { err } from "$lib/logging";
-
-app.register(fastifySecureSession, {
- key: config.jwt
-});
-
-app.register(fastifyPassport.initialize());
-app.register(fastifyPassport.secureSession());
-
-function cookieExtractor(req) {
- if (req && req.cookies) {
- return req.cookies["token"];
- }
- return null;
-}
-
-fastifyPassport.use(
- "jwt",
- new jwt.Strategy(
- {
- jwtFromRequest: jwt.ExtractJwt.fromExtractors([
- jwt.ExtractJwt.fromAuthHeaderAsBearerToken(),
- cookieExtractor
- ]),
- secretOrKey: config.jwt
- },
- async (payload, next) => {
- try {
- let { username } = payload;
- let user = await db.User.findOne({
- where: {
- username: { [Op.or]: [username, username.replace(/ /g, "")] }
- },
- include: { model: db.Account, as: "account" }
- });
- if (user.locked) throw new Error("account is locked");
- next(null, user);
- } catch (e) {
- if (!e.message.includes("locked")) {
- console.log(e);
- err("problem logging in", e);
- }
- next(null, { username: "guest" });
- }
- }
- )
-);
-
-export const optionalAuth = {
- preValidation: fastifyPassport.authenticate(
- "jwt",
- { session: false },
- function(req, res, err, user, info) {
- req.user = user;
- }
- )
-};
-
-export const adminAuth = {
- preValidation: fastifyPassport.authenticate(
- "jwt",
- { session: false },
- function(req, res, err, user, info) {
- if (!(user && user.admin)) return res.code(401).send("Unauthorized");
- req.user = user;
- }
- )
-};
-
-export const auth = {
- preValidation: fastifyPassport.authenticate("jwt", {
- authInfo: false,
- session: false
- })
-};
diff --git a/lib/payments.js b/lib/payments.js
new file mode 100644
index 00000000..6fd595d4
--- /dev/null
+++ b/lib/payments.js
@@ -0,0 +1,155 @@
+import config from "$config";
+import store from "$lib/store";
+import { emit } from "$lib/sockets";
+import { v4 } from "uuid";
+import { notify } from "$lib/notifications";
+import { db, g, s, t } from "$lib/db";
+import { l, err } from "$lib/logging";
+import { fail } from "$lib/utils";
+import { callWebhook } from "$lib/webhooks";
+
+export const types = {
+ internal: "internal",
+ bitcoin: "bitcoin",
+ lightning: "lightning",
+ pot: "pot",
+ classic: "classic"
+};
+
+export let debit = async (
+ hash,
+ amount,
+ fee = 0,
+ memo,
+ user,
+ type = types.internal,
+ id = v4()
+) => {
+ let ref;
+ let invoice = await g(`invoice:${hash}`);
+ if (invoice) ref = invoice.uid;
+
+ let { id: uid, currency, username } = user;
+
+ amount = parseInt(amount);
+
+ if (!amount || amount < 0) fail("Amount must be greater than zero");
+
+ let ourfee = [types.bitcoin, types.lightning].includes(type)
+ ? Math.round(amount * config.fee)
+ : 0;
+
+ await t(`balance:${uid}`, async (balance, db) => {
+ await t(`credit:${type}:${uid}`, async (credit, db) => {
+ let covered = Math.min(credit, ourfee) || 0;
+ ourfee -= covered;
+
+ if (balance < amount + ourfee) fail("Insufficient funds");
+ await db
+ .multi()
+ .decrBy(`credit:${type}:${uid}`, covered)
+ .exec();
+ });
+
+ await db
+ .multi()
+ .decrBy(`balance:${uid}`, amount + (ourfee - credit))
+ .exec();
+ });
+
+ let p = {
+ id,
+ amount: -amount,
+ fee,
+ ourfee,
+ memo,
+ uid,
+ confirmed: true,
+ rate: store.rates[currency],
+ currency,
+ type,
+ ref,
+ created: Date.now()
+ };
+
+ await s(`payment:${id}`, p);
+ await db.lPush(`${uid}:payments`, id);
+
+ l("sent", type, user.username, amount);
+ emit(user.id, "payment", p);
+
+ return p;
+};
+
+export let credit = async (hash, amount, memo, ref, type = types.internal) => {
+ amount = parseInt(amount);
+ let invoice = await g(`invoice:${hash}`);
+ if (!invoice) return;
+ if (!memo) ({ memo } = invoice);
+
+ let user = await g(`user:${invoice.uid}`);
+
+ let { id: uid, currency, username } = user;
+
+ let p = {
+ hash,
+ amount,
+ uid,
+ rate: store.rates[currency],
+ currency,
+ memo,
+ ref,
+ type,
+ confirmed: true,
+ created: Date.now()
+ };
+
+ let { tip } = invoice;
+ if (tip) {
+ p.tip = tip;
+ p.amount -= tip;
+ }
+
+ invoice.received += amount;
+
+ let balance = "balance";
+ if (type === types.bitcoin) {
+ let [txid, vout] = ref.split(":").slice(-2);
+ p.id = `${txid}:${vout}`;
+ p.confirmed = false;
+ balance = "pending";
+ } else {
+ p.id = hash;
+ }
+
+ let m = await db.multi();
+
+ if ([types.bitcoin, types.lightning].includes(type))
+ m.incrBy(`credit:${type}:${uid}`, Math.round(amount * config.fee));
+
+ m.set(`invoice:${hash}`, JSON.stringify(invoice))
+ .set(`payment:${p.id}`, JSON.stringify(p))
+ .lPush(`${uid}:payments`, p.id)
+ .incrBy(`${balance}:${uid}`, amount)
+ .exec();
+
+ l("received", type, username, amount);
+ emit(uid, "payment", p);
+ notify(user, `Received ${amount} sats`);
+ callWebhook(invoice, p);
+
+ return p;
+};
+
+export let confirm = async (address, txid, vout) => {
+ let id = `payment:${txid}:${vout}`;
+ let p = await g(id);
+ p.confirmed = true;
+
+ await db
+ .multi()
+ .set(id, JSON.stringify(p))
+ .decrBy(`pending:${p.uid}`, p.amount)
+ .incrBy(`balance:${p.uid}`, p.amount)
+ .exec();
+};
diff --git a/lib/persist.js b/lib/persist.js
deleted file mode 100644
index fd6fb146..00000000
--- a/lib/persist.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import fs from "fs";
-
-export default (path, initial = {}) => {
- if (!initial || !Object.keys(initial).length) {
- try {
- initial = JSON.parse(fs.readFileSync("/app/" + path));
- } catch (e) {
- console.log(e);
- }
- }
-
- return new Proxy(initial, {
- set(obj, prop, value) {
- fs.writeFileSync(
- path,
- JSON.stringify({ ...obj, [prop]: value }, null, 2),
- "utf-8"
- );
- return Reflect.set(...arguments);
- }
- });
-};
diff --git a/lib/rates.js b/lib/rates.js
index e896c8cc..362aaa98 100644
--- a/lib/rates.js
+++ b/lib/rates.js
@@ -1,73 +1,65 @@
-import app from "$app";
-import axios from "axios";
+import got from "got";
import config from "$config";
-import fs from "fs";
-import binance from "./binance";
-import { broadcast } from "./sockets";
-import store from "./store";
+import { broadcast } from "$lib/sockets";
+import store from "$lib/store";
import { err, warn } from "$lib/logging";
+import { g, s } from "$lib/db";
+import { sleep } from "$lib/utils";
+import WebSocket from "ws";
-let b = binance();
-setInterval(() => {
- b.terminate();
- b = binance();
-}, 360000);
+let last;
+let ws;
+let connect = async () => {
+ if (ws && ws.readyState === 1 && Date.now() - last < 5000) return;
+ if (ws) ws.terminate() && (await sleep(Math.round(Math.random() * 1000)));
-let fetchRates;
-(fetchRates = async () => {
- let date, fx;
+ ws = new WebSocket("wss://stream.binance.com:9443/ws/btcusdt@ticker");
- try {
- ({ date, fx } = JSON.parse(fs.readFileSync("fx")));
- } catch (e) {
- warn("Failed to read fx file");
- }
+ ws.onmessage = async function(event) {
+ try {
+ let msg = JSON.parse(event.data);
- let today = JSON.stringify(new Date())
- .replace(/T.*/, "")
- .replace(/"/, "");
+ Object.keys(store.fx).map(symbol => {
+ store.rates[symbol] = msg.c * store.fx[symbol];
+ });
- if (date !== today) {
- try {
- let {
- data: { rates: fx }
- } = await axios.get(
- `https://api.exchangerate.host/latest?base=USD&v={(new Date()).toISOString().split('T')[0]}`
- );
- fs.writeFileSync("fx", JSON.stringify({ date, fx }));
+ store.last = msg.c;
+ last = Date.now();
} catch (e) {
- try {
- let {
- data: { rates: fx }
- } = await axios.get(
- `http://data.fixer.io/api/latest?access_key=${config.fixer}`
- );
+ console.log(e);
+ err("binance message error", e.message);
+ }
+ };
- let USD = fx["USD"];
- Object.keys(fx).map(k => {
- fx[k] = parseFloat((fx[k] / fx["USD"]).toFixed(6));
- });
+ ws.onerror = async function(error) {
+ err("binance socket error", error.message);
+ };
- fs.writeFileSync("fx", JSON.stringify({ date, fx }));
- } catch (e) {
- err("error fetching rates", e.message);
- }
- }
- }
+ return ws;
+};
- store.fx = fx;
+export let sendRates = () => broadcast("rate", store.last);
+export let getRates = async () => {
+ connect();
- setTimeout(fetchRates, 7200000);
-})();
+ let date = 0,
+ fx;
+ let rates = await g("rates");
+ if (rates) ({ date, fx } = rates);
-app.get("/rate", async (req, res, next) => {
- res.send(store.last);
-});
+ if (Date.now() - date > 24 * 60 * 60 * 1000) {
+ date = Date.now();
+ try {
+ let { rates: fx } = await got(
+ `https://api.exchangerate.host/latest?base=USD&v={(new Date()).toISOString().split('T')[0]}`
+ ).json();
+ await s("rates", { date, fx });
+ } catch (e) {
+ err("error fetching rates", e.message);
+ }
+ }
-app.get("/rates", async (req, res, next) => {
- res.send(store.rates);
-});
+ store.fx = fx;
-setInterval(() => {
- broadcast("rate", store.last);
-}, 1000);
+ setTimeout(getRates, 30000);
+};
diff --git a/lib/read.js b/lib/read.js
deleted file mode 100644
index c021cb10..00000000
--- a/lib/read.js
+++ /dev/null
@@ -1,25 +0,0 @@
-export default (stream, func) => {
- var remaining = "";
-
- stream.on("data", function(data) {
- remaining += data;
- var index = remaining.indexOf("\n");
- var last = 0;
- while (index > -1) {
- var line = remaining.substring(last, index);
- last = index + 1;
- func(line);
- index = remaining.indexOf("\n", last);
- }
-
- remaining = remaining.substring(last);
- });
-
- stream.on("error", () => {});
-
- stream.on("end", function() {
- if (remaining.length > 0) {
- func(remaining);
- }
- });
-};
diff --git a/lib/redis.js b/lib/redis.js
deleted file mode 100644
index 98a71856..00000000
--- a/lib/redis.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import { createClient } from "redis";
-
-const redis = createClient({
- url: "redis://redis",
-});
-
-redis.on("error", (err) => console.log("redis error", err));
-
-await redis.connect();
-
-export default redis;
diff --git a/lib/register.js b/lib/register.js
index 21c113c0..e4bbf526 100644
--- a/lib/register.js
+++ b/lib/register.js
@@ -1,60 +1,62 @@
import countries from "$lib/countries";
import config from "$config";
import { authenticator } from "otplib";
-import db from "$db";
-import axios from "axios";
import bcrypt from "bcrypt";
import { l } from "$lib/logging";
+import { v4 } from "uuid";
+import { s, g } from "$lib/db";
+import { got } from "got";
export default async (user, ip, requireChallenge) => {
- if (!(user && user.username)) throw new Error("Username required");
- user.username = user.username.replace(/ /g, "");
+ let { password, pubkey, username } = user;
+ l("registering", username);
- let exists = await db.User.count({ where: { username: user.username } });
- if (exists) throw new Error(`Username ${user.username} taken`);
+ if (!username) throw new Error("Username required");
- if (user.password) {
- user.password = await bcrypt.hash(user.password, 1);
+ username = username.replace(/ /g, "");
+ let id = v4();
+ user.id = id;
+
+ let exists = await g(`user:${username}`);
+ if (exists) throw new Error(`Username ${username} taken`);
+
+ if (password) {
+ user.password = await bcrypt.hash(password, 1);
}
- if (!config.ipxapi || ip.startsWith("127") || ip.startsWith("192")) {
- user.currency = "CAD";
- } else {
- let { data } = await axios.get(`https://ipxapi.com/api/ip?ip=${ip}`, {
- headers: { authorization: `Bearer ${config.ipxapi}` }
- });
+ user.currency = "USD";
+ if (config.ipxapi) {
+ let countryCode = "US";
+
+ try {
+ let r = await got(`https://ipxapi.com/api/ip?ip=${ip}`, {
+ headers: { authorization: `Bearer ${config.ipxapi}` }
+ }).json();
+ if (r.success) ({ countryCode } = r);
+ } catch (e) {
+ console.log(e);
+ }
- user.currency = countries[data.countryCode] || "USD";
+ user.currency = countries[countryCode];
}
user.currencies = [...new Set([user.currency, "CAD", "USD"])];
user.fiat = false;
user.otpsecret = authenticator.generateSecret();
+ user.migrated = true;
- user = await db.User.create(user);
- let balance = config.faucet ? 21000000 : 0;
+ await s(`balance:${id}`, 21000000);
- let account = await db.Account.create({
- user_id: user.id,
- asset: config.liquid.btcasset,
- balance,
- pending: 0,
- name: "Bitcoin",
- ticker: "BTC",
- precision: 8
- });
-
- user.accounts = [account];
-
- const d = ip.split(".");
- const numericIp = ((+d[0] * 256 + +d[1]) * 256 + +d[2]) * 256 + +d[3];
- if (Number.isInteger(numericIp)) {
- user.ip = numericIp;
- const ipExists = await db.User.findOne({ where: { ip: numericIp } });
+ let d = ip.split(".");
+ ip = ((+d[0] * 256 + +d[1]) * 256 + +d[2]) * 256 + +d[3];
+ if (Number.isInteger(ip)) {
+ user.ip = ip;
}
- user.account_id = account.id;
- await user.save();
- l("new user", user.username, ip);
+ await s(`user:${id}`, user);
+ await s(`user:${user.username}`, id);
+ await s(`user:${pubkey}`, id);
+
+ l("new user", user.username);
return user;
};
diff --git a/lib/rpc.js b/lib/rpc.js
index 9186f4cd..b8a2d0dd 100644
--- a/lib/rpc.js
+++ b/lib/rpc.js
@@ -1,4 +1,4 @@
-import wretch from "./wretch";
+import got from "got";
export default ({ host, port, wallet, username, password }) =>
new Proxy(
@@ -7,18 +7,20 @@ export default ({ host, port, wallet, username, password }) =>
get: (target, prop) => (...params) =>
((method, ...params) => {
let url = `http://${host}:${port}/wallet/${wallet}`;
- return wretch()
- .url(url)
- .auth(
- `Basic ${Buffer.from(`${username}:${password}`).toString(
- "base64"
- )}`
- )
- .post({
- method,
- params
+ return got
+ .post(url, {
+ json: {
+ method,
+ params
+ },
+ headers: {
+ authorization: `Basic ${Buffer.from(
+ `${username}:${password}`
+ ).toString("base64")}`
+ }
})
- .json(({ result }) => result);
+ .json()
+ .then(({ result }) => result);
})(prop.toLowerCase(), ...params)
}
);
diff --git a/lib/send.js b/lib/send.js
deleted file mode 100644
index 54bcd103..00000000
--- a/lib/send.js
+++ /dev/null
@@ -1,215 +0,0 @@
-import config from "$config";
-import db from "$db";
-import { emit } from "$lib/sockets";
-import store from "./store";
-import bolt11 from "bolt11";
-import { Op } from "@sequelize/core";
-import {
- computeConversionFee,
- conversionFeeReceiver
-} from "../routes/lightning/conversionFee";
-import ln from "$lib/ln";
-import { l, warn, err } from "$lib/logging";
-
-export default async (amount, memo, hash, user) => {
- l("attempting lightning payment", user.username, amount, hash);
-
- let payreq = bolt11.decode(hash);
- let routingInfo = payreq.tags.find(t => t.tagName === "routing_info");
- if (
- routingInfo &&
- routingInfo.data.find(d => d.fee_proportional_millionths > 10000)
- ) {
- warn("fee rate too high", d.fee_proportional_millionths);
- throw new Error(
- "Couldn't find a suitable route to pay to your destination"
- );
- }
-
- if (!amount || payreq.satoshis > amount) amount = payreq.satoshis;
- amount = parseInt(amount);
-
- if (store.seen.includes(hash)) {
- warn("attempted to pay a paid invoice", user.username);
- throw new Error("Invoice has been paid, can't pay again");
- }
-
- let error, fee, total, preimage, payment;
-
- let conversionFee = computeConversionFee(amount);
- let conversionFeeDeduction;
- await db.transaction(async transaction => {
- l("starting lightning send transaction");
- let account;
- if (user.account.asset === config.liquid.btcasset)
- account = await db.Account.findOne({
- where: {
- id: user.account.id,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- else
- account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset: config.liquid.btcasset,
- pubkey: null,
- balance: {
- [Op.gte]: amount
- }
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- conversionFeeDeduction = Math.min(account.lightning_credits, conversionFee);
- total = amount + conversionFee - conversionFeeDeduction;
-
- if (!account || account.balance < total) {
- warn(
- "user attempting to send more than they have",
- user.id,
- amount,
- conversionFee
- );
- throw new Error("Insufficient funds");
- }
-
- await account.decrement(
- { balance: total, lightning_credits: conversionFeeDeduction },
- { transaction }
- );
- await account.reload({ transaction });
-
- l("debited account", account.id, total);
- let tokens;
- if (!payreq.satoshis) tokens = amount;
-
- let m;
- let { msatoshi, msatoshi_sent, payment_preimage } = await ln.pay(
- hash,
- tokens ? `${tokens}sats` : undefined
- );
- preimage = payment_preimage;
- fee = parseInt((msatoshi_sent - msatoshi) / 1000);
-
- if (store.seen.includes(preimage)) {
- warn("duplicate payment detected", preimage);
- throw new Error("Duplicate payment detected");
- }
-
- store.seen.push(preimage);
- store.seen.push(hash);
- });
-
- await db.transaction(async transaction => {
- l("starting lightning fee transaction");
-
- let account;
- if (user.account.asset === config.liquid.btcasset)
- account = await db.Account.findOne({
- where: {
- id: user.account.id,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- else
- account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset: config.liquid.btcasset,
- pubkey: null,
- balance: {
- [Op.gte]: fee
- }
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- l("deducting fee", fee);
- await account.decrement({ balance: fee }, { transaction });
- await account.reload({ transaction });
-
- if (conversionFeeDeduction) {
- conversionFee -= conversionFeeDeduction;
- }
-
- l("conversion fee", conversionFee);
-
- let receiverAccount = await db.Account.findOne({
- where: {
- "$user.username$": conversionFeeReceiver
- },
- include: [
- {
- model: db.User,
- as: "user"
- }
- ],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- let fee_payment;
- let fee_payment_id = null;
- if (conversionFee) {
- await receiverAccount.increment(
- { balance: conversionFee },
- { transaction }
- );
- await receiverAccount.reload({ transaction });
- fee_payment = await db.Payment.create(
- {
- amount: conversionFee,
- fee: 0,
- memo: "Lightning conversion fee",
- account_id: receiverAccount.id,
- user_id: receiverAccount.user_id,
- rate: store.rates[receiverAccount.user.currency],
- currency: receiverAccount.user.currency,
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
- fee_payment_id = fee_payment.id;
- }
-
- payment = await db.Payment.create(
- {
- amount: -total,
- account_id: account.id,
- user_id: user.id,
- hash,
- memo,
- preimage,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed: true,
- network: "lightning",
- fee,
- fee_payment_id
- },
- { transaction }
- );
-
- l("created payment record", payment.id);
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- payment.fee_payment = fee_payment && fee_payment.get({ plain: true });
-
- emit(user.username, "account", payment.account);
- emit(user.username, "payment", payment);
-
- l("sent lightning", user.username, amount, total, fee);
- });
-
- return payment;
-};
diff --git a/lib/sendInternal.js b/lib/sendInternal.js
deleted file mode 100644
index 7204f769..00000000
--- a/lib/sendInternal.js
+++ /dev/null
@@ -1,224 +0,0 @@
-import config from "$config";
-import db from "$db";
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import { callWebhook } from "$lib/webhooks";
-import axios from "axios";
-import { v4 } from "uuid";
-import { notify } from "$lib/notifications";
-import { sendLiquid } from "$routes/liquid/send";
-import { l, err } from "$lib/logging";
-import { fail } from "$lib/utils";
-
-const { HOSTNAME: hostname } = process.env;
-
-export default async (
- { amount, address, payreq, unconfidential, asset, memo, username, tip },
- user
-) => {
- amount = parseInt(amount);
-
- if (!asset) asset = config.liquid.btcasset;
-
- if (!amount || amount < 0) fail("Amount must be greater than zero");
-
- return db.transaction(async transaction => {
- let account;
- if (user.account.asset === asset && !user.account.pubkey) {
- account = await db.Account.findOne({
- where: {
- id: user.account.id,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- } else {
- account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- }
-
- if (!account) throw new Error("Account not found");
-
- if (account.balance < amount) {
- throw new Error("Insufficient funds");
- }
-
- let fee = 0;
-
- await account.decrement({ balance: amount }, { transaction });
- await account.reload({ transaction });
-
- let params, recipient, payment;
-
- if (username) {
- recipient = await db.User.findOne(
- {
- where: { username },
- include: {
- model: db.Account,
- as: "account"
- }
- },
- { transaction }
- );
-
- params = {
- where: { user_id: recipient.id },
- order: [["id", "DESC"]]
- };
- if (address) params.where.address = address;
- else if (payreq) params.where.text = payreq;
- let invoice = (address || payreq) && (await db.Invoice.findOne(params));
-
- let a2;
- let acc = {
- user_id: recipient.id,
- asset,
- pubkey: null
- };
-
- if (recipient.account.asset === asset && !recipient.account.pubkey)
- a2 = recipient.account;
- else {
- a2 = await db.Account.findOne({
- where: acc,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- }
-
- if (a2) {
- await a2.increment({ balance: amount }, { transaction });
- await a2.reload({ transaction });
- } else {
- let name = asset.substr(0, 6);
- let domain;
- let ticker = asset.substr(0, 3).toUpperCase();
- let precision = 8;
-
- if (store.assets[asset]) {
- ({ domain, ticker, precision, name } = store.assets[asset]);
- } else {
- const existing = await db.Account.findOne({
- where: {
- asset
- },
- order: [["id", "ASC"]],
- limit: 1,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (existing) {
- ({ domain, ticker, precision, name } = existing);
- }
- }
-
- acc = { ...acc, ...{ domain, ticker, precision, name } };
- acc.balance = amount;
- acc.pending = 0;
- acc.network = "liquid";
- a2 = await db.Account.create(acc, { transaction });
- }
-
- params = {
- amount,
- account_id: a2.id,
- user_id: recipient.id,
- rate: store.rates[recipient.currency],
- currency: recipient.currency,
- confirmed: true,
- hash: `#${v4().substr(0, 6)} Payment from ${user.username}`,
- memo,
- network: "COINOS",
- received: true,
- with_id: user.id
- };
-
- if (invoice) {
- let { tip } = invoice;
- params.invoice_id = invoice.id;
- if (tip) {
- params.tip = tip;
- params.amount -= tip;
- }
-
- await invoice.increment({ received: amount }, { transaction });
- await invoice.reload({ transaction });
-
- let c = store.convert[invoice.text];
- if (c) {
- l(
- "internal payment detected for conversion",
- invoice.text,
- c.address,
- recipient.username
- );
-
- recipient.account = a2;
-
- sendLiquid({
- address: c.address,
- amount: amount - 100,
- user: recipient,
- limit: amount
- }).catch(console.log);
- }
- }
-
- let p2 = await db.Payment.create(params, { transaction });
-
- p2 = p2.get({ plain: true });
- p2.account = a2.get({ plain: true });
- if (invoice) p2.invoice = invoice.get({ plain: true });
-
- emit(recipient.username, "payment", p2);
- emit(recipient.username, "account", p2.account);
-
- l("received internal", recipient.username, amount);
- notify(recipient, `Received ${amount} ${a2.ticker} sats`);
- callWebhook(invoice, p2);
- }
-
- params = {
- amount: -amount,
- account_id: account.id,
- memo,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed: true,
- with_id: recipient && recipient.id,
- hash: `#${v4().substr(0, 6)} ${
- username ? `Payment to ${username}` : "Internal Transfer"
- }`,
- network: "COINOS",
- };
-
- if (!username) {
- l("creating redeemable payment");
- params.redeemcode = v4();
- params.hash = `${hostname}/redeem/${params.redeemcode}`;
- }
-
- payment = await db.Payment.create(params, { transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
-
- l("sent internal", user.username, -payment.amount);
-
- emit(user.username, "payment", payment);
- emit(user.username, "account", account);
-
- return payment;
- });
-};
diff --git a/lib/sockets.js b/lib/sockets.js
index 7498db62..234c647a 100644
--- a/lib/sockets.js
+++ b/lib/sockets.js
@@ -1,50 +1,41 @@
-import store from "./store";
import config from "$config";
-import app from "$app";
+import store from "$lib/store";
import jwt from "jsonwebtoken";
import { v4 } from "uuid";
-import WebSocket from "ws";
-import { differenceInSeconds, subSeconds } from "date-fns";
-import fastifyWs from "@fastify/websocket";
import whitelist from "./whitelist";
import { l, err, warn } from "$lib/logging";
-import { getUser } from "$lib/utils";
-import db from "$db";
+import { g } from "$lib/db";
+import { pick } from "$lib/utils";
const code = 1000;
-
-const wss = new WebSocket.Server({ clientTracking: false, noServer: true });
-
-const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
const all = {};
const subscriptions = [];
const lastSeen = {};
+const users = {};
-export const emit = (username, type, data) => {
- if (data.username !== undefined) data = pick(data, ...whitelist);
-
+export const emit = (uid, type, data) => {
if (type === "payment" && data.amount > 0) {
for (let i = subscriptions.length - 1; i >= 0; i--) {
let s = subscriptions[i];
- if (s.invoice.id === data.invoice_id) {
+ if (s.hash === data.hash) {
s.ws.send(JSON.stringify({ type, data }));
}
}
}
- if (!store.sockets[username]) return;
- for (let id in store.sockets[username]) {
- const ws = store.sockets[username][id];
+ if (!store.sockets[uid]) return;
+ for (let id in store.sockets[uid]) {
+ const ws = store.sockets[uid][id];
ws.send(JSON.stringify({ type, data }));
}
};
export const broadcast = (type, data) => {
const sent = [];
- for (const username in store.sockets) {
- for (const id in store.sockets[username]) {
- const ws = store.sockets[username][id];
+ for (const uid in store.sockets) {
+ for (const id in store.sockets[uid]) {
+ const ws = store.sockets[uid][id];
ws.send(JSON.stringify({ type, data }));
sent.push(ws.id);
}
@@ -55,14 +46,9 @@ export const broadcast = (type, data) => {
});
};
-function subtractSeconds(numOfSeconds, date = new Date()) {
- date.setSeconds(date.getSeconds() - numOfSeconds);
-
- return date;
-}
+export async function socketServer(app) {
+ let seconds = (n, d = new Date()) => d.setSeconds(d.getSeconds() - n) && d;
-app.register(fastifyWs);
-app.register(async function(app) {
app.get("/ws", { websocket: true }, ({ socket: ws }, req) => {
const id = v4();
ws.id = id;
@@ -86,75 +72,41 @@ app.register(async function(app) {
case "login":
let token = data;
- if (lastSeen[token] > subtractSeconds(5)) return;
+ if (lastSeen[token] > seconds(5)) return;
lastSeen[token] = new Date();
try {
if (!token || token === "null" || !jwt.decode(token))
return ws.close(code, `bad token ${token}`);
- const username = jwt.decode(token).username;
- if (!username) throw new Error("Invalid JWT token");
- if (!store.sockets[username]) store.sockets[username] = {};
- const existing = Object.keys(store.sockets[username]);
+ let { id: uid } = jwt.decode(token);
+ if (!uid) throw new Error("Invalid JWT token");
+ let user = await g(`user:${uid}`);
+ if (!user) throw new Error("User not found");
+
+ if (!store.sockets[uid]) store.sockets[uid] = {};
+ const existing = Object.keys(store.sockets[uid]);
if (existing.length > 4) {
- const p = existing.find(sid => sid !== id);
- store.sockets[username][p].send(
- JSON.stringify({ type: "logout" })
- );
+ const p = existing.find(sid => sid !== uid);
+ store.sockets[uid][p].send(JSON.stringify({ type: "logout" }));
setTimeout(() => {
- if (store.sockets[username][p])
- store.sockets[username][p].close(code, "too many sockets");
+ if (store.sockets[uid][p])
+ store.sockets[uid][p].close(code, "too many sockets");
}, 5000);
}
- store.sockets[username][id] = ws;
- names[id] = username;
-
- let user = await getUser(username);
-
- let { haspin } = user;
-
- if (user.locked) throw new Error("Account is locked");
- let payments = await user.getPayments({
- where: {
- account_id: user.account_id
- },
- order: [["id", "DESC"]],
- limit: 12,
- include: [
- {
- model: db.Account,
- as: "account"
- },
- {
- model: db.Payment,
- as: "fee_payment"
- }
- ]
- });
-
- let accounts = await user.getAccounts();
-
- let keys = await user.getKeys();
- user = user.get({ plain: true });
- user.accounts = accounts;
- user.keys = keys;
- user.payments = payments;
- user.haspin = haspin;
+ store.sockets[uid][id] = ws;
+ users[id] = uid;
ws.user = user;
ws.send(
- JSON.stringify({ type: "login", data: pick(user, ...whitelist) })
+ JSON.stringify({ type: "login", data: pick(user, whitelist) })
);
ws.send(
JSON.stringify({ type: "version", data: config.clientVersion })
);
} catch (e) {
+ console.log(e);
err("caught socket error", e.message);
- if (e.message.includes("locked")) {
- ws.send(JSON.stringify({ type: "locked" }));
- ws.send(JSON.stringify({ type: "logout" }));
- }
if (e.message.includes("not found"))
ws.send(JSON.stringify({ type: "logout" }));
setTimeout(
@@ -170,23 +122,6 @@ app.register(async function(app) {
case "lnurl":
store.sessions[data] = ws;
break;
- case "updateMemo":
- const payment = await db.Payment.findOne({
- where: {
- user_id: ws.user.id,
- id: data.id
- },
- include: {
- model: db.Account,
- as: "account"
- }
- });
- if (payment) {
- payment.memo = data.memo;
- await payment.save();
- emit(ws.user.username, "payment", payment);
- }
- break;
case "subscribe":
subscriptions.push({ invoice: data, ws });
break;
@@ -196,11 +131,10 @@ app.register(async function(app) {
});
ws.on("close", function(code, reason) {
- // console.log("closing socket", reason && reason.toString(), id);
try {
- const username = names[id];
- if (store.sockets[username] && store.sockets[username][id]) {
- delete store.sockets[username][id];
+ const uid = users[id];
+ if (store.sockets[uid] && store.sockets[uid][id]) {
+ delete store.sockets[uid][id];
}
if (all[id]) delete all[id];
@@ -209,16 +143,14 @@ app.register(async function(app) {
}
});
});
-});
-
-const names = {};
+}
-setInterval(() => {
- for (const username in store.sockets) {
- for (const id in store.sockets[username]) {
- let ws = store.sockets[username][id];
+export let sendHeartbeat = () => {
+ for (const uid in store.sockets) {
+ for (const id in store.sockets[uid]) {
+ let ws = store.sockets[uid][id];
ws.beats++;
- if (ws.beats > 10) ws.close(code, `${username} ${id} lost heartbeat`);
+ if (ws.beats > 10) ws.close(code, `${uid} ${id} lost heartbeat`);
}
}
-}, 2000);
+};
diff --git a/lib/store.js b/lib/store.js
index 6f2e47ce..bf71219e 100644
--- a/lib/store.js
+++ b/lib/store.js
@@ -1,10 +1,7 @@
-import persist from "./persist";
-
export default {
addresses: {},
challenge: {},
change: [],
- exceptions: [],
issuances: {},
logins: {},
nodes: [],
@@ -13,12 +10,13 @@ export default {
sockets: {},
unaccounted: [],
networks: [],
- convert: persist("data/conversions.json"),
- rates: {},
+ rates: { USD: 20000 },
fx: {},
assets: {},
bcAddressIndex: 0,
lqAddressIndex: 0,
last: {},
- payments: []
+ payments: [],
+ fetching: {},
+ timeouts: {}
};
diff --git a/lib/sync.js b/lib/sync.js
deleted file mode 100644
index 42291a94..00000000
--- a/lib/sync.js
+++ /dev/null
@@ -1,384 +0,0 @@
-import config from "$config";
-import { toSats } from "$lib/utils";
-import { emit } from "$lib/sockets";
-import db from "$db/db";
-import app from "$app";
-import { differenceInDays } from "date-fns";
-import fs from "fs";
-import read from "./read";
-import { Op } from "@sequelize/core";
-import store from "./store";
-import { l, err, warn } from "./logging";
-import ln from "./ln";
-import lnd from "./lnd";
-import bc from "./bitcoin";
-import lq from "./liquid";
-
-const init = async () => {
- try {
- read(fs.createReadStream("exceptions"), (data) =>
- store.exceptions.push(data)
- );
- } catch (e) {
- warn("couldn't read exceptions file", e.message);
- }
-
- try {
- const thirtyDays = new Date(new Date().setDate(new Date().getDate() - 30));
-
- (
- await db.Invoice.findAll({
- where: {
- createdAt: {
- [Op.gt]: thirtyDays,
- },
- },
- include: {
- model: db.User,
- as: "user",
- },
- })
- ).map(({ address, user, unconfidential }) => {
- if (address && user) store.addresses[address] = user.username;
- if (unconfidential && user)
- store.addresses[unconfidential] = user.username;
- });
- } catch (e) {
- console.log(e);
- }
-
- store.payments = (
- await db.Payment.findAll({
- attributes: ["hash"],
- })
- ).map((p) => p.hash);
-};
-
-init();
-
-const sync = async () => {
- const twoWeeksAgo = new Date(new Date().setDate(new Date().getDate() - 14));
-
- try {
- const payments = await db.Payment.findAll({
- attributes: ["hash", "confirmed", "preimage"],
- where: { createdAt: { [Op.gt]: twoWeeksAgo } },
- include: [
- {
- model: db.Account,
- as: "account",
- },
- {
- model: db.User,
- as: "user",
- },
- ],
- });
-
- let missed, invoices, recent;
- if (config.lnd) {
- ({ invoices } = await getInvoices({ lnd, limit: 1000 }));
-
- recent = invoices
- .filter(
- (i) =>
- i.is_confirmed &&
- differenceInDays(new Date(), new Date(i.created_at)) < 2
- )
- .map((i) => ({
- amount: parseInt(i.received),
- preimage: i.secret,
- pr: i.request,
- createdAt: new Date(i.created_at),
- }));
- } else {
- ({ invoices } = await ln.listinvoices());
-
- recent = invoices
- .filter(
- (i) =>
- i.status === "paid" &&
- Math.round(Date.now() / 1000) - i.paid_at < 60 * 60 * 48
- )
- .map((i) => ({
- amount: parseInt(Math.round(i.msatoshi_received / 1000)),
- preimage: i.payment_preimage,
- pr: i.bolt11,
- createdAt: new Date(i.paid_at * 1000),
- }));
- }
-
- await db.transaction(async (transaction) => {
- const twoDaysAgo = new Date(new Date().setDate(new Date().getDate() - 2));
- let settled = (
- await db.Payment.findAll(
- {
- where: {
- network: "lightning",
- createdAt: { [Op.gt]: twoDaysAgo },
- },
- attributes: ["preimage"],
- },
- transaction
- )
- ).map((p) => p.preimage);
-
- missed = recent.filter((i) => !settled.includes(i.preimage));
- for (let i = 0; i < missed.length; i++) {
- let { amount, preimage, pr: text, createdAt } = missed[i];
- if (!text || !text.length) continue;
-
- try {
- let invoice = await db.Invoice.findOne({
- where: { text },
- include: {
- model: db.User,
- as: "user",
- },
- transaction,
- });
-
- if (invoice && invoice.user_id) {
- let account = await db.Account.findOne({
- where: {
- user_id: invoice.user_id,
- asset: config.liquid.btcasset,
- pubkey: null,
- },
- transaction,
- });
-
- if (account) {
- let payment = await db.Payment.create({
- account_id: account.id,
- user_id: invoice.user_id,
- hash: text,
- amount,
- currency: invoice.currency,
- preimage,
- rate: invoice.rate,
- received: true,
- confirmed: true,
- network: "lightning",
- tip: invoice.tip,
- invoice_id: invoice.id,
- createdAt,
- updatedAt: createdAt,
- });
-
- await invoice.increment({ received: amount }, { transaction });
- await account.increment({ balance: amount }, { transaction });
-
- l("lightning missing from account", account.id, amount);
- }
- }
- } catch (e) {
- console.log(e);
- err("problem syncing lightning payment", JSON.stringify(missed[i]));
- }
- }
- });
-
- const unconfirmed = await db.Payment.findAll({
- where: {
- confirmed: 0,
- },
- include: [
- {
- model: db.Account,
- as: "account",
- },
- {
- model: db.Invoice,
- as: "invoice",
- },
- {
- model: db.User,
- as: "user",
- },
- ],
- });
-
- let hashes = unconfirmed.map((p) => p.hash);
-
- const transactions = [
- ...(await bc.listTransactions("*", 500)),
- ...(await lq.listTransactions("*", 500)),
- ].filter(
- (tx) =>
- ["send", "receive"].includes(tx.category) &&
- new Date(tx.time * 1000) > twoWeeksAgo
- );
-
- missed = transactions.filter(
- (tx) =>
- tx.category === "receive" &&
- tx.confirmations > 2 &&
- hashes.includes(tx.txid)
- );
-
- for (let i = 0; i < missed.length; i++) {
- let p = unconfirmed.find((p) => p.hash === missed[i].txid);
- p.confirmed = 1;
-
- try {
- await db.transaction(async (transaction) => {
- l("confirming payment", p.id, p.user_id, p.hash, p.address);
- await p.save({ transaction });
-
- if (p.invoice)
- await p.invoice.increment({ received: p.amount }, { transaction });
-
- await p.account.increment({ balance: p.amount }, { transaction });
- await p.account.decrement({ pending: p.amount }, { transaction });
- });
-
- emit(p.user.username, "account", p.account);
- emit(p.user.username, "payment", p);
- } catch (e) {
- err("problem confirming payment", p.id, e.message, e.stack);
- }
- }
-
- store.unaccounted = [];
-
- transactions.map((tx) => {
- if (
- !payments.find((p) => p.hash === tx.txid) &&
- !store.exceptions.includes(tx.txid) &&
- !store.unaccounted.find((a) => a.txid === tx.txid) &&
- new Date(tx.blocktime * 1000) >= twoWeeksAgo
- ) {
- store.unaccounted.push(tx);
- }
- });
-
- if (store.unaccounted.length)
- warn(
- "wallet transactions missing from database",
- store.unaccounted.map((tx) => tx.txid)
- );
-
- let receipts = store.unaccounted
- .filter(
- (tx) =>
- tx.category === "receive" &&
- (!tx.asset || tx.asset === config.liquid.btcasset)
- )
- .map((tx) => tx.address);
-
- invoices = await db.Invoice.findAll({
- where: {
- [Op.or]: {
- address: receipts,
- unconfidential: receipts,
- },
- },
- include: [
- {
- model: db.Account,
- as: "account",
- },
- {
- model: db.User,
- as: "user",
- },
- ],
- });
-
- for (let i = 0; i < invoices.length; i++) {
- let {
- address,
- unconfidential,
- account,
- account_id,
- currency,
- id: invoice_id,
- network,
- rate,
- tip,
- user,
- user_id,
- } = invoices[i];
-
- l("unaccounted", address);
-
- let pending = store.unaccounted.filter(
- (tx) => tx.address === address || tx.address === unconfidential
- );
-
- for (let i = 0; i < pending.length; i++) {
- let { amount, txid: hash } = pending[i];
-
- amount = toSats(amount);
-
- try {
- await db.transaction(async (transaction) => {
- l("found pending transaction", user.username, amount, hash);
- store.payments.push(hash);
- let p = await db.Payment.create(
- {
- account_id,
- address: address || unconfidential,
- amount,
- confirmed: false,
- currency,
- hash,
- invoice_id,
- network,
- rate,
- received: true,
- tip,
- user_id,
- },
- { transaction }
- );
-
- await account.increment({ pending: amount }, { transaction });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", p);
- });
- } catch (e) {
- err("problem updating pending transaction", hash, e.message, e.stack);
- }
- }
- }
- } catch (e) {
- console.log(e);
- err("sync check failed", e.message, e.stack);
- }
-
- setTimeout(sync, 300000);
-};
-
-setTimeout(sync, 5000);
-
-app.get("/conversions", async (req, res) => {
- const transactions = [
- ...(await bc.listTransactions("*", 500)),
- ...(await lq.listTransactions("*", 500)),
- ].filter((tx) => ["receive"].includes(tx.category));
-
- const { addr } = req.query;
- const { invoices } = require("./invoices");
- const persist = require("./persist");
- let conversions = persist("data/conversions.json");
- const payments = (
- await db.Payment.findAll({
- attributes: ["hash"],
- })
- ).map((p) => p.hash);
- res.send(
- Object.keys(conversions)
- .filter((c) => conversions[c].address === addr)
- .filter((c) => {
- return (
- invoices.find(
- (i) => i.payment_request === c && i.state === "SETTLED"
- ) || transactions.find((tx) => tx.txid === c)
- );
- })
- .filter((c) => !payments.includes(c))
- );
-});
diff --git a/lib/upload.js b/lib/upload.js
index 8d1c85ef..954e8d4d 100644
--- a/lib/upload.js
+++ b/lib/upload.js
@@ -1,7 +1,3 @@
-import app from "$app";
-import { auth } from "./passport";
-import fastifyMultipart from "@fastify/multipart";
-import fastifyStatic from "@fastify/static";
import { fileTypeFromStream } from "file-type";
import pump from "pump";
import Clone from "readable-stream-clone";
@@ -9,46 +5,38 @@ import fs from "fs";
import path from "path";
import sharp from "sharp";
import { pipeline } from "stream";
+import { g, s, db } from "$lib/db";
-app.register(fastifyMultipart);
+export default async (req, res) => {
+ let {
+ params: { type },
+ user
+ } = req;
+ console.log("TYPE", type);
+ if (!["banner", "profile"].includes(type)) throw new Error("invalid upload");
-app.register(fastifyStatic, {
- root: path.join("/app/uploads"),
- prefix: "/public/"
-});
+ let data = await req.file();
+ let s1 = new Clone(data.file);
+ let s2 = new Clone(data.file);
-app.post("/upload/:type", auth, async function(req, res) {
- try {
- let { type } = req.params;
- if (!["banner", "profile"].includes(type))
- throw new Error("invalid upload");
+ let [format, ext] = (await fileTypeFromStream(s1)).mime.split("/");
- let data = await req.file();
- let s1 = new Clone(data.file);
- let s2 = new Clone(data.file);
+ if (format !== "image" && !["jpg", "jpeg", "png"].includes(ext))
+ throw new Error("unsupported file type");
- let [format, ext] = (await fileTypeFromStream(s1)).mime.split("/");
+ let name = `${user.id}-${type}.webp`;
+ let path = `/app/data/uploads/${name}`;
+ let size = type === "banner" ? 1920 : 240;
- if (format !== "image" && !["jpg", "jpeg", "png"].includes(ext))
- throw new Error("unsupported file type");
+ let t = sharp()
+ .rotate()
+ .resize(size)
+ .webp();
- let name = `${req.user.username}-${type}.webp`;
- let path = `/app/uploads/${name}`;
- let size = type === "banner" ? 1920 : 240;
+ await new Promise(r => pipeline(s2, t, fs.createWriteStream(path), r));
- let t = sharp()
- .rotate()
- .resize(size)
- .webp();
+ user[type] = true;
+ await s(`user:${user.id}`, user);
- await new Promise(r => pipeline(s2, t, fs.createWriteStream(path), r));
-
- req.user[type] = true;
- await req.user.save();
-
- res.send(name);
- } catch (e) {
- console.log(e);
- return res.code(500).send(e);
- }
-});
+ res.send(name);
+};
diff --git a/lib/utils.js b/lib/utils.js
index c9670339..8291d173 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -1,173 +1,60 @@
+import store from "$lib/store";
+import { g } from "$lib/db";
import config from "$config";
-import db from "$db";
-import sequelize from "@sequelize/core";
-import { fromBase58 } from "bip32";
-import { payments as bcPayments, networks as bcNetworks } from "bitcoinjs-lib";
-import { payments as lqPayments, networks as lqNetworks } from "liquidjs-lib";
-import lnd from "$lib/lnd";
-import ln from "$lib/ln";
-const { Op } = sequelize;
+export const nada = () => {};
+
+export const sleep = n => new Promise(r => setTimeout(r, n));
+export const wait = async (f, s = 300, n = 50) => {
+ let i = 0;
+ while (!(await f()) && i < s) (await sleep(n)) && i++;
+ if (i >= s) throw new Error("timeout");
+ return f();
+};
export const requirePin = async ({ body, user }) => {
if (!user || (user.pin && user.pin !== body.pin))
throw new Error("Invalid pin");
};
-export const getUser = async (username, transaction) => {
- let params = {
- include: [
- {
- model: db.Account,
- as: "account"
- }
- ],
- where: {
- username: { [Op.or]: [username, username.replace(/ /g, "")] }
- }
- };
-
- if (transaction) {
- params.lock = transaction.LOCK.UPDATE;
- params.transaction = transaction;
- }
-
- let user = await db.User.findOne(params);
- if (!user) throw new Error(`User ${username} not found`);
-
- user.haspin = !!user.pin;
-
- return user;
-};
-
-export const getUserById = async (id, transaction) => {
- let params = {
- include: [
- {
- model: db.Account,
- as: "account"
- }
- ],
- where: { id }
- };
-
- if (transaction) {
- params.lock = transaction.LOCK.UPDATE;
- params.transaction = transaction;
- }
-
- let user = await db.User.findOne(params);
- if (!user) throw new Error("User not found");
-
- return user;
-};
-
export const prod = process.env.NODE_ENV === "production";
export const fail = msg => {
throw new Error(msg);
};
export const SATS = 100000000;
-export const toSats = n => Math.round(n * SATS);
-
-export const getBlockHeight = message => {
- let buffer = Buffer.from(message, "hex");
- if (buffer.length < 80) throw new Error("Buffer too small (< 80 bytes)");
-
- let offset = 0;
- const readSlice = n => {
- offset += n;
- return buffer.slice(offset - n, offset);
- };
+export const sats = n => Math.round(n * SATS);
+export const btc = n => parseFloat((n / SATS).toFixed(8));
- const readUInt32 = () => {
- const i = buffer.readUInt32LE(offset);
- offset += 4;
- return i;
- };
+export const uniq = (a, k) => [...new Map(a.map(x => [k(x), x])).values()];
+export const pick = (O, K) =>
+ K.reduce((o, k) => (typeof O[k] !== "undefined" && (o[k] = O[k]), o), {});
- const readUInt8 = () => {
- const i = buffer.readUInt8(offset);
- offset += 1;
- return i;
- };
-
- const readVarInt = () => {
- const vi = varuint.decode(buffer, offset);
- offset += varuint.decode.bytes;
- return vi;
- };
-
- readUInt32();
- readSlice(32);
- readSlice(32);
- readUInt32();
- return readUInt32();
-};
-
-export const deriveAddress = async (account, type) => {
- let { index, pubkey, path, network } = account;
- let n = { bitcoin: bcNetworks, liquid: lqNetworks }[network][
- prod ? "bitcoin" : "regtest"
- ];
- let p = { bitcoin: bcPayments, liquid: lqPayments }[network];
- let root = fromBase58(pubkey, n);
- let parts = path.split("/");
- let hd = root.derive(parseInt(parts[parts.length - 1]));
-
- type = {
- bech32: "p2wpkh",
- "p2sh-segwit": "p2sh",
- legacy: "p2pkh"
- }[type];
-
- console.log("TYPE", type);
-
- let r;
- if (type !== "p2sh") {
- r = p[type]({
- pubkey: hd.publicKey,
- network: n
- });
- } else {
- r = p[type]({
- redeem: p.p2wpkh({
- pubkey: hd.publicKey,
- network: n
- }),
- network: n
- });
- }
-
- index++;
- account.index = index;
- account.address = r.address;
- await account.save();
-
- return r;
-};
-
-export const bip21 = ({ address, amount, memo, tip, network }, { asset }) => {
- if (network === "liquid") network = "liquidnetwork";
-
- let url = amount || memo ? `${network}:${address}?` : address;
+export const bip21 = (address, { amount, memo, tip }) => {
+ let url = amount || memo ? `bitcoin:${address}?` : address;
if (amount)
url += `amount=${((amount + tip) / SATS).toFixed(8)}${memo ? "&" : ""}`;
if (memo) url += `message=${memo}`;
- if (network === "liquidnetwork" && amount) {
- url += `&asset=${asset}`;
- }
-
return url;
};
-export const derivePayRequest = async ({ amount, memo, tip }) => {
- if (!tip) tip = 0;
- let value = amount + tip;
-
- if (!memo) memo = "coinos";
- return (
- await ln.invoice(value ? `${value}sat` : "any", new Date(), memo, 360)
- ).bolt11;
-};
+export const fields = [
+ "cipher",
+ "pubkey",
+ "password",
+ "username",
+ "salt",
+ "currency",
+ "currencies",
+ "fiat",
+ "otpsecret",
+ "balance",
+ "ip",
+ "pin",
+ "display",
+ "haspin",
+ "profile",
+ "prompt",
+ "banner"
+];
diff --git a/lib/webhooks.js b/lib/webhooks.js
index 4741932a..c071eccb 100644
--- a/lib/webhooks.js
+++ b/lib/webhooks.js
@@ -1,5 +1,5 @@
import config from "$config";
-import wretch from "./wretch";
+import got from "got";
import { l } from "$lib/logging";
export const callWebhook = async (invoice, payment) => {
@@ -14,10 +14,9 @@ export const callWebhook = async (invoice, payment) => {
let secret = config.webhooks[webhook];
l("calling webhook", webhook, amount, hash, address, text);
- let res = await wretch()
- .headers({ "x-webhook": secret })
- .url(webhook)
- .post({
+ let res = await got(webhook, {
+ headers: { "x-webhook": secret },
+ json: {
address,
amount,
asset,
@@ -27,8 +26,8 @@ export const callWebhook = async (invoice, payment) => {
received,
text,
webhook
- })
- .res();
+ }
+ }).res();
return res;
}
} catch (e) {
diff --git a/lib/whitelist.js b/lib/whitelist.js
index 93e601c7..850dffc0 100644
--- a/lib/whitelist.js
+++ b/lib/whitelist.js
@@ -1,25 +1,30 @@
export default [
- "account",
- "account_id",
- "accounts",
+ "balance",
"address",
"admin",
"banner",
+ "cipher",
"currencies",
"currency",
+ "display",
"email",
"fiat",
+ "follows",
+ "followers",
"haspin",
"id",
"index",
+ "linked",
"keys",
+ "locktime",
"payments",
"profile",
+ "prompt",
+ "pubkey",
+ "salt",
"seed",
- "symbol",
"theme",
"twofa",
- "unit",
"username",
"verified"
];
diff --git a/lib/wretch.js b/lib/wretch.js
deleted file mode 100644
index 0be00d10..00000000
--- a/lib/wretch.js
+++ /dev/null
@@ -1,4 +0,0 @@
-import wretch from "wretch";
-import fetch from "node-fetch";
-wretch().polyfills({ fetch });
-export default wretch;
diff --git a/mine.sh b/mine.sh
deleted file mode 100755
index 0df5b6ba..00000000
--- a/mine.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-
-
-while true
-do
- docker exec -it liquid elements-cli -datadir=/config generatetoaddress 1 $(docker exec -it liquid elements-cli -datadir=/config getnewaddress)
- sleep 8
-done
diff --git a/nodemon.json b/nodemon.json
deleted file mode 100644
index 44ce3e3b..00000000
--- a/nodemon.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "ignore": ["data/*"]
-}
diff --git a/package.json b/package.json
index b868531e..0ee4096e 100644
--- a/package.json
+++ b/package.json
@@ -12,42 +12,17 @@
"@fastify/secure-session": "^5.2.0",
"@fastify/static": "^6.5.0",
"@fastify/websocket": "^7.0.1",
- "@sequelize/core": "7.0.0-alpha.10",
- "async-mutex": "^0.2.4",
- "axios": "^0.21.1",
"bcrypt": "^5.0.0",
- "bip32": "^2.0.5",
- "bip39": "^3.0.2",
- "bitcoinjs-lib": "6",
- "body-parser": "^1.19.0",
- "bolt11": "^1.3.2",
- "buffer-reverse": "^1.0.1",
+ "bech32": "^2.0.0",
"clightning-client": "^0.1.2",
- "coinselect": "^3.1.12",
- "compression": "^1.7.4",
- "cookie-parser": "^1.4.4",
- "cors": "^2.8.5",
"date-fns": "^2.21.3",
- "ecpair": "^2.0.1",
- "express": "4.17.1",
- "express-async-handler": "^1.1.4",
- "express-pino-logger": "^6.0.0",
- "express-session": "^1.16.2",
"fastify": "^4.5.3",
"file-type": "^18.0.0",
- "http-proxy-middleware": "^0.20.0",
- "imap": "^0.8.19",
+ "got": "^12.5.3",
"jsonwebtoken": "^8.5.1",
- "knex": "^2.3.0",
- "liquidjs-lib": "6.0.2-liquid.8",
"lnurl": "^0.24.2",
- "long": "^4.0.0",
- "mailgun-js": "^0.22.0",
- "mariadb": "^2.4.0",
- "mysql": "^2.18.1",
- "mysql2": "^2.2.5",
- "node-fetch": "^2.6.1",
"nodemon": "^2.0.7",
+ "nostr": "^0.2.7",
"otplib": "^12.0.1",
"passport-jwt": "^4.0.0",
"passport-local": "1.0.0",
@@ -59,13 +34,9 @@
"readable-stream-clone": "^0.0.7",
"redis": "^4.3.1",
"sharp": "^0.31.1",
- "sqlite3": "^5.0.11",
- "tiny-secp256k1": "^2.1.2",
"uuid": "8",
"web-push": "^3.4.4",
- "wretch": "^1.7.4",
- "ws": "^7.4.6",
- "zeromq": "6.0.0-beta.6"
+ "ws": "^7.4.6"
},
"devDependencies": {
"prettier": "^1.19.1"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 75af23d3..9715cbc5 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -6,42 +6,17 @@ specifiers:
'@fastify/secure-session': ^5.2.0
'@fastify/static': ^6.5.0
'@fastify/websocket': ^7.0.1
- '@sequelize/core': 7.0.0-alpha.10
- async-mutex: ^0.2.4
- axios: ^0.21.1
bcrypt: ^5.0.0
- bip32: ^2.0.5
- bip39: ^3.0.2
- bitcoinjs-lib: '6'
- body-parser: ^1.19.0
- bolt11: ^1.3.2
- buffer-reverse: ^1.0.1
+ bech32: ^2.0.0
clightning-client: ^0.1.2
- coinselect: ^3.1.12
- compression: ^1.7.4
- cookie-parser: ^1.4.4
- cors: ^2.8.5
date-fns: ^2.21.3
- ecpair: ^2.0.1
- express: 4.17.1
- express-async-handler: ^1.1.4
- express-pino-logger: ^6.0.0
- express-session: ^1.16.2
fastify: ^4.5.3
file-type: ^18.0.0
- http-proxy-middleware: ^0.20.0
- imap: ^0.8.19
+ got: ^12.5.3
jsonwebtoken: ^8.5.1
- knex: ^2.3.0
- liquidjs-lib: 6.0.2-liquid.8
lnurl: ^0.24.2
- long: ^4.0.0
- mailgun-js: ^0.22.0
- mariadb: ^2.4.0
- mysql: ^2.18.1
- mysql2: ^2.2.5
- node-fetch: ^2.6.1
nodemon: ^2.0.7
+ nostr: ^0.2.7
otplib: ^12.0.1
passport-jwt: ^4.0.0
passport-local: 1.0.0
@@ -54,13 +29,9 @@ specifiers:
readable-stream-clone: ^0.0.7
redis: ^4.3.1
sharp: ^0.31.1
- sqlite3: ^5.0.11
- tiny-secp256k1: ^2.1.2
uuid: '8'
web-push: ^3.4.4
- wretch: ^1.7.4
ws: ^7.4.6
- zeromq: 6.0.0-beta.6
dependencies:
'@fastify/multipart': 7.2.0
@@ -68,42 +39,17 @@ dependencies:
'@fastify/secure-session': 5.2.0
'@fastify/static': 6.5.0
'@fastify/websocket': 7.1.0
- '@sequelize/core': 7.0.0-alpha.10_qwzqhxtweawy7vupwb2a75td54
- async-mutex: 0.2.6
- axios: 0.21.4
bcrypt: 5.1.0
- bip32: 2.0.6
- bip39: 3.0.4
- bitcoinjs-lib: 6.0.2
- body-parser: 1.20.1
- bolt11: 1.4.0
- buffer-reverse: 1.0.1
+ bech32: 2.0.0
clightning-client: 0.1.4
- coinselect: 3.1.13
- compression: 1.7.4
- cookie-parser: 1.4.6
- cors: 2.8.5
date-fns: 2.29.3
- ecpair: 2.1.0
- express: 4.17.1
- express-async-handler: 1.2.0
- express-pino-logger: 6.0.0
- express-session: 1.17.3
fastify: 4.8.1
file-type: 18.0.0
- http-proxy-middleware: 0.20.0
- imap: 0.8.19
+ got: 12.5.3
jsonwebtoken: 8.5.1
- knex: 2.3.0_miwdxfk6g3dfg4gj6dnwby2onu
- liquidjs-lib: 6.0.2-liquid.8
lnurl: 0.24.2
- long: 4.0.0
- mailgun-js: 0.22.0
- mariadb: 2.5.6
- mysql: 2.18.1
- mysql2: 2.3.3
- node-fetch: 2.6.7
nodemon: 2.0.20
+ nostr: 0.2.7
otplib: 12.0.1
passport-jwt: 4.0.0
passport-local: 1.0.0
@@ -115,13 +61,9 @@ dependencies:
readable-stream-clone: 0.0.7
redis: 4.3.1
sharp: 0.31.1
- sqlite3: 5.1.2
- tiny-secp256k1: 2.2.1
uuid: 8.3.2
web-push: 3.5.0
- wretch: 1.7.10
ws: 7.5.9
- zeromq: 6.0.0-beta.6
devDependencies:
prettier: 1.19.1
@@ -235,11 +177,6 @@ packages:
- utf-8-validate
dev: false
- /@gar/promisify/1.1.3:
- resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
- dev: false
- optional: true
-
/@mapbox/node-pre-gyp/1.0.10:
resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==}
hasBin: true
@@ -258,23 +195,6 @@ packages:
- supports-color
dev: false
- /@npmcli/fs/1.1.1:
- resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==}
- dependencies:
- '@gar/promisify': 1.1.3
- semver: 7.3.8
- dev: false
- optional: true
-
- /@npmcli/move-file/1.1.2:
- resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==}
- engines: {node: '>=10'}
- dependencies:
- mkdirp: 1.0.4
- rimraf: 3.0.2
- dev: false
- optional: true
-
/@otplib/core/12.0.1:
resolution: {integrity: sha512-4sGntwbA/AC+SbPhbsziRiD+jNDdIzsZ3JUyfZwjtKyc/wufl1pnSIaG4Uqx8ymPagujub0o92kgBnB89cuAMA==}
dev: false
@@ -357,131 +277,36 @@ packages:
'@redis/client': 1.3.0
dev: false
- /@sequelize/core/7.0.0-alpha.10_qwzqhxtweawy7vupwb2a75td54:
- resolution: {integrity: sha512-uikpWaCiIaijsgoa9cH+3jCQl8r+FaQPhoE8AOJYvPwxOx52E1JZnRPMXNnlpbFy3Xu0qekrc5LBJq7IR8UB0Q==}
- engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
- peerDependencies:
- ibm_db: '*'
- mariadb: '*'
- mysql2: '*'
- odbc: '*'
- pg: '*'
- pg-hstore: '*'
- snowflake-sdk: '*'
- sqlite3: '*'
- tedious: '*'
- peerDependenciesMeta:
- ibm_db:
- optional: true
- mariadb:
- optional: true
- mysql2:
- optional: true
- odbc:
- optional: true
- pg:
- optional: true
- pg-hstore:
- optional: true
- snowflake-sdk:
- optional: true
- sqlite3:
- optional: true
- tedious:
- optional: true
+ /@sindresorhus/is/5.3.0:
+ resolution: {integrity: sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==}
+ engines: {node: '>=14.16'}
+ dev: false
+
+ /@szmarczak/http-timer/5.0.1:
+ resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==}
+ engines: {node: '>=14.16'}
dependencies:
- '@types/debug': 4.1.7
- debug: 4.3.4
- dottie: 2.0.2
- inflection: 1.13.4
- lodash: 4.17.21
- mariadb: 2.5.6
- moment: 2.29.4
- moment-timezone: 0.5.37
- mysql2: 2.3.3
- pg-connection-string: 2.5.0
- retry-as-promised: 5.0.0
- semver: 7.3.8
- sequelize-pool: 7.1.0
- sqlite3: 5.1.2
- toposort-class: 1.0.1
- uuid: 8.3.2
- validator: 13.7.0
- wkx: 0.5.0
- transitivePeerDependencies:
- - supports-color
+ defer-to-connect: 2.0.1
dev: false
/@tokenizer/token/0.3.0:
resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
dev: false
- /@tootallnate/once/1.1.2:
- resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
- engines: {node: '>= 6'}
- dev: false
- optional: true
-
/@types/bn.js/4.11.6:
resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==}
dependencies:
'@types/node': 18.8.5
dev: false
- /@types/debug/4.1.7:
- resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==}
- dependencies:
- '@types/ms': 0.7.31
- dev: false
-
- /@types/geojson/7946.0.10:
- resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==}
- dev: false
-
- /@types/ms/0.7.31:
- resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
- dev: false
-
- /@types/node/10.12.18:
- resolution: {integrity: sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==}
- dev: false
-
- /@types/node/11.11.6:
- resolution: {integrity: sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==}
- dev: false
-
- /@types/node/13.13.52:
- resolution: {integrity: sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==}
- dev: false
-
- /@types/node/17.0.45:
- resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
+ /@types/http-cache-semantics/4.0.1:
+ resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==}
dev: false
/@types/node/18.8.5:
resolution: {integrity: sha512-Bq7G3AErwe5A/Zki5fdD3O6+0zDChhg671NfPjtIcbtzDNZTv4NPKMRFr7gtYPG7y+B8uTiNK4Ngd9T0FTar6Q==}
dev: false
- /@types/randombytes/2.0.0:
- resolution: {integrity: sha512-bz8PhAVlwN72vqefzxa14DKNT8jK/mV66CSjwdVQM/k3Th3EPKfUtdMniwZgMedQTFuywAsfjnZsg+pEnltaMA==}
- dependencies:
- '@types/node': 18.8.5
- dev: false
-
- /@types/wif/2.0.2:
- resolution: {integrity: sha512-IiIuBeJzlh4LWJ7kVTrX0nwB60OG0vvGTaWC/SgSbVFw7uYUTF6gEuvDZ1goWkeirekJDD58Y8g7NljQh2fNkA==}
- dependencies:
- '@types/node': 18.8.5
- dev: false
-
- /@vulpemventures/secp256k1-zkp/2.1.0:
- resolution: {integrity: sha512-86EGAkPqEwy5KKeC8Ow8+fMhSiFtorvIQQ9yhTwwHqT0UdUVOW/Fu2ZDoooQK5KAQbyISBB+vf0jK3eYH+Dlqw==}
- engines: {node: '>=12.0.0'}
- dependencies:
- '@types/node': 13.13.52
- long: 4.0.0
- dev: false
-
/abbrev/1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
dev: false
@@ -505,20 +330,6 @@ packages:
negotiator: 0.6.3
dev: false
- /agent-base/4.2.1:
- resolution: {integrity: sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==}
- engines: {node: '>= 4.0.0'}
- dependencies:
- es6-promisify: 5.0.0
- dev: false
-
- /agent-base/4.3.0:
- resolution: {integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==}
- engines: {node: '>= 4.0.0'}
- dependencies:
- es6-promisify: 5.0.0
- dev: false
-
/agent-base/6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
@@ -528,27 +339,6 @@ packages:
- supports-color
dev: false
- /agentkeepalive/4.2.1:
- resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==}
- engines: {node: '>= 8.0.0'}
- dependencies:
- debug: 4.3.4
- depd: 1.1.2
- humanize-ms: 1.2.1
- transitivePeerDependencies:
- - supports-color
- dev: false
- optional: true
-
- /aggregate-error/3.1.0:
- resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
- engines: {node: '>=8'}
- dependencies:
- clean-stack: 2.2.0
- indent-string: 4.0.0
- dev: false
- optional: true
-
/ajv-formats/2.1.1:
resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==}
peerDependenciesMeta:
@@ -603,15 +393,6 @@ packages:
readable-stream: 3.6.0
dev: false
- /are-we-there-yet/3.0.1:
- resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- delegates: 1.0.0
- readable-stream: 3.6.0
- dev: false
- optional: true
-
/args/5.0.3:
resolution: {integrity: sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==}
engines: {node: '>= 6.0.0'}
@@ -635,25 +416,6 @@ packages:
safer-buffer: 2.1.2
dev: false
- /ast-types/0.14.2:
- resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==}
- engines: {node: '>=4'}
- dependencies:
- tslib: 2.4.0
- dev: false
-
- /async-mutex/0.2.6:
- resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==}
- dependencies:
- tslib: 2.4.0
- dev: false
-
- /async/2.6.4:
- resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==}
- dependencies:
- lodash: 4.17.21
- dev: false
-
/async/3.2.3:
resolution: {integrity: sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==}
dev: false
@@ -662,10 +424,6 @@ packages:
resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==}
dev: false
- /asynckit/0.4.0:
- resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
- dev: false
-
/atomic-sleep/1.0.0:
resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
engines: {node: '>=8.0.0'}
@@ -681,14 +439,6 @@ packages:
- supports-color
dev: false
- /axios/0.21.4:
- resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
- dependencies:
- follow-redirects: 1.15.2
- transitivePeerDependencies:
- - debug
- dev: false
-
/axios/0.25.0:
resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==}
dependencies:
@@ -731,10 +481,6 @@ packages:
resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==}
dev: false
- /bignumber.js/9.0.0:
- resolution: {integrity: sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==}
- dev: false
-
/bignumber.js/9.0.2:
resolution: {integrity: sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw==}
dev: false
@@ -744,54 +490,11 @@ packages:
engines: {node: '>=8'}
dev: false
- /bindings/1.5.0:
- resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
- dependencies:
- file-uri-to-path: 1.0.0
- dev: false
-
- /bip174-liquid/1.0.3:
- resolution: {integrity: sha512-e69sC0Cq2tBJuhG2+wieXv40DN13YBR/wbIjZp4Mqwpar5vQm8Ldqijdd6N33XG7LtfvQi/zKm5fSzdPY/9mgw==}
- engines: {node: '>=8.0.0'}
- dev: false
-
/bip174/2.1.0:
resolution: {integrity: sha512-lkc0XyiX9E9KiVAS1ZiOqK1xfiwvf4FXDDdkDq5crcDzOq+xGytY+14qCsqz7kCiy8rpN1CRNfacRhf9G3JNSA==}
engines: {node: '>=8.0.0'}
dev: false
- /bip32/2.0.6:
- resolution: {integrity: sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==}
- engines: {node: '>=6.0.0'}
- dependencies:
- '@types/node': 10.12.18
- bs58check: 2.1.2
- create-hash: 1.2.0
- create-hmac: 1.1.7
- tiny-secp256k1: 1.1.6
- typeforce: 1.18.0
- wif: 2.0.6
- dev: false
-
- /bip39/3.0.4:
- resolution: {integrity: sha512-YZKQlb752TrUWqHWj7XAwCSjYEgGAk+/Aas3V7NyjQeZYsztO8JnQUaCWhcnL4T+jL8nvB8typ2jRPzTlgugNw==}
- dependencies:
- '@types/node': 11.11.6
- create-hash: 1.2.0
- pbkdf2: 3.1.2
- randombytes: 2.1.0
- dev: false
-
- /bip66/1.1.5:
- resolution: {integrity: sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==}
- dependencies:
- safe-buffer: 5.2.1
- dev: false
-
- /bitcoin-ops/1.4.1:
- resolution: {integrity: sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==}
- dev: false
-
/bitcoinjs-lib/6.0.2:
resolution: {integrity: sha512-I994pGt9cL5s5OA6mkv1e8IuYcsKN2ORXnWbkqAXLNGvEnOHBhKBSvCjFl7YC2uVoJnfr/iwq7JMrq575SYO5w==}
engines: {node: '>=8.0.0'}
@@ -814,35 +517,10 @@ packages:
readable-stream: 3.6.0
dev: false
- /blech32/1.1.2:
- resolution: {integrity: sha512-C5qxzoF9KyX88X8Zz18cZ6BOeL0n5/Eg/cDot1frntkArRMwg1djNim5wA6QFWwu0lJ1LN8iiRMN4Lp2kZzdfA==}
- engines: {node: '>=10'}
- dependencies:
- long: 4.0.0
- dev: false
-
/bn.js/4.12.0:
resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==}
dev: false
- /body-parser/1.19.0:
- resolution: {integrity: sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==}
- engines: {node: '>= 0.8'}
- dependencies:
- 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.18
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/body-parser/1.20.0:
resolution: {integrity: sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -863,26 +541,6 @@ packages:
- supports-color
dev: false
- /body-parser/1.20.1:
- resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==}
- engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
- dependencies:
- bytes: 3.1.2
- content-type: 1.0.4
- debug: 2.6.9
- depd: 2.0.0
- destroy: 1.2.0
- http-errors: 2.0.0
- iconv-lite: 0.4.24
- on-finished: 2.4.1
- qs: 6.11.0
- raw-body: 2.5.1
- type-is: 1.6.18
- unpipe: 1.0.0
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/bolt11/1.3.4:
resolution: {integrity: sha512-x4lHDv0oid13lGlZU7cl/5gx9nRwjB2vgK/uB3c50802Wh+9WjWQMwzD2PCETHylUijx2iBAqUQYbx3ZgwF06Q==}
dependencies:
@@ -896,19 +554,6 @@ packages:
secp256k1: 4.0.3
dev: false
- /bolt11/1.4.0:
- resolution: {integrity: sha512-TeGIOpFNrvNA1XGvwBr+lYmzKfoJeyMRt7nsGmIci+5gbmSz7s46jwKLNYXH3IoxV7fjmYUEUu2NM19n9w0msg==}
- dependencies:
- '@types/bn.js': 4.11.6
- bech32: 1.1.4
- bitcoinjs-lib: 6.0.2
- bn.js: 4.12.0
- create-hash: 1.2.0
- lodash: 4.17.21
- safe-buffer: 5.2.1
- secp256k1: 4.0.3
- dev: false
-
/brace-expansion/1.1.11:
resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
dependencies:
@@ -951,10 +596,6 @@ packages:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
dev: false
- /buffer-reverse/1.0.1:
- resolution: {integrity: sha512-M87YIUBsZ6N924W57vDwT/aOu8hw7ZgdByz6ijksLjmHJELBASmYTTlNHRgjE+pTsT9oJXGaDSgqqwfdHotDUg==}
- dev: false
-
/buffer/5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
dependencies:
@@ -969,47 +610,28 @@ packages:
ieee754: 1.2.1
dev: false
- /bytes/3.0.0:
- resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==}
- engines: {node: '>= 0.8'}
- dev: false
-
- /bytes/3.1.0:
- resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==}
- engines: {node: '>= 0.8'}
- dev: false
-
/bytes/3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
dev: false
- /cacache/15.3.0:
- resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==}
- engines: {node: '>= 10'}
+ /cacheable-lookup/7.0.0:
+ resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==}
+ engines: {node: '>=14.16'}
+ dev: false
+
+ /cacheable-request/10.2.3:
+ resolution: {integrity: sha512-6BehRBOs7iurNjAYN9iPazTwFDaMQavJO8W1MEm3s2pH8q/tkPTtLDRUZaweWK87WFGf2Y5wLAlaCJlR5kOz3w==}
+ engines: {node: '>=14.16'}
dependencies:
- '@npmcli/fs': 1.1.1
- '@npmcli/move-file': 1.1.2
- chownr: 2.0.0
- fs-minipass: 2.1.0
- glob: 7.2.3
- infer-owner: 1.0.4
- lru-cache: 6.0.0
- minipass: 3.3.4
- minipass-collect: 1.0.2
- minipass-flush: 1.0.5
- minipass-pipeline: 1.2.4
- mkdirp: 1.0.4
- p-map: 4.0.0
- promise-inflight: 1.0.1
- rimraf: 3.0.2
- ssri: 8.0.1
- tar: 6.1.11
- unique-filename: 1.1.1
- transitivePeerDependencies:
- - bluebird
+ '@types/http-cache-semantics': 4.0.1
+ get-stream: 6.0.1
+ http-cache-semantics: 4.1.0
+ keyv: 4.5.2
+ mimic-response: 4.0.0
+ normalize-url: 8.0.0
+ responselike: 3.0.0
dev: false
- optional: true
/call-bind/1.0.2:
resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
@@ -1063,12 +685,6 @@ packages:
safe-buffer: 5.2.1
dev: false
- /clean-stack/2.2.0:
- resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==}
- engines: {node: '>=6'}
- dev: false
- optional: true
-
/clightning-client/0.1.4:
resolution: {integrity: sha512-M5UclkZcKvh15CmZOpbM0p6Dyua3ixRlgp7EP5IhL9jYWW8AL7qpROWLQFqSW2ANy48W1vGlw9igSyWV2A/iqw==}
dependencies:
@@ -1083,15 +699,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
- /co/4.6.0:
- resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==}
- engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'}
- dev: false
-
- /coinselect/3.1.13:
- resolution: {integrity: sha512-iJOrKH/7N9gX0jRkxgOHuGjvzvoxUMSeylDhH1sHn+CjLjdin5R0Hz2WEBu/jrZV5OrHcm+6DMzxwu9zb5mSZg==}
- dev: false
-
/color-convert/1.9.3:
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
dependencies:
@@ -1137,45 +744,11 @@ packages:
resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==}
dev: false
- /combined-stream/1.0.8:
- resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
- engines: {node: '>= 0.8'}
- dependencies:
- delayed-stream: 1.0.0
- dev: false
-
/commander/9.3.0:
resolution: {integrity: sha512-hv95iU5uXPbK83mjrJKuZyFM/LBAoCV/XhVGkS5Je6tl7sxr6A0ITMw5WoRV46/UaJ46Nllm3Xt7IaJhXTIkzw==}
engines: {node: ^12.20.0 || >=14}
dev: false
- /commander/9.4.1:
- resolution: {integrity: sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==}
- engines: {node: ^12.20.0 || >=14}
- dev: false
-
- /compressible/2.0.18:
- resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==}
- engines: {node: '>= 0.6'}
- dependencies:
- mime-db: 1.52.0
- dev: false
-
- /compression/1.7.4:
- resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- accepts: 1.3.8
- bytes: 3.0.0
- compressible: 2.0.18
- debug: 2.6.9
- on-headers: 1.0.2
- safe-buffer: 5.1.2
- vary: 1.1.2
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/concat-map/0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: false
@@ -1184,13 +757,6 @@ packages:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
dev: false
- /content-disposition/0.5.3:
- resolution: {integrity: sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==}
- engines: {node: '>= 0.6'}
- dependencies:
- safe-buffer: 5.1.2
- dev: false
-
/content-disposition/0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@@ -1203,50 +769,15 @@ packages:
engines: {node: '>= 0.6'}
dev: false
- /cookie-parser/1.4.6:
- resolution: {integrity: sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- cookie: 0.4.1
- cookie-signature: 1.0.6
- dev: false
-
/cookie-signature/1.0.6:
resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==}
dev: false
- /cookie/0.4.0:
- resolution: {integrity: sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==}
- engines: {node: '>= 0.6'}
- dev: false
-
- /cookie/0.4.1:
- resolution: {integrity: sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==}
- engines: {node: '>= 0.6'}
- dev: false
-
- /cookie/0.4.2:
- resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==}
- engines: {node: '>= 0.6'}
- dev: false
-
/cookie/0.5.0:
resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==}
engines: {node: '>= 0.6'}
dev: false
- /core-util-is/1.0.3:
- resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
- dev: false
-
- /cors/2.8.5:
- resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
- engines: {node: '>= 0.10'}
- dependencies:
- object-assign: 4.1.1
- vary: 1.1.2
- dev: false
-
/create-hash/1.2.0:
resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==}
dependencies:
@@ -1257,21 +788,6 @@ packages:
sha.js: 2.4.11
dev: false
- /create-hmac/1.1.7:
- resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==}
- dependencies:
- cipher-base: 1.0.4
- create-hash: 1.2.0
- inherits: 2.0.4
- ripemd160: 2.0.2
- safe-buffer: 5.2.1
- sha.js: 2.4.11
- dev: false
-
- /data-uri-to-buffer/1.2.0:
- resolution: {integrity: sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==}
- dev: false
-
/date-fns/2.29.3:
resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==}
engines: {node: '>=0.11'}
@@ -1292,28 +808,6 @@ packages:
ms: 2.0.0
dev: false
- /debug/3.1.0:
- resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.0.0
- dev: false
-
- /debug/3.2.7:
- resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
- peerDependencies:
- supports-color: '*'
- peerDependenciesMeta:
- supports-color:
- optional: true
- dependencies:
- ms: 2.1.3
- dev: false
-
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
@@ -1355,46 +849,20 @@ packages:
engines: {node: '>=4.0.0'}
dev: false
- /deep-is/0.1.4:
- resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
- dev: false
-
- /degenerator/1.0.4:
- resolution: {integrity: sha512-EMAC+riLSC64jKfOs1jp8J7M4ZXstUUwTdwFBEv6HOzL/Ae+eAzMKEK0nJnpof2fnw9IOjmE6u6qXFejVyk8AA==}
- dependencies:
- ast-types: 0.14.2
- escodegen: 1.14.3
- esprima: 3.1.3
- dev: false
-
- /delayed-stream/1.0.0:
- resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
- engines: {node: '>=0.4.0'}
+ /defer-to-connect/2.0.1:
+ resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==}
+ engines: {node: '>=10'}
dev: false
/delegates/1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
dev: false
- /denque/2.1.0:
- resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
- engines: {node: '>=0.10'}
- dev: false
-
- /depd/1.1.2:
- resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==}
- engines: {node: '>= 0.6'}
- dev: false
-
/depd/2.0.0:
resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
engines: {node: '>= 0.8'}
dev: false
- /destroy/1.0.4:
- resolution: {integrity: sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==}
- dev: false
-
/destroy/1.2.0:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -1405,10 +873,6 @@ packages:
engines: {node: '>=8'}
dev: false
- /dottie/2.0.2:
- resolution: {integrity: sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==}
- dev: false
-
/duplexify/4.1.2:
resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==}
dependencies:
@@ -1424,15 +888,6 @@ packages:
safe-buffer: 5.2.1
dev: false
- /ecpair/2.1.0:
- resolution: {integrity: sha512-cL/mh3MtJutFOvFc27GPZE2pWL3a3k4YvzUWEOvilnfZVlH3Jwgx/7d6tlD7/75tNk8TG2m+7Kgtz0SI1tWcqw==}
- engines: {node: '>=8.0.0'}
- dependencies:
- randombytes: 2.1.0
- typeforce: 1.18.0
- wif: 2.0.6
- dev: false
-
/ee-first/1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
dev: false
@@ -1458,52 +913,18 @@ packages:
engines: {node: '>= 0.8'}
dev: false
- /encoding/0.1.13:
- resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
- requiresBuild: true
- dependencies:
- iconv-lite: 0.6.3
- dev: false
- optional: true
-
/end-of-stream/1.4.4:
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
dependencies:
once: 1.4.0
dev: false
- /env-paths/2.2.1:
- resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
- engines: {node: '>=6'}
- dev: false
- optional: true
-
- /err-code/2.0.3:
- resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
- dev: false
- optional: true
-
/error/7.2.1:
resolution: {integrity: sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==}
dependencies:
string-template: 0.2.1
dev: false
- /es6-promise/4.2.8:
- resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==}
- dev: false
-
- /es6-promisify/5.0.0:
- resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==}
- dependencies:
- es6-promise: 4.2.8
- dev: false
-
- /escalade/3.1.1:
- resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
- engines: {node: '>=6'}
- dev: false
-
/escape-html/1.0.3:
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
dev: false
@@ -1513,46 +934,6 @@ packages:
engines: {node: '>=0.8.0'}
dev: false
- /escodegen/1.14.3:
- resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==}
- engines: {node: '>=4.0'}
- hasBin: true
- dependencies:
- esprima: 4.0.1
- estraverse: 4.3.0
- esutils: 2.0.3
- optionator: 0.8.3
- optionalDependencies:
- source-map: 0.6.1
- dev: false
-
- /esm/3.2.25:
- resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==}
- engines: {node: '>=6'}
- dev: false
-
- /esprima/3.1.3:
- resolution: {integrity: sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==}
- engines: {node: '>=4'}
- hasBin: true
- dev: false
-
- /esprima/4.0.1:
- resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
- engines: {node: '>=4'}
- hasBin: true
- dev: false
-
- /estraverse/4.3.0:
- resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==}
- engines: {node: '>=4.0'}
- dev: false
-
- /esutils/2.0.3:
- resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
- engines: {node: '>=0.10.0'}
- dev: false
-
/etag/1.8.1:
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
engines: {node: '>= 0.6'}
@@ -1563,10 +944,6 @@ packages:
engines: {node: '>=6'}
dev: false
- /eventemitter3/4.0.7:
- resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
- dev: false
-
/events/3.3.0:
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
engines: {node: '>=0.8.x'}
@@ -1577,10 +954,6 @@ packages:
engines: {node: '>=6'}
dev: false
- /express-async-handler/1.2.0:
- resolution: {integrity: sha512-rCSVtPXRmQSW8rmik/AIb2P0op6l7r1fMW538yyvTMltCO4xQEWMmobfrIxN2V1/mVrgxB8Az3reYF6yUZw37w==}
- dev: false
-
/express-handlebars/6.0.3:
resolution: {integrity: sha512-cG6/CeriAhAYKC9+VivXtj41+HNDB6xnigwzcXv/m9BBtijR2Yg5I5VWsK6nPc1+E06FIS23nGfr2COUv8sG3A==}
engines: {node: '>=v12.22.9'}
@@ -1590,66 +963,6 @@ packages:
handlebars: 4.7.7
dev: false
- /express-pino-logger/6.0.0:
- resolution: {integrity: sha512-YjBnalqgsNylRnWEpQGf8YzBP54stpoqX/o+SnpGr04OB7dRIQlsC1qvutFOyRjhLhXIWCe43pYJcjp9zM1Ccg==}
- dependencies:
- pino-http: 5.8.0
- dev: false
-
- /express-session/1.17.3:
- resolution: {integrity: sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- cookie: 0.4.2
- cookie-signature: 1.0.6
- debug: 2.6.9
- depd: 2.0.0
- on-headers: 1.0.2
- parseurl: 1.3.3
- safe-buffer: 5.2.1
- uid-safe: 2.1.5
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /express/4.17.1:
- resolution: {integrity: sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==}
- engines: {node: '>= 0.10.0'}
- dependencies:
- accepts: 1.3.8
- 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.7
- 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
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/express/4.18.1:
resolution: {integrity: sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==}
engines: {node: '>= 0.10.0'}
@@ -1689,10 +1002,6 @@ packages:
- supports-color
dev: false
- /extend/3.0.2:
- resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
- dev: false
-
/fast-decode-uri-component/1.0.1:
resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==}
dev: false
@@ -1712,10 +1021,6 @@ packages:
rfdc: 1.3.0
dev: false
- /fast-levenshtein/2.0.6:
- resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
- dev: false
-
/fast-querystring/1.0.0:
resolution: {integrity: sha512-3LQi62IhQoDlmt4ULCYmh17vRO2EtS7hTSsG4WwoKWgV7GLMKBOecEh+aiavASnLx8I2y89OD33AGLo0ccRhzA==}
dependencies:
@@ -1735,12 +1040,6 @@ packages:
resolution: {integrity: sha512-qKRta6N7BWEFVlyonVY/V+BMLgFqktCUV0QjT259ekAIlbVrMaFnFLxJ4s/JPl4tou56S1BzPufI60bLe29fHA==}
dev: false
- /fast-url-parser/1.1.3:
- resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==}
- dependencies:
- punycode: 1.4.1
- dev: false
-
/fastify-plugin/3.0.1:
resolution: {integrity: sha512-qKcDXmuZadJqdTm6vlCqioEbyewF60b/0LOFCcYN1B6BIZGlYJumWWOYs70SFYLDAH4YqdE1cxH/RKMG7rFxgA==}
dev: false
@@ -1785,10 +1084,6 @@ packages:
token-types: 5.0.1
dev: false
- /file-uri-to-path/1.0.0:
- resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
- dev: false
-
/fill-range/7.0.1:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
@@ -1801,21 +1096,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
- /finalhandler/1.1.2:
- resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==}
- engines: {node: '>= 0.8'}
- dependencies:
- 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
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/finalhandler/1.2.0:
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
engines: {node: '>= 0.8'}
@@ -1840,10 +1120,6 @@ packages:
safe-regex2: 2.0.0
dev: false
- /flatstr/1.0.12:
- resolution: {integrity: sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==}
- dev: false
-
/follow-redirects/1.15.2:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
@@ -1854,13 +1130,9 @@ packages:
optional: true
dev: false
- /form-data/2.5.1:
- resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==}
- engines: {node: '>= 0.12'}
- dependencies:
- asynckit: 0.4.0
- combined-stream: 1.0.8
- mime-types: 2.1.35
+ /form-data-encoder/2.1.4:
+ resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==}
+ engines: {node: '>= 14.17'}
dev: false
/forwarded/0.2.0:
@@ -1896,14 +1168,6 @@ packages:
dev: false
optional: true
- /ftp/0.3.10:
- resolution: {integrity: sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==}
- engines: {node: '>=0.8.0'}
- dependencies:
- readable-stream: 1.1.14
- xregexp: 2.0.0
- dev: false
-
/function-bind/1.1.1:
resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
dev: false
@@ -1923,27 +1187,6 @@ packages:
wide-align: 1.1.5
dev: false
- /gauge/4.0.4:
- resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- aproba: 2.0.0
- color-support: 1.1.3
- console-control-strings: 1.1.0
- has-unicode: 2.0.1
- signal-exit: 3.0.7
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wide-align: 1.1.5
- dev: false
- optional: true
-
- /generate-function/2.3.1:
- resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
- dependencies:
- is-property: 1.0.2
- dev: false
-
/generic-pool/3.8.2:
resolution: {integrity: sha512-nGToKy6p3PAbYQ7p1UlWl6vSPwfwU6TMSWK7TTu+WUY4ZjyZQGniGGt2oNVvyNSpyZYSB43zMXVLcBm08MTMkg==}
engines: {node: '>= 4'}
@@ -1957,26 +1200,9 @@ packages:
has-symbols: 1.0.3
dev: false
- /get-package-type/0.1.0:
- resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==}
- engines: {node: '>=8.0.0'}
- dev: false
-
- /get-uri/2.0.4:
- resolution: {integrity: sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==}
- dependencies:
- data-uri-to-buffer: 1.2.0
- debug: 2.6.9
- extend: 3.0.2
- file-uri-to-path: 1.0.0
- ftp: 0.3.10
- readable-stream: 2.3.7
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /getopts/2.3.0:
- resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==}
+ /get-stream/6.0.1:
+ resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
+ engines: {node: '>=10'}
dev: false
/github-from-package/0.0.0:
@@ -2012,6 +1238,23 @@ packages:
once: 1.4.0
dev: false
+ /got/12.5.3:
+ resolution: {integrity: sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==}
+ engines: {node: '>=14.16'}
+ dependencies:
+ '@sindresorhus/is': 5.3.0
+ '@szmarczak/http-timer': 5.0.1
+ cacheable-lookup: 7.0.0
+ cacheable-request: 10.2.3
+ decompress-response: 6.0.0
+ form-data-encoder: 2.1.4
+ get-stream: 6.0.1
+ http2-wrapper: 2.2.0
+ lowercase-keys: 3.0.0
+ p-cancelable: 3.0.0
+ responselike: 3.0.0
+ dev: false
+
/graceful-fs/4.2.10:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
dev: false
@@ -2082,29 +1325,6 @@ packages:
/http-cache-semantics/4.1.0:
resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==}
dev: false
- optional: true
-
- /http-errors/1.7.2:
- resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==}
- engines: {node: '>= 0.6'}
- dependencies:
- depd: 1.1.2
- inherits: 2.0.3
- setprototypeof: 1.1.1
- statuses: 1.5.0
- toidentifier: 1.0.0
- dev: false
-
- /http-errors/1.7.3:
- resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==}
- engines: {node: '>= 0.6'}
- dependencies:
- depd: 1.1.2
- inherits: 2.0.4
- setprototypeof: 1.1.1
- statuses: 1.5.0
- toidentifier: 1.0.0
- dev: false
/http-errors/2.0.0:
resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
@@ -2117,49 +1337,12 @@ packages:
toidentifier: 1.0.1
dev: false
- /http-proxy-agent/2.1.0:
- resolution: {integrity: sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==}
- engines: {node: '>= 4.5.0'}
- dependencies:
- agent-base: 4.3.0
- debug: 3.1.0
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /http-proxy-agent/4.0.1:
- resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==}
- engines: {node: '>= 6'}
+ /http2-wrapper/2.2.0:
+ resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==}
+ engines: {node: '>=10.19.0'}
dependencies:
- '@tootallnate/once': 1.1.2
- agent-base: 6.0.2
- debug: 4.3.4
- transitivePeerDependencies:
- - supports-color
- dev: false
- optional: true
-
- /http-proxy-middleware/0.20.0:
- resolution: {integrity: sha512-dNJAk71nEJhPiAczQH9hGvE/MT9kEs+zn2Dh+Hi94PGZe1GluQirC7mw5rdREUtWx6qGS1Gu0bZd4qEAg+REgw==}
- engines: {node: '>=8.0.0'}
- dependencies:
- http-proxy: 1.18.1
- is-glob: 4.0.3
- lodash: 4.17.21
- micromatch: 4.0.5
- transitivePeerDependencies:
- - debug
- dev: false
-
- /http-proxy/1.18.1:
- resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==}
- engines: {node: '>=8.0.0'}
- dependencies:
- eventemitter3: 4.0.7
- follow-redirects: 1.15.2
- requires-port: 1.0.0
- transitivePeerDependencies:
- - debug
+ quick-lru: 5.1.1
+ resolve-alpn: 1.2.1
dev: false
/http_ece/1.1.0:
@@ -2169,16 +1352,6 @@ packages:
urlsafe-base64: 1.0.0
dev: false
- /https-proxy-agent/3.0.1:
- resolution: {integrity: sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==}
- engines: {node: '>= 4.5.0'}
- dependencies:
- agent-base: 4.3.0
- debug: 3.2.7
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/https-proxy-agent/5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
@@ -2189,13 +1362,6 @@ packages:
- supports-color
dev: false
- /humanize-ms/1.2.1:
- resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
- dependencies:
- ms: 2.1.3
- dev: false
- optional: true
-
/iconv-lite/0.4.24:
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
engines: {node: '>=0.10.0'}
@@ -2203,13 +1369,6 @@ packages:
safer-buffer: 2.1.2
dev: false
- /iconv-lite/0.6.3:
- resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
- engines: {node: '>=0.10.0'}
- dependencies:
- safer-buffer: 2.1.2
- dev: false
-
/ieee754/1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: false
@@ -2218,46 +1377,6 @@ packages:
resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
dev: false
- /imap/0.8.19:
- resolution: {integrity: sha512-z5DxEA1uRnZG73UcPA4ES5NSCGnPuuouUx43OPX7KZx1yzq3N8/vx2mtXEShT5inxB3pRgnfG1hijfu7XN2YMw==}
- engines: {node: '>=0.8.0'}
- dependencies:
- readable-stream: 1.1.14
- utf7: 1.0.2
- dev: false
-
- /imurmurhash/0.1.4:
- resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
- engines: {node: '>=0.8.19'}
- dev: false
- optional: true
-
- /indent-string/4.0.0:
- resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==}
- engines: {node: '>=8'}
- dev: false
- optional: true
-
- /infer-owner/1.0.4:
- resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==}
- dev: false
- optional: true
-
- /inflection/1.12.0:
- resolution: {integrity: sha512-lRy4DxuIFWXlJU7ed8UiTJOSTqStqYdEb4CEbtXfNbkdj3nH1L+reUWiE10VWcJS2yR7tge8Z74pJjtBjNwj0w==}
- engines: {'0': node >= 0.4.0}
- dev: false
-
- /inflection/1.13.4:
- resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==}
- engines: {'0': node >= 0.4.0}
- dev: false
-
- /inflection/1.3.8:
- resolution: {integrity: sha512-xRvG6XhAkbneGO5BXP0uKyGkzmZ2bBbrFkx4ZVNx2TmsECbiq/pJapbbx/NECh+E85IfZwW5+IeVNJfkQgavag==}
- engines: {'0': node >= 0.4.0}
- dev: false
-
/inflight/1.0.6:
resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
dependencies:
@@ -2265,10 +1384,6 @@ packages:
wrappy: 1.0.2
dev: false
- /inherits/2.0.3:
- resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==}
- dev: false
-
/inherits/2.0.4:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: false
@@ -2277,19 +1392,6 @@ packages:
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
dev: false
- /interpret/2.2.0:
- resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==}
- engines: {node: '>= 0.10'}
- dev: false
-
- /ip/1.1.5:
- resolution: {integrity: sha512-rBtCAQAJm8A110nbwn6YdveUnuZH3WrC36IwkRXxDnq53JvXA2NVQvB7IHyKomxK1MJ4VDNw3UtFDdXQ+AvLYA==}
- dev: false
-
- /ip/1.1.8:
- resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==}
- dev: false
-
/ip/2.0.0:
resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==}
dev: false
@@ -2310,12 +1412,6 @@ packages:
binary-extensions: 2.2.0
dev: false
- /is-core-module/2.10.0:
- resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==}
- dependencies:
- has: 1.0.3
- dev: false
-
/is-extglob/2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@@ -2333,43 +1429,20 @@ packages:
is-extglob: 2.1.1
dev: false
- /is-lambda/1.0.1:
- resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
- dev: false
- optional: true
-
/is-number/7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
dev: false
- /is-property/1.0.2:
- resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==}
- dev: false
-
- /is-stream/1.1.0:
- resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==}
- engines: {node: '>=0.10.0'}
- dev: false
-
- /isarray/0.0.1:
- resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
- dev: false
-
- /isarray/1.0.0:
- resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
- dev: false
-
- /isexe/2.0.0:
- resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
- dev: false
- optional: true
-
/joycon/3.1.1:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
dev: false
+ /json-buffer/3.0.1:
+ resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
+ dev: false
+
/json-schema-traverse/1.0.0:
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
dev: false
@@ -2420,53 +1493,10 @@ packages:
safe-buffer: 5.2.1
dev: false
- /knex/2.3.0_miwdxfk6g3dfg4gj6dnwby2onu:
- resolution: {integrity: sha512-WMizPaq9wRMkfnwKXKXgBZeZFOSHGdtoSz5SaLAVNs3WRDfawt9O89T4XyH52PETxjV8/kRk0Yf+8WBEP/zbYw==}
- engines: {node: '>=12'}
- hasBin: true
- peerDependencies:
- better-sqlite3: '*'
- mysql: '*'
- mysql2: '*'
- pg: '*'
- pg-native: '*'
- sqlite3: '*'
- tedious: '*'
- peerDependenciesMeta:
- better-sqlite3:
- optional: true
- mysql:
- optional: true
- mysql2:
- optional: true
- pg:
- optional: true
- pg-native:
- optional: true
- sqlite3:
- optional: true
- tedious:
- optional: true
+ /keyv/4.5.2:
+ resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==}
dependencies:
- colorette: 2.0.19
- commander: 9.4.1
- debug: 4.3.4
- escalade: 3.1.1
- esm: 3.2.25
- get-package-type: 0.1.0
- getopts: 2.3.0
- interpret: 2.2.0
- lodash: 4.17.21
- mysql: 2.18.1
- mysql2: 2.3.3
- pg-connection-string: 2.5.0
- rechoir: 0.8.0
- resolve-from: 5.0.0
- sqlite3: 5.1.2
- tarn: 3.0.2
- tildify: 2.0.0
- transitivePeerDependencies:
- - supports-color
+ json-buffer: 3.0.1
dev: false
/leven/2.1.0:
@@ -2474,14 +1504,6 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
- /levn/0.3.0:
- resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- prelude-ls: 1.1.2
- type-check: 0.3.2
- dev: false
-
/light-my-request/5.6.1:
resolution: {integrity: sha512-sbJnC1UBRivi9L1kICr3CESb82pNiPNB3TvtdIrZZqW0Qh8uDXvoywMmWKZlihDcmw952CMICCzM+54LDf+E+g==}
dependencies:
@@ -2502,29 +1524,6 @@ packages:
- supports-color
dev: false
- /liquidjs-lib/6.0.2-liquid.8:
- resolution: {integrity: sha512-KCtO/lXfKyZUJeZ1Mok3FQ5/viNLmKEEhGEC3iySnBakIII2rd1ijn3np16/3LzBiQhQ+tFm4Q1NYEG3YhWBTg==}
- engines: {node: '>=8.0.0'}
- dependencies:
- '@types/randombytes': 2.0.0
- '@types/wif': 2.0.2
- '@vulpemventures/secp256k1-zkp': 2.1.0
- axios: 0.21.4
- bech32: 2.0.0
- bip174-liquid: 1.0.3
- bip66: 1.1.5
- bitcoin-ops: 1.4.1
- blech32: 1.1.2
- bs58check: 2.1.2
- create-hash: 1.2.0
- ecpair: 2.1.0
- typeforce: 1.18.0
- varuint-bitcoin: 1.1.2
- wif: 2.0.6
- transitivePeerDependencies:
- - debug
- dev: false
-
/lnurl-offline/1.1.1:
resolution: {integrity: sha512-iyryv7hLS/MdDzNg6wzVgRZyA8rwjyZpn61KXHlLwr9YoDc8Vf+YXvH273fNUD+5WQC6rh+pxZN0lrNvvUnVQQ==}
dev: false
@@ -2579,25 +1578,9 @@ packages:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: false
- /long/4.0.0:
- resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==}
- dev: false
-
- /long/5.2.0:
- resolution: {integrity: sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==}
- dev: false
-
- /lru-cache/4.1.5:
- resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==}
- dependencies:
- pseudomap: 1.0.2
- yallist: 2.1.2
- dev: false
-
- /lru-cache/5.1.1:
- resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
- dependencies:
- yallist: 3.1.1
+ /lowercase-keys/3.0.0:
+ resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: false
/lru-cache/6.0.0:
@@ -2607,24 +1590,6 @@ packages:
yallist: 4.0.0
dev: false
- /mailgun-js/0.22.0:
- resolution: {integrity: sha512-a2alg5nuTZA9Psa1pSEIEsbxr1Zrmqx4VkgGCQ30xVh0kIH7Bu57AYILo+0v8QLSdXtCyLaS+KVmdCrQo0uWFA==}
- engines: {node: '>=6.0.0'}
- deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
- dependencies:
- async: 2.6.4
- debug: 4.3.4
- form-data: 2.5.1
- inflection: 1.12.0
- is-stream: 1.1.0
- path-proxy: 1.0.0
- promisify-call: 2.0.4
- proxy-agent: 3.1.1
- tsscmp: 1.0.6
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/make-dir/3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'}
@@ -2632,45 +1597,6 @@ packages:
semver: 6.3.0
dev: false
- /make-fetch-happen/9.1.0:
- resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==}
- engines: {node: '>= 10'}
- dependencies:
- agentkeepalive: 4.2.1
- cacache: 15.3.0
- http-cache-semantics: 4.1.0
- http-proxy-agent: 4.0.1
- https-proxy-agent: 5.0.1
- is-lambda: 1.0.1
- lru-cache: 6.0.0
- minipass: 3.3.4
- minipass-collect: 1.0.2
- minipass-fetch: 1.4.1
- minipass-flush: 1.0.5
- minipass-pipeline: 1.2.4
- negotiator: 0.6.3
- promise-retry: 2.0.1
- socks-proxy-agent: 6.2.1
- ssri: 8.0.1
- transitivePeerDependencies:
- - bluebird
- - supports-color
- dev: false
- optional: true
-
- /mariadb/2.5.6:
- resolution: {integrity: sha512-zBx7loYY5GzLl8Y6AKxGXfY9DUYIIdGrmEORPOK9FEu0pg5ZLBKCGJuucHwKADxTBxKY7eM4rxndqxRcnMZKIw==}
- engines: {node: '>= 10.13'}
- dependencies:
- '@types/geojson': 7946.0.10
- '@types/node': 17.0.45
- denque: 2.1.0
- iconv-lite: 0.6.3
- long: 5.2.0
- moment-timezone: 0.5.37
- please-upgrade-node: 3.2.0
- dev: false
-
/md5.js/1.3.5:
resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==}
dependencies:
@@ -2693,14 +1619,6 @@ packages:
engines: {node: '>= 0.6'}
dev: false
- /micromatch/4.0.5:
- resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
- engines: {node: '>=8.6'}
- dependencies:
- braces: 3.0.2
- picomatch: 2.3.1
- dev: false
-
/mime-db/1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
@@ -2724,6 +1642,11 @@ packages:
engines: {node: '>=10'}
dev: false
+ /mimic-response/4.0.0:
+ resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ dev: false
+
/minimalistic-assert/1.0.1:
resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==}
dev: false
@@ -2749,50 +1672,6 @@ packages:
resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==}
dev: false
- /minipass-collect/1.0.2:
- resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==}
- engines: {node: '>= 8'}
- dependencies:
- minipass: 3.3.4
- dev: false
- optional: true
-
- /minipass-fetch/1.4.1:
- resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==}
- engines: {node: '>=8'}
- dependencies:
- minipass: 3.3.4
- minipass-sized: 1.0.3
- minizlib: 2.1.2
- optionalDependencies:
- encoding: 0.1.13
- dev: false
- optional: true
-
- /minipass-flush/1.0.5:
- resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==}
- engines: {node: '>= 8'}
- dependencies:
- minipass: 3.3.4
- dev: false
- optional: true
-
- /minipass-pipeline/1.2.4:
- resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==}
- engines: {node: '>=8'}
- dependencies:
- minipass: 3.3.4
- dev: false
- optional: true
-
- /minipass-sized/1.0.3:
- resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==}
- engines: {node: '>=8'}
- dependencies:
- minipass: 3.3.4
- dev: false
- optional: true
-
/minipass/3.3.4:
resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==}
engines: {node: '>=8'}
@@ -2818,16 +1697,6 @@ packages:
hasBin: true
dev: false
- /moment-timezone/0.5.37:
- resolution: {integrity: sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==}
- dependencies:
- moment: 2.29.4
- dev: false
-
- /moment/2.29.4:
- resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==}
- dev: false
-
/mri/1.1.4:
resolution: {integrity: sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==}
engines: {node: '>=4'}
@@ -2837,10 +1706,6 @@ packages:
resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==}
dev: false
- /ms/2.1.1:
- resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==}
- dev: false
-
/ms/2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: false
@@ -2849,41 +1714,6 @@ packages:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: false
- /mysql/2.18.1:
- resolution: {integrity: sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==}
- engines: {node: '>= 0.6'}
- dependencies:
- bignumber.js: 9.0.0
- readable-stream: 2.3.7
- safe-buffer: 5.1.2
- sqlstring: 2.3.1
- dev: false
-
- /mysql2/2.3.3:
- resolution: {integrity: sha512-wxJUev6LgMSgACDkb/InIFxDprRa6T95+VEoR+xPvtngtccNH2dGjEB/fVZ8yg1gWv1510c9CvXuJHi5zUm0ZA==}
- engines: {node: '>= 8.0'}
- dependencies:
- denque: 2.1.0
- generate-function: 2.3.1
- iconv-lite: 0.6.3
- long: 4.0.0
- lru-cache: 6.0.0
- named-placeholders: 1.1.2
- seq-queue: 0.0.5
- sqlstring: 2.3.3
- dev: false
-
- /named-placeholders/1.1.2:
- resolution: {integrity: sha512-wiFWqxoLL3PGVReSZpjLVxyJ1bRqe+KKJVbr4hGs1KWfTZTQyezHFBbuKj9hsizHyGV2ne7EMjHdxEGAybD5SA==}
- engines: {node: '>=6.0.0'}
- dependencies:
- lru-cache: 4.1.5
- dev: false
-
- /nan/2.17.0:
- resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==}
- dev: false
-
/napi-build-utils/1.0.2:
resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
dev: false
@@ -2897,9 +1727,9 @@ packages:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: false
- /netmask/1.0.6:
- resolution: {integrity: sha512-3DWDqAtIiPSkBXZyYEjwebfK56nrlQfRGt642fu8RPaL+ePu750+HCMHxjJCG3iEHq/0aeMvX6KIzlv7nuhfrA==}
- engines: {node: '>= 0.4.0'}
+ /noble-secp256k1/1.2.14:
+ resolution: {integrity: sha512-GSCXyoZBUaaPwVWdYncMEmzlSUjF9J/YeEHpklYJCyg8wPuJP3NzDx0BkiwArzINkdX2HJHvUJhL6vVWPOQQcg==}
+ deprecated: Switch to namespaced @noble/secp256k1 for security and feature updates
dev: false
/node-abi/3.26.0:
@@ -2913,10 +1743,6 @@ packages:
resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==}
dev: false
- /node-addon-api/4.3.0:
- resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==}
- dev: false
-
/node-addon-api/5.0.0:
resolution: {integrity: sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==}
dev: false
@@ -2938,28 +1764,6 @@ packages:
hasBin: true
dev: false
- /node-gyp/8.4.1:
- resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==}
- engines: {node: '>= 10.12.0'}
- hasBin: true
- requiresBuild: true
- dependencies:
- env-paths: 2.2.1
- glob: 7.2.3
- graceful-fs: 4.2.10
- make-fetch-happen: 9.1.0
- nopt: 5.0.0
- npmlog: 6.0.2
- rimraf: 3.0.2
- semver: 7.3.8
- tar: 6.1.11
- which: 2.0.2
- transitivePeerDependencies:
- - bluebird
- - supports-color
- dev: false
- optional: true
-
/nodemon/2.0.20:
resolution: {integrity: sha512-Km2mWHKKY5GzRg6i1j5OxOHQtuvVsgskLfigG25yTtbyfRGn/GNvIbRyOf1PSCKJ2aT/58TiuUsuOU5UToVViw==}
engines: {node: '>=8.10.0'}
@@ -2997,6 +1801,21 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
+ /normalize-url/8.0.0:
+ resolution: {integrity: sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==}
+ engines: {node: '>=14.16'}
+ dev: false
+
+ /nostr/0.2.7:
+ resolution: {integrity: sha512-Yq5tkiCTJtohs7H7Fx+Ki83bR8b3xapdwYi17HunhW5EQfZ9rI0cIXFyihj2ZRkv/0YYvVBiCp/KIaLYt5LyfQ==}
+ dependencies:
+ noble-secp256k1: 1.2.14
+ ws: 8.9.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
/npmlog/5.0.1:
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
dependencies:
@@ -3006,17 +1825,6 @@ packages:
set-blocking: 2.0.0
dev: false
- /npmlog/6.0.2:
- resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==}
- engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
- dependencies:
- are-we-there-yet: 3.0.1
- console-control-strings: 1.1.0
- gauge: 4.0.4
- set-blocking: 2.0.0
- dev: false
- optional: true
-
/object-assign/4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@@ -3034,13 +1842,6 @@ packages:
resolution: {integrity: sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==}
dev: false
- /on-finished/2.3.0:
- resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
- engines: {node: '>= 0.8'}
- dependencies:
- ee-first: 1.1.1
- dev: false
-
/on-finished/2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
@@ -3048,29 +1849,12 @@ packages:
ee-first: 1.1.1
dev: false
- /on-headers/1.0.2:
- resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==}
- engines: {node: '>= 0.8'}
- dev: false
-
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: false
- /optionator/0.8.3:
- resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- deep-is: 0.1.4
- fast-levenshtein: 2.0.6
- levn: 0.3.0
- prelude-ls: 1.1.2
- type-check: 0.3.2
- word-wrap: 1.2.3
- dev: false
-
/otplib/12.0.1:
resolution: {integrity: sha512-xDGvUOQjop7RDgxTQ+o4pOol0/3xSZzawTiPKRrHnQWAy0WjhNs/5HdIDJCrqC4MBynmjXgULc6YfioaxZeFgg==}
dependencies:
@@ -3079,6 +1863,11 @@ packages:
'@otplib/preset-v11': 12.0.1
dev: false
+ /p-cancelable/3.0.0:
+ resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==}
+ engines: {node: '>=12.20'}
+ dev: false
+
/p-limit/3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
@@ -3086,39 +1875,6 @@ packages:
yocto-queue: 0.1.0
dev: false
- /p-map/4.0.0:
- resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==}
- engines: {node: '>=10'}
- dependencies:
- aggregate-error: 3.1.0
- dev: false
- optional: true
-
- /pac-proxy-agent/3.0.1:
- resolution: {integrity: sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ==}
- dependencies:
- agent-base: 4.3.0
- debug: 4.3.4
- get-uri: 2.0.4
- http-proxy-agent: 2.1.0
- https-proxy-agent: 3.0.1
- pac-resolver: 3.0.0
- raw-body: 2.5.1
- socks-proxy-agent: 4.0.2
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /pac-resolver/3.0.0:
- resolution: {integrity: sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==}
- dependencies:
- co: 4.6.0
- degenerator: 1.0.4
- ip: 1.1.8
- netmask: 1.0.6
- thunkify: 2.1.2
- dev: false
-
/parseurl/1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
@@ -3148,40 +1904,15 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
- /path-parse/1.0.7:
- resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
- dev: false
-
- /path-proxy/1.0.0:
- resolution: {integrity: sha512-p9IuY9FRY1nU59RDW+tnLL6qMxmBnY03WGYxzy1FcqE5OMO5ggz7ahmOBH0JBS+9f95Yc7V5TZ+kHpTeFWaLQA==}
- dependencies:
- inflection: 1.3.8
- dev: false
-
/path-to-regexp/0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
dev: false
- /pbkdf2/3.1.2:
- resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==}
- engines: {node: '>=0.12'}
- dependencies:
- create-hash: 1.2.0
- create-hmac: 1.1.7
- ripemd160: 2.0.2
- safe-buffer: 5.2.1
- sha.js: 2.4.11
- dev: false
-
/peek-readable/5.0.0:
resolution: {integrity: sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==}
engines: {node: '>=14.16'}
dev: false
- /pg-connection-string/2.5.0:
- resolution: {integrity: sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==}
- dev: false
-
/picomatch/2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
@@ -3201,14 +1932,6 @@ packages:
split2: 4.1.0
dev: false
- /pino-http/5.8.0:
- resolution: {integrity: sha512-YwXiyRb9y0WCD1P9PcxuJuh3Dc5qmXde/paJE86UGYRdiFOi828hR9iUGmk5gaw6NBT9gLtKANOHFimvh19U5w==}
- dependencies:
- fast-url-parser: 1.1.3
- pino: 6.14.0
- pino-std-serializers: 4.0.0
- dev: false
-
/pino-pretty/7.6.1:
resolution: {integrity: sha512-H7N6ZYkiyrfwBGW9CSjx0uyO9Q2Lyt73881+OTYk8v3TiTdgN92QHrWlEq/LeWw5XtDP64jeSk3mnc6T+xX9/w==}
hasBin: true
@@ -3228,31 +1951,10 @@ packages:
strip-json-comments: 3.1.1
dev: false
- /pino-std-serializers/3.2.0:
- resolution: {integrity: sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==}
- dev: false
-
- /pino-std-serializers/4.0.0:
- resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==}
- dev: false
-
/pino-std-serializers/6.0.0:
resolution: {integrity: sha512-mMMOwSKrmyl+Y12Ri2xhH1lbzQxwwpuru9VjyJpgFIH4asSj88F2csdMwN6+M5g1Ll4rmsYghHLQJw81tgZ7LQ==}
dev: false
- /pino/6.14.0:
- resolution: {integrity: sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==}
- hasBin: true
- dependencies:
- fast-redact: 3.1.2
- fast-safe-stringify: 2.1.1
- flatstr: 1.0.12
- pino-std-serializers: 3.2.0
- process-warning: 1.0.0
- quick-format-unescaped: 4.0.4
- sonic-boom: 1.4.1
- dev: false
-
/pino/8.6.1:
resolution: {integrity: sha512-fi+V2K98eMZjQ/uEHHSiMALNrz7HaFdKNYuyA3ZUrbH0f1e8sPFDmeRGzg7ZH2q4QDxGnJPOswmqlEaTAZeDPA==}
hasBin: true
@@ -3270,12 +1972,6 @@ packages:
thread-stream: 2.2.0
dev: false
- /please-upgrade-node/3.2.0:
- resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==}
- dependencies:
- semver-compare: 1.0.0
- dev: false
-
/postmark/3.0.14:
resolution: {integrity: sha512-Bkt6msv+I4Z3Y/jwt2owTNVmahOOyJlS1aQLiWsFAz5fzeJPfEqIUMSPPQTk7lYyJvYnLXQuzhFNG7M8yxqPhA==}
dependencies:
@@ -3303,25 +1999,12 @@ packages:
tunnel-agent: 0.6.0
dev: false
- /prelude-ls/1.1.2:
- resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
- engines: {node: '>= 0.8.0'}
- dev: false
-
/prettier/1.19.1:
resolution: {integrity: sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==}
engines: {node: '>=4'}
hasBin: true
dev: true
- /process-nextick-args/2.0.1:
- resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
- dev: false
-
- /process-warning/1.0.0:
- resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==}
- dev: false
-
/process-warning/2.0.0:
resolution: {integrity: sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww==}
dev: false
@@ -3331,32 +2014,6 @@ packages:
engines: {node: '>= 0.6.0'}
dev: false
- /promise-inflight/1.0.1:
- resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
- peerDependencies:
- bluebird: '*'
- peerDependenciesMeta:
- bluebird:
- optional: true
- dev: false
- optional: true
-
- /promise-retry/2.0.1:
- resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==}
- engines: {node: '>=10'}
- dependencies:
- err-code: 2.0.3
- retry: 0.12.0
- dev: false
- optional: true
-
- /promisify-call/2.0.4:
- resolution: {integrity: sha512-ZX68J1+1Pe0I8NC0P6Ji3fDDcJceVfpoygfDLgdb1fp5vW9IRlwSpDaxe1T5HgwchyHV2DsL/pWzWikUiWEbLQ==}
- engines: {node: '>=4.0'}
- dependencies:
- with-callback: 1.0.2
- dev: false
-
/proxy-addr/2.0.7:
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
engines: {node: '>= 0.10'}
@@ -3365,30 +2022,6 @@ packages:
ipaddr.js: 1.9.1
dev: false
- /proxy-agent/3.1.1:
- resolution: {integrity: sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw==}
- engines: {node: '>=6'}
- dependencies:
- agent-base: 4.3.0
- debug: 4.3.4
- http-proxy-agent: 2.1.0
- https-proxy-agent: 3.0.1
- lru-cache: 5.1.1
- pac-proxy-agent: 3.0.1
- proxy-from-env: 1.1.0
- socks-proxy-agent: 4.0.2
- transitivePeerDependencies:
- - supports-color
- dev: false
-
- /proxy-from-env/1.1.0:
- resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
- dev: false
-
- /pseudomap/1.0.2:
- resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==}
- dev: false
-
/pstree.remy/1.1.8:
resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
dev: false
@@ -3400,10 +2033,6 @@ packages:
once: 1.4.0
dev: false
- /punycode/1.4.1:
- resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==}
- dev: false
-
/punycode/2.1.1:
resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==}
engines: {node: '>=6'}
@@ -3416,18 +2045,6 @@ packages:
side-channel: 1.0.4
dev: false
- /qs/6.11.0:
- resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==}
- engines: {node: '>=0.6'}
- dependencies:
- side-channel: 1.0.4
- dev: false
-
- /qs/6.7.0:
- resolution: {integrity: sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==}
- engines: {node: '>=0.6'}
- dev: false
-
/query-string/6.14.1:
resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==}
engines: {node: '>=6'}
@@ -3442,15 +2059,9 @@ packages:
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
dev: false
- /random-bytes/1.0.0:
- resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==}
- engines: {node: '>= 0.8'}
- dev: false
-
- /randombytes/2.1.0:
- resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
- dependencies:
- safe-buffer: 5.2.1
+ /quick-lru/5.1.1:
+ resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
+ engines: {node: '>=10'}
dev: false
/range-parser/1.2.1:
@@ -3458,16 +2069,6 @@ packages:
engines: {node: '>= 0.6'}
dev: false
- /raw-body/2.4.0:
- resolution: {integrity: sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==}
- engines: {node: '>= 0.8'}
- dependencies:
- bytes: 3.1.0
- http-errors: 1.7.2
- iconv-lite: 0.4.24
- unpipe: 1.0.0
- dev: false
-
/raw-body/2.5.1:
resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==}
engines: {node: '>= 0.8'}
@@ -3492,27 +2093,6 @@ packages:
resolution: {integrity: sha512-mdkQtdg5elliOR64xcHVMkghSHQGjpsdCFAs6fSe28wTaVypR0GywmK5ndKpOSQzzuNpSrzC12Rv9UEkDLX73A==}
dev: false
- /readable-stream/1.1.14:
- resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==}
- dependencies:
- core-util-is: 1.0.3
- inherits: 2.0.4
- isarray: 0.0.1
- string_decoder: 0.10.31
- dev: false
-
- /readable-stream/2.3.7:
- resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==}
- dependencies:
- core-util-is: 1.0.3
- inherits: 2.0.4
- isarray: 1.0.0
- process-nextick-args: 2.0.1
- safe-buffer: 5.1.2
- string_decoder: 1.1.1
- util-deprecate: 1.0.2
- dev: false
-
/readable-stream/3.6.0:
resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==}
engines: {node: '>= 6'}
@@ -3551,13 +2131,6 @@ packages:
engines: {node: '>= 12.13.0'}
dev: false
- /rechoir/0.8.0:
- resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
- engines: {node: '>= 10.13.0'}
- dependencies:
- resolve: 1.22.1
- dev: false
-
/redis/4.3.1:
resolution: {integrity: sha512-cM7yFU5CA6zyCF7N/+SSTcSJQSRMEKN0k0Whhu6J7n9mmXRoXugfWDBo5iOzGwABmsWKSwGPTU5J4Bxbl+0mrA==}
dependencies:
@@ -3574,22 +2147,15 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
- /requires-port/1.0.0:
- resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
- dev: false
-
- /resolve-from/5.0.0:
- resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
- engines: {node: '>=8'}
+ /resolve-alpn/1.2.1:
+ resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
dev: false
- /resolve/1.22.1:
- resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==}
- hasBin: true
+ /responselike/3.0.0:
+ resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==}
+ engines: {node: '>=14.16'}
dependencies:
- is-core-module: 2.10.0
- path-parse: 1.0.7
- supports-preserve-symlinks-flag: 1.0.0
+ lowercase-keys: 3.0.0
dev: false
/ret/0.2.2:
@@ -3597,16 +2163,6 @@ packages:
engines: {node: '>=4'}
dev: false
- /retry-as-promised/5.0.0:
- resolution: {integrity: sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==}
- dev: false
-
- /retry/0.12.0:
- resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==}
- engines: {node: '>= 4'}
- dev: false
- optional: true
-
/reusify/1.0.4:
resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
@@ -3630,10 +2186,6 @@ packages:
inherits: 2.0.4
dev: false
- /safe-buffer/5.1.2:
- resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
- dev: false
-
/safe-buffer/5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: false
@@ -3667,15 +2219,6 @@ packages:
resolution: {integrity: sha512-ZQruFgZnIWH+WyO9t5rWt4ZEGqCKPwhiw+YbzTwpmT9elgLrLcfuyUiSnwwjUiVy9r4VM3urtbNF1xmEh9IL2w==}
dev: false
- /semver-compare/1.0.0:
- resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==}
- dev: false
-
- /semver/5.3.0:
- resolution: {integrity: sha512-mfmm3/H9+67MCVix1h+IXTpDwL6710LyHuk7+cWC9T1mE0qz4iHhh6r4hU2wrIT9iTsAAC2XQRvfblL028cpLw==}
- hasBin: true
- dev: false
-
/semver/5.7.1:
resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==}
hasBin: true
@@ -3699,27 +2242,6 @@ packages:
lru-cache: 6.0.0
dev: false
- /send/0.17.1:
- resolution: {integrity: sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- 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.3
- mime: 1.6.0
- ms: 2.1.1
- on-finished: 2.3.0
- range-parser: 1.2.1
- statuses: 1.5.0
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/send/0.18.0:
resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==}
engines: {node: '>= 0.8.0'}
@@ -3741,27 +2263,6 @@ packages:
- supports-color
dev: false
- /seq-queue/0.0.5:
- resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==}
- dev: false
-
- /sequelize-pool/7.1.0:
- resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==}
- engines: {node: '>= 10.0.0'}
- dev: false
-
- /serve-static/1.14.1:
- resolution: {integrity: sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- encodeurl: 1.0.2
- escape-html: 1.0.3
- parseurl: 1.3.3
- send: 0.17.1
- transitivePeerDependencies:
- - supports-color
- dev: false
-
/serve-static/1.15.0:
resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==}
engines: {node: '>= 0.8.0'}
@@ -3782,10 +2283,6 @@ packages:
resolution: {integrity: sha512-1jeBGaKNGdEq4FgIrORu/N570dwoPYio8lSoYLWmX7sQ//0JY08Xh9o5pBcgmHQ/MbsYp/aZnOe1s1lIsbLprQ==}
dev: false
- /setprototypeof/1.1.1:
- resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==}
- dev: false
-
/setprototypeof/1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
dev: false
@@ -3855,14 +2352,6 @@ packages:
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
dev: false
- /socks-proxy-agent/4.0.2:
- resolution: {integrity: sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==}
- engines: {node: '>= 6'}
- dependencies:
- agent-base: 4.2.1
- socks: 2.3.3
- dev: false
-
/socks-proxy-agent/6.2.0:
resolution: {integrity: sha512-wWqJhjb32Q6GsrUqzuFkukxb/zzide5quXYcMVpIjxalDBBYy2nqKCFQ/9+Ie4dvOYSQdOk3hUlZSdzZOd3zMQ==}
engines: {node: '>= 10'}
@@ -3874,26 +2363,6 @@ packages:
- supports-color
dev: false
- /socks-proxy-agent/6.2.1:
- resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==}
- engines: {node: '>= 10'}
- dependencies:
- agent-base: 6.0.2
- debug: 4.3.4
- socks: 2.7.1
- transitivePeerDependencies:
- - supports-color
- dev: false
- optional: true
-
- /socks/2.3.3:
- resolution: {integrity: sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==}
- engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
- dependencies:
- ip: 1.1.5
- smart-buffer: 4.2.0
- dev: false
-
/socks/2.7.1:
resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==}
engines: {node: '>= 10.13.0', npm: '>= 3.0.0'}
@@ -3909,13 +2378,6 @@ packages:
node-gyp-build: 4.5.0
dev: false
- /sonic-boom/1.4.1:
- resolution: {integrity: sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==}
- dependencies:
- atomic-sleep: 1.0.0
- flatstr: 1.0.12
- dev: false
-
/sonic-boom/2.8.0:
resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==}
dependencies:
@@ -3943,47 +2405,6 @@ packages:
engines: {node: '>= 10.x'}
dev: false
- /sqlite3/5.1.2:
- resolution: {integrity: sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==}
- requiresBuild: true
- peerDependenciesMeta:
- node-gyp:
- optional: true
- dependencies:
- '@mapbox/node-pre-gyp': 1.0.10
- node-addon-api: 4.3.0
- tar: 6.1.11
- optionalDependencies:
- node-gyp: 8.4.1
- transitivePeerDependencies:
- - bluebird
- - encoding
- - supports-color
- dev: false
-
- /sqlstring/2.3.1:
- resolution: {integrity: sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==}
- engines: {node: '>= 0.6'}
- dev: false
-
- /sqlstring/2.3.3:
- resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
- engines: {node: '>= 0.6'}
- dev: false
-
- /ssri/8.0.1:
- resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==}
- engines: {node: '>= 8'}
- dependencies:
- minipass: 3.3.4
- dev: false
- optional: true
-
- /statuses/1.5.0:
- resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
- engines: {node: '>= 0.6'}
- dev: false
-
/statuses/2.0.1:
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
engines: {node: '>= 0.8'}
@@ -4016,16 +2437,6 @@ packages:
strip-ansi: 6.0.1
dev: false
- /string_decoder/0.10.31:
- resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==}
- dev: false
-
- /string_decoder/1.1.1:
- resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
- dependencies:
- safe-buffer: 5.1.2
- dev: false
-
/string_decoder/1.3.0:
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
dependencies:
@@ -4064,11 +2475,6 @@ packages:
has-flag: 3.0.0
dev: false
- /supports-preserve-symlinks-flag/1.0.0:
- resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
- engines: {node: '>= 0.4'}
- dev: false
-
/tar-fs/2.1.1:
resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
dependencies:
@@ -4101,11 +2507,6 @@ packages:
yallist: 4.0.0
dev: false
- /tarn/3.0.2:
- resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==}
- engines: {node: '>=8.0.0'}
- dev: false
-
/text-decoding/1.0.0:
resolution: {integrity: sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==}
dev: false
@@ -4121,39 +2522,11 @@ packages:
real-require: 0.2.0
dev: false
- /thunkify/2.1.2:
- resolution: {integrity: sha512-w9foI80XcGImrhMQ19pxunaEC5Rp2uzxZZg4XBAFRfiLOplk3F0l7wo+bO16vC2/nlQfR/mXZxcduo0MF2GWLg==}
- dev: false
-
- /tildify/2.0.0:
- resolution: {integrity: sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==}
- engines: {node: '>=8'}
- dev: false
-
/tiny-lru/9.0.3:
resolution: {integrity: sha512-/i9GruRjXsnDgehxvy6iZ4AFNVxngEFbwzirhdulomMNPGPVV3ECMZOWSw0w4sRMZ9Al9m4jy08GPvRxRUGYlw==}
engines: {node: '>=6'}
dev: false
- /tiny-secp256k1/1.1.6:
- resolution: {integrity: sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==}
- engines: {node: '>=6.0.0'}
- requiresBuild: true
- dependencies:
- bindings: 1.5.0
- bn.js: 4.12.0
- create-hmac: 1.1.7
- elliptic: 6.5.4
- nan: 2.17.0
- dev: false
-
- /tiny-secp256k1/2.2.1:
- resolution: {integrity: sha512-/U4xfVqnVxJXN4YVsru0E6t5wVncu2uunB8+RVR40fYUxkKYUPS10f+ePQZgFBoE/Jbf9H1NBveupF2VmB58Ng==}
- engines: {node: '>=14.0.0'}
- dependencies:
- uint8array-tools: 0.0.7
- dev: false
-
/to-regex-range/5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
@@ -4161,11 +2534,6 @@ packages:
is-number: 7.0.0
dev: false
- /toidentifier/1.0.0:
- resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==}
- engines: {node: '>=0.6'}
- dev: false
-
/toidentifier/1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
@@ -4179,10 +2547,6 @@ packages:
ieee754: 1.2.1
dev: false
- /toposort-class/1.0.1:
- resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==}
- dev: false
-
/touch/3.1.0:
resolution: {integrity: sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==}
hasBin: true
@@ -4194,28 +2558,12 @@ packages:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: false
- /tslib/2.4.0:
- resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
- dev: false
-
- /tsscmp/1.0.6:
- resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==}
- engines: {node: '>=0.6.x'}
- dev: false
-
/tunnel-agent/0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
dependencies:
safe-buffer: 5.2.1
dev: false
- /type-check/0.3.2:
- resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==}
- engines: {node: '>= 0.8.0'}
- dependencies:
- prelude-ls: 1.1.2
- dev: false
-
/type-is/1.6.18:
resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==}
engines: {node: '>= 0.6'}
@@ -4236,18 +2584,6 @@ packages:
dev: false
optional: true
- /uid-safe/2.1.5:
- resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==}
- engines: {node: '>= 0.8'}
- dependencies:
- random-bytes: 1.0.0
- dev: false
-
- /uint8array-tools/0.0.7:
- resolution: {integrity: sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==}
- engines: {node: '>=14.0.0'}
- dev: false
-
/undefsafe/2.0.5:
resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
dev: false
@@ -4256,20 +2592,6 @@ packages:
resolution: {integrity: sha512-ekY1NhRzq0B08g4bGuX4wd2jZx5GnKz6mKSqFL4nqBlfyMGiG10gDFhDTMEfYmDL6Jy0FUIZp7wiRB+0BP7J2g==}
dev: false
- /unique-filename/1.1.1:
- resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==}
- dependencies:
- unique-slug: 2.0.2
- dev: false
- optional: true
-
- /unique-slug/2.0.2:
- resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==}
- dependencies:
- imurmurhash: 0.1.4
- dev: false
- optional: true
-
/unpipe/1.0.0:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
@@ -4285,12 +2607,6 @@ packages:
resolution: {integrity: sha512-RtuPeMy7c1UrHwproMZN9gN6kiZ0SvJwRaEzwZY0j9MypEkFqyBaKv176jvlPtg58Zh36bOkS0NFABXMHvvGCA==}
dev: false
- /utf7/1.0.2:
- resolution: {integrity: sha512-qQrPtYLLLl12NF4DrM9CvfkxkYI97xOb5dsnGZHE3teFr0tWiEZ9UdgMPczv24vl708cYMpe6mGXGHrotIp3Bw==}
- dependencies:
- semver: 5.3.0
- dev: false
-
/util-deprecate/1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: false
@@ -4305,11 +2621,6 @@ packages:
hasBin: true
dev: false
- /validator/13.7.0:
- resolution: {integrity: sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==}
- engines: {node: '>= 0.10'}
- dev: false
-
/varuint-bitcoin/1.1.2:
resolution: {integrity: sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==}
dependencies:
@@ -4347,15 +2658,6 @@ packages:
webidl-conversions: 3.0.1
dev: false
- /which/2.0.2:
- resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
- engines: {node: '>= 8'}
- hasBin: true
- dependencies:
- isexe: 2.0.0
- dev: false
- optional: true
-
/wide-align/1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
@@ -4368,22 +2670,6 @@ packages:
bs58check: 2.1.2
dev: false
- /with-callback/1.0.2:
- resolution: {integrity: sha512-zaUhn7OWgikdqWlPYpZ4rTX/6IAV0czMVyd+C6QLVrif2tATF28CYUnHBmHs2a5EaZo7bB1+plBUPHto+HW8uA==}
- engines: {node: '>=4'}
- dev: false
-
- /wkx/0.5.0:
- resolution: {integrity: sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==}
- dependencies:
- '@types/node': 18.8.5
- dev: false
-
- /word-wrap/1.2.3:
- resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==}
- engines: {node: '>=0.10.0'}
- dev: false
-
/wordwrap/1.0.0:
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
dev: false
@@ -4392,10 +2678,6 @@ packages:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: false
- /wretch/1.7.10:
- resolution: {integrity: sha512-UgF2o63bZRsz3LoOxaxzAUdFdlIJzVYbCHHhQ+LNMSBD1FeFJn8ADaekopJclHUm6sN8Lhu0DQFGQloliS0Twg==}
- dev: false
-
/ws/7.5.9:
resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==}
engines: {node: '>=8.3.0'}
@@ -4422,18 +2704,6 @@ packages:
optional: true
dev: false
- /xregexp/2.0.0:
- resolution: {integrity: sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==}
- dev: false
-
- /yallist/2.1.2:
- resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==}
- dev: false
-
- /yallist/3.1.1:
- resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
- dev: false
-
/yallist/4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: false
@@ -4442,11 +2712,3 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: false
-
- /zeromq/6.0.0-beta.6:
- resolution: {integrity: sha512-wLf6M7pBHijl+BRltUL2VoDpgbQcOZetiX8UzycHL8CcYFxYnRrpoG5fi3UX3+Umavz1lk4/dGaQez8qiDgr/Q==}
- engines: {node: '>= 10.2'}
- requiresBuild: true
- dependencies:
- node-gyp-build: 4.5.0
- dev: false
diff --git a/prod.yml b/prod.yml
deleted file mode 100644
index e03d9352..00000000
--- a/prod.yml
+++ /dev/null
@@ -1,96 +0,0 @@
-version: '3.6'
-services:
- app:
- depends_on:
- - cl
- - maria
- - bitcoin
- - liquid
- container_name: app
- image: gcr.io/coinos-326717/github.com/coinos/coinos-server:prod
- restart: always
- environment:
- NODE_ENV: production
- NODE_OPTIONS: "--es-module-specifier-resolution=node --experimental-modules --loader ./loader.js --openssl-legacy-provider"
- HOSTNAME: "${HOSTNAME}"
- volumes:
- - ./:/app
- - ./logs:/logs
- networks:
- default:
- ipv4_address: 172.42.0.22
- maria:
- container_name: maria
- image: mariadb
- restart: always
- environment:
- MARIADB_ROOT_PASSWORD: password
- volumes:
- - ./mysql:/var/lib/mysql
- bitcoin:
- image: ghcr.io/vulpemventures/bitcoin
- container_name: bitcoin
- volumes:
- - ./config/bitcoin:/home/bitcoin/.bitcoin
- restart: always
- networks:
- default:
- ipv4_address: 172.42.0.23
- liquid:
- image: ghcr.io/vulpemventures/elements
- container_name: liquid
- volumes:
- - ./config/liquid:/home/elements/.elements
- restart: always
- networks:
- default:
- ipv4_address: 172.42.0.24
- cl:
- depends_on:
- - bitcoin
- image: elementsproject/lightningd:v0.12.0
- container_name: cl
- restart: always
- volumes:
- - ./config/lightning:/root/.lightning
- ports:
- - "9736:9735"
- networks:
- default:
- ipv4_address: 172.42.0.25
- lnd:
- depends_on:
- - bitcoin
- - tor
- image: lightninglabs/lnd:v0.15.4-beta
- container_name: lnd
- volumes:
- - ./config/lnd:/root/.lnd
- - ./config/bitcoin:/root/.bitcoin
- - ./config/tor:/etc/tor
- ports:
- - "9735:9735"
- restart: always
- networks:
- default:
- ipv4_address: 172.42.0.26
- tor:
- container_name: tor
- image: dperson/torproxy
- restart: always
- volumes:
- - ./config/tor:/etc/tor
- - ./config/tordata:/var/lib/tor
- networks:
- default:
- ipv4_address: 172.42.0.27
- redis:
- restart: always
- container_name: redis
- image: redis
- volumes:
- - ./config/redis:/data
-networks:
- default:
- name: net
- external: true
diff --git a/routes/admin.js b/routes/admin.js
deleted file mode 100644
index 3053d813..00000000
--- a/routes/admin.js
+++ /dev/null
@@ -1,566 +0,0 @@
-import express from "express";
-var router = express.Router();
-
-import * as parseInput from "../scripts/apiParse";
-import Sequelize from "@sequelize/core";
-const Op = Sequelize.Op;
-
-/**
- * @api {get} /users Retrieve user list
- * @apiName getUsers
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess {Object} users List of users
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "users" : [
- * { "username": 'John Doe', "email": '[email protected]', ...},
- * { "username": 'Jane Doe', "email": '[email protected]', ...}
- * ]
- * }
- */
-router.get(
- "/users",
- // auth,
- async (req, res) => {
- var { search, starts_with, contains } = req.query;
- var users = knex
- .select(
- "username",
- "email",
- "phone",
- "verified",
- knex.raw("LEFT(createdAt,10) as created_at")
- )
- .from("users");
-
- var timeCondition = parseInput.addTimeSearch(req.query, "users.createdAt");
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) users = users.whereRaw(timeCondition);
- if (userCondition) users = users.whereRaw(userCondition);
-
- // Alternative Sequelize query syntax
- // await db.User.findAll({
- // attributes: ['username', 'email', 'phone', 'verified', 'createdAt']
- // })
-
- const found = await users;
- return res.send({ users: found });
- }
-);
-
-/**
- * @api {get} /referrals Retrieve list of referral tokens
- * @apiName referrals
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of referral tokens
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "referrals" : [
- * { "token": '***', "status": 'pending', sponsor: 'Adam', user: 'newUsername1', expiry: null },
- * { "token": '***', "status": 'pending', sponsor: 'Adam', user: 'newUsername2', expiry: null },
- * ]
- * }
- */
-router.get("/referrals", auth, async (req, res) => {
- var referrals = knex
- .select(
- "token",
- "users.username as user",
- "sponsor.username as sponsor",
- knex.raw("LEFT(created_at, 10) as created_at"),
- "referrals.status"
- )
- .from("referrals")
- .leftJoin("users", "users.id", "referrals.user_id")
- .leftJoin("users as sponsor", "sponsor.id", "referrals.sponsor_id");
-
- // Alternative Sequelize query syntax (returns sub-tables as hash)
- // var referrals = await db.Referral.findAll({
- // include: [
- // {model: db.User, as: 'user', attributes: [['username', 'user']]},
- // {model: db.User, as: 'sponsor', attributes: [['username', 'sponsor']]}
- // ]
- // })
-
- var timeCondition = parseInput.addTimeSearch(
- req.query,
- "referrals.updated_at"
- );
- var userCondition = parseInput.addUserSearch(req.query, "sponsor");
-
- if (userCondition) {
- referrals = referrals.whereRaw(userCondition);
- }
- if (timeCondition) {
- referrals = referrals.whereRaw(timeCondition);
- }
-
- var found = await referrals;
- return res.send({ referrals: found });
-});
-
-/**
- * @api {get} /waiting_list Retrieve waiting_list
- * @apiName waiting_list
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of referral tokens
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "waiting_list" : [
- * { email: "[email protected]", phone: '604 123-4567 },
- * { email: "[email protected]", phone: '604 246-8910 },
- * ]
- * }
- */
-router.get(
- "/waiting_list",
- // auth,
- async (req, res) => {
- var { search, starts_with, contains } = req.query;
-
- var queue = knex
- .select(
- "waiting_list.email",
- "waiting_list.phone",
- "waiting_list.created_at as requested",
- "users.id as current_user_id"
- )
- .from("waiting_list")
- .leftJoin("users", "users.email", "waiting_list.email")
- .where("waiting_list.id", ">", 0);
-
- var timeCondition = parseInput.addTimeSearch(
- req.query,
- "waiting_list.updated_at"
- );
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) queue = queue.whereRaw(timeCondition);
- if (userCondition) queue = queue.whereRaw(userCondition);
-
- const found = await queue;
-
- return res.send({ queue: found });
- }
-);
-
-/**
- * @api {get} /accounts Retrieve list of accounts
- * @apiName accounts
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of accounts
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "accounts" : [
- * { "user": 'Adam', "account_id": '123', balance: 500 ... },
- * ...
- * ]
- * }
- */
-router.get("/accounts", auth, async (req, res) => {
- var { nonZero, search, starts_with, contains } = req.query;
-
- var accounts = knex
- .select(
- "username",
- "accounts.id as account_id",
- "ticker",
- "balance",
- knex.raw("LEFT(accounts.createdAt, 10) as created"),
- knex.raw("LEFT(accounts.updatedAt, 10) as updated")
- )
- .from("accounts")
- .leftJoin("users", "users.id", "accounts.user_id");
-
- if (nonZero) {
- accounts = accounts.where("balance", ">", 0);
- }
-
- var timeCondition = parseInput.addTimeSearch(req.query, "accounts.updatedAt");
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) accounts = accounts.whereRaw(timeCondition);
- if (userCondition) accounts = accounts.whereRaw(userCondition);
-
- const found = await accounts;
-
- return res.send({ accounts: found });
-});
-
-/**
- * @api {get} /transactions Retrieve summary of user transactions
- *
- * @apiName user_transactions
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of invoices, payments, orders for users
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "transactions" : [
- * { "username": 'Adam', "email": '[email protected]', invoices: 1, orders: 0, payments: 2 },
- ...
- * ]
- * }
- */
-router.get(
- "/transactions",
- // auth,
- async (req, res) => {
- var { type, since, search, starts_with, contains } = req.query;
-
- var transactions = knex
- .select(
- "users.username",
- "users.email"
- // knex.raw('LEFT(created_at, 10) as created')
- // knex.raw('LEFT(updatedAt, 10) as updated')
- // knex.raw('COUNT(invoices.id) as invoices'),
- // knex.raw('COUNT(payments.id) as payments'),
- // knex.raw('COUNT(orders.id) as orders')
- )
- .from("users");
-
- const types = ["deposits", "withdrawals", "orders", "payments", "invoices"];
- for (var i = 0; i < types.length; i++) {
- var stamp = types[i].replace(/s$/, "") + "_date";
-
- transactions = transactions
- .select(
- knex.raw("COUNT(DISTINCT " + types[i] + ".id) as " + types[i]),
- knex.raw("LEFT(MAX(" + types[i] + ".updatedAt), 10) as " + stamp)
- )
- .leftJoin(types[i], "users.id", types[i] + ".user_id");
- // .havingRaw(types[i] + ' > ?', [0])
-
- if (since) {
- transactions = transactions.havingRaw(
- "(" + stamp + " >= ? OR " + stamp + " IS NULL)",
- [since]
- );
- }
- }
-
- if (since)
- transactions = transactions.havingRaw(
- "invoices + payments + deposits + orders > ?",
- [0]
- );
-
- var userCondition = parseInput.addUserSearch(req.query);
- if (userCondition) transactions = transactions.whereRaw(userCondition);
-
- transactions = transactions.groupBy("users.id");
-
- const found = await transactions;
-
- return res.send({ transactions: found });
- }
-);
-
-/**
- * @api {get} /orders Retrieve summary of orders
- *
- * @apiName orders
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of orders
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "orders" : [
- * { "seller": 'Adam', "buyer": 'bob' ... },
- ...
- * ]
- * }
- */
-router.get("/orders", auth, async (req, res) => {
- var { type, since, search, starts_with, contains } = req.query;
-
- var orders = knex
- .select(
- "u1.username as seller",
- "u2.username as buyer",
- "v1 as sell_amount",
- "v2 as buy_amount",
- "rate",
- "a1.name as from",
- "a2.name as to",
- knex.raw("Left(completedAt,16) as completed")
- )
- .from("orders")
- .leftJoin("accounts as a1", "a1.id", "orders.a1_id")
- .leftJoin("accounts as a2", "a2.id", "orders.a2_id")
- .leftJoin("users as u1", "a1.user_id", "u1.id")
- .leftJoin("users as u2", "a2.user_id", "u2.id");
-
- var timeCondition = parseInput.addTimeSearch(req.query, "orders.updatedAt");
- if (timeCondition) orders = orders.whereRaw(timeCondition);
-
- var userCondition1 = parseInput.addUserSearch(req.query, "u1");
- var userCondition2 = parseInput.addUserSearch(req.query, "u2");
-
- if (userCondition1)
- orders = orders.where(function() {
- this.whereRaw(userCondition1);
- this.orWhere(knex.raw(userCondition2));
- });
-
- var found = await orders;
- return res.send({ orders: found });
-});
-
-/**
- * @api {get} /invoices Retrieve summary of invoices
- *
- * @apiName invoices
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of invoices
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "invoices" : [
- * { "seller": 'Adam', "buyer": 'bob' ... },
- ...
- * ]
- * }
- */
-router.get("/invoices", auth, async (req, res) => {
- var { type, since, search, starts_with, contains } = req.query;
-
- var invoices = knex
- .select(
- "username",
- "users.email",
- "invoices.currency",
- "invoices.amount",
- "accounts.network",
- knex.raw("Left(invoices.updatedAt,16) as updated")
- )
- .from("invoices")
- .leftJoin("accounts", "invoices.account_id", "accounts.id")
- .leftJoin("users", "accounts.user_id", "users.id");
-
- var timeCondition = parseInput.addTimeSearch(req.query, "invoices.updatedAt");
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) invoices = invoices.whereRaw(timeCondition);
- if (userCondition) invoices = invoices.whereRaw(userCondition);
-
- var found = await invoices;
- return res.send({ invoices: found });
-});
-
-/**
- * @api {get} /deposits Retrieve summary of deposits
- *
- * @apiName deposits
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of deposits
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "deposits" : [
- * { "seller": 'Adam', "buyer": 'bob' ... },
- ...
- * ]
- * }
- */
-router.get("/deposits", auth, async (req, res) => {
- var { type, since, search, starts_with, contains } = req.query;
-
- var deposits = knex
- .select(
- "username",
- "users.email",
- "amount",
- "credited",
- knex.raw("Left(deposits.updatedAt,16) as deposited")
- )
- .from("deposits")
- .leftJoin("users", "deposits.user_id", "users.id");
-
- var timeCondition = parseInput.addTimeSearch(req.query, "deposits.updatedAt");
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) deposits = deposits.whereRaw(timeCondition);
- if (userCondition) deposits = deposits.whereRaw(userCondition);
-
- var found = await deposits;
- return res.send({ deposits: found });
-});
-
-/**
- * @api {get} /withdrawals Retrieve summary of withdrawals
- *
- * @apiName withdrawals
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of withdrawals
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "withdrawals" : [
- * { "seller": 'Adam', "buyer": 'bob' ... },
- ...
- * ]
- * }
- */
-router.get("/withdrawals", auth, async (req, res) => {
- var { type, since, search, starts_with, contains } = req.query;
-
- var withdrawals = knex
- .select(
- "username",
- "users.email",
- "amount",
- "notes",
- knex.raw("Left(withdrawals.updatedAt,16) as withdrawn")
- )
- .from("withdrawals")
- .leftJoin("users", "withdrawals.user_id", "users.id");
-
- var timeCondition = parseInput.addTimeSearch(
- req.query,
- "withdrawals.updatedAt"
- );
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) withdrawals = withdrawals.whereRaw(timeCondition);
- if (userCondition) withdrawals = withdrawals.whereRaw(userCondition);
-
- var found = await withdrawals;
- return res.send({ withdrawals: found });
-});
-
-/**
- * @api {get} /payments Retrieve summary of payments
- *
- * @apiName payments
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of payments
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "payments" : [
- * { "seller": 'Adam', "buyer": 'bob' ... },
- ...
- * ]
- * }
-**/
-router.get("/payments", auth, async (req, res) => {
- var { type, since, search, starts_with, contains } = req.query;
-
- var payments = knex
- .select(
- "username",
- "users.email",
- "amount",
- "payments.network",
- knex.raw("LEFT(hash,20) as hash"),
- knex.raw("Left(payments.updatedAt,16) as deposited")
- )
- .from("payments")
- .leftJoin("accounts", "payments.account_id", "accounts.id")
- .leftJoin("users", "accounts.user_id", "users.id");
-
- var timeCondition = parseInput.addTimeSearch(req.query, "payments.updatedAt");
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) payments = payments.whereRaw(timeCondition);
- if (userCondition) payments = payments.whereRaw(userCondition);
-
- var found = await payments;
- return res.send({ payments: found });
-});
-
-/**
- * @api {get} /user_kyc Retrieve user kyc details
- *
- * @apiName user_kyc
- * @apiGroup Admin
- *
- * @apiPermission admin
- *
- * @apiSuccess returns list of kyc details for each user
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "users" : [
- * { "username": 'Adam', "email": '[email protected]', ... kyc_data... },
- ...
- * ]
- * }
- */
-router.get("/kyc_required", auth, async (req, res) => {
- var { since, search, starts_with, contains } = req.query;
-
- var threshold = "0.2";
-
- var kyc = knex
- .select(
- knex.raw("CONCAT( FORMAT(Max(amount)/1000000, 1), ' M') as max"),
- "username",
- "users.email",
- "users.verified as kyc_verified",
- // 'payments.currency',
- // 'payments.network',
- // knex.raw('LEFT(hash,20) as hash'),
- // knex.raw('Left(payments.updatedAt,16) as transferred')
- // knex.raw( parseInput.readableDate('Max(payments.updatedAt)', 'last_changed') )
- knex.raw(
- "DATE_FORMAT(Max(payments.updatedAt), ?) AS last_changed",
- "%M %d, %Y"
- )
- )
- .from("payments")
- .leftJoin("accounts", "payments.account_id", "accounts.id")
- .leftJoin("users", "payments.user_id", "users.id") // should really point to accounts
- .groupBy("users.id");
- // .groupBy('payments.currency')
- // .groupBy('payments.network')
-
- var timeCondition = parseInput.addTimeSearch(req.query, "payments.updatedAt");
- var userCondition = parseInput.addUserSearch(req.query);
-
- if (timeCondition) kyc = kyc.whereRaw(timeCondition);
- if (userCondition) kyc = kyc.whereRaw(userCondition);
-
- var found = await kyc.having("max", ">=", threshold);
-
- return res.send({ found: found });
-});
-
-export default router;
diff --git a/routes/assets.js b/routes/assets.js
deleted file mode 100644
index ed0d3036..00000000
--- a/routes/assets.js
+++ /dev/null
@@ -1,536 +0,0 @@
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import db from "$db";
-import config from "$config";
-import app from "$app";
-import { auth } from "$lib/passport";
-import axios from "axios";
-import crypto from "crypto";
-import fs from "fs";
-import { err, l } from "$lib/logging";
-import lq from "$lib/liquid";
-import { SATS } from "$lib/utils";
-
-let fetchAssets;
-(fetchAssets = async () => {
- try {
- const { data } = await axios.get("https://assets.blockstream.info/");
-
- store.assets = data;
- } catch (e) {
- var liquid_assets = JSON.parse(fs.readFileSync("/app/assets.json"));
- if (liquid_assets) {
- store.assets = liquid_assets;
- console.debug("using static assets..." + e.message);
- } else {
- err("error fetching assets", e.message);
- res.code(500).send("error fetching assets");
- }
- }
-
- setTimeout(fetchAssets, 7200000);
-})();
-
-app.get("/assets", async (req, res) => {
- if (store.assets) {
- const accounts = await db.Account.findAll({
- // group: ["asset"]
- });
- Object.keys(store.assets).map(a => {
- store.assets[a].registered = true;
- if (!store.assets[a].asset)
- store.assets[a].asset = store.assets[a].asset_id;
- if (
- (store.assets[a].ticker === "BTC" &&
- store.assets[a].asset !== config.liquid.btcasset) ||
- (store.assets[a].ticker === "EUR" &&
- store.assets[a].asset !== config.liquid.eurasset) ||
- (store.assets[a].ticker === "CAD" &&
- store.assets[a].asset !== config.liquid.cadasset) ||
- (store.assets[a].ticker === "USDt" &&
- store.assets[a].asset !== config.liquid.usdtasset)
- )
- delete store.assets[a];
- });
- accounts.map(({ asset, name, domain, ticker, precision }) => {
- if (!store.assets[asset])
- store.assets[asset] = {
- asset,
- name,
- domain,
- ticker,
- precision
- };
- });
-
- res.send(store.assets);
- } else {
- console.log("error getting blockstream assets");
- res.code(500).send("Problem fetching blockstream asset registry data");
- }
-});
-
-app.post("/assets", auth, async (req, res) => {
- try {
- const sha256 = crypto.createHash("sha256");
- const { id: user_id } = req.user;
- const blind = false;
-
- if (!user_id) throw new Error("unauthorized");
-
- const {
- address,
- domain,
- name,
- asset_amount,
- filename,
- token_amount,
- precision,
- pubkey,
- ticker
- } = req.body;
-
- const asset_address = address
- ? address
- : await lq.getNewAddress("", "legacy");
-
- const token_address =
- token_amount && (await lq.getNewAddress("", "legacy"));
-
- const issuer_pubkey = pubkey
- ? pubkey
- : (await lq.getAddressInfo(asset_address)).pubkey;
- const version = 0;
-
- let contract = {
- entity: { domain },
- issuer_pubkey,
- name,
- precision,
- version
- };
-
- if (filename) contract.file = filename;
- if (ticker) contract.ticker = ticker;
-
- contract = Object.keys(contract)
- .sort()
- .reduce((r, k) => ((r[k] = contract[k]), r), {});
-
- l(
- "attempting issuance",
- req.user.username,
- JSON.stringify(contract),
- "address",
- address,
- "pubkey",
- pubkey
- );
-
- sha256.update(JSON.stringify(contract));
- const hash = sha256.digest("hex");
- const contract_hash = hash
- .match(/[a-f0-9]{2}/g)
- .reverse()
- .join("");
- const rawtx = await lq.createRawTransaction([], [{ data: "00" }]);
- const funded = await lq.fundRawTransaction(rawtx, { feeRate: 0.000002 });
- const params = {
- asset_amount,
- asset_address,
- blind,
- contract_hash
- };
-
- params.asset_amount = asset_amount / (SATS / 10 ** precision);
-
- if (token_amount) {
- params.token_amount = token_amount;
- params.token_address = token_address;
- params.token_amount = parseInt(params.token_amount);
- }
-
- let ria;
- try {
- ria = await lq.rawIssueAsset(funded.hex, [params]);
- } catch (e) {
- l(asset_amount, token_amount, params);
- throw new Error(e.message);
- }
-
- const { asset, hex, token } = ria[0];
- const brt = await lq.blindRawTransaction(hex, true, [], false);
- const srt = await lq.signRawTransactionWithWallet(brt);
- const allowed = (await lq.testMempoolAccept([srt.hex]))[0].allowed;
- if (!allowed) throw new Error("issuance rejected by mempool", srt.hex);
- const txid = await lq.sendRawTransaction(srt.hex);
-
- await db.transaction(async transaction => {
- let account = await db.Account.findOne({
- where: {
- user_id,
- asset: config.liquid.btcasset,
- pubkey: null
- },
- include: {
- model: db.User,
- as: "user"
- },
- order: [["balance", "DESC"]],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- let { user } = account;
-
- if (Math.round(funded.fee * SATS) > account.balance) {
- err(
- "amount exceeds balance",
- asset_amount,
- funded.fee,
- account.balance
- );
- throw new Error(`Insufficient funds to pay fee of ${funded.fee} BTC`);
- }
-
- await account.decrement(
- { balance: Math.round(funded.fee * SATS) },
- { transaction }
- );
- await account.reload({ transaction });
- emit(user.username, "account", account);
-
- let invoice;
- let recipient = user;
- if (address) {
- invoice = await db.Invoice.findOne({
- where: { address },
- include: {
- model: db.User,
- as: "user"
- }
- });
- recipient = invoice.user;
- }
-
- if (!invoice) {
- invoice = await db.Invoice.create(
- {
- account_id: account.id,
- user_id,
- amount: Math.round(params.asset_amount * SATS),
- address: asset_address,
- currency: user.currency,
- rate: store.rates[user.currency],
- network: "liquid"
- },
- { transaction }
- );
- }
-
- account = await db.Account.create(
- {
- asset,
- contract,
- domain,
- user_id: invoice.user_id,
- ticker,
- precision,
- name,
- balance: 0,
- network: "liquid",
- pending: Math.round(params.asset_amount * SATS)
- },
- { transaction }
- );
-
- emit(recipient.username, "account", account);
- l(
- "issued asset",
- user.username,
- params.asset_amount,
- ticker,
- name,
- account.id
- );
-
- const asset_payment = await db.Payment.create(
- {
- account_id: account.id,
- user_id: invoice.user_id,
- invoice_id: invoice.id,
- hash: txid,
- amount: Math.round(params.asset_amount * SATS),
- received: true,
- confirmed: false,
- address: asset_address,
- network: "liquid"
- },
- { transaction }
- );
- emit(recipient.username, "payment", asset_payment);
-
- if (invoice.user_id !== user.id) {
- const asset_send = await db.Payment.create(
- {
- account_id: account.id,
- user_id,
- hash: txid,
- amount: -Math.round(params.asset_amount * SATS),
- received: false,
- confirmed: false,
- address,
- network: "liquid"
- },
- { transaction }
- );
- emit(recipient.username, "payment", asset_send);
- }
-
- store.issuances[txid] = {
- user_id,
- asset,
- asset_amount: params.asset_amount,
- asset_payment_id: asset_payment.id
- };
-
- if (token_amount) {
- invoice = null;
- recipient = user;
-
- if (address) {
- invoice = await db.Invoice.findOne({
- where: { address },
- include: {
- model: db.User,
- as: "user"
- }
- });
- recipient = invoice.user;
- }
-
- if (!invoice) {
- invoice = await db.Invoice.create(
- {
- account_id: account.id,
- user_id,
- amount: Math.round(params.token_amount * SATS),
- address: token_address,
- currency: user.currency,
- rate: store.rates[user.currency],
- network: "liquid"
- },
- { transaction }
- );
- }
-
- account = await db.Account.create(
- {
- asset: token,
- user_id: invoice.user_id,
- domain,
- ticker: `${ticker}REISSUANCETOKEN`,
- precision: 8,
- name: `${name} Reissuance Token`,
- balance: 0,
- pending: address ? 0 : Math.round(token_amount * SATS)
- },
- { transaction }
- );
- emit(recipient.username, "account", account);
-
- const token_payment = await db.Payment.create(
- {
- account_id: account.id,
- invoice_id: invoice.id,
- user_id,
- hash: txid,
- amount: Math.round(token_amount * SATS),
- received: true,
- confirmed: false,
- address: token_address,
- network: "liquid"
- },
- { transaction }
- );
- emit(recipient.username, "payment", token_payment);
-
- if (invoice.user_id !== user.id) {
- const token_send = await db.Payment.create(
- {
- account_id: account.id,
- invoice_id: invoice.id,
- user_id,
- hash: txid,
- amount: -Math.round(token_amount * SATS),
- received: false,
- confirmed: false,
- address,
- network: "liquid"
- },
- { transaction }
- );
- emit(recipient.username, "payment", token_send);
- }
-
- store.issuances[txid].token = token;
- store.issuances[txid].token_amount = token_amount;
- store.issuances[txid].token_payment_id = token_payment.id;
- }
- });
-
- res.send(store.issuances[txid] ? store.issuances[txid] : { asset });
- } catch (e) {
- err("asset issuance failed", e.message, e.stack);
- res.code(500).send(e.message);
- }
-});
-
-app.post("/assets/register", auth, async (req, res) => {
- const { asset } = req.body;
- const account = await db.Account.findOne({
- where: {
- user_id: req.user.id,
- asset
- }
- });
-
- l("registering", asset, account.contract);
-
- try {
- const { data: result } = await axios.post(
- "https://assets.blockstream.info/",
- {
- asset_id: asset,
- contract: account.contract
- }
- );
- l("register asset result", req.user.username, result);
- res.send(result);
- } catch (e) {
- err("asset registration failed", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.post("/loadFaucet", auth, async (req, res) => {
- return res.code(500).send("Faucet feature temporarily disabled");
-
- const { user } = req;
- let { asset, amount } = req.body;
- amount = parseInt(amount);
-
- try {
- if (amount <= 0) throw new Error("Amount to load cannot be negative");
-
- await db.transaction(async transaction => {
- let account = await getAccount(config.liquid.btcasset, user, transaction);
-
- if (account.asset !== config.liquid.btcasset)
- throw new Error(
- "Faucet has to be funded with bitcoin. Try sending from another wallet."
- );
- if (account.balance < amount) throw new Error("Insufficient funds");
-
- let fee = 0;
-
- await account.decrement({ balance: amount }, { transaction });
- await account.reload({ transaction });
-
- let a2;
- let acc = {
- user_id: null,
- asset
- };
-
- a2 = await db.Account.findOne({
- where: acc,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (a2) {
- await a2.increment({ balance: amount }, { transaction });
- await a2.reload({ transaction });
- } else {
- let name = asset.substr(0, 6);
- let domain;
- let ticker = asset.substr(0, 3).toUpperCase();
- let precision = 8;
-
- const assets = assets;
-
- if (assets[asset]) {
- ({ domain, ticker, precision, name } = assets[asset]);
- } else {
- const existing = await db.Account.findOne({
- where: {
- asset
- },
- order: [["id", "ASC"]],
- limit: 1,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (existing) {
- ({ domain, ticker, precision, name } = existing);
- }
- }
-
- acc = { ...acc, ...{ domain, ticker, precision, name } };
- acc.balance = amount;
- acc.pending = 0;
- acc.network = "liquid";
- a2 = await db.Account.create(acc, { transaction });
- }
-
- let params = {
- amount: -amount,
- account_id: account.id,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed: true,
- hash: `Loaded Faucet - ${a2.ticker}`,
- network: "COINOS"
- };
-
- let payment = await db.Payment.create(params, { transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
-
- l("sent internal", user.username, -payment.amount);
-
- emit(user.username, "payment", payment);
- emit(user.username, "account", account);
- emit(user.username, "user", user);
-
- l("loaded faucet", asset, amount);
- res.send({});
- });
- } catch (e) {
- err("problem loading faucet", user.username, e.message);
- return res.code(500).send(e.message);
- }
-});
-
-app.get("/faucet", auth, async (req, res) => {
- let { asset } = req.query;
- let faucet = await db.Account.findOne({
- where: {
- asset,
- user_id: null
- }
- });
-
- if (!faucet)
- faucet = {
- asset,
- balance: 0,
- ticker: "Unknown"
- };
-
- res.send(faucet);
-});
diff --git a/routes/bitcoin/broadcast.js b/routes/bitcoin/broadcast.js
deleted file mode 100644
index 85c8cf66..00000000
--- a/routes/bitcoin/broadcast.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import { requirePin } from "$lib/utils";
-
-export default async (req, res) => {
- try {
- await requirePin(req);
-
- const { user } = req;
- let hash = await bc.sendRawTransaction(req.body.tx);
-
- if (user) {
- await db.transaction(async transaction => {
- let account = await db.Account.findOne({
- where: {
- id: user.account_id
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- let payment = await db.Payment.create(
- {
- ...req.body.payment,
- hash,
- amount: -req.body.payment.amount,
- tip: 0,
- account_id: account.id,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed: true,
- received: false,
- network: "bitcoin"
- },
- { transaction }
- );
-
- await account.increment(
- { balance: payment.amount - payment.fee },
- { transaction }
- );
- await account.reload({ transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- emit(user.username, "payment", payment);
- emit(user.username, "account", payment.account);
- res.send(payment);
- });
- } else {
- res.send(result);
- }
- } catch (e) {
- res.code(500).send(e.message);
- }
-};
diff --git a/routes/bitcoin/conversionFee.js b/routes/bitcoin/conversionFee.js
deleted file mode 100644
index 7e305659..00000000
--- a/routes/bitcoin/conversionFee.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Code for the conversion fee
-// This is in a separate file so that the same function can be used by ./send and ./receive
-
-const conversionFeeMultiplier = 0.001;
-export const conversionFeeReceiver = "coinosfees"; // account that receives the fees
-
-/**
- * Returns the fee you have to pay for withdrawing 'amount' bitcoin.
- */
-export function computeConversionFee(amount) {
- return Math.floor(amount * conversionFeeMultiplier);
-}
diff --git a/routes/bitcoin/fee.js b/routes/bitcoin/fee.js
deleted file mode 100644
index 74c26a92..00000000
--- a/routes/bitcoin/fee.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import config from "$config";
-import db from "$db";
-import bc from "$lib/bitcoin";
-import { err } from "$lib/logging";
-import { emit } from "$lib/sockets";
-import buildTx from "$lib/buildtx";
-import { SATS } from "$lib/utils";
-
-export default async (req, res) => {
- let { user } = req;
- let { address, amount, feeRate, replaceable = true } = req.body;
- let tx, fee;
-
- if (user.account.pubkey) {
- try {
- let psbt = await buildTx({ address, amount, feeRate, replaceable, user });
- return res.send(psbt);
- } catch (e) {
- return res.code(500).send(e.message);
- }
- }
-
- let invoice = await db.Invoice.findOne({
- where: { address },
- include: {
- attributes: ["username"],
- model: db.User,
- as: "user"
- }
- });
-
- if (invoice) {
- let { ismine } = await bc.getAddressInfo(address);
- if (ismine) {
- emit(user.username, "to", invoice.user);
- return res.send({});
- }
- }
-
- try {
- amount = parseInt(amount);
-
- let partial = await bc.createRawTransaction(
- [],
- {
- [address]: (amount / SATS).toFixed(8)
- },
- 0,
- replaceable
- );
-
- let params = {
- subtractFeeFromOutputs: amount === user.balance ? [0] : [],
- replaceable
- };
-
- if (feeRate) params.feeRate = (feeRate / SATS).toFixed(8);
-
- tx = await bc.fundRawTransaction(partial, params);
-
- if (config.bitcoin.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
-
- let signed = await bc.signRawTransactionWithWallet(tx.hex);
- let decoded = await bc.decodeRawTransaction(signed.hex);
- feeRate = Math.round((tx.fee * SATS * 1000) / decoded.vsize);
-
- res.send({ feeRate, tx });
- } catch (e) {
- err("bitcoin fee estimation error", e);
- return res.code(500).send(e.message);
- }
-};
diff --git a/routes/bitcoin/generate.js b/routes/bitcoin/generate.js
deleted file mode 100644
index 6285492d..00000000
--- a/routes/bitcoin/generate.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default async (req, res) => {
- let address = await bc.getNewAddress();
- await bc.generateToAddress(1, address);
- res.send({});
-};
diff --git a/routes/bitcoin/index.js b/routes/bitcoin/index.js
deleted file mode 100644
index 58b0d193..00000000
--- a/routes/bitcoin/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import broadcast from "./broadcast";
-import generate from "./generate";
-import sweep from "./sweep";
-import fee from "./fee";
-import send from "./send";
-
-export default {
- broadcast,
- generate,
- sweep,
- fee,
- send
-};
diff --git a/routes/bitcoin/receive.js b/routes/bitcoin/receive.js
deleted file mode 100644
index 10193ceb..00000000
--- a/routes/bitcoin/receive.js
+++ /dev/null
@@ -1,281 +0,0 @@
-import config from "$config";
-import db from "$db";
-import bc from "$lib/bitcoin";
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import { notify } from "$lib/notifications";
-import { callWebhook } from "$lib/webhooks";
-import reverse from "buffer-reverse";
-import zmq from "zeromq/v5-compat";
-import { Op } from "@sequelize/core";
-import { fromBase58 } from "bip32";
-import bitcoin from "bitcoinjs-lib";
-import { sendLiquid } from "$routes/liquid/send";
-import { computeConversionFee } from "./conversionFee";
-import { l, warn, err } from "$lib/logging";
-
-const zmqRawBlock = zmq.socket("sub");
-zmqRawBlock.connect(config.bitcoin.zmqrawblock);
-zmqRawBlock.subscribe("rawblock");
-
-const zmqRawTx = zmq.socket("sub");
-zmqRawTx.connect(config.bitcoin.zmqrawtx);
-zmqRawTx.subscribe("rawtx");
-
-const network =
- bitcoin.networks[
- config.bitcoin.network === "mainnet" ? "bitcoin" : config.bitcoin.network
- ];
-
-const queue = {};
-const seen = [];
-
-console.warn = () => {};
-
-zmqRawTx.on("message", async (topic, message, sequence) => {
- try {
- const hex = message.toString("hex");
- let tx = bitcoin.Transaction.fromHex(message);
-
- let hash = reverse(tx.getHash()).toString("hex");
-
- if (seen.includes(hash)) return;
- seen.push(hash);
- if (seen.length > 5000) seen.shift();
-
- Promise.all(
- tx.outs.map(async o => {
- try {
- const { value } = o;
-
- let address;
- try {
- address = bitcoin.address.fromOutputScript(o.script, network);
- } catch (e) {
- return;
- }
-
- if (
- Object.keys(store.addresses).includes(address) &&
- !store.change.includes(address)
- ) {
- await db.transaction(async transaction => {
- let user = await db.User.findOne({
- where: {
- username: store.addresses[address]
- },
- transaction
- });
-
- let invoice = await db.Invoice.findOne({
- where: {
- address,
- user_id: user.id,
- network: "bitcoin"
- },
- order: [["id", "DESC"]],
- include: {
- model: db.Account,
- as: "account"
- },
- transaction
- });
-
- if (!invoice) return;
-
- const currency = invoice ? invoice.currency : user.currency;
- const rate = invoice ? invoice.rate : store.rates[user.currency];
- const tip = invoice ? invoice.tip : 0;
- const memo = invoice ? invoice.memo : "";
-
- let confirmed = false;
-
- let { account } = invoice;
-
- if (account.asset !== config.liquid.btcasset) {
- account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset: config.liquid.btcasset,
- pubkey: null
- },
- transaction
- });
- }
-
- await invoice.increment({ pending: value }, { transaction });
- await invoice.reload({ transaction });
-
- await account.increment({ pending: value }, { transaction });
- await account.reload({ transaction });
-
- if (config.bitcoin.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
-
- let totalOutputs = tx.outs.reduce((a, b) => a + b.value, 0);
- let totalInputs = 0;
- for (let i = 0; i < tx.ins.length; i++) {
- let { hash, index } = tx.ins[i];
- hash = reverse(hash).toString("hex");
- let hex = await bc.getRawTransaction(hash);
- let inputTx = bitcoin.Transaction.fromHex(hex);
- totalInputs += inputTx.outs[index].value;
- }
- let fee = totalInputs - totalOutputs;
-
- let payment = await db.Payment.create(
- {
- account_id: account.id,
- user_id: user.id,
- hash,
- fee,
- memo,
- amount: value - tip,
- currency,
- rate,
- received: true,
- tip,
- confirmed,
- address,
- network: "bitcoin",
- invoice_id: invoice.id
- },
- { transaction }
- );
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- payment.invoice = invoice.get({ plain: true });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", payment);
- l("bitcoin detected", user.username, value);
- notify(user, `${value} SAT payment detected`);
- callWebhook(invoice, payment);
- });
- }
- } catch (e) {
- console.log("problem parsing bitcoin tx", e);
- }
- })
- );
- } catch (e) {
- console.log("problem receiving bitcoin tx", e);
- }
-});
-
-zmqRawBlock.on("message", async (topic, message, sequence) => {
- try {
- const payments = await db.Payment.findAll({
- where: { confirmed: false }
- });
-
- let block = bitcoin.Block.fromHex(message.toString("hex"));
- block.transactions.map(tx => {
- let hash = reverse(tx.getHash()).toString("hex");
- if (payments.find(p => p.hash === hash)) queue[hash] = 1;
- });
- } catch (e) {
- console.log(e);
- }
-});
-
-setInterval(async () => {
- try {
- const arr = Object.keys(queue);
- for (let i = 0; i < arr.length; i++) {
- const hash = arr[i];
-
- let account, address, invoice, user, total;
- await db.transaction(async transaction => {
- let payments = await db.Payment.findAll({
- where: { hash, confirmed: 0, received: 1 },
- include: [
- {
- model: db.Account,
- as: "account"
- },
- {
- model: db.Invoice,
- as: "invoice"
- },
- {
- model: db.User,
- as: "user"
- }
- ],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- for (let i = 0; i < payments.length; i++) {
- let p = payments[i];
- if (p && p.address) address = p.address;
- if (p && p.user) user = p.user;
-
- if (p && p.account) {
- ({ account, invoice } = p);
- total = p.amount + p.tip;
-
- p.confirmed = 1;
- await account.save({ transaction });
-
- await invoice.increment({ received: total }, { transaction });
- await invoice.decrement(
- { pending: Math.min(invoice.pending, total) },
- { transaction }
- );
-
- await account.increment({ balance: total }, { transaction });
- await account.decrement(
- { pending: Math.min(account.pending, total) },
- { transaction }
- );
- // get the # of fee credits you would need to pay off this amount of bitcoin
- await account.increment(
- { btc_credits: computeConversionFee(total) },
- { transaction }
- );
- await account.reload({ transaction });
- await invoice.reload({ transaction });
- await p.save({ transaction });
-
- p = p.get({ plain: true });
- p.account = account.get({ plain: true });
- p.invoice = invoice.get({ plain: true });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", p);
- l("bitcoin confirmed", user.username, p.amount, p.tip);
- notify(user, `${total} SAT payment confirmed`);
- callWebhook(p.invoice, p);
-
- let c = store.convert[address];
- if (address && c) {
- l(
- "bitcoin detected to conversion address",
- address,
- c.address,
- user.username
- );
- user.account = account;
-
- sendLiquid({
- address: c.address,
- amount: total - 100,
- user,
- limit: total
- });
- }
- } else {
- warn("couldn't find bitcoin payment", hash);
- }
- }
-
- delete queue[hash];
- });
- }
- } catch (e) {
- err("problem processing queued bitcoin transaction", e.message, e.stack);
- }
-}, 1000);
diff --git a/routes/bitcoin/send.js b/routes/bitcoin/send.js
deleted file mode 100644
index c52592ae..00000000
--- a/routes/bitcoin/send.js
+++ /dev/null
@@ -1,193 +0,0 @@
-import bc from "$lib/bitcoin";
-import { emit } from "$lib/sockets";
-import db from "$db";
-import { toSats } from "$lib/utils";
-import store from "$lib/store";
-import config from "$config";
-import { l, warn, err } from "$lib/logging";
-import { requirePin } from "$lib/utils";
-
-const btc = config.liquid.btcasset;
-import {
- computeConversionFee,
- conversionFeeReceiver,
-} from "./conversionFee.js";
-
-export default async (req, res) => {
- try {
- await requirePin(req);
-
- let { user } = req;
- let { address, memo, tx } = req.body;
- let { hex } = tx;
-
- let fee = toSats(tx.fee);
- if (fee < 0) throw new Error("fee cannot be negative");
-
- const isChange = async ({ address }) =>
- (await bc.getAddressInfo(address)).ismine &&
- !Object.keys(store.addresses).includes(address);
-
- tx = await bc.decodeRawTransaction(hex);
-
- let total = 0;
- let change = 0;
-
- for (let i = 0; i < tx.vout.length; i++) {
- let o = tx.vout[i];
- total += toSats(o.value);
-
- if (await isChange(o.scriptPubKey)) {
- change += toSats(o.value);
- }
- }
-
- total = total - change + fee;
- let amount = total - fee;
-
- // get conversion fee
- // 'total' refers to the total before the conversion fee
- // (i.e. the total bitcoin that leaves this server)
- let conversionFee = computeConversionFee(amount);
-
- // withdraw bitcoin
- await db.transaction(async (transaction) => {
- let { account } = user;
- if (account.asset !== btc) {
- account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset: btc,
- pubkey: null,
- },
- lock: transaction.LOCK.UPDATE,
- transaction,
- });
- }
-
- // use user's credits to reduce fee, if available
- let conversionFeeDeduction = Math.min(account.btc_credits, conversionFee);
- if (conversionFeeDeduction) {
- await account.decrement(
- { btc_credits: conversionFeeDeduction },
- { transaction }
- );
- await account.reload({ transaction });
- conversionFee -= conversionFeeDeduction;
- }
-
- l(
- "attempting to send bitcoin",
- user.username,
- account.id,
- address,
- total,
- conversionFee,
- conversionFeeDeduction
- );
-
- if (total > account.balance) {
- err("amount exceeds balance", amount, fee, account.balance);
- throw new Error("low");
- } else if (total + conversionFee > account.balance) {
- err(
- "total (after conversion fee) exceeds balance",
- amount,
- fee,
- account.balance
- );
- throw new Error("low");
- }
-
- await account.decrement(
- { balance: total + conversionFee },
- { transaction }
- );
- await account.reload({ transaction });
-
- let receiverAccount = await db.Account.findOne({
- where: {
- "$user.username$": conversionFeeReceiver,
- },
- include: [
- {
- model: db.User,
- as: "user",
- },
- ],
- lock: transaction.LOCK.UPDATE,
- transaction,
- });
-
- let fee_payment;
- let fee_payment_id = null;
- if (conversionFee) {
- await receiverAccount.increment(
- { balance: conversionFee },
- { transaction }
- );
- await receiverAccount.reload({ transaction });
- fee_payment = await db.Payment.create(
- {
- amount: conversionFee,
- fee: 0,
- memo: "Bitcoin conversion fee",
- account_id: receiverAccount.id,
- user_id: receiverAccount.user_id,
- rate: store.rates[receiverAccount.user.currency],
- currency: receiverAccount.user.currency,
- confirmed: true,
- received: true,
- network: "COINOS",
- },
- { transaction }
- );
- fee_payment_id = fee_payment.id;
- }
-
- // record the external bitcoin transaction
- let params = {
- amount: -amount,
- fee,
- memo,
- account_id: account.id,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- address,
- confirmed: true,
- received: false,
- network: "bitcoin",
- fee_payment_id: fee_payment_id,
- };
-
- if (config.bitcoin.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
-
- hex = (await bc.signRawTransactionWithWallet(hex)).hex;
- params.hash = await bc.sendRawTransaction(hex);
-
- let payment = await db.Payment.create(params, { transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- payment.fee_payment = fee_payment && fee_payment.get({ plain: true });
-
- emit(user.username, "payment", payment);
- res.send(payment);
-
- store.payments.push(params.hash);
- l("sent bitcoin", user.username, total);
- });
- } catch (e) {
- if (e.message.includes("Insufficient"))
- e.message =
- "Our server has insufficient funds, try again later";
-
- if (e.message === "low") e.message = "Insufficient funds in account"
-
- err("error sending bitcoin", e.message);
- console.log(e);
- return res.code(500).send(e.message);
- }
-};
diff --git a/routes/bitcoin/sweep.js b/routes/bitcoin/sweep.js
deleted file mode 100644
index 49fb1f04..00000000
--- a/routes/bitcoin/sweep.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import config from "$config";
-import { prod } from "$lib/utils";
-import axios from "axios";
-import bitcoin from "bitcoinjs-lib";
-import coinselect from "coinselect";
-import split from "coinselect/split";
-
-const api = prod ? "https://blockstream.info/api" : config.bitcoin.electrs;
-const SATS = 100000000;
-const network = prod
- ? bitcoin.networks["bitcoin"]
- : bitcoin.networks["regtest"];
-
-export default async (req, res) => {
- let { address: from, amount, feeRate, target } = req.body;
- let utxos;
- if (!feeRate) feeRate = (await bc.estimateSmartFee(6)).feerate * SATS;
- feeRate = Math.round(feeRate / 1000);
- l("sweeping", req.user.username, from, amount, feeRate);
-
- try {
- let {
- data: {
- chain_stats: { funded_txo_sum: funded, spent_txo_sum: spent }
- }
- } = await axios.get(`${api}/address/${from}`);
- let balance = funded - spent;
- console.log("boom");
-
- try {
- console.log("fetching utxo");
- ({ data: utxos } = await axios.get(`${api}/address/${from}/utxo`));
- console.log("got utxos", utxos);
- } catch (e) {
- err("problem fetching utxos", e.message);
- }
-
- let targets = [
- {
- address: target,
- value: amount
- }
- ];
-
- let { inputs, outputs, fee } = coinselect(utxos, targets, feeRate);
-
- if (balance === amount) {
- delete targets[0].value;
- ({ inputs, outputs, fee } = split(utxos, targets, feeRate));
- l("split", inputs, outputs, fee);
- }
-
- if (!inputs || !outputs)
- return res
- .code(500)
- .send("Unable to construct sweep transaction, try a lower fee rate?");
-
- let psbt = new bitcoin.Psbt({ network });
- let total = 0;
-
- outputs.map(({ address, value }) => {
- total += value;
- psbt = psbt.addOutput({
- address: address || from,
- value
- });
- });
-
- for (let i = 0; i < inputs.length; i++) {
- let { txid, vout } = inputs[i];
- let nonWitnessUtxo = Buffer.from(await bc.getRawTransaction(txid), "hex");
- psbt = psbt.addInput({
- hash: txid,
- index: vout,
- nonWitnessUtxo
- });
- }
-
- feeRate = Math.round(feeRate * 1000);
- psbt = psbt.toBase64();
-
- if (balance !== amount) total = 0;
- res.send({ feeRate, psbt, total });
- } catch (e) {
- err("problem getting address stats", from, e.message);
- }
-};
diff --git a/routes/email.js b/routes/email.js
new file mode 100644
index 00000000..529307e6
--- /dev/null
+++ b/routes/email.js
@@ -0,0 +1,24 @@
+import config from "$config";
+
+export default {
+ async send({ body }, res) {
+ try {
+ let postmark = await import("postmark");
+ let client = new postmark.ServerClient(config.postmark);
+
+ await client.sendEmail({
+ Subject: body.subject || "Email Signup",
+ HtmlBody: JSON.stringify(body),
+ TextBody: JSON.stringify(body),
+ MessageStream: "outbound"
+ });
+
+ res.send({ ok: true });
+ } catch (e) {
+ console.log("problem sending email", e);
+ res.code(500).send(e.message);
+ }
+ }
+};
diff --git a/routes/funding.js b/routes/funding.js
deleted file mode 100644
index e65a704e..00000000
--- a/routes/funding.js
+++ /dev/null
@@ -1,96 +0,0 @@
-import { emit } from "$lib/sockets";
-import app from "$app";
-import config from "$config";
-import mailgunFactory from "mailgun-js";
-const mailgun = mailgunFactory(config.mailgun);
-
-app.post("/id", auth, upload.single("id"), async (req, res) => {
- const { user } = req;
- if (user.verified === "proof") user.verified = "pending";
- else user.verified = "id";
- await user.save();
- emit(user.username, "user", user);
-
- let data = {
- subject: "KYC Documents",
- text: `ID uploaded for ${user.username}`,
- };
-
- mailgun.messages().send(data);
- l("id uploaded", user.username);
-
- res.send({});
-});
-
-app.post("/proof", auth, upload.single("proof"), async (req, res) => {
- const { user } = req;
- if (user.verified === "id") user.verified = "pending";
- else user.verified = "proof";
- await user.save();
- emit(user.username, "user", user);
- l("id proof uploaded", user.username);
-
- res.send({});
-});
-
-app.post("/funding", auth, async (req, res) => {
- try {
- let { id, amount, code } = req.body;
-
- if (!code) {
- code = "";
- let d = "ABCDEFGHIJKLMNPQRSTUVWXYZ23456789";
- let l = d.length;
- for (let i = 0; i < 8; i++) {
- code += d.charAt(Math.floor(Math.random() * l));
- }
- }
-
- let params = {
- user_id: req.user.id,
- amount,
- code
- };
-
- let deposit;
- if (id) {
- if (!parseFloat(amount) || parseFloat(amount) < 0)
- throw new Error("Invalid amount");
- deposit = await db.Deposit.findOne({ where: { id } });
- deposit.update(params);
- await deposit.save();
- } else {
- deposit = await db.Deposit.create(params);
- }
-
- res.send(deposit);
- } catch (e) {
- err("funding error", e.message);
- res.code(500).send("Funding request failed");
- }
-});
-
-app.post("/withdrawal", auth, async (req, res) => {
- try {
- const { account, amount, email, institution, transit, notes } = req.body;
- if (!parseFloat(amount) || parseFloat(amount) < 0)
- throw new Error("Invalid amount");
-
- await db.Withdrawal.create({
- user_id: req.user.id,
- account,
- amount,
- email,
- institution,
- transit,
- notes
- });
-
- res.send({});
- } catch (e) {
- err("withdrawaerr", e.message);
- res.code(500).send("Withdrawal request failed");
- }
-});
diff --git a/routes/info.js b/routes/info.js
index eb42ca35..017e473a 100644
--- a/routes/info.js
+++ b/routes/info.js
@@ -1,90 +1,32 @@
-import app from "$app";
-import db from "$db";
-import config from "$config";
-import store from "$lib/store";
-
-import bc from "$lib/bitcoin";
-import lq from "$lib/liquid";
+import db from "$lib/db";
import ln from "$lib/ln";
-import sequelize from "@sequelize/core";
-import { SATS } from "$lib/utils";
-
-const { Op } = sequelize;
-
-/**
- * @api {get} /info Request server information
- * @apiName GetInfo
- * @apiGroup Info
- *
- * @apiSuccess {Object} fx Exchange rates relative to USD - fx.CUR is the value of one CUR in USD.
- * @apiSuccess {String[]} networks Array of supported networks; possible values are "bitcoin", "liquid" and "lightning".
- * @apiSuccess {String} clientVersion the current git commit of the ui
- */
-app.get("/info", async (req, res, next) => {
- const { clientVersion } = config;
-
- const info = {
- fx: store.fx,
- nodes: store.networks,
- clientVersion
- };
-
- res.send(info);
-});
+export default {
+ async balances(req, res) {
+ let lnchannel;
+ let lnwallet;
-app.get("/balances", async (req, res, next) => {
- try {
- const accounts = await db.Account.findAll({
- where: {
- pubkey: null
- },
- attributes: [
- "asset",
- [sequelize.fn("sum", sequelize.col("balance")), "total"]
- ],
- group: ["asset"]
+ const stream = db.scanStream({
+ match: "balance:*",
+ count: 100
});
- let lnchannel;
- let lnwallet;
+ let b = 0;
+ for await (let keys of stream) {
+ for (let k of keys) b += parseInt(await db.get(k));
+ }
+ console.log(b);
const funds = await ln.listfunds();
lnchannel = parseInt(funds.channels.reduce((a, b) => a + b.channel_sat, 0));
lnwallet = parseInt(funds.outputs.reduce((a, b) => a + b.value, 0));
- let bitcoin, bitcoind;
- if (config.bitcoin) {
- bitcoin = parseInt((await bc.getBalance()) * SATS);
- bitcoind = await bc.getNetworkInfo();
- }
-
- let assets, liquid, elementsd;
- if (config.liquid) {
- assets = await lq.getBalance();
- liquid = parseInt(assets.bitcoin * SATS);
- elementsd = await lq.getNetworkInfo();
- }
-
const info = {
- bitcoind,
- elementsd,
- accounts,
- assets,
- bitcoin,
- liquid,
lnchannel,
- lnwallet
+ lnwallet,
+ total: lnchannel + lnwallet
};
- info.total =
- parseInt(bitcoin) +
- parseInt(liquid) +
- parseInt(lnchannel) +
- parseInt(lnwallet);
-
res.send(info);
- } catch (e) {
- console.log("problem getting balances", e);
}
-});
+};
diff --git a/routes/invoices.js b/routes/invoices.js
index 7fa82afb..d856ef6b 100644
--- a/routes/invoices.js
+++ b/routes/invoices.js
@@ -1,209 +1,39 @@
-import app from "$app";
-import db from "$db";
-import store from "$lib/store";
-import { optionalAuth } from "$lib/passport";
-import { Op } from "@sequelize/core";
-import axios from "axios";
-import { err, l } from "$lib/logging";
-import bc from "$lib/bitcoin";
-import lq from "$lib/liquid";
-import { SATS, bip21, deriveAddress, derivePayRequest } from "$lib/utils";
-import { emit } from "$lib/sockets";
+import { g, s } from "$lib/db";
+import { generate } from "$lib/invoices";
+import got from "got";
+import config from "$config";
-app.get("/invoice", async (req, res, next) => {
- try {
- const invoice = await db.Invoice.findOne({
- where: {
- uuid: req.query.uuid
- },
- include: [
- {
- model: db.User,
- as: "user",
- attributes: ["username", "currency", "profile"]
- },
- {
- model: db.Request,
- as: "request"
- }
- ]
- });
-
- res.send(invoice);
- } catch (e) {
- err("invoice not found", e);
- res.code(500).send("Invoice not found");
- }
-});
-
-app.get("/invoice/:text", async (req, res, next) => {
- try {
- let { text } = req.params;
- let where =
- text.split("-").length > 4
- ? { uuid: text }
- : text.startsWith("ln")
- ? { text }
- : {
- [Op.or]: [{ unconfidential: text }, { address: text }]
- };
-
- const invoice = await db.Invoice.findOne({
- where,
- include: {
- model: db.User,
- as: "user",
- attributes: ["username", "currency", "profile"]
- }
- });
-
- res.send(invoice);
- } catch (e) {
- err("invoice not found", e);
- res.code(500).send("Invoice not found");
- }
-});
-
-app.post("/invoice", optionalAuth, async (req, res, next) => {
- try {
- let { type = "bech32", liquidAddress, id, invoice, user, tx } = req.body;
- let {
- blindkey,
- currency,
- tip,
- amount,
- rate,
- network,
- request_id
- } = invoice;
- let address, unconfidential, text;
-
- if (amount < 0) throw new Error("amount out of range");
- if (tip > 5 * amount || tip < 0) throw new Error("tip amount out of range");
-
- if (!user) ({ user } = req);
- else {
- user = await db.User.findOne({
- where: {
- username: user.username
- },
- include: {
- model: db.Account,
- as: "account"
- }
- });
- }
- if (!user) throw new Error("user not provided");
- if (!currency) currency = user.currency;
- if (!rate) rate = store.rates[currency];
- if (amount < 0) throw new Error("invalid amount");
+export default {
+ async get({ params: { hash } }, res) {
+ let invoice = await g(`invoice:${hash}`);
- if (user.account.pubkey) {
- let { address, confidentialAddress } = await deriveAddress(
- user.account,
- type
- );
- if (confidentialAddress) {
- address = confidentialAddress;
- unconfidential = address;
- } else {
- address = address;
- }
- } else if (network !== "lightning") {
- address = await { bitcoin: bc, liquid: lq }[network].getNewAddress();
- if (network === "liquid")
- ({ unconfidential } = await lq.getAddressInfo(address));
- }
-
- invoice = {
- ...invoice,
- account_id: user.account.id,
- address,
- amount,
- currency,
- rate,
- tip,
- unconfidential,
- user_id: user.id
- };
-
- if (network === "lightning") {
- invoice.text = await derivePayRequest(invoice);
+ if (invoice) {
+ invoice.user = await g(`user:${invoice.uid}`);
} else {
- invoice.text = bip21(invoice, user.account);
+ invoice = await got(`${config.classic}/invoice/${hash}`).json();
+ invoice.id = invoice.uuid;
+ invoice.classic = true;
+ invoice.user.id = invoice.user.uuid;
+ invoice.user.username += "@classic";
}
- if (liquidAddress) {
- if (network === "lightning") {
- l("conversion request for", liquidAddress, invoice.text);
- store.convert[invoice.text] = { address: liquidAddress, tx };
- } else if (network === "liquid") {
- l("conversion request for", liquidAddress, invoice.unconfidential);
- store.convert[invoice.unconfidential] = { address: liquidAddress, tx };
- } else {
- l("conversion request for", liquidAddress, invoice.address);
- store.convert[invoice.address] = { address: liquidAddress, tx };
- }
- }
-
- l(
- "creating invoice",
- user.username,
- invoice.network,
- invoice.amount,
- invoice.tip,
- invoice.currency,
- invoice.text && `${invoice.text.substr(0, 8)}..${invoice.text.substr(-6)}`
- );
-
- if (!invoice.tip) invoice.tip = 0;
-
- invoice = await db.Invoice.create(invoice);
- store.addresses[invoice.address] = user.username;
- if (invoice.unconfidential) {
- store.addresses[invoice.unconfidential] = user.username;
- if (blindkey) await lq.importBlindingKey(invoice.address, blindkey);
- }
+ res.send(invoice);
+ },
- if (request_id) {
- let request = await db.Request.findOne({
- where: { id: request_id },
+ async create({ body: { invoice, user }, user: sender }, res) {
+ res.send(await generate({ invoice, user, sender }));
+ },
- include: {
- model: db.User,
- as: "requester",
- attributes: ["username"]
+ async classic({ params: { username } }, res) {
+ let invoice = await got
+ .post(`${config.classic}/invoice`, {
+ json: {
+ invoice: { amount: 0, network: "lightning" },
+ user: { username }
}
- });
-
- if (request) {
- let existing = request.invoice_id;
- request.invoice_id = invoice.id;
- await request.save();
-
- if (!existing)
- emit(request.requester.username, "invoice", {
- amount: invoice.amount,
- currency: invoice.currency,
- rate: invoice.rate,
- request_id,
- uuid: invoice.uuid,
- user: { username: user.username, profile: user.profile }
- });
- }
- }
+ })
+ .json();
res.send(invoice);
- } catch (e) {
- err(e.message, e.stack);
- res.code(500).send(`Problem during invoice creation: ${e.message}`);
- }
-});
-
-app.post(
- "/:username/:network/invoice",
- optionalAuth,
- async (req, res, next) => {
- let { network, username } = req.params;
}
-);
+};
diff --git a/routes/lightning/channel.js b/routes/lightning/channel.js
deleted file mode 100644
index d5d5b7b2..00000000
--- a/routes/lightning/channel.js
+++ /dev/null
@@ -1,29 +0,0 @@
-import axios from "axios";
-import ln from "$lib/ln";
-
-export default async (req, res) => {
- const { params } = req.body;
- const [public_key, socket] = params.uri.split("@");
-
- l("connecting to peer", req.user.username, public_key, socket);
- let result;
-
- const { callback, k1 } = params;
- let remoteid;
- try {
- remoteid = (await ln.getinfo()).id;
- } catch (e) {
- err("problem getting lightning node info", e.message);
- return res.code(500).send(e.message);
- }
-
- let url = `${callback}?k1=${k1}&remoteid=${remoteid}&private=0`;
-
- try {
- let response = await axios.get(url);
- res.send(response.data);
- } catch (e) {
- err("problem sending channel request", e.message);
- return res.code(500).send({ status: "ERROR", reason: e.message });
- }
-};
diff --git a/routes/lightning/channelRequest.js b/routes/lightning/channelRequest.js
deleted file mode 100644
index 74e4cbba..00000000
--- a/routes/lightning/channelRequest.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { lnurlServer } from "$routes/lnurl";
-import { err } from "$lib/logging";
-
-export const channelRequest = async (req, res) => {
- let { localAmt, pushAmt } = req.body;
-
- pushAmt = 0;
-
- try {
- if (localAmt < 20000)
- throw new Error("amount must be greater than 20000 SAT");
- if (localAmt > 1000000) throw new Error("amount must be <= 1000000");
-
- const result = await lnurlServer.generateNewUrl("channelRequest", {
- localAmt,
- pushAmt
- });
-
- res.send(result);
- } catch (e) {
- err("problem generating channel request", e.message);
- res.code(500).send(e.message);
- }
-};
diff --git a/routes/lightning/conversionFee.js b/routes/lightning/conversionFee.js
deleted file mode 100644
index f6cf434c..00000000
--- a/routes/lightning/conversionFee.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Code for the conversion fee
-// This is in a separate file so that the same function can be used by ./send and ./receive
-
-const conversionFeeMultiplier = 0.001;
-export const conversionFeeReceiver = "coinosfees"; // account that receives the fees
-
-/**
- * Returns the fee you have to pay for withdrawing 'amount' lightning BTC.
- */
-export function computeConversionFee(amount) {
- return Math.floor(amount * conversionFeeMultiplier);
-}
diff --git a/routes/lightning/index.js b/routes/lightning/index.js
deleted file mode 100644
index b4611ef5..00000000
--- a/routes/lightning/index.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import channel from "./channel";
-import invoice from "./invoice";
-import query from "./query";
-import send from "./send";
-import parse from "./parse";
-
-export default {
- channel,
- invoice,
- query,
- send,
- parse
-};
diff --git a/routes/lightning/invoice.js b/routes/lightning/invoice.js
deleted file mode 100644
index ae974120..00000000
--- a/routes/lightning/invoice.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import config from "$config";
-import { err } from "$lib/logging";
-import ln from "$lib/ln";
-import { v4 } from "uuid";
-
-export default async (req, res) => {
- let { amount, memo, tip } = req.body;
- if (!tip) tip = 0;
- let value = amount + tip;
-
- try {
- if (!memo) memo = "coinos";
- const invoice = await ln.invoice(
- value ? `${value}sat` : "any",
- v4(),
- memo,
- 360
- );
- res.send({ text: invoice.bolt11 });
- } catch (e) {
- console.log(e);
- err("problem creating invoice", e.message);
- res.code(500).send(e.message);
- }
-};
diff --git a/routes/lightning/parse.js b/routes/lightning/parse.js
deleted file mode 100644
index 1b77019a..00000000
--- a/routes/lightning/parse.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import ln from "$lib/ln";
-import store from "$lib/store";
-
-export default async (req, res) => {
- let { payreq } = req.body;
- let hour = 1000 * 60 * 60;
- let { last } = store.nodes;
- let { nodes } = store;
-
- if (!last || last > Date.now() - hour) ({ nodes } = await ln.listnodes());
- store.nodes = nodes;
-
- let twoWeeksAgo = new Date(new Date().setDate(new Date().getDate() - 14));
- let { msatoshi, payee } = await ln.decodepay(payreq);
- let node = nodes.find((n) => n.nodeid === payee);
- let alias = node ? node.alias : payee.substr(0, 12);
-
- res.send({ alias, amount: Math.round(msatoshi / 1000) });
-};
diff --git a/routes/lightning/query.js b/routes/lightning/query.js
deleted file mode 100644
index 1c217a08..00000000
--- a/routes/lightning/query.js
+++ /dev/null
@@ -1,20 +0,0 @@
-import db from "$db";
-import { emit } from "$lib/sockets";
-
-export default async (req, res) => {
- const { payreq } = req.body;
-
- const invoice = await db.Invoice.findOne({
- include: {
- attributes: ["username"],
- model: db.User,
- as: "user"
- },
- where: {
- text: payreq
- }
- });
-
- if (invoice) emit(req.user.username, "to", invoice.user);
- res.send({});
-};
diff --git a/routes/lightning/receive.js b/routes/lightning/receive.js
deleted file mode 100644
index ef973acc..00000000
--- a/routes/lightning/receive.js
+++ /dev/null
@@ -1,162 +0,0 @@
-import db from "$db";
-import store from "$lib/store";
-import { emit } from "$lib/sockets";
-import config from "$config";
-import { notify } from "$lib/notifications";
-import { callWebhook } from "$lib/webhooks";
-import { computeConversionFee } from "./conversionFee";
-import { sendLiquid } from "$routes/liquid/send";
-import ln from "$lib/ln";
-import { l, err, warn } from "$lib/logging";
-
-const handlePayment = async msg => {
- try {
- l("incoming lightning payment", msg.received);
-
- if (!msg.secret) return;
- let account, total, user;
-
- const invoice = await db.Invoice.findOne({
- where: {
- text: msg.request
- }
- });
-
- if (!invoice)
- return warn("received lightning with no invoice", msg.request);
-
- await db.transaction(async transaction => {
- const { text: hash, currency, memo, rate, tip, user_id } = invoice;
- const amount = parseInt(msg.received) - tip;
- if (amount < 0) throw new Error("amount out of range");
-
- account = await db.Account.findOne({
- where: {
- user_id,
- asset: config.liquid.btcasset,
- pubkey: null
- },
- include: {
- model: db.User,
- as: "user"
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- ({ user } = account);
-
- let preimage = msg.secret;
-
- let payment = await db.Payment.create(
- {
- account_id: account.id,
- user_id,
- hash,
- memo,
- amount,
- currency,
- preimage,
- rate,
- received: true,
- confirmed: true,
- network: "lightning",
- tip,
- invoice_id: invoice.id
- },
- { transaction }
- );
-
- total = amount + tip;
-
- invoice.status = "paid";
- await invoice.save({ transaction });
-
- await invoice.increment({ received: total }, { transaction });
- await account.increment({ balance: total }, { transaction });
- // get the # of fee credits you would need to pay off this amount of bitcoin
- await account.increment(
- { lightning_credits: computeConversionFee(total) },
- { transaction }
- );
- await account.reload({ transaction });
- await invoice.reload({ transaction });
- await payment.save({ transaction });
- store.payments.push(msg.request);
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- payment.invoice = invoice.get({ plain: true });
-
- callWebhook(invoice, payment);
-
- emit(user.username, "payment", payment);
- emit(user.username, "account", payment.account);
- notify(user, `Received ${total} SAT`);
-
- l(
- "lightning payment received",
- user.username,
- payment.amount,
- payment.tip
- );
- });
-
- let c = store.convert[msg.request];
- if (msg.request && c) {
- l(
- "lightning detected for conversion request",
- msg.request,
- c.address,
- user.username
- );
-
- user.account = account;
-
- try {
- sendLiquid({
- address: c.address,
- amount: total - 100,
- user,
- limit: total
- });
- } catch (e) {
- err("problem sending liquid payment", e.message, e.stack);
- }
- }
- } catch (e) {
- console.log(e);
- err("problem receiving lightning payment", e.message);
- }
-};
-
-const poll = async ln => {
- try {
- const wait = async i => {
- const {
- bolt11: request,
- pay_index,
- status,
- msatoshi_received,
- payment_preimage: secret
- } = await ln.waitanyinvoice(i);
-
- let settled = status === "paid";
- let received = parseInt(msatoshi_received / 1000);
-
- await handlePayment({
- request,
- received,
- secret
- });
- await wait(pay_index);
- };
-
- const { invoices } = await ln.listinvoices();
- await wait(Math.max(...invoices.map(i => i.pay_index).filter(n => n)));
- } catch (e) {
- err("problem waiting for c-lightning invoice", e.message);
- }
-};
-
-poll(ln);
diff --git a/routes/lightning/send.js b/routes/lightning/send.js
deleted file mode 100644
index b41d5ed0..00000000
--- a/routes/lightning/send.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { err } from "$lib/logging";
-import send from "$lib/send";
-import { requirePin } from "$lib/utils";
-
-export default async (req, res) => {
- let { amount, route, memo, payreq } = req.body;
- let { user } = req;
-
- try {
- await requirePin(req);
- res.send(await send(amount, memo, payreq, user));
- } catch (e) {
- console.log(e);
- err("problem sending lightning payment", user.username, payreq, e.message);
- res.code(500).send(e.message);
- }
-};
diff --git a/routes/liquid/broadcast.js b/routes/liquid/broadcast.js
deleted file mode 100644
index 820c0be1..00000000
--- a/routes/liquid/broadcast.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import { requirePin } from "$lib/utils";
-
-export default async (req, res) => {
- try {
- await requirePin(req);
-
- const { user } = req;
- let hash = await lq.sendRawTransaction(req.body.tx);
-
- if (user) {
- await db.transaction(async transaction => {
- let account = await db.Account.findOne({
- where: {
- id: user.account_id
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- let payment = await db.Payment.create(
- {
- ...req.body.payment,
- hash,
- amount: -req.body.payment.amount,
- tip: 0,
- account_id: account.id,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed: true,
- received: false,
- network: "liquid"
- },
- { transaction }
- );
-
- await account.increment(
- { balance: payment.amount - payment.fee },
- { transaction }
- );
- await account.reload({ transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- emit(user.username, "payment", payment);
- emit(user.username, "account", payment.account);
- res.send(payment);
- });
- } else {
- res.send(hash);
- }
- } catch (e) {
- err("problem broadcasting liquid transaction", e);
- res.code(500).send(e.message);
- }
-};
diff --git a/routes/liquid/conversionFee.js b/routes/liquid/conversionFee.js
deleted file mode 100644
index a25c2e7d..00000000
--- a/routes/liquid/conversionFee.js
+++ /dev/null
@@ -1,12 +0,0 @@
-// Code for the conversion fee
-// This is in a separate file so that the same function can be used by ./send and ./receive
-
-const conversionFeeMultiplier = 0.001;
-export const conversionFeeReceiver = "coinosfees"; // account that receives the fees
-
-/**
- * Returns the fee you have to pay for withdrawing 'amount' L-BTC.
- */
-export function computeConversionFee(amount) {
- return Math.floor(amount * conversionFeeMultiplier);
-}
diff --git a/routes/liquid/fee.js b/routes/liquid/fee.js
deleted file mode 100644
index ae6e4393..00000000
--- a/routes/liquid/fee.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import config from "$config";
-import db from "$db";
-import { emit } from "$lib/sockets";
-import buildTx from "$lib/buildliquidtx";
-import { err, l } from "$lib/logging";
-import { SATS } from "$lib/utils";
-import lq from "$lib/liquid";
-
-export const liquidTx = async ({ address, asset, amount, feeRate, replaceable, user }) => {
- let tx, fee;
-
- if (user.account.pubkey) {
- let psbt = await buildTx({
- address,
- asset,
- amount,
- feeRate,
- replaceable,
- user
- });
- return psbt;
- }
-
- let invoice = await db.Invoice.findOne({
- where: { address },
- include: {
- attributes: ["username"],
- model: db.User,
- as: "user"
- }
- });
-
- if (invoice) {
- let { ismine } = await lq.getAddressInfo(address);
- if (ismine) {
- emit(user.username, "to", invoice.user);
- return;
- }
- }
-
- if (config.liquid.walletpass)
- await lq.walletPassphrase(config.liquid.walletpass, 300);
-
- amount = parseInt(amount);
-
- let params = {
- subtractFeeFromOutputs: amount === user.balance ? [0] : []
- };
-
- let value = (amount / SATS).toFixed(8);
- if (feeRate) params.feeRate = (feeRate / SATS).toFixed(8);
-
- let info = await lq.getAddressInfo(address);
-
- tx = await lq.createRawTransaction(
- [],
- [
- {
- [address]: (amount / SATS).toFixed(8),
- asset
- }
- ],
- 0,
- replaceable
- );
-
- l("funding tx for fee estimate", tx);
-
- tx = await lq.fundRawTransaction(tx, params);
-
- let blinded = await lq.blindRawTransaction(tx.hex);
- let signed = await lq.signRawTransactionWithWallet(blinded);
-
- let decoded = await lq.decodeRawTransaction(signed.hex);
- feeRate = Math.round((tx.fee * SATS * 1000) / decoded.vsize);
- l("estimated", asset, feeRate);
-
- return { feeRate, tx };
-};
-
-export default async (req, res) => {
- try {
- let tx = await liquidTx({ ...req.body, user: req.user });
- res.send(tx);
- } catch (e) {
- err("error estimating liquid fee", e.message, e.stack);
- return res.code(500).send(e.message);
- }
-};
diff --git a/routes/liquid/generate.js b/routes/liquid/generate.js
deleted file mode 100644
index 423d8b6a..00000000
--- a/routes/liquid/generate.js
+++ /dev/null
@@ -1,5 +0,0 @@
-export default async (req, res) => {
- let address = await lq.getNewAddress();
- await lq.generateToAddress(1, address);
- res.send({});
-};
diff --git a/routes/liquid/index.js b/routes/liquid/index.js
deleted file mode 100644
index c4c50021..00000000
--- a/routes/liquid/index.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import broadcast from "./broadcast";
-import generate from "./generate";
-import fee from "./fee";
-import send from "./send";
-
-export default {
- broadcast,
- generate,
- fee,
- send,
-};
diff --git a/routes/liquid/receive.js b/routes/liquid/receive.js
deleted file mode 100644
index 718feba5..00000000
--- a/routes/liquid/receive.js
+++ /dev/null
@@ -1,406 +0,0 @@
-import db from "$db";
-import config from "$config";
-import { getBlockHeight, getUser, getUserById, toSats, SATS } from "$lib/utils";
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import { sendLiquid } from "$routes/liquid/send";
-import { notify } from "$lib/notifications";
-import { callWebhook } from "$lib/webhooks";
-import reverse from "buffer-reverse";
-import zmq from "zeromq/v5-compat";
-import { Op } from "@sequelize/core";
-import { fromBase58 } from "bip32";
-import bitcoin from "bitcoinjs-lib";
-import liquidJs from "liquidjs-lib";
-import { l, err, warn } from "$lib/logging";
-import lq from "$lib/liquid";
-
-const { Block, networks, Transaction } = liquidJs;
-
-const network =
- networks[
- config.liquid.network === "mainnet" ? "liquid" : config.liquid.network
- ];
-
-import { computeConversionFee } from "./conversionFee";
-
-const getAccount = async (params, transaction) => {
- let account = await db.Account.findOne({
- where: params,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (account) {
- l("found account", params, account.asset, account.id);
- return account;
- }
-
- let { asset, pubkey } = params;
- let name = asset.substr(0, 6);
- let domain = "";
- let ticker = asset.substr(0, 3).toUpperCase();
- let precision = 8;
-
- if (pubkey) {
- const nc = await db.Account.findOne({
- where: { pubkey },
- order: [["id", "ASC"]],
- limit: 1,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- params.index = 0;
- params.path = nc.path;
- params.pubkey = nc.pubkey;
- params.privkey = nc.privkey;
- params.seed = nc.seed;
- }
-
- if (store.assets[asset]) {
- ({ domain, ticker, precision, name } = store.assets[asset]);
- } else {
- const existing = await db.Account.findOne({
- where: {
- asset
- },
- order: [["id", "ASC"]],
- limit: 1,
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (existing) {
- l("existing", existing.id);
- ({ domain, ticker, precision, name } = existing);
- }
- }
-
- params = { ...params, ...{ domain, ticker, precision, name } };
- params.balance = 0;
- params.pending = 0;
- params.network = "liquid";
- return db.Account.create(params, { transaction });
-};
-
-const zmqRawBlock = zmq.socket("sub");
-zmqRawBlock.connect(config.liquid.zmqrawblock);
-zmqRawBlock.subscribe("rawblock");
-
-const zmqRawTx = zmq.socket("sub");
-zmqRawTx.connect(config.liquid.zmqrawtx);
-zmqRawTx.subscribe("rawtx");
-
-const queue = {};
-const seen = [];
-
-zmqRawTx.on("message", async (topic, message, sequence) => {
- try {
- const hex = message.toString("hex");
-
- let unblinded, tx, blinded, txid;
- try {
- txid = Transaction.fromHex(hex).getId();
- if (seen.includes(txid)) return;
- seen.push(txid);
- if (seen.length > 5000) seen.shift();
-
- unblinded = await lq.unblindRawTransaction(hex);
- tx = await lq.decodeRawTransaction(unblinded.hex);
- blinded = await lq.decodeRawTransaction(hex);
- } catch (e) {
- return err("problem decoding liquid tx", e.message);
- }
-
- for (let o of tx.vout) {
- try {
- if (!(o.scriptPubKey && o.scriptPubKey.address)) return;
-
- const { asset } = o;
- const value = toSats(o.value);
- const { address } = o.scriptPubKey;
-
- if (
- Object.keys(store.addresses).includes(address) &&
- !store.change.includes(address)
- ) {
- await db.transaction(async transaction => {
- let user = await getUser(store.addresses[address], transaction);
-
- let invoice = await db.Invoice.findOne({
- where: {
- [Op.or]: {
- unconfidential: address,
- address
- },
- user_id: user.id,
- network: "liquid"
- },
- order: [["id", "DESC"]],
- transaction
- });
-
- if (!invoice) return;
-
- let confirmed = 0;
-
- let account = await db.Account.findOne({
- where: {
- id: invoice.account_id,
- asset
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (!account) {
- let pubkey = account ? account.pubkey : null;
-
- account = await getAccount(
- {
- user_id: user.id,
- asset,
- pubkey
- },
- transaction
- );
- }
-
- await account.increment({ pending: value }, { transaction });
- await account.reload({ transaction });
-
- if (config.liquid.walletpass)
- await lq.walletPassphrase(config.liquid.walletpass, 300);
-
- await user.save({ transaction });
-
- const currency = invoice ? invoice.currency : user.currency;
- const rate = invoice ? invoice.rate : store.rates[user.currency];
- const tip = invoice ? invoice.tip : 0;
- const memo = invoice ? invoice.memo : "";
-
- let payment = await db.Payment.create(
- {
- account_id: account.id,
- user_id: user.id,
- hash: blinded.txid,
- amount: value - tip,
- currency,
- memo,
- rate,
- received: true,
- tip,
- confirmed,
- address,
- network: "liquid",
- invoice_id: invoice.id
- },
- { transaction }
- );
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- payment.invoice = invoice.get({ plain: true });
-
- emit(user.username, "payment", payment);
- emit(user.username, "account", payment.account);
- l("liquid detected", address, user.username, asset, value);
- notify(user, `${value} SAT payment detected`);
- callWebhook(invoice, payment);
- });
- }
- } catch (e) {
- console.log(e);
- err("Problem processing transaction", e.message, e.stack);
- }
- }
- } catch (e) {
- console.log(e);
- }
-});
-
-zmqRawBlock.on("message", async (topic, message, sequence) => {
- try {
- const payments = await db.Payment.findAll({
- where: { confirmed: 0 }
- });
-
- let hash, json;
-
- hash = await lq.getBlockHash(getBlockHeight(message));
- json = await lq.getBlock(hash, 2);
-
- for (let tx of json.tx) {
- if (store.issuances[tx.txid]) {
- await db.transaction(async transaction => {
- const {
- user_id,
- asset,
- asset_amount,
- asset_payment_id,
- token,
- token_amount,
- token_payment_id
- } = store.issuances[tx.txid];
-
- const user = await getUserById(user_id);
-
- let account = await db.Account.findOne({
- where: { user_id, asset },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- account.balance = Math.round(asset_amount * SATS);
- account.pending = 0;
- await account.save({ transaction });
-
- let payment = await db.Payment.findOne({
- where: { id: asset_payment_id },
- include: {
- model: db.Account,
- as: "account"
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- payment.confirmed = true;
- await payment.save({ transaction });
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", payment);
-
- if (token) {
- account = await db.Account.findOne({
- where: { user_id, asset: token },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- account.balance = token_amount * SATS;
- account.pending = 0;
- await account.save({ transaction });
-
- payment = await db.Payment.findOne({
- where: { id: token_payment_id },
- include: {
- model: db.Account,
- as: "account"
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- payment.confirmed = true;
- await payment.save({ transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", payment);
- }
- });
- } else if (payments.find(p => p.hash === tx.txid)) queue[tx.txid] = 1;
- }
- } catch (e) {
- return console.log(e);
- }
-});
-
-setInterval(async () => {
- try {
- const arr = Object.keys(queue);
-
- for (let i = 0; i < arr.length; i++) {
- const hash = arr[i];
-
- let account, invoice, address, user, total, p;
- await db.transaction(async transaction => {
- p = await db.Payment.findOne({
- where: { hash, confirmed: 0, received: 1 },
- include: [
- {
- model: db.Account,
- as: "account"
- },
- {
- model: db.Invoice,
- as: "invoice"
- },
- {
- model: db.User,
- as: "user"
- }
- ],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (p && p.address) address = p.address;
- if (p && p.user) user = p.user;
-
- if (p && p.account) {
- ({ account, invoice } = p);
- total = p.amount + p.tip;
- p.confirmed = 1;
- await account.save({ transaction });
-
- await invoice.increment({ received: total }, { transaction });
- await account.increment({ balance: total }, { transaction });
- await account.decrement(
- { pending: Math.min(account.pending, total) },
- { transaction }
- );
- await account.increment(
- { liquid_credits: computeConversionFee(total) },
- { transaction }
- );
- await account.reload({ transaction });
- await invoice.reload({ transaction });
-
- await p.save({ transaction });
-
- p = p.get({ plain: true });
- account = account.get({ plain: true });
- invoice = invoice.get({ plain: true });
-
- emit(user.username, "account", account);
- emit(user.username, "payment", p);
-
- l("liquid confirmed", user.username, account.asset, p.amount, p.tip);
-
- notify(user, `${total} SAT payment confirmed`);
- callWebhook(p.invoice, p);
- } else {
- warn("couldn't find liquid payment", hash);
- }
-
- delete queue[hash];
- });
-
- let c = store.convert[address];
- if (address && c && p.account.asset === network.assetHash) {
- l(
- "liquid detected for conversion request",
- address,
- c.address,
- user.username
- );
-
- user.account = p.account;
-
- sendLiquid({
- address: c.address,
- amount: total - 100,
- user,
- limit: total
- });
- }
- }
- } catch (e) {
- err("problem processing queued liquid transaction", e.message, e.stack);
- }
-}, 1000);
diff --git a/routes/liquid/send.js b/routes/liquid/send.js
deleted file mode 100644
index 83b5d6ca..00000000
--- a/routes/liquid/send.js
+++ /dev/null
@@ -1,276 +0,0 @@
-import db from "$db";
-import lq from "$lib/liquid";
-import { toSats } from "$lib/utils";
-import { emit } from "$lib/sockets";
-import store from "$lib/store";
-import config from "$config";
-import { l, warn, err } from "$lib/logging";
-import { liquidTx } from "$routes/liquid/fee";
-import { Transaction } from 'liquidjs-lib';
-import { requirePin } from "$lib/utils";
-
-import {
- computeConversionFee,
- conversionFeeReceiver
-} from "./conversionFee.js";
-
-const btc = config.liquid.btcasset;
-const lcad = config.liquid.cadasset;
-
-export const sendLiquid = async ({ asset, amount, user, address, memo, tx, limit }) => {
- try {
- l("sending liquid", amount, address);
- if (!tx) {
- ({ tx } = await liquidTx({
- address,
- asset,
- amount,
- feeRate: 200,
- replaceable: false,
- user
- }));
- }
-
- const isChange = async address =>
- (await lq.getAddressInfo(address)).ismine &&
- !Object.keys(store.addresses).includes(address);
-
- let totals = {};
- let change = {};
- let fee = 0;
-
- let { vout } = await lq.decodeRawTransaction(tx.hex);
-
- for (let i = 0; i < vout.length; i++) {
- let {
- asset,
- value,
- scriptPubKey
- } = vout[i];
-
- if (scriptPubKey.type === "fee") fee = toSats(value);
- else {
- if (!totals[asset]) totals[asset] = change[asset] = 0;
- totals[asset] += toSats(value);
-
- if (scriptPubKey.address) {
- if (await isChange(scriptPubKey.address)) {
- change[asset] += toSats(value);
- }
- }
- }
- }
-
- const assets = Object.keys(totals);
- const payments = [];
-
- let main, signed;
- await db.transaction(async transaction => {
- let fee_payment;
- let fee_payment_id = null;
-
- for (let i = 0; i < assets.length; i++) {
- let asset = assets[i];
- let amount = totals[asset];
- if (change[asset]) amount -= change[asset];
- let total = amount;
-
- if (asset === btc) {
- let covered = 0;
- let nonbtc = assets.filter(a => a !== btc);
- if (nonbtc.length === 1) {
- let faucet = await db.Account.findOne({
- where: {
- asset: nonbtc[0],
- user_id: null
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (faucet) {
- covered = faucet.balance;
- if (covered > fee) covered = fee;
- await faucet.decrement({ balance: covered }, { transaction });
- await faucet.reload({ transaction });
- await faucet.save({ transaction });
- }
- }
-
- total += fee - covered;
- }
-
- var conversionFee = computeConversionFee(amount);
-
- if (limit && total > limit + fee)
- throw new Error("Tx amount exceeds authorized amount");
-
- if (asset !== btc || total) {
- l("creating liquid payment", user.username, asset, total, fee);
-
- let account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset,
- pubkey: null
- },
- lock: transaction.LOCK.UPDATE,
- order: [["balance", "DESC"]],
- transaction
- });
-
- // use user's credits to reduce fee, if available
- let conversionFeeDeduction = Math.min(
- account.liquid_credits,
- conversionFee
- );
- if (conversionFeeDeduction) {
- await account.decrement(
- { liquid_credits: conversionFeeDeduction },
- { transaction }
- );
- await account.reload({ transaction });
- conversionFee -= conversionFeeDeduction;
- }
-
- if (asset !== btc) conversionFee = 0;
-
- if (total > account.balance) {
- warn("amount exceeds balance", {
- total,
- fee,
- balance: account.balance
- });
- throw new Error(
- `Insufficient funds, need ${total} ${
- account.ticker === "BTC" ? "SAT" : account.ticker
- }, have ${account.balance}`
- );
- } else if (total + conversionFee > account.balance) {
- warn("amount plus conversion fee exceeds balance", {
- total,
- fee,
- conversionFee,
- balance: account.balance
- });
- throw new Error(
- `Insufficient funds, need ${total + conversionFee} ${
- account.ticker === "BTC" ? "SAT" : account.ticker
- }, have ${account.balance}`
- );
- }
-
- await account.decrement(
- { balance: total + conversionFee },
- { transaction }
- );
- await account.reload({ transaction });
-
- let receiverAccount = await db.Account.findOne({
- where: {
- "$user.username$": conversionFeeReceiver
- },
- include: [
- {
- model: db.User,
- as: "user"
- }
- ],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- if (conversionFee) {
- await receiverAccount.increment(
- { balance: conversionFee },
- { transaction }
- );
- await receiverAccount.reload({ transaction });
- fee_payment = {
- amount: conversionFee,
- fee: 0,
- memo: "Liquid conversion fee",
- account_id: receiverAccount.id,
- user_id: receiverAccount.user_id,
- rate: store.rates[receiverAccount.user.currency],
- currency: receiverAccount.user.currency,
- confirmed: true,
- received: true,
- network: "COINOS"
- };
- fee_payment.account = receiverAccount;
- ({ id: fee_payment_id } = await db.Payment.create(fee_payment, {
- transaction
- }));
- }
-
- let payment = {
- amount: -amount,
- account_id: account.id,
- fee,
- memo,
- user_id: user.id,
- rate: store.rates[user.currency],
- currency: user.currency,
- address,
- confirmed: true,
- received: false,
- network: "liquid",
- fee_payment_id
- };
-
- payment.account = account;
- payments.push(payment);
- }
- }
-
- signed = await lq.signRawTransactionWithWallet(
- await lq.blindRawTransaction(tx.hex)
- );
- let txid = Transaction.fromHex(signed.hex).getId();
-
- for (let i = 0; i < payments.length; i++) {
- let p = payments[i];
- if (p) {
- let { account } = p;
- p.hash = txid;
- p = await db.Payment.create(p, { transaction });
- if (p.user_id === user.id && (account.ticker !== "BTC" || !main)) {
- main = p.get({ plain: true });
- main.fee_payment = fee_payment;
- main.account = account.get({ plain: true });
- }
- }
- }
-
- emit(user.username, "account", main.account);
- emit(user.username, "payment", main);
- });
-
- if (config.liquid.walletpass)
- await lq.walletPassphrase(config.liquid.walletpass, 300);
-
- let txid = await lq.sendRawTransaction(signed.hex);
- l("sent liquid tx", txid, address);
-
- return main;
- } catch (e) {
- err("problem sending liquid", e.message);
- return e;
- }
-};
-
-export default async (req, res) => {
- let { user } = req;
-
- try {
- await requirePin(req);
- let result = await sendLiquid({ ...req.body, user })
- if (result instanceof Error) throw result;
- res.send(result);
- } catch (e) {
- console.log(e)
- err("problem sending liquid", user.username, e.message);
- return res.code(500).send(e);
- }
-};
diff --git a/routes/lnurl.js b/routes/lnurl.js
index 1ad7b814..63488033 100644
--- a/routes/lnurl.js
+++ b/routes/lnurl.js
@@ -1,578 +1,66 @@
-import app from "$app";
-import config from "$config";
-import db from "$db";
-import store from "$lib/store";
-import { optionalAuth, auth } from "$lib/passport";
-import { l, err, warn } from "$lib/logging";
+import { g, s } from "$lib/db";
+import { l } from "$lib/logging";
+import { fail } from "$lib/utils";
+import { v4 } from "uuid";
+import got from "got";
+import { generate } from "$lib/invoices";
+import { bech32 } from "bech32";
-import ln from "$lib/ln";
-import persist from "$lib/persist";
-import { emit } from "$lib/sockets";
+export default {
+ async encode({ query: { address } }, res) {
+ let [name, domain] = address.split("@");
+ let url = `https://${domain}/.well-known/lnurlp/${name}`;
+ let r = await got(url).json();
+ if (r.tag !== "payRequest") fail("not an ln address");
+ let enc = bech32.encode("lnurl", bech32.toWords(Buffer.from(url)), 20000);
+ res.send(enc);
+ },
-import axios from "axios";
-import lnurl from "lnurl";
-import jwt from "jsonwebtoken";
-import qs from "query-string";
-import bolt11 from "bolt11";
+ async decode({ query: { text } }, res) {
+ let url = Buffer.from(
+ bech32.fromWords(bech32.decode(text, 20000).words)
+ ).toString();
-import {
- computeConversionFee,
- conversionFeeReceiver
-} from "./lightning/conversionFee.js";
+ res.send(await got(url).json());
+ },
-import send from "$lib/send";
-import sendInternal from "$lib/sendInternal";
-import register from "$lib/register";
+ async lnurlp({ params: { username } }, res) {
+ let uid = await g(`user:${username}`);
+ if (!uid) fail("user not found");
-const logins = persist("data/logins.json");
-const recipients = persist("data/recipients.json");
-const lnurlPayments = persist("data/payments.json");
-const withdrawals = persist("data/withdrawals.json");
+ let id = v4();
+ await s(`lnurl:${id}`, uid);
+ let { URL } = process.env;
+ let host = URL.split("/").at(-1);
-const { HOSTNAME: hostname } = process.env;
-
-export const lnurlServer = lnurl.createServer(config.lnurl);
-
-app.get("/url", async (req, res, next) => {
- try {
- const code = await db.Code.findOne({
- where: {
- code: req.query.code
- }
- });
-
- if (code) {
- res.send(code.text);
- } else {
- throw new Error("code not found");
- }
- } catch (e) {
- err("couldn't find url", e.message);
- }
-});
-
-app.get("/withdraw", auth, async (req, res, next) => {
- const { min, max } = req.query;
- try {
- const result = await lnurlServer.generateNewUrl("withdrawRequest", {
- minWithdrawable: min * 1000,
- maxWithdrawable: max * 1000,
- defaultDescription: "coinos voucher"
- });
-
- withdrawals[result.secret] = req.user;
-
- res.send(result);
- } catch (e) {
- err("problem generating withdrawl url", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.post("/code", async (req, res, next) => {
- try {
- const { encoded } = req.body.lnurl;
- const code = await db.Code.findOrCreate({
- where: {
- code: `lnurl:${encoded.substr(-32)}`,
- text: encoded
- }
- });
-
- res.send(code);
- } catch (e) {
- err(e.errors);
- res.code(500).send(e.message);
- }
-});
-
-app.post("/withdraw", auth, async (req, res, next) => {
- const { user } = req;
- const {
- amount: value,
- params: { callback, k1 }
- } = req.body;
-
- let invoice;
- let label = new Date();
- let desc = label;
-
- invoice = await ln.invoice(`${value}sats`, label, desc);
-
- const { payment_request: pr } = invoice;
- const url = `${callback}?k1=${k1}&pr=${pr}`;
-
- await db.Invoice.create({
- user_id: user.id,
- text: pr,
- rate: store.rates[user.currency],
- currency: user.currency,
- amount: value,
- tip: 0,
- network: "bitcoin"
- });
-
- try {
- result = (await axios.get(url)).data;
- res.send(result);
- } catch (e) {
- err("failed to withdraw", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.get("/lnurlp/:username", async (req, res, next) => {
- try {
- const { username } = req.params;
- let user = await db.User.findOne({
- where: {
- username
- }
- });
-
- if (!user) throw new Error("user not found");
-
- let { amount, minSendable, maxSendable } = req.query;
- minSendable = minSendable || 1000;
- maxSendable = maxSendable || 1000000000;
- if (parseInt(amount)) minSendable = maxSendable = amount * 1000;
-
- let result = await lnurlServer.generateNewUrl("payRequest", {
- minSendable,
- maxSendable,
- metadata: JSON.stringify([
- ["text/plain", `paying ${user.username}`],
- ["text/identifier", `${user.username}@coinos.io`]
- ])
- });
-
- recipients[result.secret] = {
- id: user.id,
- currency: user.currency,
- username
- };
-
- l("recipient", user.username, result.secret);
-
- result = await axios.get(result.url);
-
- res.send(result.data);
- } catch (e) {
- err("problem generating payment url", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.get("/pay/:username", async (req, res, next) => {
- const { username } = req.params;
- let user = await db.User.findOne({
- where: {
- username
- }
- });
-
- let { amount, minSendable, maxSendable } = req.query;
- minSendable = minSendable || 1000;
- maxSendable = maxSendable || 1000000000;
- if (parseInt(amount)) minSendable = maxSendable = amount * 1000;
-
- try {
- const result = await lnurlServer.generateNewUrl("payRequest", {
- minSendable,
- maxSendable,
- metadata: JSON.stringify([
- ["text/plain", `paying ${user.username}`],
- ["text/identifier", `${user.username}@coinos.io`]
- ])
+ res.send({
+ metadata: [
+ ["text/plain", `Paying ${username}@${host}`],
+ ["text/identifier", `${username}@${host}`]
+ ],
+ callback: `${URL}/lnurl/${id}`,
+ tag: "payRequest"
});
+ },
- recipients[result.secret] = {
- id: user.id,
- currency: user.currency,
- username
- };
-
- l("recipient", user.username, result.secret);
- res.send(result);
- } catch (e) {
- err("problem generating payment url", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.post("/pay", auth, async (req, res, next) => {
- const { user } = req;
-
- const {
- amount,
- comment,
- params: { callback }
- } = req.body;
-
- let url = `${callback}${callback.includes("?") ? "&" : "?"}amount=${amount *
- 1000}${comment ? "&comment=" + comment : ""}`;
+ async lnurl({ params: { id }, query: { amount } }, res) {
+ let pr = await g(`lnurlp:${id}`);
- try {
- const parts = callback.split("/");
- const secret = parts[parts.length - 1];
- lnurlPayments[secret] = user.id;
+ if (!pr) {
+ let uid = await g(`lnurl:${id}`);
+ let user = await g(`user:${uid}`);
- if (recipients[secret]) {
- let data = await sendInternal(
- {
+ ({ text: pr } = await generate({
+ invoice: {
amount,
- memo: comment,
- username: recipients[secret].username
+ type: types.lightning
},
user
- );
+ }));
- res.send(data);
- } else {
- const { data } = await axios.get(url);
- res.send(await send(amount, "", data.pr, user));
+ await s(`lnurlp:${id}`, pr);
}
- } catch (e) {
- console.log(e);
- err("failed to send payment", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.get("/login", optionalAuth, async (req, res, next) => {
- try {
- const result = await lnurlServer.generateNewUrl("login");
-
- if (req.user) {
- logins[result.secret] = req.user.username;
- }
-
- res.send(result);
- } catch (e) {
- err("problem generating login url", e.message);
- res.code(500).send(e.message);
- }
-});
-app.get("/encode", async (req, res, next) => {
- let { domain, name } = req.query;
- let url = `https://${domain}/.well-known/lnurlp/${name}`;
- res.send(lnurl.encode(url));
-});
-
-app.get("/decode", async (req, res, next) => {
- const { text } = req.query;
-
- try {
- const url = lnurl.decode(text);
- let spl = url.split("?");
- if (spl.length > 1 && qs.parse(spl[1]).tag === "login") {
- return res.send({
- tag: "login",
- k1: qs.parse(spl[1]).k1,
- callback: url,
- domain: url
- .split("://")[1]
- .split("/")[0]
- .split("@")
- .slice(-1)[0]
- .split(":")[0]
- });
- }
-
- const { data: params } = await axios.get(url);
-
- res.send(params);
- } catch (e) {
- err("problem decoding lnurl", e.message);
- res.code(500).send(e.message);
- }
-});
-
-lnurlServer.on("payRequest:action:processed", async function(event) {
- const { secret, params, result } = event;
- const { id, invoice } = result;
- const recipient = recipients[secret];
- let payreq = bolt11.decode(invoice);
-
- try {
- let i = await db.Invoice.create({
- user_id: recipient.id,
- text: invoice,
- rate: store.rates[recipient.currency],
- currency: recipient.currency,
- amount: payreq.satoshis,
- tip: 0,
- network: "lightning"
- });
-
- l("invoice created", i.text, i.amount);
- } catch (e) {
- err("problem finding lnurl invoice", e.message);
- }
-});
-
-lnurlServer.bindToHook(
- "middleware:signedLnurl:afterCheckSignature",
- async (req, res, next) => {
- try {
- let user;
- const { amount: msats, key, tag, pr, k1 } = req.query;
-
- if (msats) {
- let amount = Math.round(msats / 1000);
- const parts = req.originalUrl.split("/");
- const secret = parts[parts.length - 1].split("?")[0];
- let user_id = lnurlPayments[secret];
-
- if (user_id) {
- let account = await db.Account.findOne({
- where: {
- user_id,
- asset: config.liquid.btcasset,
- pubkey: null
- }
- });
-
- if (account.balance < amount) {
- throw new Error("Insufficient funds");
- }
- }
- }
-
- if (tag === "login") {
- let username = logins[k1];
-
- if (!username) {
- const keyObj = await db.Key.findOne({
- where: { hex: key },
- include: [
- {
- model: db.User,
- as: "user"
- }
- ]
- });
-
- if (keyObj) ({ user } = keyObj);
-
- if (!user) {
- let ip =
- req.headers["x-forwarded-for"] || req.connection.remoteAddress;
-
- let username = `satoshi-${key.substr(0, 12)}`;
- let existing = await db.User.findOne({ where: { username } });
- if (existing) user = existing;
- else {
- user = await register(
- {
- username,
- password: key
- },
- ip
- );
- }
- }
-
- ({ username } = user);
- }
-
- logins[key] = { k1, username };
- }
-
- if (pr) {
- user = withdrawals[k1];
- if (!user) {
- if (next) next(new Error("withdrawal not found"));
- return;
- }
-
- try {
- let amount;
-
- let { msatoshi } = await ln.decodepay(pr);
- amount = parseInt(msatoshi / 1000);
- let conversionFee = computeConversionFee(amount);
-
- await db.transaction(async transaction => {
- let account = await db.Account.findOne({
- where: {
- user_id: user.id,
- asset: config.liquid.btcasset
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- // account that receives conversion fees
- let receiverAccount = await db.Account.findOne({
- where: {
- "$user.username$": conversionFeeReceiver
- },
- include: [
- {
- model: db.User,
- as: "user"
- }
- ],
- lock: transaction.LOCK.UPDATE,
- transaction
- });
-
- let conversionFeeDeduction = Math.min(
- account.lightning_credits,
- conversionFee
- );
- if (conversionFeeDeduction) {
- await account.decrement(
- { lightning_credits: conversionFeeDeduction },
- { transaction }
- );
- await account.reload({ transaction });
- conversionFee -= conversionFeeDeduction;
- }
-
- if (account.balance < amount) {
- throw new Error("Insufficient funds");
- } else if (account.balance < amount + conversionFee) {
- throw new Error("Insufficient funds for conversion fee");
- }
-
- let fee_payment_id = null;
- if (conversionFee) {
- await receiverAccount.increment(
- { balance: conversionFee },
- { transaction }
- );
- await receiverAccount.reload({ transaction });
- let fee_payment = await db.Payment.create(
- {
- amount: conversionFee,
- fee: 0,
- memo: "Bitcoin conversion fee",
- account_id: receiverAccount.id,
- user_id: receiverAccount.user_id,
- rate: store.rates[receiverAccount.user.currency],
- currency: receiverAccount.user.currency,
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
- fee_payment_id = fee_payment.id;
- }
-
- let payment = await db.Payment.create(
- {
- amount: -amount,
- account_id: account.id,
- user_id: user.id,
- hash: pr,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed: true,
- network: "lightning",
- fee_payment_id
- },
- { transaction }
- );
-
- setTimeout(async () => {
- try {
- let { payments } = await ln.getPayments({
- limit: 5
- });
-
- let p = payments.find(p => p.request === pr);
- if (p) {
- l("found payment", pr);
- payment.fee = p.fee;
- await account.decrement({ balance: p.fee }, { transaction });
- await account.reload({ transaction });
- await payment.save();
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- emit(user.username, "account", account);
- emit(user.username, "payment", payment);
- } else {
- warn("payment not found, fee not set", pr);
- }
- } catch (e) {
- err("problem trying to get ln withdrawal payment", e);
- }
- }, 1000);
-
- await account.decrement(
- { balance: amount + conversionFee },
- { transaction }
- );
- await account.reload({ transaction });
-
- let p = payment.get({ plain: true });
- p.account = account.get({ plain: true });
-
- emit(user.username, "account", p.account);
- emit(user.username, "payment", p);
- });
- } catch (e) {
- err("failed to process withdrawal", e.message);
- return next(e);
- }
- }
-
- if (next) next();
- } catch (e) {
- err("unhandled lnurerr", e.message);
- }
- }
-);
-
-lnurlServer.bindToHook("login", async key => {
- try {
- if (!key) throw new Error("login key not defined");
-
- const exists = await db.Key.findOne({
- where: { hex: key },
- include: [{ model: db.User, as: "user" }]
- });
-
- let user;
- if (logins[key] && logins[key] !== "undefined") {
- const { username } = logins[key];
- user = await db.User.findOne({
- where: { username }
- });
-
- if (user) {
- const [k, created] = await db.Key.findOrCreate({
- where: {
- user_id: user.id,
- hex: key
- }
- });
-
- if (created) {
- l("added key", username, k);
- emit(username, "key", k);
- }
- } else {
- l("user not found");
- user = await register({
- username: key.substr(0, 8),
- password: key
- });
- }
- } else if (exists) ({ user } = exists);
-
- if (user && user.username) {
- const payload = { username: user.username };
- const token = jwt.sign(payload, config.jwt);
- const ws = store.sessions[logins[key].k1];
- if (ws && ws.send)
- ws.send(JSON.stringify({ type: "token", data: { token, key } }));
- }
- } catch (e) {
- err("problem with login hook", e.message);
+ res.send({ pr });
}
-});
+};
diff --git a/routes/locations.js b/routes/locations.js
index 3e0fee4c..fb4487f7 100644
--- a/routes/locations.js
+++ b/routes/locations.js
@@ -1,19 +1,7 @@
-import app from "$app";
-import redis from "$lib/redis";
-import axios from "axios";
+import { g } from "$lib/db";
-let locations;
-app.get("/locations", async (req, res) => {
- res.send({ locations });
-});
-
-let getLocations = async () => {
- let { data } = await axios.get('https://api.btcmap.org/v2/elements?updated_since=2022-09-19');
- locations = data.filter(
- (l) => l['osm_json'].tags && l['osm_json'].tags['payment:coinos'] === 'yes'
- );
-
- setTimeout(getLocations, 60000);
-}
-
-getLocations();
+export default {
+ async list(req, res) {
+ res.send({ locations: await g("locations") });
+ }
+};
diff --git a/routes/nostr.js b/routes/nostr.js
new file mode 100644
index 00000000..005a4be9
--- /dev/null
+++ b/routes/nostr.js
@@ -0,0 +1,157 @@
+import { nada, uniq } from "$lib/utils";
+import config from "$config";
+import { g, s, db } from "$lib/db";
+import { pool, q } from "$lib/nostr";
+
+export default {
+ async event({ params: { id } }, res) {
+ let event = await g(`ev:${id}`);
+ let { pubkey } = event;
+
+ event.user = (await g(`user:${pubkey}`)) || {
+ username: pubkey.substr(0, 6),
+ pubkey,
+ anon: true,
+ follows: [],
+ followers: []
+ };
+
+ res.send(event);
+ },
+
+ async notes({ params: { pubkey } }, res) {
+ let user = await g(`user:${pubkey}`);
+
+ if (!user)
+ user = {
+ username: pubkey.substr(0, 6),
+ pubkey,
+ anon: true,
+ follows: [],
+ followers: []
+ };
+
+ let params = {
+ kinds: [1],
+ authors: [pubkey]
+ },
+ opts = { since: 0 };
+
+ q(`${pubkey}:notes`, params, opts).catch(nada);
+
+ await s(`user:${pubkey}`, user);
+
+ let ids = await db.sMembers(pubkey);
+
+ let events = ids.length
+ ? (await db.mGet(ids.map(k => "ev:" + k))).map(JSON.parse)
+ : [];
+
+ res.send(events.map(e => ({ ...e, user })));
+ },
+
+ async broadcast(req, res) {
+ let { event } = req.body;
+ pool.send(["EVENT", event]);
+ res.send(event);
+ },
+
+ async follows({ params: { pubkey }, query: { tagsonly } }, res) {
+ let sub = `${pubkey}:follows`,
+ params = {
+ limit: 1,
+ kinds: [3],
+ authors: [pubkey]
+ },
+ opts = { timeout: 60000, eager: 60000 };
+
+ q(sub, params, opts).catch(nada);
+
+ let tags = (await g(`${pubkey}:follows`)) || [];
+ if (tagsonly) return res.send(tags);
+
+ let follows = [];
+ for (let f of tags) {
+ let [_, pubkey] = f;
+
+ q(`${pubkey}:profile:f1`, {
+ limit: 1,
+ kinds: [0],
+ authors: [pubkey]
+ }).catch(nada);
+
+ let user = await g(`user:${pubkey}`);
+
+ if (!user)
+ user = {
+ username: pubkey.substr(0, 6),
+ pubkey,
+ anon: true
+ };
+
+ follows.push(user);
+ }
+
+ follows = uniq(follows, e => e.pubkey);
+ follows.sort((a, b) => a.username.localeCompare(b.username));
+
+ res.send(follows);
+ },
+
+ async followers({ params: { pubkey } }, res) {
+ try {
+ let pubkeys = [
+ ...new Set([...(await db.sMembers(`${pubkey}:followers`))])
+ ];
+
+ let followers = [];
+
+ q(
+ `${pubkey}:followers`,
+ { kinds: [3], "#p": [pubkey] },
+ { timeout: 60000, eager: 60000 }
+ ).catch(nada);
+
+ for (let pubkey of pubkeys) {
+ let user = await g(`user:${pubkey}`);
+ if (!user || !user.updated) {
+ q(`${pubkey}:profile:f2`, {
+ limit: 1,
+ kinds: [0],
+ authors: [pubkey]
+ }).catch(nada);
+
+ user = await g(`user:${pubkey}`);
+ }
+
+ if (!user)
+ user = {
+ username: pubkey.substr(0, 6),
+ pubkey,
+ anon: true
+ };
+
+ followers.push(user);
+ }
+
+ followers = uniq(followers, e => e.pubkey);
+ followers.sort((a, b) => a.username.localeCompare(b.username));
+
+ res.send(followers);
+ } catch (e) {
+ console.log(e);
+ res.code(500).send(e && e.message);
+ }
+ },
+
+ async identities(req, res) {
+ res.send({
+ names: {
+ adam:
+ "566c166f3adab0c8fba5da015b0b3bcc8eb3696b455f2a1d43bfbd97059646a8",
+ asoltys:
+ "566c166f3adab0c8fba5da015b0b3bcc8eb3696b455f2a1d43bfbd97059646a8"
+ }
+ });
+ }
+};
diff --git a/routes/payments.js b/routes/payments.js
index 416bc20a..1043959c 100644
--- a/routes/payments.js
+++ b/routes/payments.js
@@ -1,163 +1,258 @@
-import app from "$app";
-import db from "$db";
import config from "$config";
import store from "$lib/store";
-
-import { auth, adminAuth, optionalAuth } from "$lib/passport";
-import fs from "fs";
-import { join } from "path";
-import { Op } from "@sequelize/core";
-import send from "./send";
-import { l, warn } from "$lib/logging";
-import { fail } from "$lib/utils";
+import { emit } from "$lib/sockets";
+import { v4 } from "uuid";
+import { db, g, s, t } from "$lib/db";
+import { l, err } from "$lib/logging";
+import { fail, btc, sats } from "$lib/utils";
+import { requirePin } from "$lib/auth";
+import { debit, credit, confirm, types } from "$lib/payments";
+import got from "got";
import bc from "$lib/bitcoin";
-import lq from "$lib/liquid";
+import ln from "$lib/ln";
-import btcRoutes from "./bitcoin/index";
-import lnRoutes from "./lightning/index";
-import lqRoutes from "./liquid/index";
+export default {
+ async create({ body, user }, res) {
+ let { amount, hash, maxfee, name, memo, payreq, tip, username } = body;
-import "./bitcoin/receive";
-import "./lightning/receive";
-import "./liquid/receive";
+ amount = parseInt(amount);
+ maxfee = parseInt(maxfee);
+ tip = parseInt(tip);
-app.post("/send", auth, send);
-app.post("/sendToTokenHolders", auth, async (req, res, next) => {
- let { asset, amount } = req.body;
+ await requirePin({ body, user });
- let accounts = await db.Account.findAll({
- where: {
- asset,
- "$user.username$": { [Op.ne]: "gh" }
- },
+ let p;
- include: [{ model: db.User, as: "user" }]
- });
+ if (username && username.endsWith("@classic")) {
+ let { username: source } = user;
+ username = username.replace("@classic", "");
+ p = await debit(hash, amount, 0, memo, user, types.classic);
- let totalTokens = accounts.reduce((a, b) => a + b.balance, 0);
+ await got
+ .post(`${config.classic}/admin/credit`, {
+ json: { username, amount, source },
+ headers: { authorization: `Bearer ${config.admin}` }
+ })
+ .json();
+ } else if (payreq) {
+ p = await debit(
+ hash,
+ amount + maxfee,
+ maxfee,
+ memo,
+ user,
+ types.lightning
+ );
- let totalSats = Math.floor(amount / totalTokens);
+ let r = await ln.pay(payreq);
- if (totalSats < 1) throw new Error("amount is too low to distribute");
+ p.amount = -amount;
+ p.hash = r.payment_hash;
+ p.fee = r.msatoshi_sent - r.msatoshi;
+ p.ref = r.payment_preimage;
- for (let i = 0; i < accounts.length; i++) {
- let account = accounts[i];
- console.log(account.user.username, account.balance);
- }
- accounts.map(({ balance, user: { username } }) => ({ username, balance }));
+ await s(`payment:${p.id}`, p);
+ await db.incrBy(`balance:${p.uid}`, maxfee - p.fee);
+ } else if (hash) {
+ p = await debit(hash, amount, 0, memo, user);
+ await credit(hash, amount, memo, user.id);
+ } else {
+ let pot = name || v4();
+ p = await debit(hash, amount, 0, memo, user, types.pot);
+ await db.incrBy(`pot:${pot}`, amount);
+ await db.lPush(`pot:${pot}:payments`, p.id);
+ l("funded pot", pot);
+ }
- res.send({ success: "it worked" });
-});
+ res.send(p);
+ },
-app.get("/except", adminAuth, (req, res) => {
- let s = fs.createWriteStream("exceptions", { flags: "a" });
- store.unaccounted.map(tx => s.write(tx.txid + "\n"));
- l("updated exceptions");
- res.send("updated exceptions");
-});
+ async list({ user: { id }, query: { start, end, limit, offset } }, res) {
+ if (limit) limit = parseInt(limit);
+ offset = parseInt(offset) || 0;
-app.post("/lightning/parse", lnRoutes.parse);
-app.post("/lightning/channel", lnRoutes.channel);
-app.post("/lightning/query", auth, lnRoutes.query);
-app.post("/lightning/send", auth, lnRoutes.send);
+ let payments = (await db.lRange(`${id}:payments`, 0, -1)) || [];
+ payments = (
+ await Promise.all(
+ payments.map(async id => {
+ let p = await g(`payment:${id}`);
+ if (p.created < start || p.created > end) return;
+ if (p.type === types.internal) p.with = await g(`user:${p.ref}`);
+ return p;
+ })
+ )
+ )
+ .filter(p => p)
+ .sort((a, b) => b.created - a.created);
-if (config.lnurl) {
- let { channelRequest } = await import("$routes/lightning/channelRequest");
- app.post("/lightning/channelRequest", channelRequest);
-}
+ let total = payments.length;
-app.post("/bitcoin/broadcast", optionalAuth, btcRoutes.broadcast);
-app.get("/bitcoin/generate", auth, btcRoutes.generate);
-app.post("/bitcoin/sweep", auth, btcRoutes.sweep);
-app.post("/bitcoin/fee", auth, btcRoutes.fee);
-app.post("/bitcoin/send", auth, btcRoutes.send);
+ if (limit) payments = payments.slice(offset, offset + limit);
-setTimeout(async () => {
- try {
- const address = await bc.getNewAddress();
- const { hdkeypath } = await bc.getAddressInfo(address);
- const parts = hdkeypath.split("/");
- store.bcAddressIndex = parts[parts.length - 1].replace("'", "");
- } catch (e) {
- console.error(e);
- }
-}, 50);
+ res.send({ payments, total });
+ },
-app.post("/liquid/broadcast", optionalAuth, lqRoutes.broadcast);
-app.get("/liquid/generate", auth, lqRoutes.generate);
-app.post("/liquid/fee", auth, lqRoutes.fee);
-app.post("/liquid/send", auth, lqRoutes.send);
+ async get({ params: { hash } }, res) {
+ res.send(await g(`payment:${hash}`));
+ },
-setTimeout(async () => {
- try {
- const address = await lq.getNewAddress();
- const { hdkeypath } = await lq.getAddressInfo(address);
- const parts = hdkeypath.split("/");
- store.lqAddressIndex = parts[parts.length - 1].slice(0, -1);
- } catch (e) {
- warn("Problem getting liquid address index", e.message);
- }
-}, 50);
+ async parse({ body: { payreq } }, res) {
+ let hour = 1000 * 60 * 60;
+ let { last } = store.nodes;
+ let { nodes } = store;
-app.get("/payments", auth, async (req, res) => {
- let { start, end, limit, offset, v2 } = req.query;
+ if (!last || last > Date.now() - hour) ({ nodes } = await ln.listnodes());
+ store.nodes = nodes;
- if (limit) limit = parseInt(limit);
- if (offset) offset = parseInt(offset);
+ let twoWeeksAgo = new Date(new Date().setDate(new Date().getDate() - 14));
+ let decoded = await ln.decodepay(payreq);
+ let { msatoshi, payee } = decoded;
+ let node = nodes.find(n => n.nodeid === payee);
+ let alias = node ? node.alias : payee.substr(0, 12);
- let where = {
- account_id: req.user.account_id,
- };
+ res.send({ alias, amount: Math.round(msatoshi / 1000) });
+ },
- if (start || end) where.createdAt = {};
- if (start) where.createdAt[Op.gte] = new Date(parseInt(start));
- if (end) where.createdAt[Op.lte] = new Date(parseInt(end));
+ async pot({ params: { name } }, res) {
+ let amount = await g(`pot:${name}`);
+ let payments = (await db.lRange(`pot:${name}:payments`, 0, -1)) || [];
+ payments = await Promise.all(payments.map(hash => g(`payment:${hash}`)));
- if (!req.user.account_id) return res.send([]);
+ await Promise.all(
+ payments.map(async p => (p.user = await g(`user:${p.uid}`)))
+ );
- let total = await db.Payment.count({ where });
+ payments = payments.filter(p => p);
+ res.send({ amount, payments });
+ },
- let payments = await db.Payment.findAll({
- where,
- order: [["id", "DESC"]],
- include: {
- model: db.Account,
- as: "account"
- },
- include: {
- attributes: ["username", "profile"],
- model: db.User,
- as: "with"
- },
- limit,
- offset
- });
+ async take({ body: { name, amount }, user }, res) {
+ amount = parseInt(amount);
+ await t(`pot:${name}`, async (balance, db) => {
+ if (balance < amount) fail("Insufficient funds");
+ await db
+ .multi()
+ .decrBy(`pot:${name}`, amount)
+ .exec();
+ });
- if (v2) {
- res.send({ transactions: payments, total });
- } else {
- res.send(payments);
- }
-});
+ let hash = v4();
+ await s(`invoice:${hash}`, {
+ uid: user.id,
+ received: 0
+ });
-app.get("/payment/:redeemcode", async (req, res) => {
- try {
- const { redeemcode } = req.params;
- let payment = await db.Payment.findOne({
- where: {
- redeemcode
- },
- include: {
- model: db.Account,
- as: "account"
+ let payment = await credit(hash, amount, "", name, types.pot);
+ await db.lPush(`pot:${name}:payments`, hash);
+
+ res.send({ payment });
+ },
+
+ async bitcoin({ body: { txid, wallet } }, res) {
+ if (wallet === config.bitcoin.wallet) {
+ let { confirmations, details } = await bc.getTransaction(txid);
+ for (let { address, amount, vout } of details) {
+ if (confirmations > 0) {
+ await confirm(address, txid, vout);
+ } else {
+ await credit(
+ address,
+ sats(amount),
+ "",
+ `${txid}:${vout}`,
+ types.bitcoin
+ );
+ }
}
+ }
+ res.send({});
+ },
+
+ async fee(req, res) {
+ let { amount, address, feeRate, subtract } = req.body;
+ let subtractFeeFromOutputs = subtract ? [0] : [];
+ let replaceable = true;
+ let outs = [{ [address]: btc(amount) }];
+ let count = await bc.getBlockCount();
+
+ let raw = await bc.createRawTransaction([], outs, 0, replaceable);
+ let tx = await bc.fundRawTransaction(raw, {
+ feeRate,
+ subtractFeeFromOutputs,
+ replaceable
});
- if (!payment) fail("invalid code");
+ if (config.bitcoin.walletpass)
+ await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+
+ let { hex } = await bc.signRawTransactionWithWallet(tx.hex);
+ let { vsize } = await bc.decodeRawTransaction(hex);
+ feeRate = Math.round((sats(tx.fee) * 1000) / vsize);
+
+ res.send({ feeRate, tx });
+ },
+
+ async send(req, res) {
+ await requirePin(req);
+
+ let { user } = req;
+ let { address, memo, tx } = req.body;
+ let { hex, fee } = tx;
+
+ if (config.bitcoin.walletpass)
+ await bc.walletPassphrase(config.bitcoin.walletpass, 300);
+
+ ({ hex } = await bc.signRawTransactionWithWallet(hex));
+
+ let r = await bc.testMempoolAccept([hex]);
+ if (!r[0].allowed) fail("transaction rejected");
+
+ fee = sats(fee);
+ if (fee < 0) fail("fee cannot be negative");
+
+ tx = await bc.decodeRawTransaction(hex);
+ let { txid } = tx;
+
+ let total = 0;
+ let change = 0;
+
+ for (let {
+ scriptPubKey: { address },
+ value
+ } of tx.vout) {
+ total += sats(value);
+ if (
+ (await bc.getAddressInfo(address)).ismine &&
+ !(await g(`invoice:${address}`))
+ )
+ change += sats(value);
+ }
+
+ total = total - change + fee;
+ let amount = total - fee;
+
+ if (change && !amount) fail("Cannot send to unregistered coinos address");
+
+ await debit(txid, amount, fee, null, user, types.bitcoin, txid);
+ await bc.sendRawTransaction(hex);
+
+ res.send({ txid });
+ },
+
+ async del({ params: { username }, headers: { authorization } }, res) {
+ if (!authorization.includes(config.admin))
+ return res.code(401).send("unauthorized");
+ let { id, pubkey } = await g(`user:${await g(`user:${username}`)}`);
+ let invoices = await db.lRange(`${id}:invoices`, 0, -1);
+ let payments = await db.lRange(`${id}:payments`, 0, -1);
+
+ for (let { id } of invoices) db.del(`invoice:${id}`);
+ for (let { id } of payments) db.del(`payment:${id}`);
+ db.del(`user:${username}`);
+ db.del(`user:${id}`);
+ db.del(`user:${pubkey}`);
- res.send(payment);
- } catch (e) {
- res.code(500).send(e.message);
+ res.send({});
}
-});
+};
diff --git a/routes/rates.js b/routes/rates.js
new file mode 100644
index 00000000..c36c7ae8
--- /dev/null
+++ b/routes/rates.js
@@ -0,0 +1,11 @@
+import store from "$lib/store";
+
+export default {
+ async last(req, res) {
+ res.send(store.last);
+ },
+
+ async index(req, res) {
+ res.send(store.rates);
+ }
+};
diff --git a/routes/referrals.js b/routes/referrals.js
deleted file mode 100644
index 7193964d..00000000
--- a/routes/referrals.js
+++ /dev/null
@@ -1,272 +0,0 @@
-import express from "express";
-var router = express.Router();
-
-import { v4 } from "uuid";
-
-router.get("/", function(req, res, next) {
- res.send("list of referrals...");
-});
-
-// Grant & Retrieve Referral tokens for existing user
-
-// usage: GET '/grant?sponsor_id=N&expiry=2021-09-01'
-//
-// Required:
-// sponsor_id (= user.id)
-// Changes to DB:
-// adds record to referrals table:
-// { token: <uuid>, sponsor_id: <user.id>, status: "available" }
-
-/**
- * @api {post} /grant Grant Referral code
- * @apiName Grant
- * @apiGroup Referrals
- *
- *
- * @apiPermission member
- *
- * @apiParam {sponsor_id} user_id of member generating referral code.
- * @apiParam {expiry} optional expiry date for token.
- *
- * @apiSuccess {String} token referral token
- * @apiSuccess {Date} expiry optional expiry
- *
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "token": "*********",
- * "status": "available",
- * "expiry": null
- * }
- */
-router.post("/grant", auth, async (req, res) => {
- const { sponsor_id, expiry } = req.body;
- var token = v4();
-
- var ref = await knex.table("referrals").insert({
- sponsor_id: sponsor_id,
- token: token,
- status: "available"
- });
-
- return res.send({ token: token, status: "available", expiry: expiry });
-});
-
-/**
- * @api {get} /grant Grant Referral code (variation using get)
- * @apiName Grant
- * @apiGroup Referrals
- *
- * @apiPermission member
- *
- * @apiPermission member
- * @apiParam {sponsor_id} user_id of member generating referral code.
- * @apiParam {expiry} optional expiry date for token.
- *
- * @apiSuccess {String} token referral token
- * @apiSuccess {Status} status referral status
- * @apiSuccess {Date} expiry optional expiry
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "token": "*********",
- * "status": "available",
- * "expiry": null
- * }
- */
-router.get("/grant", auth, async (req, res) => {
- const { sponsor_id, expiry } = req.query;
- var token = v4();
-
- var ref = await knex.table("referrals").insert({
- sponsor_id: sponsor_id,
- token: token,
- status: "available"
- });
-
- return res.send({ token: token, status: "available", expiry: expiry });
-});
-
-/**
- * @api {get} /checkTokens/:sponsor_id Retrieve list of referral tokens generated by this user
- *
- * @apiName checkTokens
- * @apiGroup Referrals
- *
- *
- * @apiPermission member
- *
- * @apiParam {sponsor_id} user_id of member generating referral code.
- * @apiParam {status} optional token status.
- *
- * @apiSuccess tokens array of token objects
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "tokens": [
- * {"token": "*********", "status": "available", "expiry": null}
- * ]
- * }
- */
-
-// TO FIX - change sponsor_id so that it is retrieved from current payload (NOT FROM URL)
-
-router.get("/checkTokens/:sponsor_id", auth, async (req, res) => {
- const { sponsor_id } = req.params;
- const { status } = req.query;
-
- var tokens = knex
- .select(
- "token",
- "created_at",
- knex.raw("LEFT(created_at,10) as created"),
- "username",
- "status"
- )
- .from("referrals")
- .leftJoin("users", "users.id", "referrals.user_id")
- .where("sponsor_id", "like", sponsor_id);
-
- if (status && status !== "all")
- tokens = tokens.where("status", "like", status);
- const found = await tokens;
-
- return res.send({ tokens: found });
-});
-
-/**
- * @api {get} /verify/:user_id Verify token and apply to existing user
- *
- * @apiName verify
- * @apiGroup Referrals
- *
- * @apiPermission member
- *
- * @apiParam {user_id} Current user
- * @apiParam {token} Token to validate
- *
- * @apiSuccess verified = true
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "verified": true
- * }
- *
- * @apiDescription referral token is updated from 'available' to 'used'
- * @apiDescription referral token is updated with existing user_id
- */
-router.get("/verify/:user_id/:token", auth, async (req, res) => {
- const { user_id, token } = req.params;
-
- const found = await knex
- .select("status")
- .from("referrals")
- .where("token", "like", token)
- .whereNull("user_id");
-
- if (found && found.length) {
- if (found[0].status === "available") {
- await knex("referrals")
- .where("token", "like", token)
- .update({
- status: "used",
- user_id: user_id,
- updated_at: new Date().toISOString().substring(0, 10)
- });
-
- return res.send({
- verified: true,
- sponsor_id: found.sponsor_id,
- updated: found.updated_at
- });
- } else {
- res.code(500).send({
- verified: false,
- message: "Referral already " + found[0].status
- });
- }
- } else {
- res.code(500).send("Invalid referral token");
- }
-});
-
-/**
- * @api {post} /joinQueue Join waiting list (track email & phone)
- * @apiName joinQueue
- * @apiGroup Referrals
- *
- * @apiParam {email} email address
- * @apiParam {phone} phone number
- *
- * @apiSuccess verified = true
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * "success": true
- * "message": 'Added to waiting list'
- * }
- *
- * @apiDescription referral token is updated from 'available' to 'used'
- * @apiDescription referral token is updated with existing user_id
- */
-router.post("/joinQueue", async (req, res) => {
- const { email, phone, user_id } = req.body;
-
- await knex.table("waiting_list").insert({
- email: email,
- phone: phone,
- user_id: user_id
- });
-
- res.send({
- success: true,
- message: "Added " + email + " to waiting list " + phone
- });
-});
-
-router.get("/joinQueue", async (req, res) => {
- const { email, phone, user_id } = req.query;
-
- await knex("waiting_list").insert({
- email: email,
- phone: phone,
- user_id: user_id
- });
-
- res.send({
- success: true,
- message: "Added " + email + " to waiting list " + phone
- });
-});
-
-/**
- * @api {get} /isReferred/:user_id Check if user is referred
- * @apiName isReferred
- * @apiGroup Referrals
- *
- * @apiParam {user_id} user id
- *
- * @apiSuccessExample {json} Success-Response:
- * HTTP/1.1 200 OK
- * {
- * true
- * }
- *
- * @apiDescription returns boolean indicating if user is referred or not
- */
-router.get("/isReferred/:user_id", async (req, res) => {
- const { user_id } = req.params;
-
- var referred = await knex("referrals")
- .select("referrals.id")
- .where("user_id", "like", user_id)
- .where("status", "like", "used");
-
- if (referred && referred.length) {
- res.send({ referred: true });
- } else {
- res.send({ referred: false });
- }
-});
-
-export default router;
diff --git a/routes/requests.js b/routes/requests.js
index 70ab2b07..79af1fb6 100644
--- a/routes/requests.js
+++ b/routes/requests.js
@@ -1,137 +1,49 @@
-import app from "$app";
-import db from "$db";
-import { auth } from "$lib/passport";
import { emit } from "$lib/sockets";
-import { Op, col } from "@sequelize/core";
+import { g, db } from "$lib/db";
-app.get("/request/:id", auth, async (req, res) => {
- try {
- let request = await db.Request.findOne({
- where: { id: req.params.id },
- include: [
- {
- attributes: ["username", "profile"],
- model: db.User,
- as: "recipient"
- },
- {
- attributes: ["username", "profile"],
- model: db.User,
- as: "requester"
- },
- {
- model: db.Invoice,
- as: "invoice"
- }
- ]
- });
+export default {
+ async get({ params: { id } }, res) {
+ try {
+ res.send({ request: await g(id) });
+ } catch (e) {
+ console.log(e);
+ res.code(500).send(e.message);
+ }
+ },
- res.send({ request });
- } catch (e) {
- console.log(e);
- res.code(500).send(e.message);
- }
-});
-
-app.get("/requests", auth, async (req, res) => {
- try {
- const day = new Date(new Date().setDate(new Date().getDate() - 1));
+ async list({ user: { id } }, res) {
+ try {
+ const day = new Date(new Date().setDate(new Date().getDate() - 1));
- let invoices = (
- await db.Request.findAll({
- where: {
- [Op.or]: {
- recipient_id: req.user.id,
- requester_id: req.user.id
- },
- createdAt: { [Op.gt]: day }
- },
- order: [["createdAt", "DESC"]],
- include: [
- {
- model: db.Invoice,
- as: "invoice",
- where: { received: { [Op.lt]: col("invoice.amount") } },
- include: {
- model: db.User,
- as: "user",
- attributes: ["username", "profile"]
- }
- },
- {
- model: db.User,
- as: "requester",
- attributes: ["username", "profile"]
- }
- ]
- })
- )
- .map(
- r =>
- r.invoice && {
- request_id: r.id,
- requester: r.requester.get({ plain: true }),
- ...r.invoice.get({ plain: true })
- }
- )
- .filter(r => r);
+ let invoices = await db.lRange(`${id}:invoices`, 0, -1);
+ let requests = await db.lRange(`${id}:requests`, 0, -1);
- let requests = await db.Request.findAll({
- where: {
- recipient_id: req.user.id,
- createdAt: { [Op.gt]: day },
- invoice_id: { [Op.eq]: null }
- },
- order: [["createdAt", "DESC"]],
- include: {
- attributes: ["username", "profile"],
- model: db.User,
- as: "requester"
- }
- });
-
- res.send({ invoices, requests });
- } catch (e) {
- console.log(e);
- res.code(500).send(e.message);
- }
-});
+ res.send({ invoices, requests });
+ } catch (e) {
+ console.log(e);
+ res.code(500).send(e.message);
+ }
+ },
-app.post("/requests", auth, async (req, res) => {
- try {
- let { recipient: username, ...params } = req.body;
- let { id: recipient_id } = await db.User.findOne({ where: { username } });
+ async create(
+ { body: { recipient, ...params }, user: { username, profile } },
+ res
+ ) {
+ let { id: recipient_id } = await g(`user:${recipient}`);
- let request = await db.Request.create({ recipient_id, ...params });
- request = request.get({ plain: true });
+ let request = { recipient_id, ...params };
request.requester = {
- username: req.user.username,
- profile: req.user.profile
+ username,
+ profile
};
- emit(username, "request", request);
- res.send(request);
- } catch (e) {
- console.log(e);
- res.code(500).send(e.message);
- }
-});
+ emit(recipient, "request", request);
-app.post("/requests/delete", auth, async (req, res) => {
- try {
- let r = await db.Request.findOne({
- where: {
- id: req.body.request_id,
- [Op.or]: { requester_id: req.user.id, recipient_id: req.user.id }
- }
- });
-
- if (!r) throw new Error("request not found");
- await r.destroy();
+ res.send(request);
+ },
+ async destroy({ body: { request_id }, user: { id } }, res) {
+ await db.lrem(`user:${id}:requests`, request_id);
res.send();
- } catch (e) {
- console.log(e);
- res.code(500).send(e.message);
}
-});
+};
diff --git a/routes/send.js b/routes/send.js
deleted file mode 100644
index 591b5ab7..00000000
--- a/routes/send.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import { err } from "$lib/logging";
-import sendInternal from "$lib/sendInternal";
-import { requirePin } from "$lib/utils";
-
-export default async (req, res, next) => {
- try {
- await requirePin(req);
- let payment = await sendInternal(req.body, req.user);
- res.send(payment);
- } catch (e) {
- err("problem sending internal payment", e.message);
- return res.code(500).send(e.message);
- }
-};
diff --git a/routes/swaps.js b/routes/swaps.js
deleted file mode 100644
index 169c2b8f..00000000
--- a/routes/swaps.js
+++ /dev/null
@@ -1,587 +0,0 @@
-import { emit } from "$lib/sockets";
-import app from "$app";
-import config from "$config";
-import { auth, optionalAuth } from "$lib/passport";
-import store from "$lib/store";
-import axios from "axios";
-import crypto from "crypto";
-import fs from "fs";
-import getAccount from "../lib/account";
-import { Op, col } from "@sequelize/core";
-
-const shallow = a => {
- let b = {};
- for (x in a) {
- if (a[x] instanceof Date || typeof a[x] !== "object") b[x] = a[x];
- }
- return b;
-};
-
-const assets = {
- b2e15d0d7a0c94e4e2ce0fe6e8691b9e451377f6e46e8045a86f7c4b5d4f0f23: "bitcoin",
- "4eebe36eb0819e6daa5dd3c97733251ff4eb728c810d949365d6dacaad5ef6e8": "tether"
-};
-
-const timeout = 20000;
-
-const swap = async (user, { a1, a2, v1, v2 }) => {
- if (!parseInt(v1) || v1 < 0 || !parseInt(v2) || v2 < 0)
- throw new Error("Invalid amount");
- let rate = v2 / v1;
-
- const b = await lq.getBalance();
-
- Object.keys(b).map(asset => {
- assets[asset] = asset;
- });
-
- assets[config.liquid.btcasset] = "bitcoin";
- assets["ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"] =
- "tether";
- assets["a0c358a0f6947864af3a06f3f6a2aeb304df7fd95c922f2f22d7412399ce7691"] =
- "adamcoin";
-
- if (!assets[a1]) throw new Error("Asset not found on server");
- if (v1 > Math.round(b[assets[a1]] * SATS))
- throw new Error(`Insufficient server funds, ${v1} ${b[assets[a1]]}`);
-
- await db.transaction(async transaction => {
- let a1acc = await getAccount(a1, user, transaction);
- let a2acc = await getAccount(a2, user, transaction);
-
- if (v1 > a1acc.balance)
- throw new Error(`Insufficient funds, ${v1} ${a1acc.balance}`);
-
- l(
- `placing order ${v1} ${a1.substr(0, 6)} for ${v2} ${a2.substr(0, 6)}`,
- user.username
- );
-
- await a1acc.decrement({ balance: v1 }, { transaction });
- await a1acc.reload({ transaction });
-
- let payment = await db.Payment.create(
- {
- hash: "Trade Funding",
- amount: -v1,
- account_id: a1acc.id,
- user_id: user.id,
- currency: user.currency,
- rate: store.rates[user.currency],
- confirmed: true,
- received: false,
- network: "COINOS"
- },
- { transaction }
- );
-
- emit(user.username, "payment", payment.get({ plain: true }));
- emit(user.username, "account", a1acc.get({ plain: true }));
-
- const orders = await db.Order.findAll(
- {
- where: {
- "$acc1.asset$": a2,
- "$acc2.asset$": a1,
- rate: { [Op.lte]: v1 / v2 },
- accepted: false
- },
- order: [
- ["rate", "ASC"],
- ["id", "ASC"]
- ],
- include: [
- {
- model: db.User,
- as: "user"
- },
- {
- model: db.Account,
- as: "acc1"
- },
- {
- model: db.Account,
- as: "acc2"
- }
- ]
- },
- transaction
- );
-
- for (let i = 0; i < orders.length; i++) {
- if (!v1) break;
- let order = orders[i];
- if (order.v2 > v1) {
- let rate = order.rate;
- await order.decrement(
- {
- v2: v1
- },
- { transaction }
- );
- await order.save({ transaction });
- await order.reload({ transaction });
- order.v1 = Math.round(order.v2 / rate);
- await order.save({ transaction });
-
- await order.acc1.increment({ balance: v2 }, { transaction });
- await order.acc1.reload({ transaction });
-
- emit(order.user.username, "account", order.acc1.get({ plain: true }));
-
- payment = await db.Payment.create(
- {
- hash: "Trade Fill",
- amount: v1,
- account_id: a1acc.id,
- user_id: user.id,
- currency: user.currency,
- rate: store.rates[user.currency],
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
-
- emit(user.username, "payment", payment.get({ plain: true }));
- emit(user.username, "account", a1acc.get({ plain: true }));
-
- if (order.fee) {
- const btc = await getAccount(
- config.liquid.btcasset,
- order.user,
- transaction
- );
-
- payment = await db.Payment.create(
- {
- hash: "Swap Fee Refund",
- amount: order.fee,
- account_id: btc.id,
- user_id: order.user_id,
- currency: order.user.currency,
- rate: store.rates[order.user.currency],
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
-
- await btc.increment({ balance: order.fee }, { transaction });
- await btc.reload({ transaction });
-
- emit(order.user.username, "account", btc.get({ plain: true }));
- }
-
- emit(order.user.username, "payment", payment.get({ plain: true }));
-
- order = order.get({ plain: true });
- order.a1 = order.acc1.asset;
- order.a2 = order.acc2.asset;
- order.rate = order.v2 / order.v1;
-
- broadcast("order", shallow(order));
- v1 = 0;
- } else {
- v1 -= order.v2;
- v2 = Math.round(v1 * rate);
-
- order.accepted = true;
- order.completedAt = new Date();
-
- await order.save({ transaction });
-
- let payment = await db.Payment.create(
- {
- hash: "Trade Fill",
- amount: order.v1,
- account_id: a2acc.id,
- user_id: user.id,
- currency: user.currency,
- rate: store.rates[user.currency],
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
-
- await a2acc.increment({ balance: order.v1 }, { transaction });
- await a2acc.reload({ transaction });
-
- emit(user.username, "payment", payment.get({ plain: true }));
- emit(user.username, "account", a2acc.get({ plain: true }));
-
- payment = await db.Payment.create(
- {
- hash: "Trade Fill",
- amount: order.v2,
- account_id: order.a2_id,
- user_id: order.user_id,
- currency: order.user.currency,
- rate: store.rates[order.user.currency],
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
-
- emit(order.user.username, "payment", payment.get({ plain: true }));
- await order.acc2.increment({ balance: order.v2 }, { transaction });
- await order.acc2.reload({ transaction });
-
- order = order.get({ plain: true });
- order.a1 = order.acc1.asset;
- order.a2 = order.acc2.asset;
- order.rate = order.v2 / order.v1;
-
- broadcast("order", shallow(order));
- }
- }
-
- let order;
- if (v1) {
- order = await db.Order.create(
- {
- v1,
- v2,
- user_id: user.id,
- a1_id: a1acc.id,
- a2_id: a2acc.id
- },
- { transaction }
- );
-
- order = order.get({ plain: true });
- order.rate = v2 / v1;
- order.a1 = a1;
- order.a2 = a2;
-
- broadcast("order", order);
- }
- });
-};
-
-const cancel = async (user, id) => {
- await db.transaction(async transaction => {
- let order = await db.Order.findOne(
- {
- where: {
- id,
- user_id: user.id
- },
- include: {
- model: db.Account,
- as: "acc1"
- }
- },
-
- { transaction }
- );
-
- let { acc1: account, v1, v2 } = order;
- await account.increment({ balance: v1 }, { transaction });
- await account.reload({ transaction });
-
- let rate = v2 / v1;
- let payment = await db.Payment.create(
- {
- hash: "Trade Cancelled",
- amount: v1,
- account_id: account.id,
- user_id: user.id,
- currency: user.currency,
- rate: store.rates[user.currency],
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
-
- emit(user.username, "account", account.get({ plain: true }));
- emit(user.username, "payment", payment.get({ plain: true }));
-
- if (order.fee) {
- const btc = await getAccount(config.liquid.btcasset, user, transaction);
-
- payment = await db.Payment.create(
- {
- hash: "Swap Fee Refund",
- amount: order.fee,
- account_id: btc.id,
- user_id: user.id,
- currency: user.currency,
- rate: store.rates[user.currency],
- confirmed: true,
- received: true,
- network: "COINOS"
- },
- { transaction }
- );
-
- await btc.increment({ balance: order.fee }, { transaction });
- await btc.reload({ transaction });
-
- emit(user.username, "account", btc.get({ plain: true }));
- emit(user.username, "payment", payment.get({ plain: true }));
- }
-
- broadcast("removeOrder", id);
- await order.destroy({ transaction });
- });
-};
-
-app.delete("/order/:id", auth, async (req, res) => {
- const { id } = req.params;
- const { user } = req;
-
- await cancel(user, id);
- res.send({});
-});
-
-app.post("/orders", auth, async (req, res) => {
- return res.code(500).send("Trading temporarily disabled");
- const { user } = req;
- try {
- await swap(user, req.body);
- res.send({});
- } catch (e) {
- err(req.user.username, e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.get("/orders", optionalAuth, async (req, res) => {
- try {
- let orders = await db.Order.findAll({
- attributes: {
- include: [
- [col("acc1.asset"), "a1"],
- [col("acc2.asset"), "a2"]
- ]
- },
- include: [
- {
- model: db.Account,
- as: "acc1",
- attributes: []
- },
- {
- model: db.Account,
- as: "acc2",
- attributes: []
- }
- ]
- });
-
- res.send(
- orders.map(order => {
- if (order.user_id !== req.user.id) order.user_id = null;
- return order;
- })
- );
- } catch (e) {
- res.code(500).send(e.message);
- }
-});
-
-if (config.maker) {
- debug("setup maker account...");
- config.maker.map(
- ({ amount, c1, c2, currency, askMultiplier, bidMultiplier }) => {
- setInterval(async () => {
- if (!rates) return;
-
- const user = await db.User.findOne({
- where: {
- username: "maker"
- }
- });
-
- if (!user) {
- debug("maker user not defined in database");
- } else {
- debug("maker: " + JSON.stringify(user));
- await db.transaction(async transaction => {
- let order = await db.Order.findOne(
- {
- where: {
- user_id: user.id,
- "$acc1.asset$": c1,
- "$acc2.asset$": c2,
- accepted: false
- },
- include: [
- {
- model: db.Account,
- as: "acc1"
- },
- {
- model: db.Account,
- as: "acc2"
- }
- ]
- },
- { transaction }
- );
-
- let params = {
- a1: c1,
- a2: c2,
- v1: amount * SATS,
- v2: Math.round(
- amount *
- SATS *
- (((app.get("ask") * store.rates[currency]) /
- store.rates["USD"]) *
- askMultiplier)
- )
- };
-
- if (order) {
- let bestBid = await db.Order.findOne(
- {
- where: {
- "$acc1.asset$": c2,
- "$acc2.asset$": c1,
- accepted: false,
- id: {
- [Op.ne]: order.id
- }
- },
- include: [
- {
- model: db.Account,
- as: "acc1"
- },
- {
- model: db.Account,
- as: "acc2"
- }
- ],
- order: [["rate", "DESC"]],
- limit: 1
- },
- { transaction }
- );
- if (
- !bestBid ||
- (params.v2 / params.v1 > bestBid.rate &&
- order.acc2.balance >= params.v2)
- ) {
- order.v1 = params.v1;
- order.v2 = params.v2;
- await order.save();
- order = order.get({ plain: true });
- order.a1 = params.a1;
- order.a2 = params.a2;
- order.rate = order.v2 / order.v1;
-
- broadcast("order", shallow(order));
- }
- } else {
- try {
- await swap(user, params);
- } catch (e) {
- warn("Failed to make ask", e.message);
- }
- }
-
- order = await db.Order.findOne(
- {
- where: {
- user_id: user.id,
- "$acc1.asset$": c2,
- "$acc2.asset$": c1,
- accepted: false
- },
- include: [
- {
- model: db.Account,
- as: "acc1"
- },
- {
- model: db.Account,
- as: "acc2"
- }
- ]
- },
- { transaction }
- );
-
- params = {
- a1: c2,
- a2: c1,
- v1: Math.round(
- amount *
- SATS *
- ((app.get("bid") * store.rates[currency]) /
- store.rates["USD"]) *
- bidMultiplier
- ),
- v2: amount * SATS
- };
-
- if (order) {
- let bestAsk = await db.Order.findOne(
- {
- where: {
- "$acc1.asset$": c1,
- "$acc2.asset$": c2,
- accepted: false,
- id: {
- [Op.ne]: order.id
- }
- },
- include: [
- {
- model: db.Account,
- as: "acc1"
- },
- {
- model: db.Account,
- as: "acc2"
- }
- ],
- order: [["rate", "ASC"]],
- limit: 1
- },
- transaction
- );
-
- if (bestAsk)
- if (
- !bestAsk ||
- (params.v1 / params.v2 < bestAsk.rate &&
- order.acc1.balance >= params.v1)
- ) {
- order.v1 = params.v1;
- order.v2 = params.v2;
- await order.save();
- order = order.get({ plain: true });
- order.a1 = params.a1;
- order.a2 = params.a2;
- order.rate = order.v2 / order.v1;
-
- broadcast("order", shallow(order));
- } else {
- broadcast("removeOrder", order.id);
- await order.destroy({ transaction });
- }
- } else {
- try {
- await swap(user, params);
- } catch (e) {
- warn("Failed to make bid", e.message);
- }
- }
- });
- }
- }, 5000);
- }
- );
-}
diff --git a/routes/tickets.js b/routes/tickets.js
deleted file mode 100644
index 7ca56740..00000000
--- a/routes/tickets.js
+++ /dev/null
@@ -1,22 +0,0 @@
-import app from "$app";
-import redis from "$lib/redis";
-import { auth } from "$lib/passport";
-
-app.get("/ticket", async (req, res) => {
- res.send({ ticket: await redis.lLen("tickets") });
-});
-
-app.get("/tickets", async (req, res) => {
- res.send(await redis.lRange("tickets", 0, -1));
-});
-
-app.post("/ticket", auth, async (req, res) => {
- try {
- let { asset } = req.body;
- if (!asset || asset.length !== 64) throw new Error("invalid asset");
-
- res.send(await redis.rPush("tickets", req.body.asset));
- } catch (e) {
- res.code(500).send(e.message);
- }
-});
diff --git a/routes/users.js b/routes/users.js
index 02e7e3ed..17d4e1da 100644
--- a/routes/users.js
+++ b/routes/users.js
@@ -1,693 +1,394 @@
-import app from "$app";
+import { g, s, db } from "$lib/db";
import config from "$config";
import store from "$lib/store";
-import { auth, optionalAuth } from "$lib/passport";
-import { getUser } from "$lib/utils";
-import axios from "axios";
+import { fields, nada, pick, uniq, wait } from "$lib/utils";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { authenticator } from "otplib";
-import getAccount from "$lib/account";
-import Sequelize from "@sequelize/core";
-import bitcoin from "bitcoinjs-lib";
-import liquid from "liquidjs-lib";
-import { fromBase58, fromPrivateKey } from "bip32";
-import { Mutex } from "async-mutex";
-import bip32 from "bip32";
import whitelist from "$lib/whitelist";
import { l, err, warn } from "$lib/logging";
-import db from "$db";
-import bc from "$lib/bitcoin";
-import lq from "$lib/liquid";
import { emit } from "$lib/sockets";
import register from "$lib/register";
import { requirePin } from "$lib/utils";
+import { v4 } from "uuid";
+import { parseISO } from "date-fns";
+import { types } from "$lib/payments";
-const pick = (O, ...K) => K.reduce((o, k) => ((o[k] = O[k]), o), {});
+import got from "got";
+import upload from "$lib/upload";
-app.get("/me", auth, async (req, res) => {
- try {
- let user = req.user.get({ plain: true });
- let payments = await req.user.getPayments({
- where: {
- account_id: user.account_id
- },
- order: [["id", "DESC"]],
- limit: 12,
- include: [
- {
- model: db.Account,
- as: "account"
- },
- {
- model: db.Payment,
- as: "fee_payment"
- }
- ]
- });
- user.accounts = await req.user.getAccounts();
- user.payments = payments;
- user.haspin = !!user.pin;
- res.send(pick(user, ...whitelist));
- } catch (e) {
- res.code(500).send(e.message);
- }
-});
+export default {
+ upload,
-app.get("/users/:username", async (req, res) => {
- const { username } = req.params;
+ async me({ user }, res) {
+ try {
+ user.balance = await g(`balance:${user.id}`);
+ user.prompt = !!user.prompt;
+ res.send(pick(user, whitelist));
+ } catch (e) {
+ console.log("problem fetching user", e);
+ res.code(500).send(e.message);
+ }
+ },
- const user = await db.User.findOne({
- attributes: ["username", "banner", "profile", "address", "currency"],
- where: Sequelize.where(
- Sequelize.fn("lower", Sequelize.col("username")),
- username.toLowerCase()
- )
- });
+ async get({ params: { key } }, res) {
+ try {
+ if (key.startsWith("npub")) {
+ try {
+ key = Buffer.from(fromWords(decode(key).words)).toString("hex");
+ } catch (e) {}
+ }
- if (user) res.send(user);
- else res.code(500).send("User not found");
-});
+ let user = await g(`user:${key}`);
+ if (typeof user === "string") {
+ user = await g(`user:${user}`);
+ }
-app.post("/register", async (req, res) => {
- try {
- const ip = req.headers["x-forwarded-for"] || req.connection.remoteAddress;
- const user = await register(req.body.user, ip, false);
- res.send(pick(user, ...whitelist));
- } catch (e) {
- res.code(500).send(e.message);
- }
-});
+ if (!user && key.length === 64) {
+ user = {
+ currency: "USD",
+ username: key,
+ display: key.substr(0, 6),
+ pubkey: key,
+ anon: true
+ };
+ }
-app.post("/disable2fa", auth, async (req, res) => {
- try {
- let {
- user,
- body: { token }
- } = req;
+ if (!user) return res.code(500).send("User not found");
- if (user.twofa && !authenticator.check(token, user.otpsecret)) {
+ let whitelist = [
+ "username",
+ "banner",
+ "profile",
+ "address",
+ "currency",
+ "pubkey",
+ "display",
+ "prompt",
+ "id"
+ ];
+
+ user.prompt = !!user.prompt;
+
+ res.send(pick(user, whitelist));
+ } catch (e) {
+ console.log(e);
+ res.code(500).send(e.message);
+ }
+ },
+
+ async create(req, res) {
+ try {
+ const ip = req.headers["x-forwarded-for"] || req.socket.remoteAddress;
+ let { cipher, pubkey, password, username, salt } = req.body.user;
+
+ let user = {
+ cipher,
+ pubkey,
+ password,
+ username,
+ salt
+ };
+
+ user = await register(user, ip, false);
+ l("registered new user", username);
+ res.send(pick(user, whitelist));
+ } catch (e) {
+ res.code(500).send(e.message);
+ }
+ },
+
+ async disable2fa({ user, body: { token } }, res) {
+ let { id, twofa, username, otpsecret } = user;
+ if (twofa && !authenticator.check(token, otpsecret)) {
return res.code(401).send("2fa required");
}
user.twofa = false;
- await user.save();
- emit(user.username, "user", user);
- emit(user.username, "otpsecret", user.otpsecret);
- l("disabled 2fa", user.username);
+ await s(`user:${id}`, user);
+ emit(username, "user", user);
+ emit(username, "otpsecret", user.otpsecret);
+ l("disabled 2fa", username);
res.send({});
- } catch (e) {
- res.code(500).send("Problem disabling 2fa");
- }
-});
+ },
-app.post("/2fa", auth, async (req, res) => {
- let { user } = req;
- try {
- const isValid = authenticator.check(req.body.token, req.user.otpsecret);
+ async enable2fa({ user, body: { token } }, res) {
+ let { id, otpsecret, username } = user;
+ const isValid = authenticator.check(token, otpsecret);
if (isValid) {
user.twofa = true;
- user.save();
- emit(user.username, "user", req.user);
+ await s(`user:${id}`, user);
+ emit(username, "user", user);
} else {
return res.code(500).send("Invalid token");
}
- } catch (e) {
- err("error setting up 2fa", e);
- }
- l("enabled 2fa", user.username);
- res.send({});
-});
-
-app.get("/exists", async (req, res) => {
- let exists = await db.User.findOne({
- where: { username: req.query.username }
- });
+ l("enabled 2fa", username);
+ res.send({});
+ },
- res.send(!!exists);
-});
+ async update({ user, body }, res) {
+ l("updating user", user.username);
-app.post("/user", auth, async (req, res) => {
- try {
- let { user } = req;
- let {
- address,
- confirm,
- currencies,
- currency,
- email,
- fiat,
- password,
- newpin,
- pin,
- seed,
- tokens,
- twofa,
- unit,
- username
- } = req.body;
+ let { confirm, password, pin, newpin, username } = body;
if (user.pin && !(pin === user.pin)) throw new Error("Pin required");
+ if (typeof newpin !== "undefined") user.pin = newpin;
+ if (!user.pin || user.pin === "undefined") delete user.pin;
- let exists = await db.User.findOne({
- where: { username }
- });
+ let exists;
+ if (username) exists = await g(`user:${username}`);
let token;
if (user.username !== username && exists) {
err("username taken", username, user.username, exists.username);
throw new Error("Username taken");
- } else {
- store.sockets[username] = store.sockets[user.username];
+ } else if (username) {
if (user.username !== username)
l("changing username", user.username, username);
user.username = username;
-
- token = jwt.sign({ username }, config.jwt);
- res.cookie("token", token, {
- expires: new Date(Date.now() + 432000000)
- });
}
- if (unit) user.unit = unit;
- user.currency = currency;
- user.currencies = currencies;
- user.pin = newpin;
- user.tokens = tokens;
- user.twofa = twofa;
- user.seed = seed;
- user.fiat = fiat;
- user.email = email;
- user.address = address;
+ let attributes = [
+ "address",
+ "cipher",
+ "currencies",
+ "currency",
+ "display",
+ "email",
+ "fiat",
+ "locktime",
+ "prompt",
+ "pubkey",
+ "salt",
+ "seed",
+ "tokens",
+ "twofa"
+ ];
+
+ for (let a of attributes) {
+ if (body[a]) user[a] = body[a];
+ }
if (password && password === confirm) {
user.password = await bcrypt.hash(password, 1);
}
- await user.save();
-
- user = user.get({ plain: true });
user.haspin = !!user.pin;
+ await s(`user:${user.id}`, user);
emit(user.username, "user", user);
res.send({ user, token });
- } catch (e) {
- err("error updating user", e.message);
- res.code(500).send(e.message);
- }
-});
-
-app.post("/keys", auth, async (req, res) => {
- const { key: hex } = req.body;
- const key = await db.Key.create({
- user_id: req.user.id,
- hex
- });
- emit(req.user.username, "key", key);
- res.send(key);
-});
-
-app.post("/keys/delete", auth, async (req, res) => {
- const { hex } = req.body;
- (
- await db.Key.findOne({
- where: {
- user_id: req.user.id,
- hex
- }
- })
- ).destroy();
-});
-
-app.post("/updateSeeds", auth, async (req, res) => {
- let { user } = req;
- let { seeds } = req.body;
- let keys = Object.keys(seeds);
-
- for (let i = 0; i < keys.length; i++) {
- let id = keys[i];
- let seed = seeds[id];
- await db.Account.update(
- { seed },
- {
- where: { id, user_id: user.id }
- }
- );
-
- const account = await db.Account.findOne({
- where: { id }
- });
-
- emit(user.username, "account", account);
- }
-
- res.send({});
-});
-
-app.post("/accounts/delete", auth, async (req, res) => {
- const { id } = req.body;
- const account = await db.Account.findOne({ where: { id } });
- if (account) await account.destroy();
- res.send({});
-});
-
-app.post("/accounts", auth, async (req, res) => {
- const {
- name,
- seed,
- pubkey,
- ticker,
- precision,
- path,
- privkey,
- network
- } = req.body;
- const { user } = req;
-
- let account = await db.Account.create({
- user_id: user.id,
- asset: config.liquid.btcasset,
- balance: 0,
- pending: 0,
- name,
- ticker,
- precision,
- pubkey,
- privkey,
- seed,
- path,
- network
- });
-
- emit(user.username, "account", account);
-
- if (pubkey) user.index++;
- user.account_id = account.id;
- await user.save();
- user.account = account;
- emit(user.username, "user", user);
-
- res.send(account);
-});
-
-let login = async (req, res) => {
- try {
- const { params, sig, key } = req.body;
-
- if (sig) {
- const { callback } = params;
-
- try {
- const url = `${callback}&sig=${sig}&key=${key}`;
- const response = await axios.get(url);
- res.send(response.data);
- } catch (e) {
- err("problem calling lnurl login", e.message);
- res.code(500).send(e.message);
- }
+ },
- return;
- }
+ async login(req, res) {
+ try {
+ const { username, password, token: twofa } = req.body;
+ l("logging in", username);
- let twofa = req.body.token;
+ let uid = await g(`user:${username}`);
+ let user = await g(`user:${uid}`);
- let user = await getUser(req.body.username);
+ if (!(user && user.migrated)) {
+ uid = user ? user.id : v4();
- if (
- !user ||
- (user.password &&
- !(await bcrypt.compare(req.body.password, user.password)))
- ) {
- warn("invalid username or password attempt", req.body.username);
- return res.code(401).send({});
- }
+ let { classic } = config;
+ try {
+ let { token } = await got
+ .post(`${classic}/login`, { json: { username, password } })
+ .json();
- if (
- user.twofa &&
- (typeof twofa === "undefined" ||
- !authenticator.check(twofa, user.otpsecret))
- ) {
- return res.code(401).send("2fa required");
- }
+ if (!token) fail();
- l(
- "login",
- req.body.username,
- req.headers["x-forwarded-for"] || req.connection.remoteAddress
- );
+ user = await got(`${classic}/admin/migrate/${username}?zero=true`, {
+ headers: { authorization: `Bearer ${config.admin}` }
+ }).json();
- let payload = { username: user.username };
- let token = jwt.sign(payload, config.jwt);
- res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
- user.accounts = await user.getAccounts();
- user.keys = await user.getKeys();
- user = pick(user, ...whitelist);
- res.send({ user, token });
- } catch (e) {
- err("login error", e.message, req.connection.remoteAddress);
- res.code(401).send({});
- }
-};
+ let { balance, pubkey } = user;
+ if (!user) fail();
-app.post("/login", login);
-app.post("/taboggan", login);
-app.post("/doggin", login);
+ uid = user.uuid;
-app.post("/logout", optionalAuth, async (req, res) => {
- let { subscription } = req.body;
- if (!subscription) return res.send({});
+ user = {
+ ...pick(user, fields),
+ id: uid,
+ about: user.address,
+ migrated: true
+ };
- const { username } = req.user;
+ await s(`user:${pubkey}`, uid);
+ await s(`user:${username}`, uid);
+ await s(`user:${uid}`, user);
+ await s(`balance:${uid}`, balance);
- if (username) {
- l("logging out", username);
- let i = req.user.subscriptions.findIndex(
- s => JSON.stringify(s) === subscription
- );
- if (i > -1) {
- req.user.subscriptions.splice(i, 1);
- }
- await req.user.save();
- Object.keys(logins).map(
- k => logins[k]["username"] === username && delete logins[k]
- );
- }
+ let payments = await got(`${classic}/payments`, {
+ headers: { authorization: `Bearer ${token}` }
+ }).json();
- res.send({});
-});
+ for (let p of payments) {
+ let n = pick(p, ["amount", "fee", "confirmed", "rate", "currency"]);
+ n.id = v4();
+ n.created = parseISO(p.createdAt).getTime();
+ n.type = p.network;
+ if (!["bitcoin", "lightning"].includes(n.type))
+ n.type = types.internal;
-app.post("/account", auth, async (req, res) => {
- const { user } = req;
- const {
- id,
- name,
- ticker,
- precision,
- domain,
- seed,
- pubkey,
- privkey,
- path,
- hide,
- index
- } = req.body;
+ if (n.type === types.internal) {
+ if (!p.with) continue;
- try {
- await db.transaction(async transaction => {
- let account = await db.Account.findOne({
- where: { id, user_id: user.id },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
+ let id = await g(`user:${p.with.username}`);
+ let u = id && (await g(`user:${id}`));
- let params = {
- name,
- ticker,
- precision,
- domain,
- seed,
- pubkey,
- path,
- hide,
- index,
- privkey
- };
+ if (!u) {
+ u = await got(`${classic}/admin/migrate/${p.with.username}`, {
+ headers: { authorization: `Bearer ${config.admin}` }
+ }).json();
- if (!account || (account.pubkey && !pubkey)) delete params.pubkey;
+ u = { id: u.uuid, about: u.address, ...pick(u, fields) };
+ delete u.address;
- await db.Account.update(params, {
- where: { id, user_id: user.id },
- transaction
- });
+ await s(`user:${u.pubkey}`, u.id);
+ await s(`user:${p.with.username}`, u.id);
+ await s(`user:${u.id}`, u);
- await account.reload({ transaction });
- emit(user.username, "account", account);
- res.send({});
- });
- } catch (e) {
- err("problem updating account", e.message);
- return res.code(500).send("There was a problem updating the account");
- }
-});
-
-app.post("/shiftAccount", auth, async (req, res) => {
- let { user } = req;
- let { id } = req.body;
+ l("added missing user", u.username);
+ }
- try {
- const account = await db.Account.findOne({
- where: { id }
- });
+ if (!(u && u.id)) continue;
+ n.ref = u.id;
+ }
- if (account.user_id !== user.id)
- return res.code(500).send("Failed to open wallet");
+ await s(`payment:${n.id}`, n);
+ await db.lPush(`${uid}:payments`, n.id);
+ }
- user.account_id = account.id;
- await user.save();
- let payments = await db.Payment.findAll({
- where: {
- account_id: id
- },
- order: [["id", "DESC"]],
- limit: 12,
- include: {
- model: db.Account,
- as: "account"
+ l("migrated user", user.username);
+ } catch (e) {
+ console.log(e);
+ }
}
- });
-
- user = user.get({ plain: true });
- user.payments = payments;
- user.account = account.get({ plain: true });
-
- emit(user.username, "account", user.account);
- emit(user.username, "user", user);
-
- res.send(user);
- } catch (e) {
- err("problem switching account", e.message);
- return res.code(500).send("There was a problem switching accounts");
- }
-});
-
-app.get("/vapidPublicKey", function(req, res) {
- res.send(config.vapid.publicKey);
-});
-
-app.post("/subscribe", auth, async function(req, res) {
- let { subscriptions } = req.user;
- let { subscription } = req.body;
- if (!subscriptions) subscriptions = [];
- if (
- !subscriptions.find(s => JSON.stringify(s) === JSON.stringify(subscription))
- )
- subscriptions.push(subscription);
- req.user.subscriptions = subscriptions;
- l("subscribing", req.user.username);
- await req.user.save();
- res.sendStatus(201);
-});
-
-let redeeming = {};
-app.post("/redeem", optionalAuth, async function(req, res) {
- const { redeemcode } = req.body;
- try {
- await db.transaction(async transaction => {
- if (redeeming[redeemcode]) fail("redemption in progress");
- redeeming[redeemcode] = true;
- if (!redeemcode) fail("no code provided");
-
- let { user } = req;
-
- const source = await db.Payment.findOne({
- where: {
- redeemcode: req.body.redeemcode
- },
- include: {
- model: db.Account,
- as: "account"
- },
- lock: transaction.LOCK.UPDATE,
- transaction
- });
- l("redeeming", redeemcode);
-
- if (!source) fail("Invalid code");
- if (source.redeemed) fail("Voucher has already been redeemed");
- let { amount } = source;
- amount = -amount;
-
- if (!user) {
- const ip =
- req.headers["x-forwarded-for"] || req.connection.remoteAddress;
-
- user = await register(
- {
- username: redeemcode.substr(0, 8),
- password: ""
- },
- ip,
- false
- );
-
- let payload = { username: user.username };
- let token = jwt.sign(payload, config.jwt);
- res.cookie("token", token, {
- expires: new Date(Date.now() + 432000000)
- });
-
- delete redeeming[redeemcode];
- return res.send({ user });
+ if (
+ !user ||
+ (user.password && !(await bcrypt.compare(password, user.password)))
+ ) {
+ warn("invalid username or password attempt", username);
+ return res.code(401).send({});
}
- let account = await getAccount(source.account.asset, user, transaction);
- let { hash, memo, confirmed, fee, network } = source;
-
- source.redeemed = true;
- await source.save({ transaction });
+ if (
+ user.twofa &&
+ (typeof twofa === "undefined" ||
+ !authenticator.check(twofa, user.otpsecret))
+ ) {
+ return res.code(401).send("2fa required");
+ }
- let payment = await db.Payment.create(
- {
- amount,
- account_id: account.id,
- user_id: user.id,
- hash: "Voucher " + redeemcode,
- memo,
- rate: store.rates[user.currency],
- currency: user.currency,
- confirmed,
- network,
- received: true,
- fee
- },
- { transaction }
+ l(
+ "login",
+ username,
+ req.headers["x-forwarded-for"] || req.socket.remoteAddress
);
- await account.increment({ balance: amount }, { transaction });
- await account.reload({ transaction });
-
- payment = payment.get({ plain: true });
- payment.account = account.get({ plain: true });
- emit(user.username, "payment", payment);
- emit(user.username, "account", account);
-
- res.send({ payment });
- });
- } catch (e) {
- delete redeeming[redeemcode];
- console.log(e);
- err("problem redeeming", e.message);
- return res.code(500).send("There was a problem redeeming the voucher");
- }
-});
+ let payload = { username, id: uid };
+ let token = jwt.sign(payload, config.jwt);
+ res.cookie("token", token, { expires: new Date(Date.now() + 432000000) });
+ user = pick(user, whitelist);
+ res.send({ user, token });
+ } catch (e) {
+ console.log(e);
+ err("login error", e.message, req.socket.remoteAddress);
+ res.code(401).send({});
+ }
+ },
-app.post("/checkRedeemCode", auth, async function(req, res) {
- const { redeemcode } = req.body;
+ async logout(req, res) {
+ let { subscription } = req.body;
+ if (!subscription) return res.send({});
- const payment = await db.Payment.findOne({ where: { redeemcode } });
- res.send(payment);
-});
+ const { username } = req.user;
-app.post("/password", auth, async function(req, res) {
- const { user } = req;
- const { password } = req.body;
+ if (username) {
+ l("logging out", username);
+ let i = req.user.subscriptions.findIndex(
+ s => JSON.stringify(s) === subscription
+ );
+ if (i > -1) {
+ req.user.subscriptions.splice(i, 1);
+ }
+ await req.user.save();
+ Object.keys(logins).map(
+ k => logins[k]["username"] === username && delete logins[k]
+ );
+ }
- if (!user.password) return res.send(true);
- res.send(await bcrypt.compare(password, user.password));
-});
+ res.send({});
+ },
-app.get("/isInternal", auth, async function(req, res) {
- let { user } = req;
- let { address } = req.query;
- if (!address) throw new Error("Address not provided");
+ async subscribe({ body, user }, res) {
+ let { subscriptions } = user;
+ let { subscription } = body;
+ if (!subscriptions) subscriptions = [];
+ if (
+ !subscriptions.find(
+ s => JSON.stringify(s) === JSON.stringify(subscription)
+ )
+ )
+ subscriptions.push(subscription);
+ user.subscriptions = subscriptions;
+ l("subscribing", user.username);
+ await user.save();
+ res.sendStatus(201);
+ },
- let invoice = await db.Invoice.findOne({
- where: { address },
- include: {
- attributes: ["username"],
- model: db.User,
- as: "user"
- }
- });
+ async password({ body: { password }, user }, res) {
+ if (!user.password) return res.send(true);
+ res.send(await bcrypt.compare(password, user.password));
+ },
- if (invoice) {
- let info;
+ async otpsecret(req, res) {
try {
- info = await bc.getAddressInfo(address);
+ await requirePin(req);
+ let { otpsecret, username } = req.user;
+ res.send({ secret: otpsecret, username });
} catch (e) {
- info = await lq.getAddressInfo(address);
+ res.code(500).send(e.message);
}
- if (info.ismine) {
- emit(user.username, "to", invoice.user);
- return res.send(true);
- }
- }
+ },
- res.send(false);
-});
+ async contacts({ user: { id } }, res) {
+ let i = (await g(`${id}:cindex`)) || 0;
+ let payments = (await db.lRange(`${id}:payments`, i, -1)) || [];
+ await db.incrBy(`${id}:cindex`, payments.length);
-app.get("/invoices", auth, async function(req, res) {
- let invoices = await db.Invoice.findAll({
- where: { user_id: req.user.id }
- });
- res.send(invoices);
-});
+ let contacts = (await g(`${id}:contacts`)) || [];
-app.post("/signMessage", auth, async function(req, res) {
- let { address, message } = req.body;
+ for (let { ref } of (
+ await Promise.all(payments.map(async id => await g(`payment:${id}`)))
+ ).filter(p => p.type === types.internal && p.ref)) {
+ !~contacts.findIndex(({ id }) => id === ref) &&
+ contacts.push(await g(`user:${ref}`));
+ }
- let invoices = await db.Invoice.findAll({
- where: { user_id: req.user.id }
- });
+ await s(`${id}:contacts`, contacts);
- if (invoices.find(i => i.address === address)) {
- if (config.bitcoin.walletpass)
- await bc.walletPassphrase(config.bitcoin.walletpass, 300);
- return res.send(await bc.signMessage(address, message));
- }
+ res.send(contacts);
+ },
- res.code(500).send("Address not found for user");
-});
+ async del({ params: { username }, headers: { authorization } }, res) {
+ if (!(authorization && authorization.includes(config.admin)))
+ return res.code(401).send("unauthorized");
-app.post("/otpsecret", auth, async function(req, res) {
- try {
- await requirePin(req);
- let { otpsecret } = req.user;
- res.send({ secret: otpsecret });
- } catch (e) {
- res.code(500).send(e.message);
- }
-});
+ let { id, pubkey } = await g(`user:${await g(`user:${username}`)}`);
+ let invoices = await db.lRange(`${id}:invoices`, 0, -1);
+ let payments = await db.lRange(`${id}:payments`, 0, -1);
-app.get("/contacts", auth, async function(req, res) {
- try {
- let contacts = await db.Payment.findAll({
- where: {
- user_id: req.user.id,
- with_id: { [Sequelize.Op.ne]: null }
- },
- include: {
- attributes: ["username", "profile"],
- model: db.User,
- as: "with"
- },
- attributes: [
- [Sequelize.fn("max", Sequelize.col("payments_model.createdAt")), "last"]
- ],
- group: ["with_id"],
- order: [[{ model: db.User, as: "with" }, "username", "ASC"]]
- });
+ for (let { id } of invoices) db.del(`invoice:${id}`);
+ for (let { id } of payments) db.del(`payment:${id}`);
+ db.del(`user:${username}`);
+ db.del(`user:${id}`);
+ db.del(`user:${pubkey}`);
- res.send(
- contacts.map(c => {
- c = c.get({ plain: true });
- return { ...c.with, last: c.last };
- })
- );
- } catch (e) {
- console.log(e);
- res.code(500).send(e.message);
+ res.send({});
}
-});
+};
diff --git a/sampleconfig.js b/sampleconfig.js
new file mode 100644
index 00000000..9284866a
--- /dev/null
+++ b/sampleconfig.js
@@ -0,0 +1,22 @@
+export default {
+ db: "redis://db",
+ nostr: "ws://nostr:8080",
+ relays: [
+ "ws://nostr:8080",
+ "wss://nostr-pub.wellorder.net",
+ "wss://brb.io",
+ "wss://nostr.v0l.io",
+ "wss://relay.nostr.bg",
+ "wss://nostr.orangepill.dev"
+ ],
+ jwt: "00d0ab4f7738a83feb37f661526512063c41e49278b7c32cba87314269a5788b",
+ bitcoin: {
+ host: "bc",
+ wallet: "coinos",
+ username: "admin1",
+ password: "123",
+ network: "regtest",
+ port: 18443,
+ },
+ lightning: "/app/data/lightning/regtest/lightning-rpc"
+};
diff --git a/sampleconfig/certbot/.gitkeep b/sampleconfig/certbot/.gitkeep
deleted file mode 100644
index 8b137891..00000000
--- a/sampleconfig/certbot/.gitkeep
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/sampleconfig/index.js b/sampleconfig/index.js
deleted file mode 100644
index b45e9baa..00000000
--- a/sampleconfig/index.js
+++ /dev/null
@@ -1,78 +0,0 @@
-import lnurl from "./lnurl";
-
-const db = {
- user: "root",
- password: "password",
- database: "coinos",
- options: {
- logging: false,
- host: "maria",
- dialect: "mariadb",
- dialectOptions: { multipleStatements: true, timezone: "Etc/GMT+7" }
- }
-};
-
-const btcasset =
- "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225";
-
-export default {
- ipxapi: "4275|PqKjKaxIlzooToria2m4XFLzvHihSpsZMX4hvgxu",
- webhooks: {
- "http://172.18.0.1:5173/wallet/purchase": "horsey"
- },
- postmark: "d64dffd2-84ea-47c7-ba9f-95505332d0ae",
- db,
- clientVersion: "3b96359d6a6ce68fe4a32f495fc9a6f78af0aa63",
- lnurl,
- knex: {
- client: "mysql2",
- connection: db
- },
- jwt: Buffer.from(
- "00d0ab4f7738a83feb37f661526512063c41e49278b7c32cba87314269a5788b",
- "hex"
- ),
- port: 3119,
- taxi: "864234bccdd230ecb6db05ebdf5061c3af42fefb9f186b3326e6454fdd3a9475",
- bitcoin: {
- masterkey:
- "tprv8ZgxMBicQKsPdTUoagV41nang9pQUA2DKoVWLmTrWmb2PfsC8pDTHveCMyzUyMguKJCjd5uyHcqg27r7gDzz4TY3MgucpLsSXwCbjn2C3Q1",
- host: "bitcoin",
- wallet: "coinos",
- username: "admin1",
- password: "123",
- network: "regtest",
- port: 18443,
- zmqrawblock: "tcp://bitcoin:18506",
- zmqrawtx: "tcp://bitcoin:18507"
- },
- liquid: {
- masterkey:
- "tprv8ZgxMBicQKsPfBjZp16yQUmZM3DWh5fb366inBXF3Xk6ANhJYqxXYL4FeQxAW5kjT3ku1A1wmS79c5y6RajKr2TkCADG8A3h4WdggbFMXX1",
- blindkey:
- "099e599b1d79dbc536c6f8461772d7f2f9583d7b6f3fba70394d60b599c3bd96",
- host: "liquid",
- username: "admin1",
- password: "123",
- network: "regtest",
- wallet: "coinos",
- port: 7040,
- zmqrawblock: "tcp://liquid:18606",
- zmqrawtx: "tcp://liquid:18607",
- btcasset
- },
- lna: {
- clightning: true,
- dir: "/app/config/lightning/regtest/lightning-rpc"
- /*
- lnd: true
- socket: "lnd:10009",
- // get this with: sudo base64 config/lnd/tls.cert | tr -d '\n'
- cert:
- "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNLVENDQWMrZ0F3SUJBZ0lRVE4wWEhJdTI1eitKaUpmVUxSOTROVEFLQmdncWhrak9QUVFEQWpBNE1SOHcKSFFZRFZRUUtFeFpzYm1RZ1lYVjBiMmRsYm1WeVlYUmxaQ0JqWlhKME1SVXdFd1lEVlFRREV3d3haREkyWVRkagpObUZqTVRZd0hoY05Nakl3TlRFMU1qSTFOVFEyV2hjTk1qTXdOekV3TWpJMU5UUTJXakE0TVI4d0hRWURWUVFLCkV4WnNibVFnWVhWMGIyZGxibVZ5WVhSbFpDQmpaWEowTVJVd0V3WURWUVFERXd3eFpESTJZVGRqTm1Gak1UWXcKV1RBVEJnY3Foa2pPUFFJQkJnZ3Foa2pPUFFNQkJ3TkNBQVFjdzRtR0lNbEpkTWsvT2pEWkJ6U21HTm5kY3pQZgphSGlCQytqd0F5RVBnOUhqY3o2MlhYSXdxcTFiV2xmOGtuck5lamg2cm5zQTgrYkNOWTBkNFlxRW80RzZNSUczCk1BNEdBMVVkRHdFQi93UUVBd0lDcERBVEJnTlZIU1VFRERBS0JnZ3JCZ0VGQlFjREFUQVBCZ05WSFJNQkFmOEUKQlRBREFRSC9NQjBHQTFVZERnUVdCQlNZTmx4NTBXU2VIN0VTSTZ2eVJCL2JNMG01QmpCZ0JnTlZIUkVFV1RCWApnZ3d4WkRJMllUZGpObUZqTVRhQ0NXeHZZMkZzYUc5emRJSURiRzVrZ2dSMWJtbDRnZ3AxYm1sNGNHRmphMlYwCmdnZGlkV1pqYjI1dWh3Ui9BQUFCaHhBQUFBQUFBQUFBQUFBQUFBQUFBQUFCaHdTc0VnQUhNQW9HQ0NxR1NNNDkKQkFNQ0EwZ0FNRVVDSUU5M3hBWEFxQzBuejdqRWVXWVN3czB2dlZWZmcvSEFNYnNLSzVXMFFNMCtBaUVBME5EVgpOV0VVdU9Vdk4ydTZ0UjBpRFh3dXhPMmJtTDltVEZwejhHc3RUKzA9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
- // get this with: sudo base64 config/lnd/data/chain/bitcoin/regtest/admin.macaroon | tr -d '\n'
- macaroon:
- "AgEDbG5kAvgBAwoQFdsmSt7tRRKg8kFR+avH0BIBMBoWCgdhZGRyZXNzEgRyZWFkEgV3cml0ZRoTCgRpbmZvEgRyZWFkEgV3cml0ZRoXCghpbnZvaWNlcxIEcmVhZBIFd3JpdGUaIQoIbWFjYXJvb24SCGdlbmVyYXRlEgRyZWFkEgV3cml0ZRoWCgdtZXNzYWdlEgRyZWFkEgV3cml0ZRoXCghvZmZjaGFpbhIEcmVhZBIFd3JpdGUaFgoHb25jaGFpbhIEcmVhZBIFd3JpdGUaFAoFcGVlcnMSBHJlYWQSBXdyaXRlGhgKBnNpZ25lchIIZ2VuZXJhdGUSBHJlYWQAAAYgR93/t3TVABMMqjYOdcYG/B70ZczhSoLXVT7NlocedG0="
- */
- }
-};
diff --git a/sampleconfig/liquid/elements.conf b/sampleconfig/liquid/elements.conf
deleted file mode 100644
index 08b60dd6..00000000
--- a/sampleconfig/liquid/elements.conf
+++ /dev/null
@@ -1,17 +0,0 @@
-chain=liquidregtest
-listen=1
-txindex=1
-
-[liquidregtest]
-rpcuser=admin1
-rpcpassword=123
-rpcbind=0.0.0.0
-rpcallowip=0.0.0.0/0
-rpcwallet=coinos
-
-validatepegin=0
-initialfreecoins=2100000000000000
-wallet=coinos
-
-zmqpubrawblock=tcp://0.0.0.0:18606
-zmqpubrawtx=tcp://0.0.0.0:18607
diff --git a/sampleconfig/lnd/lnd.conf b/sampleconfig/lnd/lnd.conf
deleted file mode 100644
index a979284a..00000000
--- a/sampleconfig/lnd/lnd.conf
+++ /dev/null
@@ -1,25 +0,0 @@
-externalip=lnd:9735
-alias=coinos
-color=#FF3200
-tlsextradomain=lnd
-listen=0.0.0.0:9735
-rpclisten=0.0.0.0:10009
-restlisten=0.0.0.0:8080
-accept-amp=1
-accept-keysend=1
-
-# uncomment this after lnd wallet is initialized
-# wallet-unlock-password-file=/root/.lnd/pwd
-
-[Bitcoin]
-bitcoin.active=1
-bitcoin.node=bitcoind
-bitcoin.regtest=1
-
-[Bitcoind]
-bitcoind.rpchost=bitcoin
-bitcoind.dir=/root/.bitcoin
-bitcoind.rpcuser=admin1
-bitcoind.rpcpass=123
-bitcoind.zmqpubrawblock=tcp://bitcoin:18506
-bitcoind.zmqpubrawtx=tcp://bitcoin:18507
diff --git a/sampleconfig/lnd/pwd b/sampleconfig/lnd/pwd
deleted file mode 100644
index f3097ab1..00000000
--- a/sampleconfig/lnd/pwd
+++ /dev/null
@@ -1 +0,0 @@
-password
diff --git a/sampleconfig/lnurl.js b/sampleconfig/lnurl.js
deleted file mode 100644
index b101e23c..00000000
--- a/sampleconfig/lnurl.js
+++ /dev/null
@@ -1,36 +0,0 @@
-import fs from "fs";
-
-export default {
- host: "app",
- port: 3118,
- protocol: "http",
- url: "https://staging.coinos.io",
- endpoint: "/lnurl",
- listen: true,
- auth: {
- apiKeys: [
- {
- id: "50bdeb634d",
- key: "ac9bdd15a983072311c74c13877d122f16a27a8f40cb4dfa5014eece4da5cda2"
- }
- ]
- },
- lightning: {
- backend: "c-lightning",
- config: {
- unixSockPath: "/app/config/lightning/regtest/lightning-rpc"
- }
- },
- store: {
- backend: "knex",
- config: {
- client: "mysql",
- connection: {
- host: "maria",
- user: "root",
- password: "password",
- database: "coinos"
- }
- }
- }
-};
diff --git a/sampleconfig/nginx/default.conf.template b/sampleconfig/nginx/default.conf.template
deleted file mode 100644
index 453f368f..00000000
--- a/sampleconfig/nginx/default.conf.template
+++ /dev/null
@@ -1,38 +0,0 @@
-server {
- listen 80;
- server_name .${NGINX_HOST};
- server_tokens off;
-
- location @rewrites {
- rewrite ^(.+)$ /index.html last;
- }
-
- location / {
- root /coinos;
- index index.html;
- try_files $uri $uri/ /index.html;
- }
-
- location /api/ {
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-Proto https;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Host $remote_addr;
- rewrite ^ $request_uri?;
- rewrite ^/api/(.*) /$1 break;
- return 400;
- proxy_pass http://app:3119$uri$is_args;
- }
-
- location /ws {
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_http_version 1.1;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header Host $host;
- rewrite ^/ws/(.*) /$1 break;
-
- proxy_pass http://app:3119;
- }
-}
diff --git a/sampleconfig/bitcoin/bitcoin.conf b/sampledata/bitcoin/bitcoin.conf
index 16ff8e91..3aa44186 100644
--- a/sampleconfig/bitcoin/bitcoin.conf
+++ b/sampledata/bitcoin/bitcoin.conf
@@ -15,6 +15,8 @@ rpcbind=0.0.0.0
rpcwallet=coinos
wallet=coinos
+wallet=external
+walletnotify=/home/bitcoin/.bitcoin/transaction.sh %s %w
zmqpubrawblock=tcp://0.0.0.0:18506
zmqpubrawtx=tcp://0.0.0.0:18507
diff --git a/sampledata/bitcoin/transaction.sh b/sampledata/bitcoin/transaction.sh
new file mode 100755
index 00000000..e44789d1
--- /dev/null
+++ b/sampledata/bitcoin/transaction.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+wget -O- --post-data='{"txid": "'$1'", "wallet": "'$2'"}' --header='Content-Type:application/json' 'http://app:3119/bitcoin'
diff --git a/sampledata/conversions.json b/sampledata/conversions.json
deleted file mode 100644
index 2c63c085..00000000
--- a/sampledata/conversions.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
diff --git a/sampledata/emails.json b/sampledata/emails.json
deleted file mode 100644
index 5fbac846..00000000
--- a/sampledata/emails.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "emails": [
- ]
-}
diff --git a/sampledata/index.js b/sampledata/index.js
new file mode 100644
index 00000000..8fcb0a6f
--- /dev/null
+++ b/sampledata/index.js
@@ -0,0 +1,16 @@
+export default {
+ port: 3119,
+ nostr: "ws://nostr:8080",
+ ipxapi: "4275|PqKjKaxIlzooToria2m4XFLzvHihSpsZMX4hvgxu",
+ postmark: "f64dffd2-84ea-47c7-ba9f-95e053a2d0ae",
+ jwt: "00d0ab4f7738a83feb37f661526512063c41e49278b7c32cba87314269a5788b",
+ bitcoin: {
+ host: "bitcoin",
+ wallet: "coinos",
+ username: "admin1",
+ password: "123",
+ network: "regtest",
+ port: 18443
+ },
+ lightning: "/app/config/lightning/regtest/lightning-rpc"
+};
diff --git a/sampleconfig/lightning/config b/sampledata/lightning/config
index 9ac922ba..9ac922ba 100644
--- a/sampleconfig/lightning/config
+++ b/sampledata/lightning/config
diff --git a/sampledata/logins.json b/sampledata/logins.json
deleted file mode 100644
index 0967ef42..00000000
--- a/sampledata/logins.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/sampledata/payments.json b/sampledata/payments.json
deleted file mode 100644
index 2c63c085..00000000
--- a/sampledata/payments.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
diff --git a/sampledata/recipients.json b/sampledata/recipients.json
deleted file mode 100644
index 2c63c085..00000000
--- a/sampledata/recipients.json
+++ /dev/null
@@ -1,2 +0,0 @@
-{
-}
diff --git a/sampledata/withdrawals.json b/sampledata/withdrawals.json
deleted file mode 100644
index 0967ef42..00000000
--- a/sampledata/withdrawals.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/scripts/apiParse.js b/scripts/apiParse.js
deleted file mode 100644
index ec2a33c1..00000000
--- a/scripts/apiParse.js
+++ /dev/null
@@ -1,46 +0,0 @@
-export const addUserSearch = function(input, table) {
- var { search, starts_with, contains } = input;
-
- if (!table) {
- table = "users";
- }
- // if (since) cmd = cmd.havingRaw('invoices + payments + deposits + orders > ?', [0])
-
- if (search) {
- if (starts_with) {
- search = search + "%";
- } else if (contains) {
- search = "%" + search + "%";
- }
-
- var condition =
- "(" +
- table +
- ".email like '" +
- search +
- "' OR " +
- table +
- ".username like '" +
- search +
- "')";
-
- return condition;
- } else {
- return "";
- }
-};
-
-export const addTimeSearch = function(input, field) {
- if (!field) {
- field = "updatedAt";
- }
-
- var { since } = input;
- if (since) {
- condition = field + " >= '" + since + "'";
-
- return condition;
- } else {
- return "";
- }
-};
diff --git a/scripts/check.js b/scripts/check.js
deleted file mode 100644
index e86940da..00000000
--- a/scripts/check.js
+++ /dev/null
@@ -1,24 +0,0 @@
-let config = require("./config");
-let fs = require("fs");
-
-let mailgun = require("mailgun-js")({
- apiKey: config.mailgun,
- domain: config.domain
-});
-
-let data = {
- ...config.mail,
- subject: "User Documents",
- text: "Documents uploaded"
-};
-
-fs.readdir("./uploads", (err, files) => {
- files.forEach(file => {
- console.log(file);
- data.text = file;
- fs.rename(file, "../verified" + file);
- mailgun.messages().send(data, function(error, body) {
- console.log(body);
- });
- });
-});
diff --git a/scripts/purge-except-git.sh b/scripts/purge-except-git.sh
deleted file mode 100755
index 066b082f..00000000
--- a/scripts/purge-except-git.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-# purge coinos-ui and coinos-server
-# ie- fresh install/clean working dirs but without the clone -
-# useful for local dev when you have stashed changes or branches
-# you don't want to destroy
-
-# start script from coinos-server/scripts ie:
-# $ cd /var/node/coinos-server/scripts
-# $ ./purge-except-git.sh
-
-# you may have to run it with sudo to remove the directories created by docker
-
-# and now the script will move up a dir and do its thing:
-cd ../
-
-# if you have docker-compose process running
-docker-compose down
-
-#purge:
-rm -rf config
-rm -rf mysql
-rm -rf node_modules
-rm .env
-rm fx
-rm docker-compose.override.yml
-
-#also on ui:
-cd ../coinos-ui
-rm -rf node_modules
-
-# (and then follow instructions in root README to rebuild/install)
diff --git a/secret b/secret
deleted file mode 100644
index e69de29b..00000000
--- a/secret
+++ /dev/null
diff --git a/setup.sh b/setup.sh
new file mode 100644
index 00000000..c3e58161
--- /dev/null
+++ b/setup.sh
@@ -0,0 +1,7 @@
+cp sampleconfig.js config.js
+cp -r sampledata data
+docker compose up -d
+docker run -it -v $(pwd):/app --entrypoint pnpm cs i
+docker exec -it bc bitcoin-cli createwallet coinos
+docker exec -it bc bitcoin-cli rescanblockchain
+docker exec -it bc bitcoin-cli generatetoaddress 500 $(docker exec -it bitcoin bitcoin-cli getnewaddress "" "p2sh-segwit")